Есть несколько незначительных ошибок (получение из неправильного узла), но есть две основные проблемы.
Первая - getElementsByTagName()
, выбирающая все дочерние элементы с этим именем тега. это не ограничивается непосредственными дочерними узлами, поэтому каждый раз будет больше тегов, чем вы ожидаете. В этом коде он использует XPath
, поскольку DOMDocument
не имеет удобного способа сделать просто непосредственными дочерними узлами, называемыми , поэтому XPath просто использует узел контекста в качестве начальной точки и что-то вроде a
сказать только <a>
теги, которые являются прямыми потомками узла контекста.
Другое (главное) это то, что вы строите вывод, используя операторы echo
. Это может работать, но также подвержено опечаткам, неверной структуре и т. Д. Этот код использует вызовы API DOM для создания документа.
$doc = new DomDocument;
$doc->validateOnParse = true;
$doc->loadHtml($html);
$xp = new DOMXPath($doc);
$header = $doc->getElementById('headerLara');
$mainUls = $xp->query('div/ul', $header);
foreach ($mainUls as $mainUl) {
$mainULE = $doc->createElement("ul");
$mainLis = $xp->query('li', $mainUl);
foreach ($mainLis as $mainLi) {
$li = $doc->createElement("li");
$mainAnc = $xp->query('a', $mainLi)[0];
$href = $mainAnc->getAttribute('href');
$a = $doc->createElement("a", htmlspecialchars($mainAnc->nodeValue));
$href = $mainAnc->getAttribute('href');
if ( !empty($href) ) {
$a->setAttribute("href", $href);
}
$li->appendChild($a);
$secUls = $xp->query('ul', $mainLi);
if($secUls->length < 2){
foreach ($secUls as $secUl) {
$a->setAttribute("class", "has-child");
$secULE = $doc->createElement("ul");
$secLis = $xp->query('li', $secUl);
foreach ($secLis as $secLi) {
$secLIE = $doc->createElement("li");
$secAnc = $xp->query('a', $secLi);
$shref = $secAnc[0]->getAttribute('href');
$secA = $doc->createElement("a", htmlspecialchars($secAnc[0]->nodeValue));
$secA->setAttribute("href", $shref);
$secLIE->appendChild($secA);
$secULE->appendChild($secLIE);
}
$li->appendChild($secULE);
}
}
$mainULE->appendChild($li);
}
echo PHP_EOL.PHP_EOL.">>>>".$doc->saveHTML($mainULE);
// Next line replaces existing HTML
//$mainUl->parentNode->replaceChild($mainULE,$mainUl);
}