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

如何实现XSLT 2.0样式表:type属性为WILD时给指定标签追加字符w

解决XSLT 2.0中根据<name>的type属性修改<Identity>文本的问题

需求说明

当XML文档中存在type="WILD"的<name>标签时,给<farm>和<Site>下的<Identity>标签文本末尾追加字符"w"。

输入XML

<root>
    <Header>
        <farm>
            <Identity>0123</Identity>
        </farm>
        <Site>
            <Identity>0123</Identity>
        </Site>
    </Header>
    <body>
        <animal>
            <name place="ocean" type="WILD">
                <species>Tortoise</species>
            </name>
        </animal>
    </body>
</root>

期望输出

<root>
    <Header>
        <farm>
            <Identity>0123w</Identity>
        </farm>
        <Site>
            <Identity>0123w</Identity>
        </Site>
    </Header>
    <body>
        <animal>
            <name place="ocean" type="WILD">
                <species>Tortoise</species>
            </name>
        </animal>
    </body>
</root>

错误的尝试及问题分析

我尝试了以下XSLT,但将type属性改为"XXX"时,结果仍错误地追加了"w":

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
  <!-- identity template -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- add 'w' to Identity elements inside <farm> and <Site> -->
  <xsl:template match="farm/Identity | Site/Identity">
    <xsl:copy>
      <xsl:value-of select="if (../name/@type='WILD') then . else concat(., 'w')"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- add 'w' to Identity elements inside <name> with attribute 'type' = 'WILD' -->
  <xsl:template match="name[@type='WILD']/Identity">
    <xsl:copy>
      <xsl:value-of select="concat(., 'w')"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

问题根源

  1. 逻辑完全写反:第一个模板的条件if (../name/@type='WILD') then . else concat(., 'w'),意思是"当<farm>/<Site>的同级存在type为WILD的<name>时,保持原文本;否则追加w",和需求完全相反。
  2. 路径错误:../name是查找<farm>/<Site>的同级节点,但实际<name>在<body>/<animal>下,和<Header>下的<farm>/<Site>层级完全无关,这个条件永远不成立,导致一直执行else分支追加w。
  3. 无用模板:第三个模板匹配name[@type='WILD']/Identity,但输入XML中<name>下根本没有<Identity>节点,这个模板不会触发。

正确的XSLT实现

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
  <!-- 身份模板:默认复制所有节点和属性 -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 全局检查是否存在type为WILD的name,存在则给farm/Site下的Identity追加w -->
  <xsl:template match="farm/Identity | Site/Identity">
    <xsl:copy>
      <xsl:value-of select="if (//name[@type='WILD']) then concat(., 'w') else ."/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

实现说明

  • 使用//name[@type='WILD']全局查找文档中是否存在符合条件的<name>节点,确保判断逻辑准确。
  • 修正条件逻辑:当存在目标<name>时,给<Identity>追加"w";否则保持原文本。
  • 移除无用的第三个模板,精简代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:33:28