36

我有以下 xml:

<doc>
    <divider />
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <divider />
    <p>text</p>
    <p>text</p>
    <divider />
    <p>text</p>
    <divider />
</doc>

我想在第一个分隔元素之后选择所有 p 节点,直到下一次出现分隔元素。我尝试使用以下 xpath:

//divider[1]/following-sibling::p[following::divider]

但问题是它在最后一个分隔符元素之前选择所有 p 元素。我不确定如何使用 xpath 1 来做到这一点。

4

4 回答 4

36

与 bytebuster 的概念相同,但 xpath 不同:

/*/p[count(preceding-sibling::divider)=1]
于 2012-06-02T04:50:36.950 回答
21

这是一个通用的 XPath 表达式

/*/divider[$k]
    /following-sibling::p
       [count(.|/*/divider[$k+1]/preceding-sibling::p)
       =
        count(/*/divider[$k+1]/preceding-sibling::p)
       ]

如果您替换$k为,1则恰好p选择了所需的节点。

如果你$k2then替换p2nd 和 3rd 之间的所有元素divider,...,等等。

说明

这是节点集交集的Kayessian XPath 1.0 公式的简单应用:

$ns1[count(.|$ns2) = count($ns2)]

选择同时属于节点集$ns1和的所有节点$ns2

在这种特定情况下,我们替换$ns1为:

/*/divider[$k]/following-sibling::p

我们$ns2用:

/*/divider[$k+1]/preceding-sibling::p
于 2012-06-02T05:04:09.993 回答
8

I think there's a much simpler and probably faster solution: you want all preceding siblings of the second divider that have at least one preceding sibling divider:

/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]

It gets a bit more complex, of course, if you want to find the paras between the second and third dividers: then you want something more like Daniel Haley's solution.

于 2012-06-02T17:40:43.707 回答
5

选择所有p只有一个元素divider的东西preceding-sibling怎么样?

//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
于 2012-06-02T04:21:40.397 回答