如何使HTML5与DOMDocument一起工作?更新:

2022-08-30 19:11:51

我正在尝试使用DOMDocument解析HTML代码,对它进行更改之类的操作,然后将其组装回我发送到输出的字符串。

但是关于解析存在一些问题,这意味着我发送到DOMDocument的内容并不总是以相同的形式返回:)

下面是一个列表:

  1. 使用 ->loadHTML

    • 设置文档格式,而不考虑 和 设置(在预先格式化的文本上丢失空格)preserveWhitespaceformatOutput
    • 当我有html5标签时,给我错误,比如,等等。但是他们可以被压制,所以我可以忍受这一点。<header><footer>
    • 产生不一致的标记 - 例如,如果我添加一个元素(带有自闭合标记),在解析/保存HTML之后,输出将是<link ... /><link .. >
  2. 使用 ->loadXML

    • 对实体(如 from 或 tags)进行编码:变为><style><script>body > divbody &gt; div
    • 所有标签都以相同的方式关闭,例如变成;但这可以用正则表达式修复。<meta ... /><meta...></meta>

我没有尝试HTML5lib,但由于性能原因,我更喜欢DOMDocument而不是自定义解析器


更新:

因此,就像Honeymonster提到的使用CDATA修复了loadXML的主要问题一样。

有没有办法防止在不使用正则表达式的情况下自关闭除特定集合之外的所有空HTML标记?

现在我有:

$html = $dom->saveXML($node);

$html = preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', function($matches){

       // ignore only these tags
       $xhtml_tags = array('br', 'hr', 'input', 'frame', 'img', 'area', 'link', 'col', 'base', 'basefont', 'param' ,'meta');

       // if a element that is not in the above list is empty,
       // it should close like   `<element></element>` (for eg. empty `<title>`)
       return in_array($matches[1], $xhtml_tags) ? "<{$matches[1]}{$matches[2]} />" : "<{$matches[1]}{$matches[2]}></{$matches[1]}>";
}, $html);

这有效,但它也会在CDATA内容中进行替换,我不想要...


答案 1

使用 html5lib。它可以解析html5并生成DOMDocument。例:

require_once '/path/to/HTML5/Parser.php';
$dom = HTML5_Parser::parse('<html><body>...');

文档


答案 2

如果你想支持HTML5,就不要碰DOMDocument。

目前最好的选择似乎是 https://github.com/Masterminds/html5-php

以前最好的选择是 https://github.com/html5lib/html5lib-php 但正如描述所说,它“目前尚未维护”。自2011年10月以来,这一直是状态,所以我不再屏住呼吸了。

我没有在生产中使用过,所以我无法提供任何关于此的真实世界体验。我已经在生产中使用过,我会说它正确地解析了格式良好的文档,但它有一些简单的语法错误的意外错误。另一方面,它似乎正确地实现了收养机构算法和其他一些奇怪的角落案例。如果仍然维护,我仍然更喜欢它。但是,就目前的情况来看,我更喜欢使用并可能帮助修复剩余的错误。html5-phphtml5lib-phphtml5lib-phphtml5-php


推荐