PHP DOM - подсчет дочерних узлов?
Фрагмент 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 =
#1
1
3
Вывод с помощью фрагмента $x =
#2
0
1
Смотрите рабочую демонстрацию: http://codepad.viper-7.com/11BGge
Мои вопросы
1. Как это может быть?
2. Как правильно подсчитывать дочерние узлы с помощью DOM
?
РЕДАКТИРОВАТЬ:
как сказал Шелковый огонь, пустое пространство считается текстовым узлом. Я установил
$doc->preserveWhiteSpace = false;
Но результаты все те же: http://codepad.viper-7.com/bnG5io
Есть идеи?
3 answers
Просто посчитайте нетекстовые узлы в своем цикле:
$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>';
}