>我有以下模板:
<xsl:template match="/">
<Envelopes>
<xsl:variable name="var1" select="ExtObj:GetXml()"/>
<xsl:apply-templates select="$var1/*"/>
</Envelopes>
</xsl:template>
<xsl:template match='xyz/abc'>
<xsl:variable name="pos" select="position()"/>
</xsl:template>
现在$var1
具有与第二个模板匹配的元素,但$pos
始终设置为 1。如何获得比赛位置?
position()
函数本质上是上下文相关的 - 它为您提供当前节点在导致此模板触发的apply-templates
选择的节点集中的位置。 因此,这取决于$var1
变量包含的内容。 如果$var1
是包含xyz
元素的节点集,每个元素都有一个abc
子元素,则$var1/*
将一次性选择所有abc
元素:
<xyz> <!-- $var1 -->
<abc/> <!-- $var1/* -->
</xyz>
<xyz> <!-- $var1 -->
<abc/> <!-- $var1/* -->
</xyz>
(空格文本节点和注释仅用于说明,假设实际的 XML 树仅包含元素节点(,您将获得所需的position()
值。
但是,如果$var1
是 XPath 数据模型中的单个根节点(例如文档片段(,该节点将xyz
元素作为其子元素,则$var1/*
将选择xyz
元素,而不是abc
元素。
<!-- $var1 (the root node) -->
<xyz> <!-- $var1/* -->
<abc/>
</xyz>
<xyz> <!-- $var1/* -->
<abc/>
</xyz>
现在,当您将模板应用于这些模板时,隐式默认模板将匹配它们,并且对于每个模板,它将在该节点的子节点(单个abc
元素(上递归调用apply-templates
。 所以现在position()
会给你 abc
在其父子项集合中的位置,该位置将始终为 1。
如果这是正在发生的事情,那么最简单的解决方法是说
<xsl:apply-templates select="$var1/*/*"/>
一次性选择所有abc
元素。
使用 <xsl:for-each ...>
。这将正确设置 position((。
<xsl:for-each select="$var/xyz/abc">
<xsl:variable name="pos" select="position()"/>
...
</xsl:for-each>