Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath to query multiple selectors

Tags:

regex

php

xpath

I want to get values and attributes from a selector and then get attributes and values of its children based on a query.

allow me to give an example.

this is the structure

<div class='message'>
   <div>
   <a href='http://www.whatever.com'>Text</a>
   </div>

   <div>
    <img src='image_link.jpg' />
   </div>

</div>

<div class='message'>
   <div>
   <a href='http://www.whatever2.com'>Text2</a>
   </div>

   <div>
    <img src='image_link2.jpg' />
   </div>

</div>

So I would like to make a query to match all of those once.

Something like this:

 //$dom is the DomDocument() set up after loaded HTML with $dom->loadHTML($html);
$dom_xpath = new DOMXpath($dom);
$elements = $dom_xpath->query('//div[@class="message"], //div[@class="message"] //a, //div[@class="message"] //img');

foreach($elements as $ele){
   echo $ele[0]->getAttribute('class'); //it should return 'message'
   echo $ele[1]->getAttribute('href'); //it should return 'http://www.whatever.com' in the 1st loop, and 'http://www.whatever2.com' in the second loop
   echo $ele[2]->getAttribute('src'); //it should return image_link.jpg in the 1st loop and 'image_link2.jpg' in the second loop
}

Is there some way of doing that using multiple xpath selectors like I did in the example? to avoid making queries all the time and save some CPU.

like image 869
Grego Avatar asked Jan 17 '23 15:01

Grego


1 Answers

Use the union operator (|) in a single expression like this:

//div[@class="message"]|//div[@class="message"]//a|//div[@class="message"]//img

Note that this will return a flattened result set (so to speak). In other words, you won't access the elements in groups of three like your example shows. Instead, you'll just iterate everything the expressions matched (in document order). For this reason, it might be even smarter to simply iterate the nodes returned by //div[@class="message"] and use DOM methods to access their children (for the other elements).

like image 150
Wayne Avatar answered Jan 25 '23 23:01

Wayne