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

时间:2013-12-13 18:09:21

标签: xslt xpath

考虑使用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()&gt;=2]/ChildThree"/>

(2)相比之下,这一个将返回/ Parent的/ ChildThree子元素的值,其中/ Parent是第二个或后续/父元素,它们具有值为“x”的两个/ ChildOne a / ChildTwo,值为“y”:

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

1 个答案:

答案 0 :(得分:1)

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

position()是上下文相关的。它将为您提供先前选择的节点集中当前节点的位置。因此,当你有表达式Parent[ChildOne='x'][ChildTwo='y']时,它返回一组两个条件为真的节点。执行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 实际上应该为您提供您期望的结果。