使用xpath查找倒数第二个节点

时间:2012-05-02 19:48:08

标签: xpath xslt-1.0 docbook

我有一个包含chapters和嵌套sections的XML文档。 我试图找到第一个二级部分祖先的任何部分。 这是ancestor-or-self轴中倒数第二个部分。 伪代码:

<chapter><title>mychapter</title>
  <section><title>first</title>
     <section><title>second</title>
       <more/><stuff/>
     </section>
  </section>
</chapter>

我的选择器:

<xsl:apply-templates 
    select="ancestor-or-self::section[last()-1]" mode="title.markup" />

当然直到last() - 1还没有定义(当前节点是first部分)。

如果当前节点低于second部分,我想要标题second。 否则我想要标题first

2 个答案:

答案 0 :(得分:4)

用这个替换你的xpath:

ancestor-or-self::section[position()=last()-1 or count(ancestor::section)=0][1]

由于您已经可以在除一个之外的所有情况下找到正确的节点,我将您的xpath更新为同时找到first部分(or count(ancestor::section)=0),然后选择( [1])第一个匹配(按相反的文档顺序,因为我们使用的是ancestor-or-self轴)。

答案 1 :(得分:2)

这是一个更短,更有效的解决方案

(ancestor-or-self::section[position() > last() -2])[last()]

这将选择名为section的前两个最顶层祖先中的最后一个。如果只有一个这样的祖先,那么它本身就是最后一个。

这是一个完整的转型

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="section">
  <xsl:value-of select="title"/>
  <xsl:text> --> </xsl:text>

  <xsl:value-of select=
  "(ancestor-or-self::section[position() > last() -2])[last()]/title"/>
  <xsl:text>&#xA;</xsl:text>
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

对以下文档应用此转换(基于提供的,但添加了更多嵌套的section元素):

<chapter>
    <title>mychapter</title>
    <section>
        <title>first</title>
        <section>
            <title>second</title>
            <more/>
            <stuff/>
        <section>
            <title>third</title>
        </section>
        </section>
    </section>
</chapter>

产生了正确的结果

first --> first
second --> second
third --> second