我有以下模板:
<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.我如何获得匹配的位置?
答案 0 :(得分:2)
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
1}}元素,而不是abc
元素。
<!-- $var1 (the root node) -->
<xyz> <!-- $var1/* -->
<abc/>
</xyz>
<xyz> <!-- $var1/* -->
<abc/>
</xyz>
现在,当您对这些模板应用模板时,隐式默认模板将与它们匹配,并且对于每个模板,它将递归调用该节点的子节点(单个apply-templates
元素)上的abc
。因此,现在position()
将为您提供其父级子集中abc
的位置,该位置始终为1.
如果 正在发生什么,那么最简单的解决方法就是说
<xsl:apply-templates select="$var1/*/*"/>
一次性选择所有abc
元素。
答案 1 :(得分:-1)
您可能需要使用<xsl:for-each ...>
。这将正确设置position()。
<xsl:for-each select="$var/xyz/abc">
<xsl:variable name="pos" select="position()"/>
...
</xsl:for-each>