From: take_tk Date: 2006-02-25T12:02:17+09:00 Subject: [ruby-list:41856] Re: rexml で doc.xml_decl.encoding = "shift-jis" は駄目ですか? たけ(tk)です。 [ruby-list:41855] Re: rexml で doc.xml_decl.encoding = "shift-jis" は駄 目ですか? にて Kouhei Sutou さん 曰く: > よく覚えていませんが,REXMLの内部エンコーディングはUTF-8なの > で値を設定するときはdoc.xml_decl.encodingに関わらずUTF-8で指 > 定しなければいけなかった気がします. いろいろと複雑でしたが、次のようにまとめられそうです。 まず、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 の inspect はどうにかして欲しい。クラス名がでないので役に立た ない・・。 ---- #! ruby -Ks require "iconv" class Iconv def self.sjis_to_utf8(str) Iconv.iconv("utf-8", "shift_jis", str).join('') end def self.utf8_to_sjis(str) Iconv.iconv("shift_jis", "utf-8", str).join('') end end require 'uconv' module Uconv def self.sjis_to_utf8(str) Uconv.sjistou8( str ) end def self.utf8_to_sjis(str) Uconv.u8tosjis( str ) end end require "nkf" module NKF def self.sjis_to_utf8(str) NKF.nkf('-u', str ) end def self.utf8_to_sjis(str) NKF.nkf('-s', str ) end end #(1)NKF.nkf("-u","一覧表")で変換したutf文字列と、Uconv.sjistou8( "一覧 #表" )とで変換した文字列とでは異なる。 p NKF.sjis_to_utf8('一覧表') #=> "\e$B0lMwI=\e(B" p Uconv.sjis_to_utf8('一覧表') #=> "荳\200隕\247陦\250" #(2)NKF.nkf("-u","一覧表")で変換したutf文字列を NKF.nkf("-s",utf8)で戻 #すのはOK、Uconv.sjistou8( "一覧表" )をUconvで戻すのはOK。 p NKF.utf8_to_sjis(NKF.sjis_to_utf8('一覧表')) #=> "一覧表" p Uconv.utf8_to_sjis(Uconv.sjis_to_utf8('一覧表')) #=> "一覧表" #(3)Uconv.sjistou8( "一覧表" )をNKF.nkf("-s",utf8)で戻すのはOKだが、 #(4)NKF.nkf("-u","一覧表")で変換したutf文字列をUconvで戻すのは失敗する。 p NKF.utf8_to_sjis(Uconv.sjis_to_utf8('一覧表')) #=> "一覧表" p Uconv.utf8_to_sjis(NKF.sjis_to_utf8('一覧表')) #=> "\e$B0lMwI=\e(B" ---- ---- #! ruby -Ks require "rexml/document" require "nkf" require 'uconv' doc = REXML::Document.new doc.xml_decl.encoding = "shift-jis" doc.add_element("pxd") #(6)REXMLはDocument#to_sでは変換しようとするが、Element#to_s や #Attribute#to_s では変換しない。 doc[1].attributes["name"] = "一覧表" puts doc[1].attributes["name"] #=> 一覧表 puts doc[1] #=> #puts doc #=> illegal UTF-8 sequence (88) (Uconv::Error) # ↓ #(4)NKF.nkf("-u","一覧表")で変換したutf文字列をUconvで戻すのは失敗する。 #(5)REXMLではUconvでutf8からsjisに変換しようとするので、NKFでutf8に変 #換したutf8文字列をセットすると、失敗する。 doc[1].attributes["name"] = NKF.nkf("-u","一覧表") puts doc[1].attributes["name"] #=> 一覧表 puts doc[1] #=> puts doc #=> # ↓ #(2)Uconv.sjistou8( "一覧表" )をUconvで戻すのはOK。 #(6)REXMLはDocument#to_sでは変換しようとするが、Element#to_s や #Attribute#to_s では変換しない。 doc[1].attributes["name"] = Uconv.sjistou8("一覧表") puts doc[1].attributes["name"] #=> 荳��h�ヲァ陦ィ puts doc[1] #=> puts doc #=> p :ok ---- take_tk = kumagai hidetake