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

如何用XSLT匹配同@BEGIN-@END异@TEXT的TOKEN节点并添加标记

解决XML中同BEGIN/END但TEXT不同的TOKEN节点添加MULTIPLE节点问题

我来帮你搞定这个XSLT的问题!你的需求是给那些共享相同@BEGIN和@END属性,但@TEXT属性不全一致的<TOKEN>节点都加上<MULTIPLE TYPE='YES'>子节点,对吧?之前用key没成功,大概率是判断逻辑或者key的使用方式没到位,我给你一套完整的解决方案:

完整XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义key:按@BEGIN和@END的组合分组,用|分隔避免属性值拼接冲突 -->
    <xsl:key name="tokenByBeginEnd" match="TOKEN" use="concat(@BEGIN, '|', @END)"/>

    <!-- 默认模板:复制所有节点和属性,保证原有结构不受破坏 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 专门处理TOKEN节点的模板 -->
    <xsl:template match="TOKEN">
        <xsl:copy>
            <!-- 先复制原TOKEN的所有属性 -->
            <xsl:apply-templates select="@*"/>
            <!-- 判断当前组内是否存在不同的@TEXT值 -->
            <xsl:if test="count(distinct-values(key('tokenByBeginEnd', concat(@BEGIN, '|', @END))/@TEXT)) > 1">
                <MULTIPLE TYPE='YES'/>
            </xsl:if>
            <!-- 复制原TOKEN的子节点(如果有的话) -->
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

代码逻辑解释

  • Key的定义:用concat(@BEGIN, '|', @END)作为分组标识,这样能避免比如BEGIN="1" END="23"和BEGIN="12" END="3"被误判为同一组的情况,确保分组精准。
  • 默认模板:负责原样复制XML中所有不需要特殊处理的节点和属性,保证原有文档结构完整。
  • TOKEN处理逻辑:
    1. 先复制当前<TOKEN>节点本身及其所有属性;
    2. 通过key()获取和当前TOKEN同@BEGIN+@END的所有节点,用distinct-values()提取组内所有不同的@TEXT值,只要数量大于1,就说明组内存在TEXT不一致的情况,此时添加<MULTIPLE TYPE='YES'>节点;
    3. 最后复制原TOKEN的子节点(如果有)。

输入输出示例

输入XML

<ROOT>
    <TOKEN BEGIN="1" END="5" TEXT="apple"/>
    <TOKEN BEGIN="1" END="5" TEXT="apple"/>
    <TOKEN BEGIN="1" END="5" TEXT="orange"/>
    <TOKEN BEGIN="6" END="10" TEXT="banana"/>
    <TOKEN BEGIN="6" END="10" TEXT="grape"/>
    <TOKEN BEGIN="11" END="15" TEXT="pear"/>
</ROOT>

输出XML

<ROOT>
    <TOKEN BEGIN="1" END="5" TEXT="apple">
        <MULTIPLE TYPE='YES'/>
    </TOKEN>
    <TOKEN BEGIN="1" END="5" TEXT="apple">
        <MULTIPLE TYPE='YES'/>
    </TOKEN>
    <TOKEN BEGIN="1" END="5" TEXT="orange">
        <MULTIPLE TYPE='YES'/>
    </TOKEN>
    <TOKEN BEGIN="6" END="10" TEXT="banana">
        <MULTIPLE TYPE='YES'/>
    </TOKEN>
    <TOKEN BEGIN="6" END="10" TEXT="grape">
        <MULTIPLE TYPE='YES'/>
    </TOKEN>
    <TOKEN BEGIN="11" END="15" TEXT="pear"/>
</ROOT>

你看,这样就完美实现了你的需求:同BEGIN/END且TEXT不全相同的TOKEN都加上了MULTIPLE节点,而只有单个或全同TEXT的节点则保持原样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:25:05