Как заставить HTML5 работать с DOMDocument?
Я пытаюсь проанализировать HTML-код с помощью DOMDocument, сделать что-то вроде изменений в нем, а затем собрать его обратно в строку, которую я отправляю на выход.
Но есть несколько проблем, связанных с анализом, что означает, что то, что я отправляю в DOMDocument, не всегда возвращается в той же форме :)
Вот список:
using ->loadHTML:
formats my document regardless of thepreserveWhitespace
and formatOutput
settings (loosing whitespaces on preformatted text)
gives me errors when I have html5 tags like <header>
, <footer>
etc. But they can be supressed, so I can live with this.
produces inconsistent markup - for example if I add a <link ... />
element (with a self-closing tag), after parsing/saveHTML the output will be <link .. >
using ->loadXML:
encodes entities like>
from <style>
or <script>
tags: body > div
becomes body > div
all tags are closed the same way, for example <meta ... />
becomes <meta...></meta>
; but this can be fixed with an regex.
Я не пробовал HTML5lib, но я предпочел DOMDocument вместо пользовательского парсера по соображениям производительности
Update:Таким образом, как упоминается 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, который я не хочу ...