Как получить первый уровень элементов dom Domodocument PHP?
Пример с кодом, который не работает – взят из Q & A: http: //stackoverflow.com/questions/1540302/how-to-get-nodes-in-first-level-using-php–domdocument
<?php $str=<<< EOD <div id="header"> </div> <div id="content"> <div id="sidebar"> </div> <div id="info"> </div> </div> <div id="footer"> </div> EOD; $doc = new DOMDocument(); $doc->loadHTML($str); $xpath = new DOMXpath($doc); $entries = $xpath->query("/"); foreach ($entries as $entry) { var_dump($entry->firstChild->nodeValue); } ?>
Спасибо, Йосеф
К первому уровню элементов ниже корневого узла можно получить доступ с помощью
$dom->documentElement->childNodes
Свойство childNodes содержит DOMNodeList
, который вы можете выполнять с помощью foreach
.
См. DOMDocument::documentElement
Это атрибут удобства, который обеспечивает прямой доступ к дочернему узлу, который является элементом документа документа.
и DOMNode::childNodes
DOMNodeList, содержащий все дочерние элементы этого узла. Если детей нет, это пустой список DOMNodeList.
Поскольку childNodes
является свойством DOMNode
любой класс, расширяющий DOMNode
(который является большинством классов в DOM), обладает этим свойством, поэтому для получения первого уровня элементов ниже DOMElement
необходимо получить доступ к свойству childNode этого DOMElement.
Обратите внимание: если вы используете DOMDocument::loadHTML()
для недопустимых HTML или частичных документов, модуль парсера HTML добавит скелет HTML с тегами html и body, поэтому в дереве DOM HTML в вашем примере будет
<!DOCTYPE html … "> <html><body><div id="header"> </div> <div id="content"> <div id="sidebar"> </div> <div id="info"> </div> </div> <div id="footer"> </div></body></html>
которые вы должны учитывать при прохождении или использовании XPath. Следовательно, используя
$dom = new DOMDocument; $dom->loadHTML($str); foreach ($dom->documentElement->childNodes as $node) { echo $node->nodeName; // body }
будет выполнять только итерацию узла <body>
DOMElement. Зная, что libxml добавит скелет, вам придется перебирать дочерниеNodes элемента <body>
чтобы получить элементы div из вашего примера кода, например
$dom->getElementsByTagName('body')->item(0)->childNodes
Тем не менее, при этом будут учитываться любые пробельные узлы, поэтому вам нужно либо установить значение preserveWhiteSpace
в false, либо запросить нужный элемент nodeType, если вы хотите получить DOMElement
узлы DOMElement
, например
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) { if ($node->nodeType === XML_ELEMENT_NODE) { echo $node->nodeName; } }
или использовать XPath
$dom->loadHTML($str); $xpath = new DOMXPath($dom); foreach ($xpath->query('/html/body/*') as $node) { echo $node->nodeName; }
Дополнительная информация: