2016-05-28T01:08:13+09:00

Ruby の Nokogiri で読み込んだ XHTML を出力する

Ruby の Nokogiri は、HTML/XML の解析/生成/その他なんでもござれのすごいライブラリだ。Perl の HTML::Parser と HTML::TreeBuilder あわせたようなものと理解している。

先日、「Perl の HTML::TreeBuilder で元の HTML を出力する」という話をした。すなわち、HTML::TreeBuilder で HTML ファイルを読み込み、それを加工して出力するということの下準備というつもりです。入力したものをそのまま吐き出すことさえ、大変苦労した。おなじことを Ruby の Nokogiri ではどうなるだろうという話です。

結論から言えば、Nokogiri も読み込んだ XHTML を素直に吐き出してくれない。普通に to_xhtml メソッドで出力すると、Processing Instruction を Document Type Definition の後ろに出力してくれる。Processing Instruction はファイルの先頭にないと XSLT が適用されないので困る。

仕方がないので、次のスクリプトのように、Nokogiri::HTML のインスタンスから Processing Instruction を抜き出して自前で最初に出力するようにした。

#!/usr/bin/env ruby
# coding: utf-8

require 'rubygems'
require 'nokogiri'

doc =  Nokogiri::HTML <<-EOHTML
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<!-- comment1 -->
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <title>page title</title>
    <!-- comemnt2 -->
  </head>
  <body>
  <p>paragraph1</p>
  <ul>
  <li>item1</li>
  </ul>
  </body>
</html>
EOHTML
pi = doc.xpath('/processing-instruction()') 
puts pi.to_html # processing instruction を最初に出力
pi.remove
puts doc.to_xhtml(:encoding => 'UTF-8')

ストレートフォワードにはいかないけれど、HTML::TreeBuilder よりは圧倒的に素直に扱える。やっぱり、Ruby に浮気せざるえないか?