如何在XSLT 1.0中找到另一子树内的等效节点?
在XSLT 1.0中匹配subtree B对应节点的实现方案
可以实现,但由于XPath 1.0没有path()函数(这是XPath 2.0及以上特性),也没有原生字符串替换能力,同时XSLT 1.0不支持动态执行XPath表达式,我们需要通过递归遍历节点路径的方式,从subtree B的根节点开始逐层定位对应节点。
核心思路
通过递归回溯当前subtree A节点的祖先链,在subtree B中逐层匹配同名、同位置的节点,以此实现与"替换路径"等价的效果。
具体实现
递归匹配模板
编写一个递归模板,处理节点的路径回溯与对应节点定位,同时考虑同名兄弟节点的位置(避免结构中有多个同名节点时匹配错误):
<xsl:template name="get-corresponding-node"> <!-- 当前处理的subtree A节点 --> <xsl:param name="current-node"/> <!-- subtree B的根节点 --> <xsl:param name="target-root"/> <!-- 递归终止条件:当前节点是subtree A的根,直接返回subtree B的根 --> <xsl:if test="$current-node = /root/subtreeA"> <xsl:copy-of select="$target-root"/> </xsl:if> <!-- 递归逻辑:先找父节点的对应节点,再定位当前节点在父节点下的位置 --> <xsl:if test="$current-node != /root/subtreeA"> <!-- 递归获取父节点在subtree B中的对应节点 --> <xsl:variable name="parent-corresponding"> <xsl:call-template name="get-corresponding-node"> <xsl:with-param name="current-node" select="$current-node/parent::*"/> <xsl:with-param name="target-root" select="$target-root"/> </xsl:call-template> </xsl:variable> <!-- 计算当前节点在父节点同名兄弟中的位置 --> <xsl:variable name="node-position" select="count($current-node/preceding-sibling::*[name()=name($current-node)]) + 1"/> <!-- 返回subtree B中对应位置的同名节点 --> <xsl:copy-of select="$parent-corresponding/*[name()=name($current-node)][position()=$node-position]"/> </xsl:if> </xsl:template>
模板调用示例
当处理/root/subtreeA/alpha/1节点时,调用上述模板即可获取subtree B中的对应节点:
<!-- 假设当前上下文为subtreeA/alpha/1节点 --> <xsl:variable name="matching-node"> <xsl:call-template name="get-corresponding-node"> <xsl:with-param name="current-node" select="."/> <xsl:with-param name="target-root" select="/root/subtreeB"/> </xsl:call-template> </xsl:variable> <!-- 使用匹配到的节点数据 --> <xsl:value-of select="$matching-node"/>
关键细节说明
- 位置匹配:通过
preceding-sibling统计当前节点在同名兄弟中的位置,确保结构中有多个同名节点时(比如多个<alpha>节点),能精准匹配到对应位置的节点。 - 递归终止:当回溯到subtree A的根节点时,直接返回subtree B的根,完成递归链的起点定位。
内容的提问来源于stack exchange,提问作者Thomas Hilbert
相关产品推荐
相关产品推荐

