XSLT转换XML:复制全部节点排除ID,按ID条件修改薪资
解决XSLT中ID=1时薪资设为0的问题
我明白你的问题出在哪了——你当前的XSLT里,<xsl:copy-of>会直接复制节点,完全跳过了你为details[id=1]/salary写的自定义模板,所以薪资修改的逻辑根本没被触发。咱们调整一下代码就能解决这个问题:
修改后的完整XSLT
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <another-root> <xsl:for-each select="root/person"> <Insert> <xsl:apply-templates/> </Insert> </xsl:for-each> </another-root> </xsl:template> <xsl:template match="details"> <info> <!-- 把copy-of改成apply-templates,这样才能触发salary的自定义模板 --> <xsl:apply-templates select="./node()[not(self::id)]" /> </info> </xsl:template> <!-- 调整匹配表达式,更精准地定位到id=1的details下的salary --> <xsl:template match="salary[../id=1]"> <salary>0</salary> </xsl:template> <!-- 保留默认的节点复制模板,处理其他不需要修改的节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键修改点说明
- 替换
<xsl:copy-of>为<xsl:apply-templates>:
原来的copy-of是直接复制节点树,不会经过XSLT的模板匹配流程。换成apply-templates后,每个子节点(比如name、salary、age)都会去匹配对应的模板,这样你的薪资修改逻辑才能生效。 - 优化薪资模板的匹配路径:
把details[id=1]/salary改成salary[../id=1],这样更直接地匹配“父节点id为1的salary节点”,逻辑更清晰。 - 添加默认复制模板:
这个模板会复制所有没有自定义模板的节点和属性,确保你能保留<person>下的其他所有子节点(除了id),满足你的需求。
转换后的结果
运行修改后的XSLT,你会得到预期的输出:
<another-root> <Insert> <info> <name>Peter</name> <salary>0</salary> <age>29</age> </info> </Insert> <Insert> <info> <name>Oliver</name> <salary>500</salary> <age>13</age> </info> </Insert> </another-root>
这样就完全满足你的所有需求了:复制person的所有子节点、排除id、id=1时薪资设为0。
内容的提问来源于stack exchange,提问作者Faz B
相关产品推荐
相关产品推荐

