えいのうにっき

むかしのじぶんのために書いています

文字実体参照を元の文字に変換する

こんにちは、a-knowです。


前回エントリにも書いたとおり、今月からRuby / Railsを使ったお仕事をしているのですが、ちょこっと特殊なことをやった&そのときに該当する情報が見当たらなかったので、メモがてら残しておこうかと思います。
(なにぶん初学者ですのでご指摘等あればぜひお願いしますm(_ _)m)



やりたかったこと

タイトルにもあります通り、「文字実体参照を元の文字に変換する」ということをやりたかったので、いろいろと試行錯誤しました。
Rubyのバージョンは1.8.7-p174。

試したこと

CGI#unescapeHTML(string)を使ってみる

& > < "・・・という、4つの文字実体参照しかサポートしていないので不可。
数値実体参照ならサポートしてるのになぁ。・・・ん?

Hpricot::NamedCharacters に定義されているhashとCGI#unescapeHTML(string)の合わせ技

数値実体参照の変換ならサポートしてるんなら、文字実体参照を数値実体参照に変換してやってから使えばいいじゃない。と思ったので。
で、結論、数値実体参照の数値がISO-8859-1の範囲を超えると(256以上)、CGI#unescapeHTML(string)ではうまく変換できない場合があることがわかった。むむむ。

最終的なおとしどころ

で、最終的にどうしたかというと、下記。

Hpricot::NamedCharacters.each do |key, value|
    target.gsub!('&' + key.to_s + ';', [value].pack('U'))
end


Hpricot::NamedCharactersのhashで定義されているvalueの方は、単純に当該文字の「ISO 10646の文字番号」なので、それを Array#pack を用いて文字に変換。これで意図通りの変換ができました。


とはいえ、もうちょっとスマートな方法があると思うんだけど。。