我不了解以下行为:
输入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中的工作方式不同?
答案 0 :(得分:2)
此XPath表达式
list/*[3]
表示<list>
元素的第三个子元素。节点测试[3]
相对于前面路径表达式选择的节点进行评估。
另一方面,XSLT第4节指定了
最外层表达式(即不属于的表达式 获得其上下文:
[...]
- 上下文 位置来自当前节点在当前的位置 节点列表;第一个位置是1
在模板正文中,position()
和last()
显示为最外层表达式。因此,它们针对当前节点列表进行评估,并且该模板仅在当前节点列表由
<xsl:apply-templates select="article" />
当<list>
是当前节点时。该节点列表恰好包含三个节点,无论模板匹配多少个或哪些节点。此外,该节点列表中给定节点的位置不一定与模板匹配表达式的子表达式list/*
匹配的节点列表中该节点的位置相同,也不一定与其在该节点列表中的位置相同。节点列表与模板的完全匹配表达式匹配。职位衡量标准之间只有偶然的关系。