2012-03-03 271 views
5

到目前为止,我工作的一个HTML文件,这样在PHP DOM中选择所选节点的下一个节点?

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

我要选择每一个“格”有其名相等的下一个节点“节点”,我尝试:

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

但我只是得到一个错误

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

谁能告诉我有什么不对我的脚本吗?

+0

我相信这是'nextSibling' – scibuff 2012-03-03 20:00:32

回答

15

错误很明显:没有方法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); 
+0

这是正确的,我想下一个元素,但只是错过使用'nextSibling'。非常感谢你的好解释,脚本现在可以正常工作了! – Teiv 2012-03-04 00:24:16

5

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

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

我不知道php但这xpath让他们:

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

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

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