XPath选择两个标题之间的所有元素?

时间:2017-03-30 15:43:00

标签: html xml xpath

<h2>Headline 1</h2>
<p>some text</p>
<p>some more text</p>
<ul>
<li>list item 1</li>
<li>list item 2</li>
</ul>
<p>more text</p>
<h2>Headline 2</h2>

我在网页上有以上内容,我希望能够定位包含文本h2的第一个'Headline 1'之后的所有元素,但不包括元素h2包含文本'Headline 2'

我可以像这样定位元素:

//*[count(preceding-sibling::hr)=1]

但这不是特定于所包含的文本,因此如果页面发生了变化,那么xpath可能指向完全不同的东西。

在sudo代码术语中我想要的是:

  

给我标题'Headline 1'和标题之间的所有元素   标题'Headline 2'包括'Headline 1'

这一切都可能吗?

3 个答案:

答案 0 :(得分:2)

这个XPath,

//*[    preceding-sibling::h2[. = 'Headline 1'] 
    and following-sibling::h2[. = 'Headline 2']]

将选择h2 s之间的所有元素,字符串值为'Headline 1''Headline 2'

<p>some text</p>
<p>some more text</p>
<ul>
<li>list item 1</li>
<li>list item 2</li>
</ul>
<p>more text</p>

Andersson在评论中指出OP希望第一个h2包含在选择中。

Andersson最初的想法是可行的:

//h2[. = 'Headline 1'] |
//*[    preceding-sibling::h2[. = 'Headline 1'] 
    and following-sibling::h2[. = 'Headline 2']]

这是另一种方式:

//*[self::h2[. = 'Headline 1']
    or (    preceding-sibling::h2[. = 'Headline 1'] 
        and following-sibling::h2[. = 'Headline 2']]

或者,可能是理想的方式:

//h2[. = 'Headline 2']
    /preceding-sibling::*[not(following-sibling::h2[. = 'Heading 1'])]

因为它避免了两次指定'Heading 1'

答案 1 :(得分:0)

如果尝试类似

的内容怎么办?
//*[text()="Headline 1"]/following-sibling::*

答案 2 :(得分:0)

//h2[contains(.,'Headline 1')]//*

将返回标题下方的每个元素。您可以使用

进一步缩小范围
//h2[contains(.,'Headline 1')]//p

用于段落文本,但不包括li元素。