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

XSLT实现按Sfromlocation/Stolocation组合键分组XML元素

XSLT 2.0 自定义键分组合并实现方案

核心规则对齐

  • 处理范围:仅操作CISDocument/Entity/Load路径下的BaseShipmentModule节点,以节点内ShipUnitModule子节点的Sfromlocation+Stolocation组合值为分组键,同组节点合并为单个BaseShipmentModule
  • 合并逻辑:同组内所有Shnum、Container节点统一归集到同一个ShipUnitModule下,Sfromlocation、Stolocation仅保留组内唯一值
  • 保留要求:除上述待合并节点外,其余所有节点(Aheader、ResponseHeader、Page公共节点,Load下的LID、ccode等基础字段,全部S1节点)完整保留原有结构、顺序、内容,不受分组逻辑影响

可直接使用的实现代码

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 身份模板:默认复制所有节点、属性、文本内容,保证非目标节点无改动 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 匹配Load节点,处理分组逻辑,严格保留原有子节点顺序 -->
  <xsl:template match="CISDocument/Entity/Load">
    <xsl:copy>
      <!-- 预分组所有BaseShipmentModule,生成合并后的节点内容 -->
      <xsl:variable name="shipmentGroups">
        <xsl:for-each-group select="BaseShipmentModule" 
                            group-by="concat(ShipUnitModule/Sfromlocation, '||', ShipUnitModule/Stolocation)">
          <group first-node-id="{generate-id(current-group()[1])}">
            <merged-content>
              <BaseShipmentModule>
                <ShipUnitModule>
                  <xsl:copy-of select="ShipUnitModule/Sfromlocation[1],
                                       ShipUnitModule/Stolocation[1],
                                       current-group()/ShipUnitModule/Shnum,
                                       current-group()/ShipUnitModule/Container"/>
                </ShipUnitModule>
              </BaseShipmentModule>
            </merged-content>
          </group>
        </xsl:for-each-group>
      </xsl:variable>

      <!-- 按原顺序遍历Load下所有子节点、属性 -->
      <xsl:for-each select="@*|node()">
        <!-- 非BaseShipmentModule节点直接按原规则复制 -->
        <xsl:apply-templates select=".[not(self::BaseShipmentModule)]"/>
        <!-- BaseShipmentModule节点仅在为分组首节点时输出合并内容,其余同组节点跳过 -->
        <xsl:if test="self::BaseShipmentModule">
          <xsl:variable name="currentNodeId" select="generate-id(.)"/>
          <xsl:copy-of select="$shipmentGroups/group[@first-node-id = $currentNodeId]/merged-content/BaseShipmentModule"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

实现说明

  • 采用身份模板作为默认处理逻辑,从根源避免非目标节点丢失、属性丢失、结构错乱问题
  • 分组时使用||作为拼接分隔符,避免两个字段值直接拼接导致的键值冲突(如Sfromlocation="A"、Stolocation="BC"和Sfromlocation="AB"、Stolocation="C"不会被误判为同组)
  • 遍历Load子节点时严格遵循输入XML的原始顺序,即便是穿插在BaseShipmentModule之间的S1节点、其他基础字段也不会被移位,完全满足顺序保留要求
  • 同组的Sfromlocation、Stolocation取组内首节点值即可,同组这两个字段值完全一致,符合唯一值保留要求

运行注意事项

  • 本代码遵循XSLT 2.0标准,需在支持XSLT 2.0的解析器上运行(如Saxon-HE 9.x及以上版本),无法直接在仅支持XSLT 1.0的环境中使用
  • 若ShipUnitModule下存在除Sfromlocation、Stolocation、Shnum、Container外其他需要归集的字段,只需修改ShipUnitModule标签内xsl:copy-of的节点选择路径,补充对应字段即可

内容的提问来源于stack exchange,提问作者Manju Kaushik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:48:29