首页 > 解决方案 > PHP DOMDocument loadHTML 返回两个 HTML childNodes

问题描述

我在 Visual Studio 中运行 PHP,并希望跨过 HTML 字符串中的各个节点。我使用 loadHTML 将字符串加载到 DOMDocument 并从文档中提取 firstChild,检查它是一个 HTML 节点,但该节点没有任何子节点。

然后我修改了代码以遍历文档的所有子节点,令我惊讶的是,这返回了两个 HTML 节点,第二个具有预期的子节点。这是我应该期待的吗?谁能解释为什么?

附上代码和输出。

enter code here
<?php
$html = '<html><head></head><body>';
$html .= '<h1>Content 1</h1><h2>Content 1.1</h2><h3>Content 1.1.1</h3>';
$html .= '</body></html>';

define ('NEWLINE',"\r\n" );

function recurceHTML ($node, $spaces)
{
    $nextIndent = $spaces . '  ';
    print ($spaces . $node->nodeName . NEWLINE);
    foreach($node->childNodes as $childNode)
    {
        recurceHTML ($childNode, $nextIndent);
    }
}


$dom = DOMDocument::loadHTML($html);
$spaces = '  ';

foreach ($dom->childNodes as $child)
{
    recurceHTML ($child, $spaces);
}
$wait = readline();
?>

上面的输出是:

  html
  html
    head
    body
      h1
        #text
      h2
        #text
      h3
        #text

标签: phphtmldomdocument

解决方案


通过稍微更新代码以更清楚地显示它正在使用的内容,您可以看到数据的来源......

function recurceHTML ($node, $spaces)
{
    $nextIndent = $spaces . '  ';
    print ($spaces . $node->nodeName."->".$node->nodeType . NEWLINE);

    if ( $node->nodeType == 1 ) {
        foreach($node->childNodes as $childNode)
        {
            recurceHTML ($childNode, $nextIndent);
        }
    }
}

$dom = new DOMDocument();
$dom->loadHTML($html);
$spaces = '  ';

echo $dom->saveHTML().PHP_EOL;

foreach ($dom->childNodes as $child)
{
    recurceHTML ($child, $spaces);
}

第一个echo向您显示它正在使用的实际文档...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head></head><body><h1>Content 1</h1><h2>Content 1.1</h2><h3>Content 1.1.1</h3></body></html>

如您所见 - 这也将文档类型作为内容的一部分。

然后你有主函数的输出......

  html->10
  html->1
    head->1
    body->1
      h1->1
        #text->3
      h2->1
        #text->3
      h3->1
        #text->3

tagName 之后的输出显示节点类型,第一个是 10,它是DOMDocumentType节点(<!DOCTYPE html PUBLIC "-//W3...),然后第二个是 type 1,XML_ELEMENT_NODE它是你的<html>标签。

在您使用loadHTML时 - 这将始终尝试创建有效的 HTML 文档 - 这包括添加文档类型以及<html>普通 HTML 页面中需要的标签等。


推荐阅读