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

XSLT去重转换:删除fieldToDelete节点并修复gemeinde引用异常

XML转换:移除fieldToDelete节点并正确处理gemeinde引用与去重

原XML输入

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <fieldToDelete>
        <gemeinde id="10">
            <child1/>
        </gemeinde>
    </fieldToDelete>
    <fieldToDelete>
        <gemeinde id="20">
            <child2/>
        </gemeinde>
    </fieldToDelete>
    <gemeinde reference="10"/>
    <gemeinde reference="20"/>
    <gemeinde reference="10"/>
    <gemeinde reference="20"/>
</root>

预期转换结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <gemeinde id="10">
        <child1/>
    </gemeinde>
    <gemeinde id="20">
        <child2/>
    </gemeinde>
    <gemeinde reference="10"/>
    <gemeinde reference="20"/>
</root>

现有代码问题分析

你原本的思路逻辑可行,但代码存在几个关键缺陷:

  1. fieldToDelete的模板直接删除整个节点,导致内部的gemeinde节点被一并移除,后续无法引用这些完整节点。
  2. 替换gemeinde[@reference]的模板中,//gemeinde[@id = $refId]无法找到目标节点(因为已随fieldToDelete被删除),根本无法完成替换。
  3. 去重模板的preceding::gemeinde[@id=$refId]逻辑无效:一方面没有保留fieldToDelete内的gemeinde节点,另一方面XSLT按文档顺序处理节点时,preceding轴无法提前感知后续节点,无法正确判断重复。

正确XSLT解决方案

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

    <!-- 按id索引所有带id的gemeinde节点(包含fieldToDelete内的节点) -->
    <xsl:key name="gemeinde-by-id" match="gemeinde[@id]" use="@id"/>

    <!-- 默认复制模板:保留除特殊匹配外的所有节点结构 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 移除fieldToDelete节点,但保留其内部子节点 -->
    <xsl:template match="fieldToDelete">
        <xsl:apply-templates select="node()"/>
    </xsl:template>

    <!-- 重新组织root节点的子节点顺序:先输出唯一完整节点,再输出唯一引用 -->
    <xsl:template match="root">
        <root>
            <!-- 输出每个id对应的第一个完整gemeinde节点(来自fieldToDelete) -->
            <xsl:apply-templates select="key('gemeinde-by-id', //gemeinde/@id)[1]"/>
            <!-- 输出每个id仅一次的reference节点 -->
            <xsl:apply-templates select="//gemeinde[@reference][not(preceding::gemeinde[@reference = current()/@reference])]"/>
        </root>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 索引节点:用key提前索引所有带id的gemeinde节点,确保即使fieldToDelete被移除,仍能访问到这些完整节点。
  2. 保留有效节点:处理fieldToDelete时不直接删除,而是提取内部的gemeinde节点保留到文档中。
  3. 重新组织输出:
    • 先输出每个id对应的第一个完整gemeinde节点(确保每个id仅保留一份完整结构)。
    • 再输出每个id仅一次的reference节点,自动去重重复引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:18:10