XSLT:根据xsl:for-each中的并发条件测试位置



考虑使用XPath表达式测试节点位置的以下两个xsl:value-of语句。

(1) 据我所知,这一个将返回/PParent的/ChildThree子项的值,其中有三件事与该/PParent无关——(I)它有一个值为"x"的/ChildRone;AND(ii)其具有值为"y"的/ChildTwo;AND(iii)它是其直系祖先中的第二个或后续/父级:

<xsl:value-of select="Parent[ChildOne='x'][ChildTwo='y'][position()&gt;=2]/ChildThree"/>

(2) 相比之下,此项将返回Parent的/ChildThree子项的值,其中该Parent是同时具有值为"x"的/ChildSone和值为"y"的/CChildTwo的第二个或后续Parent:

<xsl:value-of select="(Parent[ChildOne='x'][ChildTwo='y'])[position()&gt;=2]/ChildThree"/>

到目前为止还不错。然而,在下面的例子中会发生什么?在这里,我试图获得前两个条件同时为真的任何/PParent的/ChildThree子项的值,但如果/PParent是该子集中的第二个或后续子项,则仅在其前面加一个空格(即,如上面的示例(2))。当xsl:for-if语句不是同一个XPath表达式的一部分时,我如何规定xsl:for-if语句中的位置标准如何应用于xsl:for-inf语句的标准?

<xsl:for-each select="Parent[ChildOne='x'][ChildTwo='y']">
<xsl:if test="position()&gt;=2">
<xsl:text>&#x20;</xsl:text>
</xsl:if>
<xsl:value-of select="ChildThree"/>
</xsl:for-each>

两个语句(1)和(2)实际上是等价的,并且将返回相同的结果。

position()是上下文相关的。它将为您提供当前节点在先前选择的节点集中的位置。因此,当您有表达式Parent[ChildOne='x'][ChildTwo='y']时,它将返回一组节点,其中两个条件为true。执行Parent[ChildOne='x'][ChildTwo='y'][position()&gt;=2]将给出此列表中的第二个(或更大)节点。

你描述你认为(1)如何运作的方式,实际上是这样的。

<xsl:value-of select="Parent[position()&gt;=2][ChildOne='x'][ChildTwo='y']/ChildThree"/>

一种方法是,把每一个条件都放在方括号里,过滤掉之前的内容。

在这个XML上尝试一下,例如

<Parents>
   <Parent>
      <ChildOne>a</ChildOne>
      <ChildTwo>b</ChildTwo>
      <ChildThree>c</ChildThree>
   </Parent>
   <Parent>
      <ChildOne>x</ChildOne>
      <ChildTwo>y</ChildTwo>
      <ChildThree>z1</ChildThree>
   </Parent>
   <Parent>
      <ChildOne>x</ChildOne>
      <ChildTwo>y</ChildTwo>
      <ChildThree>z2</ChildThree>
   </Parent>
</Parents>

您的语句(1)和(2)都返回z2,但执行Parent[position()&gt;=2][ChildOne='x'][ChildTwo='y']/ChildThree会返回z1

这意味着您的xsl:for-each实际上应该为您提供所需的结果。

最新更新