关于前驱轴和position()已经讨论过不少了,可总是意犹未尽哪!实在是它们隐含了太多东西。
XML原文件:
<people>
<person>
<name>张三</name>
<age>20</age>
</person>
<person>
<name>李四</name>
<age>21</age>
</person>
<person>
<name>王五</name>
<age> 22 </age>
</person>
<total>3</total>
</people>
XSLT文件:
....................................................................
<xsl:template match="/">
<xsl:for-each select="people/total">
<xsl:for-each select="preceding-sibling::*">
<xsl:text>
</xsl:text>
<xsl:value-of select="name"/><xsl:text> </xsl:text>
<xsl:value-of select="position()"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:value-of select="preceding-sibling::*[1]/name"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
转换后的结果:
张三 1
李四 2
王五 3
王五
噢,看到了什么,当我们用for-each来输出的时候,张三在前驱轴的position明明是1的,但我们直接用preceding-sibling::*[1]来输出,却发现position()为1的是王五。
这到底是为什么?
只能事后诸葛马后炮地这样来理解,当寻找前驱轴时,是从当前节点向XML文档的源头来找的,所以第一个找到的应该是王五,然而当用for-each来对前驱轴的所有节点输出时,前驱轴已经作为一个节点集合来处理了,这时的position()来标志节点的当前位置,只是一个累加的结果而已。
我们试着改变XSLT文件:
....................................................................
<xsl:template match="/">
<xsl:for-each select="people/total">
<xsl:for-each select="preceding-sibling::*[position()=1]">
<xsl:text>
</xsl:text>
<xsl:value-of select="name"/><xsl:text> </xsl:text>
<xsl:value-of select="position()"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:value-of select="preceding-sibling::*[1]/name"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出结果为:
王五 1
王五