[ruby-list:41856] Re: rexml で doc.xml_decl.encoding = "shift-jis" は駄目ですか?
From:
take_tk <ggb03124@...>
Date:
2006-02-25 03:02:17 UTC
List:
ruby-list #41856
たけ(tk)です。
[ruby-list:41855] Re: rexml で doc.xml_decl.encoding = "shift-jis" は駄
目ですか? にて
Kouhei Sutou <kou@cozmixng.org> さん 曰く:
> よく覚えていませんが,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] #=> <pxd name='一覧表'/>
#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] #=> <pxd name='一覧表'/>
puts doc #=> <?xml version='1.0' encoding='SHIFT-JIS'?><pxd name='一覧表'/>
# ↓
#(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] #=> <pxd name='荳hヲァ陦ィ'/>
puts doc #=> <?xml version='1.0' encoding='SHIFT-JIS'?><pxd name='一覧表'/>
p :ok
----
take_tk = kumagai hidetake