xslt位置始终返回1

时间:2013-07-09 14:38:16

标签: 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>

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

2 个答案:

答案 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>