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

请求:基于XSLT 1.0/2.0实现XML按规则分组转换

XML转换需求:基于format属性分组合并CommissionEvent节点

输入XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:CommissionEvents xmlns="urn:tracelink:mapper:sl:canonical:commontypes" xmlns:ns2="urn:tracelink:mapper:sl:canonical:serialized_operations_manager">
        <ns2:CommissionEvent>
           <NumberList>
            <Serial barcodeContent="(01)00355135132011(21)897883089643(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="0" format="AI(01)+AI(21)">010035513513201121897883089643</Serial>
            </NumberList>
    </ns2:CommissionEvent>
        <ns2:CommissionEvent>
           <NumberList>
            <Serial barcodeContent="(01)00355135132011(21)903131477120(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="0" format="AI(01)+AI(21)">010035513513201121903131477120</Serial>
           </NumberList>
    </ns2:CommissionEvent>
    <ns2:CommissionEvent>
           <NumberList>
            <Serial barcodeContent="(01)30355135132012(21)389170110454(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="3" format="AI(01)+AI(21)">013035513513201221389170110454</Serial>
           </NumberList>
    </ns2:CommissionEvent>
    <ns2:CommissionEvent>
           <NumberList>
            <Serial barcodeContent="(00)003551350000000907" companyPrefix="0355135" filterValue="0" format="AI(00)">00003551350000000907</Serial>
           </NumberList>
    </ns2:CommissionEvent>
    <ns2:CommissionEvent>
            <NumberList>
              <Serial barcodeContent="(00)103551350000000645" companyPrefix="0355135" filterValue="1" format="AI(00)">00103551350000000645</Serial>
            </NumberList>
    </ns2:CommissionEvent>
    </ns2:CommissionEvents>

期望输出XML

<ns2:CommissionEvents>              
        <ns2:CommissionEvent>
           <ns0:NumberList>
            <ns0:Serial barcodeContent="(01)00355135132011(21)897883089643(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="0" format="AI(01)+AI(21)" />
            <ns0:Serial barcodeContent="(01)00355135132011(21)903131477120(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="0" format="AI(01)+AI(21)" />
            </ns0:NumberList>
    </ns2:CommissionEvent>
    <ns2:CommissionEvent>
           <ns0:NumberList>
            <ns0:Serial barcodeContent="(01)30355135132012(21)389170110454(17)230430(10)TLSMKTST" companyPrefix="0355135" filterValue="3" format="AI(01)+AI(21)" />
           </ns0:NumberList>
    </ns2:CommissionEvent>
    <ns2:CommissionEvent>
            <ns0:NumberList>
            <ns0:Serial barcodeContent="(00)003551350000000907" companyPrefix="0355135" filterValue="0" format="AI(00)" />
            <ns0:Serial barcodeContent="(00)103551350000000645" companyPrefix="0355135" filterValue="1" format="AI(00)" />
           </ns0:NumberList>
    </ns2:CommissionEvent>
    </ns2:CommissionEvents>

解决方案

XSLT 2.0 实现方案

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="urn:tracelink:mapper:sl:canonical:serialized_operations_manager"
    xmlns:ns0="urn:tracelink:mapper:sl:canonical:commontypes"
    exclude-result-prefixes="ns2 ns0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/ns2:CommissionEvents">
        <ns2:CommissionEvents>
            <!-- 按Serial节点的format属性分组 -->
            <xsl:for-each-group select="ns2:CommissionEvent/NumberList/Serial" group-by="@format">
                <ns2:CommissionEvent>
                    <ns0:NumberList>
                        <!-- 遍历分组内的Serial,转为自闭合标签并添加ns0前缀 -->
                        <xsl:for-each select="current-group()">
                            <ns0:Serial>
                                <xsl:copy-of select="@*"/>
                            </ns0:Serial>
                        </xsl:for-each>
                    </ns0:NumberList>
                </ns2:CommissionEvent>
            </xsl:for-each-group>
        </ns2:CommissionEvents>
    </xsl:template>
</xsl:stylesheet>

XSLT 1.0 实现方案(Muenchian分组)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="urn:tracelink:mapper:sl:canonical:serialized_operations_manager"
    xmlns:ns0="urn:tracelink:mapper:sl:canonical:commontypes"
    exclude-result-prefixes="ns2 ns0">

    <xsl:output method="xml" indent="yes"/>

    <!-- 定义分组键:Serial的format属性 -->
    <xsl:key name="serial-by-format" match="ns2:CommissionEvent/NumberList/Serial" use="@format"/>

    <xsl:template match="/ns2:CommissionEvents">
        <ns2:CommissionEvents>
            <!-- 遍历所有唯一的format分组 -->
            <xsl:for-each select="ns2:CommissionEvent/NumberList/Serial[generate-id() = generate-id(key('serial-by-format', @format)[1])]">
                <ns2:CommissionEvent>
                    <ns0:NumberList>
                        <!-- 输出当前分组内的所有Serial节点 -->
                        <xsl:for-each select="key('serial-by-format', @format)">
                            <ns0:Serial>
                                <xsl:copy-of select="@*"/>
                            </ns0:Serial>
                        </xsl:for-each>
                    </ns0:NumberList>
                </ns2:CommissionEvent>
            </xsl:for-each>
        </ns2:CommissionEvents>
    </xsl:template>
</xsl:stylesheet>

核心逻辑说明

  • 两种方案均基于Serial节点的format属性进行分组,将同格式的Serial合并到同一个CommissionEvent节点下。
  • 移除原Serial节点的文本内容,转换为自闭合标签,并为NumberList和Serial添加ns0前缀(对应原默认命名空间)。
  • XSLT 2.0使用for-each-group语法更简洁,XSLT 1.0通过Muenchian分组实现相同效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:01:26