とあるプロジェクトで、通信のインターフェイスにXMLを使うことになっていて、顧客の指定で文字コードはSJISで!と言われたのでXMLの encoding は Windows-31J を使うことにした。
で、こちらのシステムはPHPを使っていたのであまり気にしていなかったのだけれど、対向のシステムが Java を使っていて、XML の文字列の要素をどうやってエンコードするんですか?と聞かれたので、普通に XML のシリアライザ使えば気にしなくて良いんじゃないの?と答えた。
そのときに、Java の変換関数があったら教えて、と言われたので、ちょっと自分で書いてみたらなかなかに謎だったので記す。
昔の Java は、xalan とか xerces とか外部ライブラリを使わないと XML が扱えなかったんだけど、最近の JDK は標準で使えるはず。
でも、SunがOracleに買収されたせいか、java.sun.com に繋がりにくくなって、APIリファレンスがみずらくてしょうがないので、適当にトライ&エラーで試した結果。
まずは、普通に XML をテキストにしてみる。試したのは、とあるLinuxで、LANGはja_JP.UTF-8。Javaは1.6.0_20。
Windows-31Jにしたかったので、
ちなみに、StreamResultのコンストラクタ引数は、OutputStream又はWriterを取れるので、
警告が気になるようであれば、
あと、TransformerにXML宣言を出させた場合、
と、言うわけで、なんで Windows-31J を runtime がサポートしてないよって言われるかが謎って言う話。誰か教えてください。
で、こちらのシステムはPHPを使っていたのであまり気にしていなかったのだけれど、対向のシステムが Java を使っていて、XML の文字列の要素をどうやってエンコードするんですか?と聞かれたので、普通に XML のシリアライザ使えば気にしなくて良いんじゃないの?と答えた。
そのときに、Java の変換関数があったら教えて、と言われたので、ちょっと自分で書いてみたらなかなかに謎だったので記す。
昔の Java は、xalan とか xerces とか外部ライブラリを使わないと XML が扱えなかったんだけど、最近の JDK は標準で使えるはず。
でも、SunがOracleに買収されたせいか、java.sun.com に繋がりにくくなって、APIリファレンスがみずらくてしょうがないので、適当にトライ&エラーで試した結果。
まずは、普通に XML をテキストにしてみる。試したのは、とあるLinuxで、LANGはja_JP.UTF-8。Javaは1.6.0_20。
Transformer t = TransformerFactory.newInstance().newTransformer(); t.transform(new DOMSource(document), new StreamResult(System.out));これだと、普通に utf-8 の XML が生成される。あ、document は適当に中身を入れた org.w3c.dom.Documentね。
Windows-31Jにしたかったので、
Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty("encoding", "Windows-31J"); t.transform(new DOMSource(document), new StreamResult(System.out));とすると、出力されるXML宣言に encoding="Windows-31J"がつくようになり、本文もちゃんと Windows-31Jでエンコーディングされるんだけど、標準出力に
Warning: The encoding 'Windows-31J' is not supported by the Java runtime.と表示される。ちゃんと変換できてるのになんでそんな警告が出るんだろうか。
ちなみに、StreamResultのコンストラクタ引数は、OutputStream又はWriterを取れるので、
Writer writer = new OutputStreamWriter(System.out, "Windows-31J"); Transformer t = TransformerFactory.newInstance().newTransformer(); t.transform(new DOMSource(document), new StreamResult(writer));みたいに書くと、XML宣言のencodingはutf-8で、本文の文字コードは Windows-31JのXMLができあがる。
警告が気になるようであれば、
Writer writer = new OutputStreamWriter(System.out, "Windows-31J"); Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty("omit-xml-declaration", "yes"); t.transform(new DOMSource(document), new StreamResult(writer));のように書いて、自分でXML宣言を前に付けてあげれば、望みどおりの出力が得られる。
あと、TransformerにXML宣言を出させた場合、
<?xml version="1.0" encoding="Windows-31J" standalone="no"?>のようにstandalone="no"が付くのも制御する方法がわからなかった。
と、言うわけで、なんで Windows-31J を runtime がサポートしてないよって言われるかが謎って言う話。誰か教えてください。
カテゴリ
Javaトラックバック(0)
このブログ記事を参照しているブログ一覧: Windows-31Jの謎
このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/2504
コメントする