Select the next node of the selected node in PHP DOM?

12,021

Solution 1

The error is quite clear: there is no method DOMElement::next_sibling(). Read the documentation for DOMElement and it's parent class DOMNode. You are thinking of the property DOMNode::nextSibling.

However, nextSibling gets the next node, not the next element. (There is no DOM method or property that gets the next element. You need to keep using nextSibling and checking nodeType until you hit another element.) Your question says you want the next node but I think you may actually want the next element (the empty <div>). This is actually quite easy to do with XPath, so why don't you do that instead?

To get it immediately:

$els = $xpath->query("//div[@name='node']/following-sibling::*[1]");

To get it when you already have a <div name="node">:

$nextelement = $xpath->query("following-sibling::*[1]", $currentdiv);

Solution 2

There's is not function called next_sibling() in DOM. You should use the property nextSibling defined in DOMNode (http://www.php.net/manual/en/class.domnode.php).

foreach($els as $el)
{
    if($el->nextSibling) $j++;
}

Solution 3

I don't know php but this xpath gets them:

//div[@name="node"]/following-sibling::*[1]

Solution 4

Ignoring text nodes (hopefully, not tested)

foreach($els as $el){
  $next = $el->nextSibling;
  while($next){
    if($next->nodeType!==3){
       $j++;
       break;
    }
    $next = $next->nextSibling;
  }
}

As a function

function nextElement($node, $name=null){
    if(!$node){
        return null;
    }
    $next = $node->nextSibling;
    if(!$next){
        return null;
    }
    if($next->nodeType === 3){
        return self::nextElement($next, $name);
    }
    if($name && $next->nodeName !== $name){
        return null;
    }
    return $next;
}

Usage

foreach($els as $el)
{
    if(nextElement($el,'div')) $j++;
}
Share:
12,021
Teiv
Author by

Teiv

Updated on June 26, 2022

Comments

  • Teiv
    Teiv almost 2 years

    So far I'm working on a HTML file like this

    <div name="node"></div>
    <div></div>
    <div name="node"></div>
    <div></div>
    <div name="node"></div>
    <div></div>
    

    I want to select the next node of every "div" which has its name equal to "node" and I try :

    $dom = new DOMdocument();
    @$dom->loadHTML($html);
    $xpath = new DOMXPath($dom);
    
    $els = $xpath->query("//div[@name='node']");
    
    $j = 0;
    
    foreach($els as $el)
    {
        if($el->next_sibling()) $j++;
    }
    
    echo $j;
    

    But I just get an error

    Fatal error: Call to undefined method DOMElement::next_sibling()

    Can anybody tell me what's wrong with my script please?

  • Teiv
    Teiv about 12 years
    That's right, I want to get the next element but just miss used nextSibling. Thank you so much for your nice explanation the script now work fine as expected!