How can I execute XPath queries on DOMElements using PHP?

I am trying to execute Xpath requests on DOMElements, but it doesn't seem to work. Here is the code

<html> <div class="test aaa"> <div></div> <div class="link">contains a link</div> <div></div> </div> <div class="test bbb"> <div></div> <div></div> <div class="link">contains a link</div> </div> </html> 

What I am doing is:

 $dom = new DOMDocument(); $html = file_get_contents("file.html"); @$dom->loadHTML($html); $xpath = new DOMXPath($dom); $entries = $xpath->query("//div[contains(@class,'test')]"); if (!$entries->length > 0) { echo "Nothing\n"; } else { foreach ($entries as $entry) { $link = $xpath->query('/div[@class=link]',$entry); echo $link->item(0)->nodeValue; // => PHP Notice: Trying to get property of non-object } } 

Everything works fine up to $xpath->query('/div[@class=link], $entry); . I do not know how to use Xpath for a specific DOMElement ($ entry).

How to use xpath queries for DOMElement?

+7
source share
1 answer

It sounds like you're trying to mix CSS selectors with XPath. You want to use the predicate ( [...] ) looking at the value of the class attribute.

For example, your //div.link might look like //div[contains(concat(' ',normalize-space(@class),' '),' link ')] .

Secondly, in a loop, you try to make a request with a node context, and then ignore it using the absolute location path (it starts with a slash).

Updated to reflect changes in the question:

Your second XPath expression ( /div[@class=link] ) is still a) absolute, and b) has the wrong condition. You want to request the appropriate elements relative to the specified node ( $entry ) context with the class attribute having the string value link .

So, /div[@class=link] should become something like a div[@class="link"] , which is looking for $entry child elements (use .//div[...] or descendant::div[...] if you want to search deeper).

+7
source

All Articles