Свойство имя_файла DOMDocument php возвращает значение '#text' с именем nodeName
Я хочу извлечь содержимое тела страницы html вместе с tagNames своего дочернего элемента. Я привел пример html, например:
<html>
<head></head>
<body>
<h1>This is H1 tag</h1>
<h2>This is H2 tag</h2>
<h3>This is H3 tag</h3>
</body>
</html>
Я реализовал PHP-код, как показано ниже, и его работоспособность.
$d=new DOMDocument();
$d->loadHTMLFile('file.html');
$l=$d->childNodes->item(1)->childNodes->item(1)->childNodes;
for($i=0;$i<$l->length;$i++)
{
echo "<".$l->item($i)->nodeName.">".$l->item($i)->nodeValue."</".$l->item($i)->nodeName.">";
}
Этот код работает отлично, но когда я попытался сделать это, используя foreach loop вместо цикла, свойство nodeName возвращало "#text" с каждым фактическим именем node.
Вот код
$l=$d->childNodes->item(1)->childNodes->item(1)->childNodes;
foreach ($l as $li) {
echo $li->childNodes->item(0)->nodeName."<br/>";
}
Почему так?
Ответы
Ответ 1
В DOM все это "node". Не только элементы (теги); комментарии и текст между элементами (даже если это просто пробелы или символы новой строки, что, как представляется, в вашем примере) также являются узлами. Поскольку текстовые узлы не имеют фактического имени node, оно заменяется на #text
, чтобы указать его особым видом node.
По-видимому, текстовые узлы не учитываются при ручном выборе дочерних узлов с помощью метода item
, но включаются при итерации по DOMNodeList
. Я не уверен, почему класс ведет себя так, кому-то придется ответить на этот вопрос.
Помимо nodeName
и nodeValue
, a DOMNode
также имеет свойство nodeType
. Проверяя это свойство на определенные константы, вы можете определить тип node и, таким образом, отфильтровать нежелательные узлы.
Ответ 2
Когда у меня возникла эта проблема, это было исправлено, выполнив следующее.
$xmlDoc = new DOMDocument();
$xmlDoc->preserveWhiteSpace = false; // important!
Вы можете проследить свой $ node → nodeType, чтобы увидеть разницу. Я получаю 3, 1, 3, хотя был только один node (ребенок). Отключите белое пространство, и теперь я просто получаю 1.
GL.
Ответ 3
Я немного опаздываю на это, но лучшее решение для меня было другим. Проблема в том, что TEXT node не знает этого имени, но его родитель делает все, что вам нужно знать, и попросите его родителя, чтобы nodeValue получил ключ.
$dom = new DOMDocument();
$dom->loadXML($stringXML);
$valorizador = $dom->getElementsByTagName("tagname");
foreach ($valorizador->item(0)->childNodes as $item) {
$childs = $item->childNodes;
$key = $item->nodeName;
foreach ($childs as $i) {
echo $key." => ".$i->nodeValue. "\n";
}
}