我不明白以下行为:
输入 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()
模板中的工作方式与匹配子句中的工作方式不同吗?
最佳答案
这个 XPath 表达式
list/*[3]
表示 <list>
的第三个子元素元素。节点测试[3]
相对于前面的路径表达式选择的节点进行评估。
另一方面,XSLT 第 4 部分指定
an outermost expression (i.e. an expression that is not part of another expression) gets its context as follows:
[...]
- the context position comes from the position of the current node in the current node list; the first position is 1
在模板正文中,position()
和last()
作为最外层的表达式出现。因此,它们是根据当前节点列表进行评估的,并且仅当当前节点列表由
<xsl:apply-templates select="article" />
当 <list>
是当前节点。该节点列表恰好包含三个节点,无论模板匹配多少个或哪些节点。此外,给定节点在该节点列表中的位置不一定与该节点在子表达式 list/*
匹配的节点列表中的位置相同。模板的匹配表达式的位置,也不与模板的完全匹配表达式匹配的节点列表中的位置相同。位置度量之间仅存在偶然关系。
关于xml - XSL : position() in template match vs position() in select,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43329186/