为什么单节点html文档中有两个html节点?

时间:2014-02-01 04:56:57

标签: php html dom domdocument

我正在尝试使用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个节点,第二个节点包含所有有价值的信息?

2 个答案:

答案 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