XPath: Select self and following sibling together

10,746

Solution 1

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.

Solution 2

When using XPath 2.0:

//dt[contains(text(), "Test")]/(self::dt, following-sibling::dd)
Share:
10,746
Umair A.
Author by

Umair A.

Updated on June 11, 2022

Comments

  • Umair A.
    Umair A. about 2 years
    <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.

  • Umair A.
    Umair A. about 11 years
    That's what I alternatively used but this is long :)
  • Navin Rawat
    Navin Rawat about 11 years
    if you are using "1.0", this is the only option
  • Umair A.
    Umair A. about 11 years
    that's very neat. but I am using 1.0