首页 文章

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

提问于
浏览
1

考虑使用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”和/ ChildTwo的/ ChildOne值“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 回答

  • 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 实际上应该给你你期望的结果 .

相关问题