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

基于XSLT 3.0按applicationId及元素名分组去重XML的技术问询

按applicationId分组并去重子元素的XSLT解决方案

问题背景

输入XML如下:

<?xml version='1.0' encoding='UTF-8'?>
<Applications>
    <Application>
        <applicationId>280</applicationId>
        <cust_IDCheckIDCollation>
            <Option>
                <id>197249</id>
            </Option>
        </cust_IDCheckIDCollation>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>292</applicationId>
        <cust_IDCheckIDCollation>
            <Option>
                <id>197249</id>
            </Option>
        </cust_IDCheckIDCollation>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>280</applicationId>
        <cust_OnlineReferenceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_OnlineReferenceCheck>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>292</applicationId>
        <cust_OnlineReferenceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_OnlineReferenceCheck>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>280</applicationId>
        <cust_AustralianWorkRights>
            <Option>
                <id>197250</id>
            </Option>
        </cust_AustralianWorkRights>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>292</applicationId>
        <cust_AustralianWorkRights>
            <Option>
                <id>197250</id>
            </Option>
        </cust_AustralianWorkRights>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>280</applicationId>
        <cust_NationalPoliceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_NationalPoliceCheck>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
    <Application>
        <applicationId>292</applicationId>
        <cust_NationalPoliceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_NationalPoliceCheck>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
    </Application>
</Applications>

需求:先按applicationId对<Application>节点分组,再对每组内的子元素按元素名去重,最终输出合并后的XML,预期结果如下:

<Applications>
    <Application>
        <applicationId>280</applicationId>
        <cust_IDCheckIDCollation>
            <Option>
                <id>197249</id>
            </Option>
        </cust_IDCheckIDCollation>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
        <cust_OnlineReferenceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_OnlineReferenceCheck>
        <cust_AustralianWorkRights>
            <Option>
                <id>197250</id>
            </Option>
        </cust_AustralianWorkRights>
        <cust_NationalPoliceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_NationalPoliceCheck>
    </Application>
    <Application>
        <applicationId>292</applicationId>
        <cust_IDCheckIDCollation>
            <Option>
                <id>197249</id>
            </Option>
        </cust_IDCheckIDCollation>
        <cust_overallduedilligencestatus>
            <Option>
                <id>197276</id>
            </Option>
        </cust_overallduedilligencestatus>
        <cust_OnlineReferenceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_OnlineReferenceCheck>
        <cust_AustralianWorkRights>
            <Option>
                <id>197250</id>
            </Option>
        </cust_AustralianWorkRights>
        <cust_NationalPoliceCheck>
            <Option>
                <id>197249</id>
            </Option>
        </cust_NationalPoliceCheck>
    </Application>
</Applications>

原有XSLT 2.0代码的问题

编写的XSLT 2.0代码无法得到预期结果,核心问题是:

<xsl:element name="{current-grouping-key()}">
    <xsl:value-of select="(current-group())[1]"/>
</xsl:element>

<xsl:value-of>仅提取节点的文本内容,丢失了子元素结构(比如<Option>和<id>节点),导致输出中带嵌套结构的子节点无法完整保留。

XSLT 3.0的简便实现

基于原有分组逻辑,替换文本提取为完整节点复制,结合XSLT 3.0的语法特性,可实现简洁高效的解决方案:

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/Applications">
        <xsl:copy>
            <!-- 按applicationId分组 -->
            <xsl:for-each-group select="Application" group-by="applicationId">
                <xsl:copy>
                    <!-- 对组内所有子元素按元素名去重 -->
                    <xsl:for-each-group select="current-group()/*" group-by="node-name()">
                        <!-- 复制分组后的第一个完整节点(包含所有子元素) -->
                        <xsl:copy-of select="current-group()[1]"/>
                    </xsl:for-each-group>
                </xsl:copy>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

关键改进点

  1. 用<xsl:copy-of>替代<xsl:value-of>,完整复制节点及其所有子元素、属性,保留原XML结构。
  2. 使用node-name()代替name(),node-name()返回节点的QName,在有命名空间的场景下更严谨,无命名空间时效果一致。
  3. XSLT 3.0原生支持分组逻辑,代码无需额外扩展即可高效运行。

内容的提问来源于stack exchange,提问作者Madhu N G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:20:55