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

13,921

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.

Share:
13,921
stefkey
Author by

stefkey

Updated on June 09, 2022

Comments

  • stefkey
    stefkey almost 2 years

    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...
    
  • stefkey
    stefkey over 7 years
    Thanks a lot. Now I have add a code snipped. What do you think?
  • kjhughes
    kjhughes over 7 years
    I think you should think carefully about what you really want to select. If I show you how to select 2 br elements before and after a h3, what will you do with them? They have no content themselves.
  • stefkey
    stefkey over 7 years
    hi and thanks! I would like to remove the <br> tags, because after and before the h3 tag there is now a padding, and the space with be is to large.
  • kjhughes
    kjhughes over 7 years
    Ok, I've updated the answer to show you how to grab 2 br elements before and 2 br elements after the targeted h3.
  • stefkey
    stefkey over 7 years
    Thanks a lot! And Interesting! And when there are sometimes 3 or 4 brtags? Can I set easy <5 instead <3 ?
  • kjhughes
    kjhughes over 7 years
    Yes, you can change the 3 if your requirements change. Remember two points: (1) First position is 1, not 0 and (2) count away from the h3.
  • stefkey
    stefkey over 7 years
    ok, i check it, but it removes all following br tags. What I search is a code to remove only brtags directly after the h3 tag. Not the br tags after a text after a h3 tag. `<h3>alright</h3><br><br>Text with important br-Tag<br>...
  • kjhughes
    kjhughes over 7 years
    Now you're changing the requirements (again). Last time: I've updated the answer to accomodate your latest request. If this helps, please accept this answer. Thanks.
  • stefkey
    stefkey over 7 years
    Thanks so much! Great, your are the xpath-boss. It's actually possible to solve. It works, many thanks! And sorry for the changing requirements, I will try in the future the question to ask clearly. But its difficult for me, I have to take more time to build the question.
  • myworldbox
    myworldbox almost 3 years
    perfect answer bro