XSL:模板匹配中的position()与select中的position()

时间:2017-04-10 17:13:50

标签: xml xslt saxon

我不了解以下行为:

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<list>
    <article>Title1</article>
    <other>Other</other>
    <article>Title2</article> 
    <article>Title3</article>
</list>

XSL 1:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:strip-space elements="*"/>

    <xsl:template match="list">
        <xsl:apply-templates select="article" />
    </xsl:template>

    <xsl:template match="list/*">
        Content: <xsl:value-of select="."/> | Position: <xsl:value-of select="position()"/> | Last: <xsl:value-of select="last()"/>
    </xsl:template>

    <xsl:template match="text()" />

</xsl:stylesheet>

XSL1的输出

<?xml version="1.0" encoding="UTF-8"?>
Content: Title1 | Position: 1 | Last: 3
Content: Title2 | Position: 2 | Last: 3
Content: Title3 | Position: 3 | Last: 3

到目前为止一切顺利。

现在,如果我将上面的匹配从list/*更改为list/*[2],我就无法获得任何输出。我认为这是因为第二项是<other>,它与select="article"不匹配。

奇怪的是,当我将匹配更改为list/*[3]时,我得到位置为2的行:

<xsl:template match="list/*[3]">
    Content: <xsl:value-of select="."/> | Position: <xsl:value-of select="position()"/> | Last: <xsl:value-of select="last()"/>
</xsl:template>

<?xml version="1.0" encoding="UTF-8"?>
Content: Title2 | Position: 2 | Last: 3   

为什么position()在模板中的工作方式与match-clause中的工作方式不同?

1 个答案:

答案 0 :(得分:2)

此XPath表达式

list/*[3]

表示<list>元素的第三个子元素。节点测试[3]相对于前面路径表达式选择的节点进行评估。

另一方面,XSLT第4节指定了

  

最外层表达式(即不属于的表达式   获得其上下文:

     

[...]

     
      
  • 上下文   位置来自当前节点在当前的位置   节点列表;第一个位置是1
  •   

在模板正文中,position()last()显示为最外层表达式。因此,它们针对当前节点列表进行评估,并且该模板仅在当前节点列表由

选择的三个节点组成时适用。
<xsl:apply-templates select="article" />

<list>是当前节点时。该节点列表恰好包含三个节点,无论模板匹配多少个或哪些节点。此外,该节点列表中给定节点的位置不一定与模板匹配表达式的子表达式list/*匹配的节点列表中该节点的位置相同,也不一定与其在该节点列表中的位置相同。节点列表与模板的完全匹配表达式匹配。职位衡量标准之间只有偶然的关系。