XPath表达式以获得所有前面的兄弟节点UNTIL条件满足

时间:2013-06-03 20:38:08

标签: xml xslt xpath

这是我的XML:

...
<table></table>
<p class="source"></p>
<p class="notes"></p>
<p class="notes"></p>
<p class="notes"></p>
<p />
<p />
...
<table></table>
<p class="notes"></p>
<p class="notes"></p>
<p />
...

我正在尝试编写一个为每个"<p>"标记调用的模板。此模板将返回此标记相对于其前一个"<table>"标记所在的索引。它应该只计算属性“class”等于“notes”的"<p>"个标记。

因此,对于上面的示例,我想要在下面的评论中注明索引:

...
<table></table>
<p class="source"></p>
// should return 0 <p class="notes"></p>
// should return 1 <p class="notes"></p>
// should return 2 <p class="notes"></p>
<p />
<p />
...
<table></table>
// should return 0 <p class="notes"></p>
// should return 1 <p class="notes"></p>
<p />
...

这是我到目前为止所提出的:

 <xsl:template name="PrintTableNumberedNote">
 <xsl:variable name="currentPosition" select="count(preceding-sibling::p[(@class='notes')])"/>
 <xsl:value-of select="$currentPosition"/>.     
 </xsl:template>

我需要添加逻辑以使计数在前一个表的第一次出现时停止,因为这是结果在此模板中错误显示的结果:

...
<table></table>
<p class="source"></p>
// returns 0 <p class="notes"></p>
// returns 1 <p class="notes"></p>
// returns 2 <p class="notes"></p>
<p />
<p />
...
<table></table>
// returns 3 <p class="notes"></p>
// returns 4 <p class="notes"></p>
<p />
...

如何将此其他条件与我的XPath语句结合使用?

谢谢,

1 个答案:

答案 0 :(得分:2)

一个简单的解决方案是在前一个p之前减去table个元素:

<xsl:variable name="currentPosition" select="
    count(preceding-sibling::p[@class='notes']) -
    count(preceding-sibling::table/preceding-sibling::p[@class='notes']"/>

如果您希望节点集包含前面p和当前节点之间的所有table元素,您可以尝试:

<xsl:variable name="numTables" select="count(preceding-sibling::table)"/>
<xsl:variable name="paragraphs" select="
    preceding-sibling::p[
        @class='notes' and
        count(preceding-sibling::table) = $numTables]"/>

或者,使用上面的变量$currentPosition

<xsl:variable name="paragraphs" select="preceding-sibling::p
    [@class='notes']
    [position() &lt;= $currentPosition]"/>

另见this similar question