Jak sprawić, by HTML5 działał z DOMDocument?
Próbuję przeanalizować kod HTML za pomocą DOMDocument, zrobić coś takiego jak zmiany w nim, a następnie złożyć go z powrotem do łańcucha, który wysyłam na wyjście.
Ale istnieje kilka problemów dotyczących parsowania, co oznacza, że to, co wysyłam do DOMDocument, nie zawsze wraca w tej samej formie :)
Oto lista:
za pomocą-> loadHTML:
formatuje mój dokument niezależnie odpreserveWhitespace
iformatOutput
ustawienia (utrata białych znaków we wstępnie sformatowanym tekście)daje mi błędy, gdy mam znaczniki html5<header>
, <footer>
itd. Ale mogą być tłumione, więc mogę z tym żyć.produkuje niespójne znaczniki - na przykład, jeśli dodam<link ... />
element (z samozamykającym się tagiem), po analizie / saveHTML wyjście będzie<link .. >
za pomocą-> loadXML:
koduje elementy takie jak>
z<style>
lub<script>
tagi:body > div
staje siębody > div
na przykład wszystkie znaczniki są zamknięte w ten sam sposób<meta ... />
staje się<meta...></meta>
; ale można to naprawić za pomocą wyrażenia regularnego.Nie próbowałem HTML5lib, ale wolę DOMDocument zamiast niestandardowego parsera ze względu na wydajność
Aktualizacja:Tak jak Honeymonster wspomniany przy użyciu CDATA naprawia główny problem z loadXML.
Czy jest jakiś sposób, w jaki mógłbym zapobiec samoczynnemu zamknięciu wszystkich pustych znaczników HTML oprócz określonego zestawu, bez używania wyrażenia regularnego?
W tej chwili mam:
$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);
który działa, ale zastąpi także zawartość CDATA, której nie chcę ...