JavaによるDOM Level 3 Load and Saveの利用方法
はじめに
ここではJavaでDOM Level 3 Load and Saveを利用する方法を説明します。Javaのバージョンは1.5(J2SE 5.0)以降である必要があります。また、XMLプロセッサとしてXercesを利用します。以下のページからダウンロードしてください。
以下のサンプルコードはJDK 5.0 Update 8、Xerces2 Java 2.8.0でコンパイル&実行可能であることを確認しています。
Note: Java 1.6(Java SE 6)では、別途Xercesを用意する必要はありません。
概要
DOM 3 Load and Saveでは、LSParserでXMLの読み込みを行い、LSSerializerでXMLの書き込みを行います。LSParserやLSSerializerなど、必要なオブジェクトはDOMImplementationLSを用いて取得することができます。
DOMImplementationLSの取得
Java 1.5ではorg.w3c.dom.bootstrapパッケージが追加され、DOMImplementationRegistryクラスを用いてDOMImplementationのインスタンスを取得できるようになりました。DOMImplementationRegistryで取得できるインスタンスはシステムプロパティ"DOMImplementationSourceList"によって決まります。つまり、"DOMImplementationSourceList"プロパティを変更するだけで、ソースコードを書き換えなくてもDOMの実装を変更できます。
xercesImpl.jarには、このプロパティを設定するためのファイルが含まれています。そのため、xercesImpl.jarをクラスパスに含めるだけでXercesを利用することができます。
DOMImplementationRegistryのインスタンスはnewInstance()メソッドを用いて取得できます。また、DOMImplementationLSのインスタンスはDOMImplementationRegistryのgetDOMImplementation()メソッドで取得します。
/* DOMImplementationRegistryからDOMImplementationLSの取得 */
DOMImplementationRegistry registry =
DOMImplementationRegistry.newInstance();
DOMImplementationLS domImpLS =
(DOMImplementationLS)registry.getDOMImplementation("LS 3.0");
DOMツリーの読み込み - LSParserとLSInput
XML文書を読み込むときは、LSInputで読み込み元を指定し、それをLSParserで読み込みます。LSInputとLSParserのインスタンスはDOMImplementationLSを用いて生成します。
/* ファイル(sample.xml)から読み込む場合の例 */
// LSInputの生成
FileInputStream fin = new FileInputStream("./sample.xml");
LSInput input = domImpLS.createLSInput();
input.setByteStream(fin);
// LSParserの生成とXML文書の読み込み
LSParser parser = domImpLS.createLSParser(
DOMImplementationLS.MODE_SYNCHRONOUS, null);
Document doc = parser.parse(input);
同期モードと非同期モードについて
DOMImplementationLSのcreateLSParser()メソッドの第1引数にはMODE_SYNCHRONOUS(同期モード)またはMODE_ASYNCHRONOUS(非同期モード)を指定します。
同期モードでは、LSParserのparse()メソッドやparseURI()メソッドによりXML文書が解析され、これらのメソッドがDocumentオブジェクトを返します。この時、解析処理はメソッドの呼び出し元と同一のスレッドで行われます。
一方、非同期モードでは、LSParserのparse()メソッドやparseURI()メソッドを呼ぶと別スレッドでXML文書が解析されます。そのため、これらのメソッドはnullを返し、解析結果はLSLoadEventのgetNewDocument()メソッドで取得します。非同期LSParserオブジェクトはEventTargetインタフェースを実装していて、addEventListener()メソッドでLSLoadEventのEventListenerを登録できます。
Note: Java 1.6のデフォルトの実装では、非同期モードはサポートされていないようです。
DOMツリーの書き込み - LSSerializerとLSOutput
DOMツリーを保存するときは、LSOutputで書き込み先を指定し、LSSerializerでそれに書き込みます。LSOutputとLSSerializerのインスタンスはDOMImplementationLSを用いて生成します。
/* 標準出力に書き出す場合の例 */
// LSOutputの生成
LSOutput output = domImpLS.createLSOutput();
output.setByteStream(System.out);
output.setEncoding("Shift_JIS"); // 文字コードの指定
// LSSerializerの生成とXML文書の出力
LSSerializer serializer = domImpLS.createLSSerializer();
serializer.write(doc, output);
サンプルコード
上記のコードをまとめると以下のようになります。
/* sample.xmlを読み込んで標準出力に書き出すプログラム */
import java.io.FileInputStream;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSSerializer;
import org.w3c.dom.ls.LSOutput;
public class Sample {
public static void main(String[] args) {
try {
// DOMImplementationLSのインスタンスを取得
DOMImplementationRegistry registry =
DOMImplementationRegistry.newInstance();
DOMImplementationLS domImpLS =
(DOMImplementationLS)registry.getDOMImplementation("LS 3.0");
// LSInputの生成
FileInputStream fin = new FileInputStream("./sample.xml");
LSInput input = domImpLS.createLSInput();
input.setByteStream(fin);
// LSParserの生成とXML文書の読み込み
LSParser parser = domImpLS.createLSParser(
DOMImplementationLS.MODE_SYNCHRONOUS, null);
Document doc = parser.parse(input);
// LSOutputの生成
LSOutput output = domImpLS.createLSOutput();
output.setByteStream(System.out);
output.setEncoding("Shift_JIS");
// LSSerializerの生成とXML文書の出力
LSSerializer serializer = domImpLS.createLSSerializer();
serializer.write(doc, output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
実行するときはxercesImpl.jarをクラスパスに含めます。例えば以下のように。
java -cp .;xercesImpl.jar Sample
Note: Java 1.6(Java SE 6)では、xercesImpl.jarをクラスパスに設定しなくても作動します。