如何使HTML5与DOMDocument一起工作?
我试图用DOMDocument解析HTML代码,做类似于它的修改,然后将其组装回我发送给输出的字符串。
但是有几个关于解析的问题,这意味着我发送给DOMDocument的东西并不总是以相同的形式回来:)
这里是一个列表:
使用 - > loadHTML:
preserveWhitespace
和formatOutput
设置(丢失预格式化文本上的空格) <header>
, <footer>
等html5标签时,会给我带来错误,但是它们可以被抑制,所以我可以忍受这一点。 <link ... />
元素(带有一个自动关闭标记),解析/ saveHTML后,输出将是<link .. >
使用 - > loadXML:
>
从<style>
或<script>
标签: body > div
变body > div
body > 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内容的替换,我不想...
不幸的是,幸运的是,domdocument的目的不是试图保留原始文档的格式。 这是为了通过保持所有元素具有相同样式来使解析器的内部状态更容易管理。 Afaik大多数解析器都会在内存中创建一个树形表示,而不用担心文本格式化,直到用户请求为止。 这就是为什么你的自封闭标签是用单独的结束标签输出的。 好消息是没关系。
至于将<>
转换为<>
样式标签和脚本标签<>
,您可以通过以下方式避免使用建议的cdata标记来围绕相关元素的内容进行转换:
<style>
/*<![CDATA[*/
body > div {
width: 50%;
}
/*]]>*/
</style>
cdata声明中的注释/* */
允许不知道cdata节的破坏的客户端将声明视为CSS代码。 如果您仅在内部使用该文档,那么您可以省略/* */
注释环绕声并仅具有cdata声明。 如果您操作文档,然后将其发送到浏览器而不进行检查以确保保留/* */
注释,则可能会遇到上述损坏的客户端的问题; 我不确定domdocument是否会保留这些信息。
使用html5lib。 它可以解析html5并生成一个DOMDocument。 例:
require_once '/path/to/HTML5/Parser.php';
$dom = HTML5_Parser::parse('<html><body>...');
文档
如果您想要支持HTML5,请不要触摸DOMDocument。
目前最好的选择似乎是https://github.com/Masterminds/html5-php
以前最好的选择是https://github.com/html5lib/html5lib-php,但正如描述所说,它“目前无人维护”。 这是自2011年10月以来的状态,所以我不再屏住呼吸。
我没有在生产中使用html5-php
,所以我无法提供任何有关这方面的实际经验。 我在制作中使用了html5lib-php
,我会说它正确地解析格式正确的文档,但它有一些意想不到的错误,并带有一些简单的语法错误。 另一方面,它似乎正确实施了收养代理算法和一些其他奇怪的角落案例。 如果html5lib-php
仍然保留,我仍然会更喜欢它。 然而,正如目前的情况,我宁愿使用html5-php
并可能帮助修复其中的错误。