DOMDocument を使用して HTML コードを解析し、変更などを行ってから、出力に送信する文字列にアセンブルしようとしています。
ただし、解析に関していくつかの問題があります。つまり、DOMDocument に送信したものが常に同じ形式で返されるとは限りません:)
リストは次のとおりです。
->loadHTMLを使用:
preserveWhitespace
との設定に関係なくドキュメントをフォーマットしformatOutput
ます (整形済みテキストの空白を失います)<header>
などのhtml5タグがあるとエラーが発生しますが、<footer>
それらは抑制できるため、これで問題ありません。- 一貫性のないマークアップを生成します-たとえば、
<link ... />
(自己終了タグを使用して) 要素を追加すると、HTML の解析/保存後に出力は次のようになります<link .. >
->loadXMLを使用:
>
from<style>
または<script>
tags:の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コンテンツの置換も行いますが、これは望ましくありません...