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

XSLT 3.0如何在apply-templates中用变量动态选择节点?

解决动态构造xsl:apply-templates的select路径问题

这个问题我之前也碰到过,你原来的写法foo/bar/$x之所以无效,是因为XPath语法里不能直接把字符串变量当作节点名使用——$x在这里是字符串值,不是合法的节点测试。针对Saxon-HE 9.8,这里有几个可行的解决方案:

方案1:用节点名称匹配(最稳妥,兼容XSLT 2.0)

如果你的变量$x只是节点的本地名称,直接用local-name()函数匹配即可,这是兼容性最好的方法,不需要依赖扩展或高版本特性:

<xsl:variable name="x" select="'baz'"/>
<!-- 匹配foo/bar下本地名称等于$x的所有节点 -->
<xsl:apply-templates select="foo/bar/*[local-name() = $x]"/>

如果你的XML涉及命名空间,还可以加上namespace-uri()的判断来精准匹配:

<xsl:variable name="x" select="'baz'"/>
<xsl:variable name="target-namespace" select="'http://your-target-namespace.com'"/>
<xsl:apply-templates select="foo/bar/*[local-name() = $x and namespace-uri() = $target-namespace]"/>

方案2:用XSLT 3.0的xsl:evaluate(动态构造完整XPath)

Saxon-HE 9.8已经支持XSLT 3.0的核心特性,如果你需要构造更复杂的动态路径(比如变量是路径的多个部分),可以用xsl:evaluate函数来动态执行XPath表达式:

首先确保样式表声明为3.0版本:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="x" select="'baz'"/>
  <!-- 动态拼接XPath并执行 -->
  <xsl:apply-templates select="xsl:evaluate(concat('foo/bar/', $x))"/>
</xsl:stylesheet>

注意:使用xsl:evaluate时要注意XPath注入风险,如果$x的内容来自不可信源,需要做校验。

方案3:Saxon扩展函数(仅PE/EE版本可用)

如果你的环境是Saxon PE或EE版本(HE版本不支持),可以用Saxon的扩展函数saxon:evaluate来实现动态XPath:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:saxon="http://saxon.sf.net/"
                exclude-result-prefixes="saxon">
  <xsl:variable name="x" select="'baz'"/>
  <xsl:apply-templates select="saxon:evaluate(concat('foo/bar/', $x))"/>
</xsl:stylesheet>

但因为你用的是HE版本,这个方案就不适用了,优先考虑前两种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:03:09