HTML-фрагмент # 1
<div> </div> <div> <h1>headline</h1> </div>
HTML-фрагмент # 2
<div></div> <div><h1>headline</h1></div>
PHP-код
$doc = new DOMDocument(); $doc->loadHTML($x); $xpath = new DOMXpath($doc); $divs = $xpath->query("//div"); foreach ($divs as $div) echo $div->childNodes->length,"<br />";
Вывод с помощью $x =
snippet # 1
1
3
Вывод с помощью $x =
snippet # 2
0
1
см. рабочую демонстрацию: http://codepad.viper-7.com/11BGge
Мои вопросы
1. Как это может быть?
2. Как правильно правильно подсчитать дочерние узлы с помощью DOM
?
EDIT :
как сказал Silkfire, пустое пространство считается текстовым узлом. Я установил
$doc->preserveWhiteSpace = false;
но результаты все те же: http://codepad.viper-7.com/bnG5io
Есть идеи?
Просто подсчитайте нетекстовые узлы в своем цикле:
$count = 0; foreach($div->childNodes as $node) if(!($node instanceof \DomText)) $count++; print $count;
Использование xpath:
$nodesFromDiv1 = $xpath->query("//div[1]/*")->length; $nodesFromDiv2 = $xpath->query("//div[2]/*")->length;
Чтобы удалить пустые текстовые узлы, когда preserveWhiteSpace=false
не работает (как я предложил в чате):
$textNodes = $xpath->query('//text()'); foreach($textNodes as $node) if(trim($node->wholeText) === '') $node->parentNode->removeChild($node);
Пробел считается узлом, поскольку он является узлом text () ( DOMText
).
Вы можете сделать эту работу, изменив цикл foreach
:
foreach ($divs as $div) { echo $div->childNodes->length - $xpath->query('./text()', $div)->length, '<br>'; }
Firefox, Chrome и большинство других браузеров будут обрабатывать пустые белые пробелы или новые строки в качестве текстовых узлов, Internet Explorer не будет. Check Here