Я пытаюсь разобрать HTML-код с DOMDocument, сделать что-то вроде изменений в нем, а затем собрать его обратно в строку, которую я отправляю на вывод.
Но есть несколько вопросов, касающихся разбора, что означает, что то, что я отправляю в DOMDocument, не всегда возвращается в том же виде:)
Вот список:
-
используя - > loadHTML:
- форматирует мой документ независимо от настроек
preserveWhitespace
иformatOutput
(теряя пробелы в предварительно отформатированном тексте) - дает мне ошибки, когда у меня есть теги html5, такие как
<header>
,<footer>
и т.д. Но они могут быть подавлены, поэтому я могу жить с этим. - создает несогласованную разметку - например, если я добавлю элемент
<link ... />
(с самозакрывающимся тегом), после разбора/сохраненияHTML вывод будет<link .. >
- форматирует мой документ независимо от настроек
-
используя - > loadXML:
- кодирует такие объекты, как
>
из тегов<style>
или<script>
:body > div
становитсяbody > div
- все теги закрываются одинаково, например
<meta ... />
становится<meta...></meta>
; но это может быть исправлено с помощью регулярного выражения.
- кодирует такие объекты, как
Я не пробовал 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, чего я не хочу...