Пока я работаю над HTML-файлом, подобным этому
<div name="node"></div> <div></div> <div name="node"></div> <div></div> <div name="node"></div> <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;
Но я просто получаю сообщение об ошибке
Неустранимая ошибка: вызов неопределенного метода DOMElement :: next_sibling ()
Может кто-нибудь сказать мне, что случилось с моим сценарием, пожалуйста?
Ошибка довольно ясна: метода DOMElement::next_sibling()
. Прочтите документацию для DOMElement
и родительский класс DOMNode
. Вы думаете о свойстве DOMNode::nextSibling
.
Однако nextSibling
получает следующий узел , а не следующий элемент . (Нет метода или свойства DOM, который получает следующий элемент. Вам нужно продолжать использовать nextSibling
и проверять nextSibling
nodeType
пока не нажмете на другой элемент.) В вашем вопросе говорится, что вы хотите следующий узел, но я думаю, что вы можете действительно хотеть следующий элемент ( пустой <div>
). На самом деле это довольно легко сделать с XPath, так почему бы вам не сделать это вместо этого?
Чтобы получить его сразу:
$els = $xpath->query("//div[@name='node']/following-sibling::*[1]");
Чтобы получить его, когда у вас уже есть <div name="node">
:
$nextelement = $xpath->query("following-sibling::*[1]", $currentdiv);
В DOM нет функции, называемой next_sibling (). Вы должны использовать свойство nextSibling, определенное в DOMNode (http://www.php.net/manual/en/class.domnode.php).
foreach($els as $el) { if($el->nextSibling) $j++; }
Я не знаю php
но это xpath
получает их:
//div[@name="node"]/following-sibling::*[1]
Игнорирование текстовых узлов (надеюсь, не проверено)
foreach($els as $el){ $next = $el->nextSibling; while($next){ if($next->nodeType!==3){ $j++; break; } $next = $next->nextSibling; } }
в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++; }