DOMDocument::loadHTML 错误

Posted

技术标签:

【中文标题】DOMDocument::loadHTML 错误【英文标题】:DOMDocument::loadHTML error 【发布时间】:2012-02-27 06:47:06 【问题描述】:

我构建了一个脚本,它将页面上的所有 css 组合在一起以在我的 cms 中使用它。它工作了很长时间现在我得到这个错误:

警告:DOMDocument::loadhtml() [domdocument.loadhtml]:实体中的标记标题无效,行:10 in css.php26 行警告: DOMDocument::loadHTML() [domdocument.loadhtml]:标签导航无效 实体,行:css.php 中的第 10 行 26警告:DOMDocument::loadHTML() [domdocument. loadhtml]: 标签 实体中的部分无效,行:css.php 中的第 22 行 26这是php脚本

这是我的代码:

<?php
header('Content-type: text/css');
include ('../global.php');

if ($usetpl == '1') 
    $client = New client();
    $tplname = $client->template();
    $location = "../templates/$tplname/header.php";
    $page = file_get_contents($location);
 else 
    $page = file_get_contents('../index.php');


class StyleSheets extends DOMDocument implements IteratorAggregate


    public function __construct ($source)
    
        parent::__construct();
        $this->loadHTML($source);
    

    public function getIterator ()
    
        static $array;
        if (NULL === $array) 
            $xp = new DOMXPath($this);
            $expression = '//head/link[@rel="stylesheet"]/@href';
            $array = array();
            foreach ($xp->query($expression) as $node)
                $array[] = $node->nodeValue;
        
        return new ArrayIterator($array);
    


foreach (new StyleSheets($page) as $index => $file) 
    $css = file_get_contents($file);
    echo $css;

【问题讨论】:

这个问题已经在bugs.php.net/bug.php?id=60021 上报告了 PHP,这反过来又在底层 libxml2 中产生了一个功能请求:bugzilla.gnome.org/show_bug.cgi?id=761534 【参考方案1】:

Header、Nav 和 Section 是来自 HTML5 的元素。因为 HTML5 开发者觉得记住 Public 和 System Identifiers 太难了,所以 DocType 声明就是:

<!DOCTYPE html>

换句话说,没有要检查的 DTD,这将使 DOM 使用 HTML4 过渡 DTD 并且不包含那些元素,因此警告。

要取消警告,请放置

libxml_use_internal_errors(true);

在致电loadHTML

之前
libxml_use_internal_errors(false);

在它之后。

另一种方法是使用https://github.com/html5lib/html5lib-php。

【讨论】:

这样做了,现在我得到一个空白页 @user1079160 这是另一个问题!戈登有很好的答案,谢谢! @Gordan 你如何解决空白页问题? 我遇到了同样的空白页问题。我的错误是使用print $document-&gt;saveXML() 而不是$document-&gt;saveHTML()。 HTML 版本不会像 XML 版本那样进行某些格式转换。如果这不是问题,请尝试检查输出源以查看存在哪些标签(如果有)。它应该让您了解幕后发生的事情。另外,别忘了var_dump【参考方案2】:

使用 DOMDocument 对象,您应该能够在加载方法之前放置一个 @ 以抑制所有警告。

$dom = new DOMDocument;
@$dom->loadHTML($source);

然后继续。

【讨论】:

这是一个糟糕的解决方案,因为您将在此行上出错,成为调试的噩梦。 @Gordon 的解决方案要好得多。【参考方案3】:

仍然不支持 HTML5 元素,但您可以使用 $options 参数完全消除 libxml 错误。

刚刚设置

$doc = new DOMDocument();
$doc->loadHTMLFile("html5.html", LIBXML_NOERROR);

此选项优于 @,后者可消除 PHP 错误。

但要小心,libxml 非常宽容,它会解析损坏的 HTML 文档。 如果您忽略 libxml 错误,您甚至可能不会意识到 HTML 格式错误。

【讨论】:

【参考方案4】:

大多数人没有意识到 HTML 和 XML 作为语言以及 HTML 和 XML 在解析器方面的区别。解析器接受代码,而 HTML 和 XML 解析器完全不同。虽然 XML 解析器会在浏览器中容忍一些小事情(例如重复的 id 值),但它们不会乱处理看起来像代码的垃圾。

PHP 的 XML 解析器更加严格,不允许重复的 id 值。此外,由于任何东西都可以是元素(例如 footerheadersection),PHP 的 XML 解析器不会抱怨未知的 HTML5+ 元素。

$dom->loadXML($xml);

对于在客户端开发的任何人,我强烈建议使用 XML 解析器来处理您的 HTML5 代码,并且自从我在 2000 年代到 2020 年开始开发以来,Gecko 浏览器(例如 Waterfox、Firefox)拥有最好的 XML 解析器,因为整个页面将break 你会得到一个explicit错误信息。如果您能够理解质量最终会产生数量,那么更严格的代码会产生更好的结果,但相反则不然。

【讨论】:

以上是关于DOMDocument::loadHTML 错误的主要内容,如果未能解决你的问题,请参考以下文章

DOMDocument::loadHTML(): 由于输入错误,输入转换失败

防止 DOMDocument::loadHTML() 转换实体

使用 php 从 html 文件中计算 li 项

错误:EPERM:不允许操作,错误时统计“D:\System Volume Information”(本机)

从 3.4.d(社区)升级到 4.0.d(社区)后,Alfresco Explorer 出现错误

热图 Seaborn fmt='d' 错误