Что касается моего комментария, вы могли бы сделать следующее:
//i[contains(.,'foo')]/following-sibling::h1
или даже
//*[contains(.,'foo')]/following-sibling::h1
Обновление: Если вы считаете предыдущий h1
тем, который "содержит" foo
, вы можете сделать это:
//*[contains(., 'foo')]/(following-sibling::h1 | remove(preceding-sibling::h1, 1)))
это работает, например,
<h1>text1</h1> <b> description1 </b>
<h1>text2</h1> <b> description2 </b> <i>foo</i>
<h1>text3</h1>
<h1>text4</h1> <b> description4 </b>