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

基于PlayBack--ControlInfo-ControlName去重XML节点的XSLT求助

解决XML中按ControlName在GStep内部去重Step节点的XSLT方案

我看了你提供的输入XML、期望输出和尝试的XSLT代码,发现问题出在全局的key定义上——你当前的key是把所有<Step>节点按PlayBack--ControlInfo-ControlName做全局分组,这会导致不同<GStep>下相同ControlName的节点也被误删,但你的需求是每个<GStep>内部按ControlName去重对吧?

修正后的XSLT代码

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

<!-- 关键:将父GStep的唯一标识与ControlName拼接,实现每个GStep内部独立分组 -->
<xsl:key name="ControlNameInfo" match="Step" use="concat(generate-id(..), '|', PlayBack--ControlInfo-ControlName)"/>

<!-- 身份转换模板:复制所有节点和属性 -->
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<!-- 删除当前GStep内重复的Step节点,只保留每个ControlName分组的第一个节点 -->
<xsl:template match="GStep/Step[not(generate-id() = generate-id(key('ControlNameInfo', concat(generate-id(..), '|', PlayBack--ControlInfo-ControlName))[1]))]"/>
</xsl:stylesheet>

代码说明

  1. 分组逻辑优化:
    原来的key没有区分不同的<GStep>容器,现在用concat(generate-id(..), '|', PlayBack--ControlInfo-ControlName)作为key的取值——generate-id(..)会生成当前<Step>父节点(<GStep>)的唯一标识,和ControlName拼接后,就能保证每个<GStep>内部的分组是完全独立的,不会跨GStep去重。

  2. 去重规则:
    匹配模板中,我们只保留每个分组里的第一个<Step>节点,删除后续重复的节点,这正好符合你期望的输出效果:

    • 第一个<GStep>(Untitled - Notepad)里,空ControlName只保留Step-ID3,后续的空节点(12)被删除;Edit、Replace各保留首次出现的节点(5、6),重复的(13、14)被删除;Cancel节点唯一,保留15。
    • 第二个<GStep>(Replace)里,空ControlName只保留Step-ID8,后续的空节点(10、16)被删除;Cancel节点唯一,保留9。

用这个XSLT处理你的输入XML,就能得到你想要的输出结果啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:52:32