Theo van der Zee
Theo van der Zee

Reputation: 229

XPath: get closest heading element (h1, h2, h3, etc.)

I want to select the heading element (whether h1, h2, h3, h4, h5 or h6) that is closest above the form using XPath in PHP.

<h2>Foo</h2>
<h3>Bar</h3>
<form>
    <input />
</form>

The example above should return the h3 (Bar) because it is closest to the form.

<h4>Kee</h4>
<form>
    <input />
</form>

This example on the other hand should return the h4 (Kee) because it is closest.

This query (from https://stackoverflow.com/a/2216795/4391251) works fine for just the h2 tags. I could modify it for h1, h3, h4, h5, etc. but I want a catch-all query.

$headings = $xpath->query('((//form)[2]/ancestor::*/h2[.!=""])[last()]');

Basically I want something like this

$headings = $xpath->query('((//form)['.$i.']/ancestor::*/[h2 or h3][.!=""])[last()]');

Except for that doesn't return any results, and neither does (based on https://stackoverflow.com/a/7995095/4391251)

$headings = $xpath->query('((//form)['.$i.']/ancestor::*/[self::h2 or self::h3][.!=""])[last()]');

What query will give the desired results?

Upvotes: 3

Views: 3347

Answers (3)

awuu
awuu

Reputation: 251

/html/body/*[starts-with(name(),'h')]

Upvotes: -1

har07
har07

Reputation: 89295

You can try something like this :

$xpath->query('//form['.$i.']/preceding-sibling::*[self::h2 or self::h3][1]')

basically, the xpath get the first preceding sibling of form[i] that is of type <h2> or <h3> (or whatever, just list all other elements as needed in the xpath predicate).

Upvotes: 2

splash58
splash58

Reputation: 26153

Take the fist h before form

//form/preceding::*[starts-with(name(),'h')][1]

Upvotes: 1

Related Questions