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代码存在以下几个问题:
- 变量引用错误:模板中引用变量时缺少
$前缀,原代码里的myvar应该写成$myvar - 未正确计算差值:直接写死了
-1,没有实现查找第一个符合条件的<node>并计算差值的逻辑 - 字符串比较问题:
@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
相关产品推荐
相关产品推荐

