在PHP DOM中选择所选节点的下一个节点?

时间:2012-03-03 19:50:33

标签: php dom xpath

到目前为止,我正在处理像这样的HTML文件

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

我想选择每个“div”的下一个节点,其名称等于“node”,我尝试:

$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;

但我刚收到错误

  

致命错误:调用未定义的方法DOMElement :: next_sibling()

有人可以告诉我我的剧本有什么问题吗?

4 个答案:

答案 0 :(得分:17)

错误很明显:没有方法DOMElement::next_sibling()。阅读documentation for DOMElement及其家长班DOMNode。您正在考虑属性 DOMNode::nextSibling

但是,nextSibling获取下一个节点,而不是下一个元素。 (没有DOM方法或属性可以获取下一个元素。您需要继续使用nextSibling并检查nodeType,直到您点击另一个元素。)您的问题是您想要下一个节点,但我认为您实际上可能想要下一个元素(空<div>)。这实际上很容易用XPath做,所以为什么不这样做呢?

立即获取:

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

要在已有<div name="node">

时获取此信息
$nextelement = $xpath->query("following-sibling::*[1]", $currentdiv);

答案 1 :(得分:6)

在DOM中没有名为next_sibling()的函数。您应该使用DOMNode中定义的属性nextSibling(http://www.php.net/manual/en/class.domnode.php)。

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

答案 2 :(得分:4)

我不知道php但是xpath得到了它们:

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

答案 3 :(得分:1)

忽略文本节点(希望,未经测试)

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

作为一项功能

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;
}

用法

foreach($els as $el)
{
    if(nextElement($el,'div')) $j++;
}