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

XSLT获取属性值并修改其他属性值的实现问题

XSLT 1.0 实现XML节点ID调整及节点删除需求

需求说明

  • 获取<special>节点的id属性值
  • 找到第一个id大于该值的<node>节点,计算其id与该值的差值,将所有id大于该值的<node>节点的id减去这个差值
  • 删除<special>节点

输入XML示例

<xml>
    <node id="1">
        <item>2</item>
    </node>
    <node id="3">
        <item>4</item>
    </node>
    <special id="5">
        <item>6</item>
    </special>
    <node id="7">
        <item>8</item>
    </node>
    <node id="9">
        <item>10</item>
    </node>
    <node id="11">
        <item>12</item>
    </node>
</xml>

期望输出XML示例

<xml>
    <node id="1">
        <item>2</item>
    </node>
    <node id="3">
        <item>4</item>
    </node>
    <node id="5">
        <item>8</item>
    </node>
    <node id="7">
        <item>10</item>
    </node>
    <node id="9">
        <item>12</item>
    </node>
</xml>

原代码问题分析

你写的XSLT代码存在以下几个问题:

  1. 变量引用错误:模板中引用变量时缺少$前缀,原代码里的myvar应该写成$myvar
  2. 未正确计算差值:直接写死了-1,没有实现查找第一个符合条件的<node>并计算差值的逻辑
  3. 字符串比较问题:@id是字符串类型,直接比较会按字符串排序规则处理,需要转换成数值后再进行比较

正确实现代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
    <!-- 转换为数值类型存储special节点的id -->
    <xsl:variable name="special-id" select="number(//special/@id)"/>
    
    <!-- 获取第一个id大于special-id的node节点的id数值 -->
    <xsl:variable name="first-node-id" select="number(//node[@id > $special-id][1]/@id)"/>
    
    <!-- 计算需要减去的差值 -->
    <xsl:variable name="diff" select="$first-node-id - $special-id"/>
    
    <!-- 身份模板:默认复制所有节点和属性 -->
    <xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>

    <!-- 匹配special节点,不输出,实现删除 -->
    <xsl:template match="special"/>
    
    <!-- 处理node节点的id属性 -->
    <xsl:template match="node/@id">
        <xsl:variable name="current-id" select="number(.)"/>
        <xsl:attribute name="id">
            <xsl:choose>
                <xsl:when test="$current-id > $special-id">
                    <!-- 大于special-id的id减去差值 -->
                    <xsl:value-of select="$current-id - $diff"/>
                </xsl:when>
                <xsl:otherwise>
                    <!-- 保留原id -->
                    <xsl:value-of select="$current-id"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </xsl:template>
 </xsl:stylesheet>

代码关键点说明

  • 所有涉及id的变量都用number()转换为数值类型,确保数值比较的正确性
  • 用//node[@id > $special-id][1]定位第一个id大于special-id的<node>节点
  • 通过<xsl:template match="special"/>实现删除<special>节点,因为匹配该节点后不做任何输出
  • 对<node>的id属性单独处理,根据条件调整数值后重新生成属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:52:22