如何在XSLT 1.0中动态获取XML对应父节点的属性值?
XSLT 1.0 动态匹配节点名称获取属性的解决方案
问题原因
XSLT 1.0 不支持动态节点测试——也就是不能直接把变量作为节点名称写在路径表达式里(比如/Root/Features/$nodeName这种写法是非法的),这就是你触发Unexpected token '$myVariable' during parsing of '<AnyKindTest>'错误的原因。
解决方案:用name()/local-name()函数匹配节点名称
核心思路是先选中目标节点的所有子节点,再通过节点名称的字符串匹配过滤出对应节点,具体步骤如下:
示例XML结构
先假设你的XML结构如下(和描述一致):
<Root> <Features> <ProductID unit="none"/> <Width unit="cm"/> <Height unit="cm"/> </Features> <ProductID> <Width>20</Width> <Height>30</Height> </ProductID> </Root>
基础实现写法
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 遍历ProductID下的所有数值子节点 --> <xsl:template match="/Root/ProductID/*"> <!-- 获取当前节点的名称 --> <xsl:variable name="nodeName" select="name(.)"/> <!-- 匹配Features下名称相同的节点 --> <xsl:variable name="featureNode" select="/Root/Features/*[name(.) = $nodeName]"/> <!-- 输出结果 --> <xsl:value-of select="$nodeName"/> <xsl:text>: </xsl:text> <xsl:value-of select="."/> <xsl:text> (单位: </xsl:text> <xsl:value-of select="$featureNode/@unit"/> <xsl:text>) </xsl:text> </xsl:template> </xsl:stylesheet>
优化写法(用key提高效率)
如果你的XML节点数量较多,用key建立索引可以提升查找效率:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 定义key:以节点名称为键,关联Features下的子节点 --> <xsl:key name="featureKey" match="/Root/Features/*" use="name(.)"/> <xsl:template match="/Root/ProductID/*"> <xsl:value-of select="name(.)"/> <xsl:text>: </xsl:text> <xsl:value-of select="."/> <xsl:text> (单位: </xsl:text> <!-- 通过key直接获取对应节点的unit属性 --> <xsl:value-of select="key('featureKey', name(.))/@unit"/> <xsl:text>) </xsl:text> </xsl:template> </xsl:stylesheet>
补充说明
- 如果你的XML使用了命名空间,建议用
local-name()代替name(),避免命名空间前缀干扰匹配(比如local-name(.) = $nodeName)。 - 两种写法都完全符合XSLT 1.0的语法规范,不会触发语法错误。
内容的提问来源于stack exchange,提问作者Softfusion
相关产品推荐
相关产品推荐

