Я думаю, что вы неправильно понимаете, какие элементы являются повторяемыми существами, поскольку вы выбираете все <div>
s и затем передаете каждый из них на getMessages
.Однако внутри getMessages
вы затем перебираете XML_TEXT_NODE
childNodes каждого <div>
, откуда и происходит двойное дублирование.
Давайте возьмем HTML:
<div>
Message <b>bold</b>, <s>strike</s>
</div>
Элементы DOM и текстовые узлы логически различны и имеют разные типы - XML_ELEMENT_NODE и XML_TEXT_NODE (см. здесь для полного списка), поэтому <div>
фактически содержит 5 дочерних элементов (TEXT, ELEMENT, ТЕКСТ, ЭЛЕМЕНТ, ТЕКСТ).Вы правильно определили проблемное if
условие, однако простое изменение типа на * XML_ELEMENT_NODE * не полностью решает проблему.Есть еще несколько дочерних узлов, где типом является XML_ELEMENT_NODE для каждого <div>
.
. Чтобы полностью решить проблему, я изменил элемент, передаваемый в функцию getMessages
, чтобы функция могла выполнять итерации на правильном уровне иустранение дублирования.Я также убрал некоторые сложности, улучшающие читабельность, переименовав некоторые переменные.
Вот мое полное решение:
<?php
libxml_use_internal_errors(true);
$html = <<<HTML
<html>
<body>
<div>
Message <b>bold</b>, <s>strike</s>
</div>
<div>
<span class="how">
<a href="link" title="text">Link</a>, <b> BOLD </b>
</span>
</div>
</body>
</html>
HTML;
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->strictErrorChecking = false;
$dom->recover = true;
$dom->loadHTML($html);
function getMessages($allDivs) {
$messages = array();
foreach ($allDivs as $div) {
if ($div->nodeType == XML_ELEMENT_NODE) {
$messages[] = trim(DOMinnerHTML($div));
}
}
return $messages;
}
function DOMinnerHTML($element) {
$innerHTML = null;
$children = $element->childNodes;
foreach ($children as $child) {
$tmp_dom = new DOMDocument();
$tmp_dom->appendChild($tmp_dom->importNode($child, true));
$innerHTML .= trim($tmp_dom->saveHTML());
}
return $innerHTML;
}
$xpath = new DOMXPath($dom);
$messagesXpath = $xpath->query("//div");
$messages[] = getMessages($messagesXpath);
print_r($messages);
?>