- PR -

UTF-8ファイルの読み込み

1
投稿者投稿内容
masa
会議室デビュー日: 2004/12/01
投稿数: 1
投稿日時: 2004-12-01 14:06
初めて投稿します。
初心者なので、非常に基本的な質問なのですが、どなたかご教授ください。

現在、UTF-8のXMLファイルを読み込もうとしているのですが、うまくいきません。
下記ソース

//DOMの準備をする
DocumentBuilderFactory dbf
= DocumentBuilderFactory.newInstance();
DocumentBuilder db
= dbf.newDocumentBuilder();

//文書を読み込む
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("TEST.xml"), "UTF-8"));

// パースのパターン1
InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");
Document doc = db.parse(is.getByteStream());

// パースのパターン2
Document doc = db.parse(new InputSource(reader));

//ルート要素を得る
Element root = doc.getDocumentElement();

//ノードの子をたどる
walk(root);

//文書を書き出す
XmlDocument xdoc = (XmlDocument) doc;
BufferedWriter bw = new BufferedWriter(new FileWriter("TEST.xml"));
xdoc.write(bw,"UTF-8");
bw.close();

パターン1でやると、実行エラーとなり、
パターン2で実行すると、出力が文字化けしてしまいます。

どなたかご教授いただければと思います。よろしくお願いします。
JW
常連さん
会議室デビュー日: 2004/01/14
投稿数: 49
投稿日時: 2004-12-02 16:34
引用:

masaさんの書き込み (2004-12-01 14:06) より:
初めて投稿します。
初心者なので、非常に基本的な質問なのですが、どなたかご教授ください。



-どんな開発環境で
  -おそらくJavaで、バージョンは不明。XMLDocumentクラスは標準ライブラリではない(ドキュメントとしては公式にはそうなっていない)ので、org.apache.crimson.tree.XMLDocumentならそう書く、と良いかと思います(後述のimport文もある方が良い、というのと被りますが)
-どんなプログラムを動かしたら
  -ほぼ良いですが、[code]タグを使用するようにした方が良いです。インデントが崩れるので。
  -個人的にはimport文もある方が、試してもらえる可能性が高くなるんじゃないかと思います。
-どんなエラーがでた
  -どの行で XxxxExceptionが発生したなど
-文字化けした
  -どう化けたのか、読めないならダンプしてコードを出してみる。
  -実際は「UTF-8で出力したいのに(Windowsなら)SJISででてるよ」だと思いますが。
というあたりを具体的に書くと良いかと思います。

コード:
    //文書を読み込む
      BufferedReader reader =  new BufferedReader(
          new InputStreamReader(
             new FileInputStream("TEST.xml"), "UTF-8"));

  // パースのパターン1
  InputSource is = new InputSource(reader);
  is.setEncoding("UTF-8");                         //←(1)
  Document doc  = db.parse(is.getByteStream());    //←(2)



(1)の InputSource#setEncodingを呼んでいますが、InputSourceのドキュメントでコンストラクタの部分を見るとInputSource(InputStream) の方では 「setEncodingを使ってオブジェクトの文字セットを指定することもできます」とありますが、InputSource(reader)の方はそういう記述はありません。
(Readerで読めばすでに文字単位(内部的にUnicode)になっているのは明白だから)
(2)ではせっかくInputSourceを使っているのにわざわざByteStreamに戻すという摩訶不思議なことをしています。DocumentBuilder#parseには InputSourceをそのまま渡せるようになっているのでそのまま渡してみてはどうでしょうか。

ってそれがパターン2ですね。

で、出力側ですが、
コード:
  //文書を書き出す
  XmlDocument xdoc = (XmlDocument) doc;
  BufferedWriter bw = new BufferedWriter(new FileWriter("TEST.xml")); //(3)
  xdoc.write(bw,"UTF-8");
  bw.close();


(3)がまずいです。
コード:
  BufferedWriter bw = new BufferedWriter(
    new FileOutputStreamWriter(
      new FileOutputStream("TEST.xml"),
      "UTF-8"));


とやらないと、Writerのエンコードがマシンの環境によって異なってしまいます。(WindowsならMS932≒SJIS)
それか、
コード:
  //文書を書き出す
  XmlDocument xdoc = (XmlDocument) doc;
  BufferedOutputStream stream = new BufferedOutputStream(
    new FileOutputStream("TEST2.xml"));
  xdoc.write(stream);


と、XMLDocument#write(OutputStream) の形式のメソッドを使えば勝手にUTF-8で書いてくれる(少なくともJDK1.4.2_05付属のソースではそうなっている)ので、こちらを使ってみてください。

余談ですが、入力ファイルと出力ファイルが同じというのは危険すぎます。
1

スキルアップ/キャリアアップ(JOB@IT)