考虑使用XPath表达式测试节点位置的以下两个xsl:value-of语句 .
(1)根据我的理解,这一个将返回/ Parent的/ ChildThree子项的值,其中三个事物独立于/ Parent:(i)它具有值为“x”的/ ChildOne; (ii)它有一个/ ChildTwo,其值为“y”; (iii)它是其直系祖先的第二个或后续/父母:
<xsl:value-of select="Parent[ChildOne='x'][ChildTwo='y'][position()>=2]/ChildThree"/>
(2)相比之下,这个将返回/ Parent的/ ChildThree子项的值,其中/ Parent是第二个或后续的/父/那些具有值为“x”和/ ChildTwo的/ ChildOne值“y”:
<xsl:value-of select="(Parent[ChildOne='x'][ChildTwo='y'])[position()>=2]/ChildThree"/>
到现在为止还挺好 . 但是,以下示例中会发生什么?在这里,我试图获得前两个条件同时为真的任何/ Parent的/ ChildThree子元素的值,但是如果/ Parent是该子集中的第二个或后续条件,则仅在其前面加上空格(即,例如上面的例子(2) . 我如何指示xsl:if语句中的位置标准如何应用于xsl:for-if语句中的条件,当它不是同一XPath表达式的一部分时?
<xsl:for-each select="Parent[ChildOne='x'][ChildTwo='y']">
<xsl:if test="position()>=2">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="ChildThree"/>
</xsl:for-each>
1 回答
两个语句(1)和(2)实际上是等价的,并且将返回相同的结果 .
position() 是上下文相关的 . 它将为您提供先前选择的节点集中当前节点的位置 . 因此,当你有表达式
Parent[ChildOne='x'][ChildTwo='y']
时,它返回一组节点,其中两个条件为真 . 执行Parent[ChildOne='x'][ChildTwo='y'][position()>=2]
将在此列表中提供第二个(或更高)节点 .你描述你的思维方式(1)的方式实际上就是这样的 .
想到它的一种方法是考虑方括号中的每个条件来过滤之前的情况 .
例如,尝试使用此XML
你的语句(1)和(2)都返回 z2 ,但是
Parent[position()>=2][ChildOne='x'][ChildTwo='y']/ChildThree
返回 z1 .这意味着你的 xsl:for-each 实际上应该给你你期望的结果 .