如何用<xsl:for-each>提取PlanDetail中唯一的Number对应Description值?
如何用
<xsl:for-each>提取每个Number对应的首个PlanDetail的Description(去重) 问题场景
需要从多个PlanDetail节点中提取Description值,但要求每个Number只取对应的首个PlanDetail条目,避免重复输出。
输入XML示例
<Root> <Plan> <Number>PLAN001</Number> <PlanDetail> <Description>基础套餐</Description> </PlanDetail> <PlanDetail> <Description>升级套餐</Description> </PlanDetail> </Plan> <Plan> <Number>PLAN002</Number> <PlanDetail> <Description>标准套餐</Description> </PlanDetail> </Plan> <Plan> <Number>PLAN001</Number> <PlanDetail> <Description>基础套餐</Description> </PlanDetail> </Plan> </Root>
现有XSLT代码(导致重复输出)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <xsl:for-each select="Root/Plan/PlanDetail"> <p> <xsl:value-of select="../Number"/> - <xsl:value-of select="Description"/> </p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
当前重复输出结果
PLAN001 - 基础套餐 PLAN001 - 升级套餐 PLAN002 - 标准套餐 PLAN001 - 基础套餐
期望的唯一输出结果
PLAN001 - 基础套餐 PLAN002 - 标准套餐
修正后的XSLT方案
方案1:XSLT 1.0(Muenchian分组,兼容旧版处理器)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义分组键:以Number的值作为去重依据 --> <xsl:key name="planGroup" match="Plan" use="Number"/> <xsl:template match="/"> <html> <body> <!-- 遍历每个唯一Number对应的首个Plan节点 --> <xsl:for-each select="Root/Plan[generate-id() = generate-id(key('planGroup', Number)[1])]"> <p> <!-- 提取当前Number及对应的首个PlanDetail的Description --> <xsl:value-of select="Number"/> - <xsl:value-of select="PlanDetail[1]/Description"/> </p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
方案2:XSLT 2.0+(原生分组,语法更简洁)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <!-- 按Number分组,每组取第一个Plan的首个PlanDetail --> <xsl:for-each-group select="Root/Plan" group-by="Number"> <p> <xsl:value-of select="current-grouping-key()"/> - <xsl:value-of select="current-group()[1]/PlanDetail[1]/Description"/> </p> </xsl:for-each-group> </body> </html> </xsl:template> </xsl:stylesheet>
核心逻辑说明
- XSLT 1.0:利用Muenchian分组技术,通过
<xsl:key>定义分组规则,筛选出每个Number对应的第一个Plan节点,再提取该节点下的首个PlanDetail内容,实现去重。 - XSLT 2.0+:使用原生的
<xsl:for-each-group>语法,直接按Number分组后,取每组第一个元素的首个PlanDetail,代码更直观易读。
内容的提问来源于stack exchange,提问作者User501
相关产品推荐
相关产品推荐

