You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:41:16