xslt 位置总是返回 1

Vic*_*jee 5 xslt xslt-1.0

我有以下模板:

<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>
Run Code Online (Sandbox Code Playgroud)

现在$var1有与第二个模板匹配的元素,但$pos始终设置为 1。如何获得匹配的位置?

Ian*_*rts 3

position()函数本质上是上下文相关的 - 它为您提供当前节点在由导致apply-templates此模板触发的节点所选择的节点集中的位置。所以这取决于变量到底$var1包含什么。如果$var1是一个包含元素的节点集xyz,每个元素都有一个abc子元素,那么将一次性$var1/*选择所有元素:abc

<xyz>        <!-- $var1    -->
  <abc/>     <!-- $var1/*  -->
</xyz>
<xyz>        <!-- $var1    -->
  <abc/>     <!-- $var1/*  -->
</xyz>
Run Code Online (Sandbox Code Playgroud)

(空白文本节点和注释仅用于说明,假设真实的 XML 树仅包含元素节点),您将获得position()您期望的值。

但如果$var1是 XPath 数据模型(例如文档片段)中的单个根节点,并且将元素xyz作为其子元素,则将$var1/*选择xyz元素,而不是元素abc

             <!-- $var1  (the root node)  -->
<xyz>        <!-- $var1/*                 -->
  <abc/>
</xyz>
<xyz>        <!-- $var1/*                 -->
  <abc/>
</xyz>
Run Code Online (Sandbox Code Playgroud)

现在,当您将模板应用于这些时,隐式默认模板将与它们匹配,并且对于每个模板,它将递归调用apply-templates该节点的子节点(单个abc元素)。现在将为您提供其父级子级集合中position()的位置,该位置始终为 1。abc

如果发生这种情况,那么最简单的解决方法就是说

<xsl:apply-templates select="$var1/*/*"/>
Run Code Online (Sandbox Code Playgroud)

abc一次性选择所有元素。