Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath to select tags near (before and after) another element?

Tags:

html

xml

xpath

It is possible to select all br tags before and after an h3 element with XPath?

This selects only the first br tag: //h3/following-sibling::*[1][name()='br']

Here is a code snippet, I would like to select the 2 br tags before and the 2 br tags after the h3 tag:

<br />22111 Hamburg<br />(U- und Busbahnhof Billstedt)<br /><br /><h3>Wir treffen uns</h3><br /><br />um Erfahrungen auszutauschen...
like image 866
stefkey Avatar asked Oct 22 '25 21:10

stefkey


1 Answers

Notes:

  1. You probably don't mean all h3 elements but rather one particular h3 element.
  2. [1] is causing only the next following sibling to be selected.
  3. Rather than *[name()='br'], use br.
  4. Be sure you mean following-sibling, not following.

Then this XPath,

//h3[.='Heading']/following-sibling::br

will select all br elements are siblings to the h3 element whose string value is Heading.


Update

For this HTML,

<div>
   <br/>22111 Hamburg<br/>
   (U- und Busbahnhof Billstedt)
   <br/><br/>
   <h3>Wir treffen uns</h3>
   <br/><br/>
   um Erfahrungen auszutauschen...
   <br/>abc<br/>
</div>

this XPath will select the two br sibling elements immediately before the targeted h3,

//h3[.='Wir treffen uns']/preceding-sibling::br[position() < 3]

this XPath will select the two br sibling elements immediately after the targeted h3,

//h3[.='Wir treffen uns']/following-sibling::br[position() < 3]

If you want to grab all 4 at the same time, you can combine the before and after XPath expressions above via |:

//h3[.='Wir treffen uns']/preceding-sibling::br[position() < 3]
|
//h3[.='Wir treffen uns']/following-sibling::br[position() < 3]

Update 2

If you want the number range to include all nodes, not just br elements, when counting, then use this XPath:

//h3[.='Wir treffen uns']/preceding-sibling::node()[position() < 3][self::br]
|
//h3[.='Wir treffen uns']/following-sibling::node()[position() < 3][self::br]

This works by testing node() position first, then making sure that those nodes within range are br elements via [self::br]. Be aware that all text nodes will count, even ones containing only whitespace.

like image 99
kjhughes Avatar answered Oct 25 '25 10:10

kjhughes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!