在 XPath 中,如何在锚元素之前和之后选择后续兄弟节点组? [英] In XPath, how can I select groups of following-sibling nodes before and after an anchor element?

查看:24
本文介绍了在 XPath 中,如何在锚元素之前和之后选择后续兄弟节点组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下的xml文档,

I have a xml document like follows,

<sec>
    <p type="Running">aa</p>
    <p type="heading 1">bb</p>
    <p type="body">cc</p>
    <p type="body">dd</p>
    <p type="Running">ee</p>
    <p type="Body">ff</p>
    <p type="heading">gg</p>
    <p type="body">hh</p>
    <p type="body">ii</p>
    <p type="Running">jj</p>
    <p type="list">kk</p>
    <p type="list">ll</p>
    <p type="list">mm</p>
    <p type="list">nn</p>
</sec>

使用 xpath 我需要从 <p> 中选择 <p> 节点的连续后续兄弟节点,其 attr 值为 Running.

using xpath I need to select consecutive following-siblings of <p> nodes from <p> that has attr value of Running.

上面例子中的SO

    <p type="heading 1">bb</p>
    <p type="body">cc</p>
    <p type="body">dd</p>

    <p type="Body">ff</p>
    <p type="heading">gg</p>
    <p type="body">hh</p>
    <p type="body">ii</p>

    <p type="list">kk</p>
    <p type="list">ll</p>
    <p type="list">mm</p>
    <p type="list">nn</p>

应选择节点组.

如何编写 XPath 查询来选择这些节点?

How can I write a XPath query to select those nodes?

XPath version - 2.0

推荐答案

这个问题目前有三个答案,但我认为他们中的任何一个都没有真正回答这个问题.

This question currently has three answers, but I don't think any of them actually answers the question.

在 XPath 2.0 中,一切都是序列.如果您选择一组节点,在 XPath 1.0 中,您将其称为节点集",而在 XPath 2.0 中,它是节点序列".序列的一个特性是它们不能嵌套:(1, (2, 3), 4)(1, 2, 3, 4) 相同.

In XPath 2.0, everything is sequences. If you select a set of nodes, in XPath 1.0 you called that a "node set", in XPath 2.0 it is a "sequence of nodes". One property of sequences is that they cannot be nested: (1, (2, 3), 4) is the same as (1, 2, 3, 4).

您要求一个选择节点集的 select 语句,这意味着您想对每个节点集做一些事情.合乎逻辑的事情是这样的:

You ask for a select statement that selects sets of nodes, which implies that you want to do something with each set. The logical thing to do is something like the following:

for $r in sec/p[@type = 'Running']
return $r
    /following-sibling::p
    [not(@type = 'Running')]
    [. << following-sibling::p[@type = 'Running'][1]]

这是一个相当复杂的表达.虽然它会在内部选择您所追求的子集,但由于序列归一化,净效果是单个序列,其选择等于 sec/p[not(@type = 'Running')].

This is a rather complex expression. While it will internally select the subsets you are after, because of sequence normalization, the net effect is a single sequence with a selection equal to sec/p[not(@type = 'Running')].

在 XPath 2.0 中不可能以不同的方式执行此操作,因此很自然的做法是使用宿主语言(如 XSLT 或 XQuery)来选择 @type = 'Running'节点,并且在每次点击时,选择(并做一些事情)以下兄弟节点,直到下一个 @type = 'Running':

In XPath 2.0 it is not possible to do this differently, so the natural thing to do then is to use a host language, like XSLT or XQuery, to select the @type = 'Running' nodes, and on each hit, select (and do something) will the following siblings until the next @type = 'Running':

<xsl:template match="sec">
    <xsl:apply-templates select="p[@type = 'Running']" />
</xsl:template>

<xsl:template match="p">
    <!-- do something before the group -->
    <xsl:apply-templates select="following-sibling::p[following-sibling::p[@type = 'Running'] >> .]" mode="group"/>
    <!-- do something after the group -->
</xsl:template>

<xsl:template match="p" mode="group">
   <!-- do something with items in the group -->
</xsl:template>

在这里使用 xsl:for-each-group 可能更容易,它适用于这种情况.

It is probably easier to use an xsl:for-each-group here, which is meant for this kind of thing.

这篇关于在 XPath 中,如何在锚元素之前和之后选择后续兄弟节点组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆