読者です 読者をやめる 読者になる 読者になる

意識の高いLISPマシン

藤原惟/すかいゆき(@sky_y)の技術用ブログ

REXMLの文字化け

ruby

Yahoo!検索のAPIでいろいろいじっていましたが、
検索結果のXML(utf-8)→ファイル(shift_jis)→XML(utf-8)→標準出力(shift_jis)
という操作をやってたら「夏目漱石」が「・・鮮・」みたいに化けてました。


lang.ruby.japanese - [ruby-list:41856] Re: rexml で doc.xml_decl.encoding = "shift-jis" は駄目ですか? - msg#00051 - Recent Discussion OSDir.com

いろいろと複雑でしたが、次のようにまとめられそうです。

まず、NKFとUconvとの関係について
(なお UconvとIconvとでは、このデータでは同じになった)、

(1)NKF.nkf("-u","一覧表")で変換したutf文字列と、Uconv.sjistou8( "一覧表" )とで変換した文字列とでは異なる。

(2)NKF.nkf("-u","一覧表")で変換したutf文字列を NKF.nkf("-s",utf8)で戻すのはOK、Uconv.sjistou8( "一覧表" )をUconvで戻すのはOK。

(3)Uconv.sjistou8( "一覧表" )をNKF.nkf("-s",utf8)で戻すのはOKだが、
(4)NKF.nkf("-u","一覧表")で変換したutf文字列をUconvで戻すのは失敗する。

REXMLはUconvで変換しているのだが・・、

(5)REXMLではUconvでutf8からsjisに変換しようとするので、NKFでutf8に変換したutf8文字列をセットすると、失敗する。

(6)REXMLはDocument#to_sでは変換しようとするが、Element#to_s やAttribute#to_s では変換しない。

* REXML は $KCODE を見て内部で変換すべきである。
C:/Program Files/Apollo/lib/ruby/1.8/rexml/encodings/SHIFT-JIS.rb には
decode メソッドも用意されているのだから、あとちょっとで実現できるはず。

(7)対症療法としては、入力値をUconvでutf8に変換すればOK。

ややこしいので、結局REXMLを使った後はファイル書き込みも含めてutf-8を使って、
表示だけshift_jisで解決。(Eclipseなので。)