XML::LibXMLでHTMLを扱うのはやめておいた方がよさそう。

HTML::Parserはあまり速くなかった気がするので、XML::LibXMLでHTMLを扱おうとしてはまった。XML::LibXMLは、load_html()みたいなメソッドもあるから大丈夫かなー、なんて思ったのが甘かった。

  1. HTMLをパースして、データ構造にする。
  2. データ構造を走査したり操作する。
  3. データ構造を出力する。

とうい一連の流れのうち、1と3が問題になる。

パースするには、load_xml()load_html()というクラスメソッドを使う。parse_fileparse_html_fileなどというインスタンスメソッドもあるが、こちらも実質的には同じである。

2つのクラスメソッドのうち、load_xml()は、<br>のような終了タグのないタグを読み込めない。それだけならXHTMLにしてしまえばなんとかなりそうに見えるが、<textarea></textarea><textarea/>に無理矢理まとめてしまう。この表記は、現状のブラウザであれば一応対応している場合が多いが、XHTMLとして扱われなかった場合には表示が崩れることを考えると使いづらい。

そして出力がまた問題である。toString(), toStringHTML(), toStringC14N(), toStringEC14N()の4つのメソッドが基本となるが、

  • toString()load_html()で読み込もうが、<textarea/>のようにまとめてしまう。
  • 逆にtoStringC14N(), toStringEC14N()は、<br><br></br>のように分離してしまう。
  • toStringHTML()は一見問題なさそうに見えるが、日本語文字列が実体参照に変えられてしまう。

というような感じで、"HTML"を扱うにはあきらかに不便すぎる。多少遅かろうが、HTML::Parser系のモジュールを使うべきだろう。HTML::TreeBuilderとかね。あれはあれでいろいろ問題あるけどね。

とはいえ動作確認は完全ではないので、もしまともにHTMLを扱う方法があるなら誰か教えてください。