我可以想出一种方法来实现这一点,但它不好看,所以希望有人会想出更好的方式...
首先,我定义的变量与当前节点的电平
<xsl:variable name="level">
<xsl:value-of select="count(ancestor::*)"/>
</xsl:variable>
接着,匹配碰巧是叶节点,并且不具有任何祖先(包括本身所有后代或当前节点,但只有当前级别),具有指定的属性@trg ='rr'。
<xsl:apply-templates select=".//*[not(node())][not(ancestor-or-self::*[count(ancestor::*) > $level][@trg='rr'])]">
<xsl:with-param name="currentLevel" select="$level"/>
</xsl:apply-templates>
匹配叶节点后,您应该能够获得父节点的路径备份到当前节点。
下面是完整的样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/t"/>
</xsl:template>
<xsl:template match="t">
<!-- The level of the current node -->
<xsl:variable name="level">
<xsl:value-of select="count(ancestor::*)"/>
</xsl:variable>
<paths>
<!-- Match all leaf nodes where there is not an ancestor (up to the current node) with the attribute @trg = 'rr' -->
<xsl:apply-templates select=".//*[not(node())][not(ancestor-or-self::*[count(ancestor::*) > $level][@trg='rr'])]">
<xsl:with-param name="currentLevel" select="$level"/>
</xsl:apply-templates>
</paths>
</xsl:template>
<!-- For leaf nodes, write out the ancestor path to a specified level -->
<xsl:template match="*[not(node())]">
<xsl:param name="currentLevel"/>
<path>
<xsl:for-each select="ancestor::*[count(ancestor::*) >= $currentLevel]">
<xsl:value-of select="name()"/>
<xsl:text>/</xsl:text>
</xsl:for-each>
<xsl:value-of select="name()"/>
</path>
</xsl:template>
</xsl:stylesheet>
当给定的XML应用,下面的结果返回
<paths>
<path>t/a1/b2/c2</path>
<path>t/a2/b3/c3</path>
</paths>