我正在尝试使用DOMdocument来检索用于执行CSS3 tree html visualization的html节点列表(免责声明:我自己的页面)。但是,我遇到以下代码的问题,这是重现错误的最小代码:
// Compressed, testing html
$text = '<!DOCTYPE html><html><head><title>Demo</title></head><body>Bla</body></html>';
// Create and load the html
$dom = new DOMdocument();
$dom->loadHTML($text);
// Error test: it prints two html nodes instead of one
foreach ($dom->childNodes as $node)
echo $node->nodeName;
预期的结果是html
,因为我正在使用html文档,这是顶级节点。但是,我正在获取htmlhtml
,第一个节点为空(另一个检查),而第二个节点包含所有有价值的信息。所以,
为什么单节点html文档中有两个
html
个节点?
注意:我尝试删除了<!DOCTYPE html>
和<html>
代码,但解决方案都没有。
如果您因任何原因无法回答上一个问题,请至少回答:是否总会有两个html
个节点,第二个节点包含所有有价值的信息?
答案 0 :(得分:1)
看起来第一个节点是DOCUMENT_TYPE(类型= 10),似乎总是创建,即使没有<!DOCTYPE>
。
我想DOMdocument需要它来处理文档的其余部分。
第二个节点是您的“真实”文档。
您可以快速查看内容:
$text = '<!DOCTYPE html><html><head><title>Demo</title><script>var a=10;</script></head><body>Bla</body></html>';
$dom = new DOMdocument();
$dom->loadHTML($text);
foreach ($dom->childNodes as $node)
{
echo $node->nodeName;
echo "<pre>";print_r($node);echo"</pre><br>\n";
echo "<pre>";print_r(getArray($node));echo"</pre><br>";
echo "<br>================================<br>";
}
function getArray($node)
{
$array = false;
if ($node->hasAttributes())
{
foreach ($node->attributes as $attr)
{
$array[$attr->nodeName] = $attr->nodeValue;
}
}
if ($node->hasChildNodes())
{
if ($node->childNodes->length == 1)
{
$array[$node->firstChild->nodeName] = $node->firstChild->nodeValue;
}
else
{
foreach ($node->childNodes as $childNode)
{
if ($childNode->nodeType != XML_TEXT_NODE)
{
$array[$childNode->nodeName][] = getArray($childNode);
}
}
}
}
return $array;
}
答案 1 :(得分:1)
如果loadHTML($ input)中没有doctype,则后者包装了 输入它自己的doctype,而且,正如你自己提到的,删除所有 html标签大吼大叫。
如果您运行此代码:
$text = '<head><title>Demo</title></head><body>Bla</body>';
$dom = new DOMdocument();
$dom->loadHTML($text);
echo $dom->saveHTML();
输出将是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head><title>Demo</title></head><body>Bla</body></html>
答案是肯定的,总会有两个父html标签,第二个标签包含dom结构;
PS:loadHTML也会自动封闭非封闭标签。见DOMDocument::loadHTML