<div>
<dt>
Test 1
</dt>
<dd>
</dd>
<dt>
Test 2
</dt>
<dd>
</dd>
</div>
I have this XPath written so far
//dt[contains(text(), "Test")]/self::dt|following-sibling::dd
But this is not bringing both dt and dd but just dt.
We can use the XPath following sibling axis to find this. So, for this scenario, the XPath expression will be. And we need to identify its sibling “div ” element, as shown below. However, if numerous siblings have the same node, XPath will recognise all of the different elements.
The preceding-sibling axis indicates all the nodes that have the same parent as the context node and appear before the context node in the source document.
The self axis indicates the context node itself. It can be abbreviated as a single period ( . ).
If it must be a single XPath 1.0 expression then you'll have to say
//dt[contains(., 'Test')] | //dt[contains(., 'Test')]/following-sibling::dd[1]
The final [1]
is important, as without that it would extract all dd elements that follow a dt containing "Test", i.e. given
<div>
<dt>
Test 1
</dt>
<dd>
Foo
</dd>
<dt>
Something else 2
</dt>
<dd>
Bar
</dd>
</div>
the version without the [1]
would match three nodes, the dt
containing "Test 1" and both the "Foo" and "Bar" dd
elements. With the [1]
you would correctly get only "Test 1" and "Foo".
But depending on exactly how you're using the XPath it may be clearer to first select
//dt[contains(., 'Test')]
and then iterate over the nodes that this matches, and evaluate
. | following-sibling::dd[1]
in the context of each of those nodes in turn.
When using XPath 2.0:
//dt[contains(text(), "Test")]/(self::dt, following-sibling::dd)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With