5

我有以下模板:

<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。我怎样才能得到匹配的位置?

4

2 回答 2

3

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>

现在,当您将模板应用于这些时,隐式默认模板将匹配它们,并且对于每个模板,它将递归调用apply-templates该节点的子节点(单个abc元素)。所以现在position()会给你在abc它的父母的孩子的集合中的位置,它总是1。

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

<xsl:apply-templates select="$var1/*/*"/>

一口气选择所有abc元素。

于 2013-07-10T09:03:09.693 回答
-1

您可能需要使用<xsl:for-each ...>. 这将正确设置 position() 。

<xsl:for-each select="$var/xyz/abc">
    <xsl:variable name="pos" select="position()"/>
    ...
</xsl:for-each>
于 2013-07-10T08:56:36.170 回答