Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP DOM previousSibling doesn't work

<?php

$dom = new \domDocument;
$dom->loadHTML('<!DOCTYPE html>
<html lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   </head>
   <body>
       <div>
        <h1>Title1</h1>
        <p><img src="" /></p>
        <h1>Title2</h1>
        <p><img src="" /></p>
        <h1>Title3</h1>
        <p><img src="" /></p>
        <h1>Title4</h1>
        <p><img src="" /></p>
        <p><img src="" /></p>
       </div>
   </body>
</html>');

        $xpath = new \DOMXPath($dom);
        $nodelist = $xpath->query('//div/p/img');
        foreach($nodelist as $k=>$v){
            $title1 = $v->parentNode->previousSibling->textContent;
        }

I want to retrieve every text inside h1 tag, but previousSibling attribute seems to be not working, it returns a node without tagname attribute and its previousSibling attribute is "(object value omitted)"

My path must be followed as img->p->previous h1 , since not every p tag has its own h1 tag in my case.

Thank you !

like image 287
user7031 Avatar asked Jul 22 '26 20:07

user7031


1 Answers

Based on your markup above, note that the immediate sibling of <p> is actually a new line character \n.

As an alternative, you could check for that preceding sibling first and check whether it's an <h1> tag, if it is, then get its ->nodeValue:

$nodelist = $xpath->query('//div/p/img');
foreach($nodelist as $k=>$v) {
    // $previousSibling = $
    $prev = $xpath->evaluate('./preceding-sibling::*[1]', $v->parentNode);
    if($prev->length > 0 && $prev->item(0)->tagName === 'h1') {
        echo $prev->item(0)->nodeValue, '<br/>';
    }
}

Sample Output

like image 133
Kevin Avatar answered Jul 25 '26 09:07

Kevin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!