我有一个类似于
的文档<root>
<element>
<subelement1 />
<subelement2 />
</element>
<element>
<subelement2 />
<subelement1 />
</element>
</root>
在/element[2]/[someNode]
上下文中的我的XSLT表中,我希望得到一个代表/element[1]/[someNode]
距离的数字(即/element1/[someNode]
的前一个兄弟的数量)。例如,在/element[2]/subelement1
的上下文中,我想要一些方法来获取数字2,即从/element[1]
到/element[1]/subelement2
的距离。我只需要<element>
的第一个实例中给定节点名称的距离。
直觉我觉得我可以像
那样构建它 <xsl:variable name="nodename" select="name()" />
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" />
但不幸的是这张表没有编译。我正在尝试在XSLT中实现什么?
答案 0 :(得分:8)
您不能将XSLT变量用作XPATH语句的轴,但可以在谓词过滤器中使用它。因此,如果要匹配任何元素(即*
),然后将其限制为名称()等于存储在变量中的值(即*[name()=$nodename]
)的元素,则XPATH将有效
您构建的XPATH将返回匹配元素的值。如果要返回与该模式匹配的元素数,可以使用count()
函数。
您的示例XML有一个文档元素<root>
,但您的XPATH不包含<root>
。
这将使用上下文节点指定的变量返回previous-sibling元素的数量:
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="count(/root/element[1]/*[name()=$nodename]/preceding-sibling::*)" />
您可以删除变量,只需使用:
<xsl:value-of select="count(/root/element[1]/*[name()=name(current())]/preceding-sibling::*)" />
答案 1 :(得分:1)
*[name() = $nodename]
可能是您想要的而不是$nodename
,但您应该更好地使用local-name()和namespace-uri()的值定义两个变量,并检查例如*[local-name() = $localname and namespace-uri() = $namespaceuri]
具有选择元素的命名空间安全方式。
答案 2 :(得分:0)
很遗憾,构建xpath是不可能的。 XPath是静态编译的;你不能动态生成它们(或者如果你这样做,它们只是字符串而且不能被执行)。
然而,你可以做的是写一个恰好交叉引用几个本身是动态的值的查询......