- - PR -
J2SE1.4でXML文書を保存/読込するとノード数が変わる
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-10-26 14:13
J2SE SDKのXMLに関する機能を使って以下のようなプログラムを書いたのですが、
XML文書として保存したときと、保存した後、再度読込んだときのノード数が異なっています。 開発環境 J2SE 1.4.0_01 + WindowsXP プログラム(XMLTest.java)
実行結果
二回目にXMLTestを実行した結果は、 1.nodelist length = 1 2.nodelist length = 2 となって欲しいです。 参考までに、XMLTest二回実行後のtest.xmlの中身は 以下のようになっております。 不要な空白や改行が多数ありました。
明示的に作成した数以上のノードが作られるのは困るのですが、 どなたか解決方法をご存知ないでしょうか。 [ メッセージ編集済み 編集者: MASATO 編集日時 2002-10-26 14:25 ] | ||||||||||||
|
投稿日時: 2002-10-27 00:05
詳細を調べてませんが、このプログラムは実行する度に、
root.appendChild(doc.createElement("sub")); を実行しますよね…。 | ||||||||||||
|
投稿日時: 2002-10-27 00:13
それと、Documentの直下にElementをappendされているようですが、
DocumentElementを飛ばしてしまわないほうが良いのではないでしょうか? | ||||||||||||
|
投稿日時: 2002-10-27 01:01
で、1つの答え。(できるだけMASATOさんのプログラムを尊重してという意味で、最適ではないかもしれませんが。)
((org.apache.crimson.tree.XmlDocument)doc).write(writer); を writer.write(doc.getDocumentElement().toString().getBytes()); にしてみてはどうでしょうか?(乱暴ですが。) 私なら, Node root = doc.getFirstChild(); も Node root = doc.getDocumentElement(); にしておきますが。 | ||||||||||||
|
投稿日時: 2002-10-27 01:04
あっ、でもこれだとXML宣言の部分が出力されないか…。
| ||||||||||||
|
投稿日時: 2002-10-27 01:17
結論、ちゃんと transformを使った例を示します。
crimsonのパッケージを裸で使うより、 javax.xml.transform関連のパッケージを使用したほうが 良いと思います。 ------------------------------------------------------------- import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import java.io.*; class XMLTest { public static void main(String[] args) { File datafile = new File("test.xml"); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = null; try { doc = builder.parse(datafile); }catch (IOException e){ doc = builder.newDocument(); } Node root = doc.getDocumentElement(); if (root == null){ root = doc.appendChild(doc.createElement("root")); } System.out.println("1.nodelist length = " + root.getChildNodes().getLength()); root.appendChild(doc.createElement("sub")); System.out.println("2.nodelist length = " + root.getChildNodes().getLength()); FileOutputStream writer = new FileOutputStream(datafile); TransformerFactory tFactory = TransformerFactory.newInstance(); Source source = new DOMSource(doc); Result target = new StreamResult(writer); if (source != null) try { tFactory.newTransformer(). transform(source, target); } catch (TransformerConfigurationException ex) { ex.printStackTrace(); } catch (TransformerException ex) { ex.printStackTrace(); } catch (IllegalArgumentException ex) { ex.printStackTrace(); } writer.close(); }catch (Exception e){ e.printStackTrace(); } } } | ||||||||||||
|
投稿日時: 2002-10-27 02:48
Kissingerさん、どうもありがとうございました。
目的通りの動作を達成することができました。
以上のプログラムを二回実行すると、 以下のようなxmlファイルが作成されました。
余計な空白や改行が何も無い(あたりまえと言えばあたりまえですが) xmlファイルとなって、 書き込み時と読込み時にノード数が変わることもなくなりました。 どうもありがとうございました。 また、org.apache.crimson.tree.XmlDocumentを使っていたのは、 他に保存する方法がわからなかったからです。 javax.xml.transformを使った例を提示して頂けましたので、 こちらを参考に作り直しました。 最後に、 今まではjavax.xml.parsersを用いて記述していた読込み部分も、 javax.xml.transformを用いて書いてみました。 DOMResultのコンストラクタの引数がNodeですので、 Node root = doc.getFirstChild()としてあります。 XMLファイルを読込むための方法として、 javax.xml.parsersを用いる方法と、 javax.xml.transformを用いる方法があり、 どちらも読込めることを確認しましたが、 どちらを使うのが適当でしょうか? | ||||||||||||
|
投稿日時: 2002-10-27 03:12
> XMLファイルを読込むための方法として、
> javax.xml.parsersを用いる方法と、 > javax.xml.transformを用いる方法があり、 > どちらも読込めることを確認しましたが、 > どちらを使うのが適当でしょうか? 私は簡単の為にはparsersの方を使ってますが、XSLTの様に柔軟な使い方をよりスマートにやりたいときはtransform系のResult, Sourceの組み合わせを使うでしょうね。 |