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

如何用XQuery过滤XML深层子节点的重复项?

解决XML中跨节点的重复/组合去重问题

需求明确:在整个<Articles>文档中,所有<Article>下的<UNIT>节点需保证<NR>与<COUNT>的组合唯一,仅保留该组合第一次出现的<UNIT>节点,后续重复的全部移除。

解决方案:使用XSLT 1.0的Muenchian分组实现去重

Muenchian分组是XSLT中处理节点去重的经典方案,通过定义基于<NR>+<COUNT>组合的键,精准识别重复节点并过滤。

以下是完整的XSLT代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义键:用NR和COUNT的文本内容拼接作为唯一标识 -->
    <xsl:key name="unitKey" match="UNIT" use="concat(NR, '|', COUNT)"/>

    <!-- 复制所有节点的默认模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 过滤重复的UNIT节点:仅保留每个键对应的第一个节点 -->
    <xsl:template match="UNIT[not(generate-id() = generate-id(key('unitKey', concat(NR, '|', COUNT))[1]))]"/>
</xsl:stylesheet>

代码说明

  1. 键定义:<xsl:key>将每个<UNIT>节点与NR|COUNT的拼接字符串绑定,这个字符串就是判断重复的唯一标识。
  2. 默认复制模板:确保原XML中除了需要过滤的<UNIT>外,其他所有节点(包括<Article>、<A1>等)都被原样复制。
  3. UNIT过滤模板:当某个<UNIT>不是其对应键组中的第一个节点时,这个模板会空输出(即移除该节点)。generate-id()函数用于判断节点是否为组内第一个。

使用方法

将上述XSLT保存为remove-duplicate-units.xsl,然后用XML处理器(比如xsltproc命令行工具)处理你的输入XML:

xsltproc remove-duplicate-units.xsl input.xml > output.xml

处理后得到的结果完全符合你的期望输出:保留第一个出现的<NR>/<COUNT>组合对应的<UNIT>,后续重复的全部移除。

对之前尝试的补充说明

你之前用string-join拼接值后删除节点时误删所有<UNIT>,大概率是因为删除逻辑没有精准定位到重复节点,而Muenchian分组通过键组的方式,能准确区分首次出现和重复出现的节点,避免误删。

内容的提问来源于stack exchange,提问作者Alexander D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:39:52