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

如何使用DataWeave或XSLT移除XML中的重复父节点及子节点

移除XML中重复的父节点及其子节点(DataWeave & XSLT实现)

我来帮你解决这个XML去重的问题——不管是用DataWeave还是XSLT,都有清晰的实现方式。你的需求是移除重复的<ns2:Parent>节点及其对应的<ns2:Children>子节点,只保留每个Parent值对应的唯一条目。假设你的XML结构是<ns1:Hierarchy>下交替出现<ns2:Parent>和<ns2:Children>节点(每个Parent紧跟对应的Children),下面是两种方案:

DataWeave 2.x 解决方案

这个方案先将Parent和Children节点配对,再根据Parent的值去重,最后重组XML结构,同时保留原有的命名空间:

%dw 2.0
output application/xml
ns ns1 http://www.example.org/Hierarchy
ns ns2 http://www.example.org/HierarchyResult
---
ns1#Hierarchy: do {
    // 1. 将Hierarchy下的Parent和Children节点按顺序每两个分组,形成Parent-Children对
    var parentChildPairs = payload.ns1#Hierarchy.*(ns2#Parent, ns2#Children) 
        groupBy ((item, index) -> floor(index / 2)) 
        mapObject ((value, key) -> {
            parent: value[0],
            children: value[1]
        })
    // 2. 根据Parent的值分组,只保留每个组的第一个条目(去重)
    var uniquePairs = parentChildPairs 
        groupBy ((pair) -> pair.parent) 
        mapObject ((group) -> group[0])
    // 3. 将去重后的Parent和Children节点重新组合到Hierarchy下
    uniquePairs.*parent ++ uniquePairs.*children
}

代码解释:

  • 首先用*(ns2#Parent, ns2#Children)获取所有Parent和Children节点,再按索引每两个分组,把相邻的Parent和Children配对成对象;
  • 通过groupBy按Parent值分组,取每个组的第一个元素实现去重;
  • 最后把去重后的Parent和Children节点拼接起来,放回<ns1:Hierarchy>根节点下。

XSLT 2.0 解决方案

这个方案使用XSLT的键(xsl:key)来分组Parent节点,只保留每个Parent值对应的第一个条目及其关联的Children:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns1="http://www.example.org/Hierarchy"
    xmlns:ns2="http://www.example.org/HierarchyResult">
    <xsl:output method="xml" indent="yes"/>

    <!-- 定义键:根据Parent节点的文本值分组 -->
    <xsl:key name="parentKey" match="ns2:Parent" use="."/>

    <xsl:template match="/ns1:Hierarchy">
        <xsl:copy>
            <!-- 复制根节点的所有属性(包括命名空间) -->
            <xsl:copy-of select="@*"/>
            <!-- 遍历每个唯一的Parent节点(仅保留每个组的第一个) -->
            <xsl:for-each select="ns2:Parent[count(. | key('parentKey', .)[1]) = 1]">
                <!-- 复制当前Parent节点 -->
                <xsl:copy-of select="."/>
                <!-- 复制紧跟在该Parent之后的第一个Children节点 -->
                <xsl:copy-of select="following-sibling::ns2:Children[1]"/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

    <!-- 忽略其他无关的文本节点 -->
    <xsl:template match="text()"/>
</xsl:stylesheet>

代码解释:

  • 用xsl:key创建一个基于Parent节点文本值的分组键;
  • 在根节点模板中,选择每个Parent组的第一个节点(通过count(. | key('parentKey', .)[1]) = 1判断是否为组内第一个);
  • 复制该Parent节点,同时复制它后面紧跟的第一个Children节点,确保每个唯一Parent对应其关联的子节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:40:34