とあるプロジェクトで、通信のインターフェイスに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。
        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 がサポートしてないよって言われるかが謎って言う話。誰か教えてください。

カテゴリ

トラックバック(0)

このブログ記事を参照しているブログ一覧: Windows-31Jの謎

このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/2504

コメントする

このブログ記事について

このページは、falseが2010年11月16日 10:49に書いたブログ記事です。

ひとつ前のブログ記事は「Redmineを動かす」です。

次のブログ記事は「iPadから印刷したい」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

広告

Powered by Movable Type 6.1.1