如何使用XPath选择最后N个元素?

时间:2009-01-19 18:21:02

标签: xml xslt xpath

我支持一个生成内容XML的网站,然后使用XSLT将其翻译成网页。我被要求创建一个新的样式表,它将“存档”页面的输出转换为Atom以进行联合。我遇到的问题是存档页面包含相当多的项目 - 142和计数 - 并且Feed应该永远不会有超过30项。

目前,存档页面的输出如下所示:

<archive>
    <year>
        <month>
            <day>
            <day>
            ...
        </month>

        ...
    </year>

    ...
</archive>

HTML转换使用yearmonth标记,但与Atom Feed完全无关。我曾希望将position()函数与后代轴一起使用(//day[position()>last()-30]),但这会选择每个月的最后30天,这根本不是我需要的。 : - )

有没有办法用XSLT或XPath做到这一点?必须修改XML生成器以添加(例如)过去30天的feed="true"属性,这似乎是一个非常讨厌的kludge。

2 个答案:

答案 0 :(得分:10)

position()/ last()返回当前上下文中的位置/最后位置,因此当导航器位于一个&lt; month&gt;中时,position()将返回&lt; day&gt;在那个月内,last()将返回最后一天&lt; day&gt;在那个月内,但我猜你知道。

因此,您可以做的是将所有&lt; day&gt;的数据展平并放入变量中,然后再像以前一样选择。

<xsl:variable name="days" select="//day"/>
<xsl:apply-templates select="$days[position()>last()-30]" />

答案 1 :(得分:4)

今天浏览XSLT spec,我找到一条说明解释//行为的原因的说明:

  

///descendant-or-self::node()/的缩写。例如,//para/descendant-or-self::node()/child::para的缩写,因此将选择文档中的任何para元素(即使作为文档元素的para元素也将由{{{ 1}}因为文档元素节点是根节点的子节点;) //paradiv//para的缩写,因此会选择所有div/descendant-or-self::node()/child::para div子女的后代。

     

注意:位置路径para与位置路径//para[1]的含义不同。后者选择第一个后代/descendant::para[1]元素;前者选择所有后代para元素,这些元素是父母的第一个para子元素。

换句话说,使用para时,//沿position()轴计算,而不是child轴。通过指定descendant-or-selfdescendant,您可以按预期获得第一个/最后一个 n 节点:

descendant-or-self