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

使用XSLT按同值字段分组XML标签并聚合子节点求助

XSLT按双字段组合分组聚合XML节点实现

需求说明

处理XML中的<Shipment>节点,按<shipFromLocation>(发货地)和<shipToLocation>(收货地)的组合值分组,将同组下所有<Shipment>包含的<container>子节点全部聚合到同一个<Shipment>节点下,同组仅保留一份收发地址字段。

输入XML示例

<?xml version="1.0" encoding="UTF-8"?>
<Entity>
  <Shipment>
       <shipFromLocation>06AC001</shipFromLocation>
       <shipToLocation>07BCDAZ</shipToLocation>
       <container>
           <key1>101</key1>
           <key1>102</key1>
       </container>
       <container>
           <key1>103</key1>
           <key1>104</key1>
       </container>
  </Shipment>
  <Shipment>
       <shipFromLocation>06AC001</shipFromLocation>
       <shipToLocation>07BCDAZ</shipToLocation>
       <container>
           <key1>105</key1>
           <key1>106</key1>
       </container>
       <container>
           <key1>107</key1>
           <key1>108</key1>
       </container>
  </Shipment>
  <Shipment>
       <shipFromLocation>06AC002</shipFromLocation>
       <shipToLocation>08BCDAZ</shipToLocation>
       <container>
           <key1>200</key1>
           <key1>201</key1>
       </container>
  </Shipment>
  <Shipment>
       <shipFromLocation>06AC002</shipFromLocation>
       <shipToLocation>08BCDAZ</shipToLocation>
       <container>
           <key1>202</key1>
           <key1>203</key1>
       </container>
  </Shipment>
</Entity>

预期输出XML

<?xml version="1.0" encoding="UTF-8"?>
<Entity>
  <Shipment>
       <shipFromLocation>06AC001</shipFromLocation>
       <shipToLocation>07BCDAZ</shipToLocation>
       <container>
           <key1>101</key1>
           <key1>102</key1>
       </container>
       <container>
           <key1>103</key1>
           <key1>104</key1>
       </container>
       <container>
           <key1>105</key1>
           <key1>106</key1>
       </container>
       <container>
           <key1>107</key1>
           <key1>108</key1>
       </container>
  </Shipment>
  <Shipment>
       <shipFromLocation>06AC002</shipFromLocation>
       <shipToLocation>08BCDAZ</shipToLocation>
       <container>
           <key1>200</key1>
           <key1>201</key1>
       </container>
       <container>
           <key1>202</key1>
           <key1>203</key1>
       </container>
  </Shipment>
</Entity>

原有代码问题

原有XSLT代码存在3个核心错误:

  • 分组键设置错误:仅使用shipFromLocation作为分组依据,未结合shipToLocation做组合判断,会导致发货地相同、收货地不同的节点被错误合并
  • 字段输出逻辑错误:循环遍历同组所有Shipment时重复输出shipFromLocation,且完全遗漏shipToLocation字段
  • 节点拷贝逻辑错误:使用xsl:value-of提取container值,会丢失container下的key1子节点结构,无法保留container的完整层级

正确实现代码

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" encoding="UTF-8"/>

<xsl:template match="/Entity">
    <xsl:copy>
        <!-- 用特殊分隔符拼接收发地址作为组合分组键,避免字段值拼接冲突 -->
        <xsl:for-each-group select="Shipment" group-by="concat(shipFromLocation, '||', shipToLocation)">
            <Shipment>
                <!-- 同组收发地址完全一致,取组内第一个节点的地址值输出即可 -->
                <shipFromLocation>
                    <xsl:value-of select="current-group()[1]/shipFromLocation"/>
                </shipFromLocation>
                <shipToLocation>
                    <xsl:value-of select="current-group()[1]/shipToLocation"/>
                </shipToLocation>
                <!-- 深拷贝同组下所有container节点,完整保留子节点结构 -->
                <xsl:copy-of select="current-group()/container"/>
            </Shipment>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

关键逻辑说明

  • 分组键使用concat(shipFromLocation, '||', shipToLocation),选择不会出现在地址编码中的双竖线作为分隔符,避免两个字段值拼接后出现误匹配
  • 同组的收发地址完全相同,仅取组内第一个节点的地址字段输出,避免重复生成冗余字段
  • 使用xsl:copy-of直接做深拷贝,一次性把同组所有Shipment下的container节点完整复制到新的Shipment节点下,不需要手动遍历container的子节点,结构不会丢失

内容的提问来源于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 17:36:28