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

XSLT中TripOverview内DropItem分组异常求助

XSLT分组问题:在独立TripOverview内分组DropItem元素

问题背景

需要对XML中每个TripOverview内部的DropItem元素进行分组,但当前XSLT实现未按预期生成分组结果,怀疑是key的层级设置有误。


输入XML示例

<MultiTripOverview>
  <TripOverview>
    <HeaderDetails>
      <DropItems>
        <DropItem>
          <GroupId>G1</GroupId>
          <ItemName>Item1</ItemName>
        </DropItem>
        <DropItem>
          <GroupId>G1</GroupId>
          <ItemName>Item2</ItemName>
        </DropItem>
        <DropItem>
          <GroupId>G2</GroupId>
          <ItemName>Item3</ItemName>
        </DropItem>
      </DropItems>
    </HeaderDetails>
  </TripOverview>
  <TripOverview>
    <HeaderDetails>
      <DropItems>
        <DropItem>
          <GroupId>G1</GroupId>
          <ItemName>ItemA</ItemName>
        </DropItem>
        <DropItem>
          <GroupId>G2</GroupId>
          <ItemName>ItemB</ItemName>
        </DropItem>
      </DropItems>
    </HeaderDetails>
  </TripOverview>
</MultiTripOverview>

当前XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="dropItemGroup" match="DropItem" use="GroupId"/>

  <xsl:template match="/MultiTripOverview">
    <Output>
      <xsl:apply-templates select="TripOverview"/>
    </Output>
  </xsl:template>

  <xsl:template match="TripOverview">
    <Trip>
      <xsl:for-each select="HeaderDetails/DropItems/DropItem[generate-id() = generate-id(key('dropItemGroup', GroupId)[1])]">
        <Group groupId="{GroupId}">
          <xsl:for-each select="key('dropItemGroup', GroupId)">
            <Item>
              <xsl:value-of select="ItemName"/>
            </Item>
          </xsl:for-each>
        </Group>
      </xsl:for-each>
    </Trip>
  </xsl:template>
</xsl:stylesheet>

当前输出(不符合预期)

<Output>
  <Trip>
    <Group groupId="G1">
      <Item>Item1</Item>
      <Item>Item2</Item>
      <Item>ItemA</Item> <!-- 错误:来自第二个TripOverview的元素被混入 -->
    </Group>
    <Group groupId="G2">
      <Item>Item3</Item>
      <Item>ItemB</Item> <!-- 错误:来自第二个TripOverview的元素被混入 -->
    </Group>
  </Trip>
  <Trip>
    <!-- 没有生成分组,因为key已经匹配过所有同GroupId的元素 -->
  </Trip>
</Output>

期望输出

<Output>
  <Trip>
    <Group groupId="G1">
      <Item>Item1</Item>
      <Item>Item2</Item>
    </Group>
    <Group groupId="G2">
      <Item>Item3</Item>
    </Group>
  </Trip>
  <Trip>
    <Group groupId="G1">
      <Item>ItemA</Item>
    </Group>
    <Group groupId="G2">
      <Item>ItemB</Item>
    </Group>
  </Trip>
</Output>

问题排查与修正方案

核心问题

当前定义的dropItemGroup key仅以GroupId为分组依据,没有限定在当前TripOverview的上下文内,导致所有TripOverview中的同GroupId元素被归为一组,跨TripOverview的元素被错误混入。

修正步骤

  1. 修改key的use属性:将分组依据改为当前TripOverview的唯一标识 + GroupId,确保分组范围限定在单个TripOverview内部。
  2. 同步修改for-each中的key调用:使用相同的组合键进行匹配。

修正后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 用TripOverview的generate-id + GroupId作为组合键,限定分组范围 -->
  <xsl:key name="dropItemGroup" match="DropItem" use="concat(generate-id(ancestor::TripOverview), '|', GroupId)"/>

  <xsl:template match="/MultiTripOverview">
    <Output>
      <xsl:apply-templates select="TripOverview"/>
    </Output>
  </xsl:template>

  <xsl:template match="TripOverview">
    <Trip>
      <xsl:variable name="currentTripId" select="generate-id()"/>
      <!-- 筛选当前TripOverview内的首个同组DropItem -->
      <xsl:for-each select="HeaderDetails/DropItems/DropItem[generate-id() = generate-id(key('dropItemGroup', concat($currentTripId, '|', GroupId))[1])]">
        <Group groupId="{GroupId}">
          <!-- 仅匹配当前TripOverview内的同组DropItem -->
          <xsl:for-each select="key('dropItemGroup', concat($currentTripId, '|', GroupId))">
            <Item>
              <xsl:value-of select="ItemName"/>
            </Item>
          </xsl:for-each>
        </Group>
      </xsl:for-each>
    </Trip>
  </xsl:template>
</xsl:stylesheet>

说明

  • 组合键concat(generate-id(ancestor::TripOverview), '|', GroupId)保证了每个TripOverview内的DropItem分组独立,不会跨TripOverview干扰。
  • 定义currentTripId变量复用当前TripOverview的唯一标识,提升代码可读性。

内容的提问来源于stack exchange,提问作者Mike Dole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:00:30