XMLStreamReader も、XMLEventReader 同様 XML 文書を解析するクラスですが、解析中に XML イベントオブジェクトを生成しないため素早く動作します。 XMLSteamReader を用いた XML 文書の解析の手順は、XMLEventReader と(解析処理の実装以外は)ほとんど同じで、以下のようになります(以前の記事参照):
- XMLInputFactory のインスタンスを取得する
- (必要なら)XMLInputFactory の設定をする
- XMLStreamReader のインスタンスを取得する
- XMLStreamReader のインスタンスを用いて XML 文書の解析を行う
- XMLStreamReader を閉じる
簡単なサンプルは次のようになります(引数の java.io.Reader オブジェクトから解析対象の XML 文書を読み込みます):
public void analyze(Reader input)throws XMLStreamException{ // 1. XMLInputFactory のインスタンスを取得する XMLInputFactory factory = XMLInputFactory.newInstance(); // 2. (必要なら)XMLInputFactory の設定をする factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true); XMLStreamReader reader = null; try{ // 3. XMLStreamReader のインスタンスを取得する reader = factory.createXMLStreamReader(input); // 4. XML 文書の解析を行う while(reader.hasNext()){ // ここで各 XML イベントに対する処理を行う } }finally{ // 5. XMLStreamReader を閉じる if(reader != null) reader.close(); } }
各ステップについて少し詳しく見ていきましょう。
XMLInputFactory のインスタンスを取得する、設定をする
XMLEventReader の場合と全く同じなので省略します。
XMLStreamReader のインスタンスを取得する
XMLStreamReader のインスタンスは XMLInputFactory のメソッド XMLInputFactory#createXMLStreamReader() によって生成します。
XMLStreamReader reader = factory.createXMLStreamReader(input);
createXMLStreamReader() メソッドに渡せるオブジェクトのうち、解析対象の XML 文書を指定するものは次の3つです:
これらのオブジェクトに加えて、createXMLEventReader() メソッド同様、エンコーディング(InputStream の場合)やシステム識別子(InputStream, Reader の場合)を指定する文字列も渡すことができます。
XML 文書の解析を行う
XMLStreamReader の使い方は XMLEventReader と同名のメソッドがありますが、XML イベントのようなオブジェクトは返しません。 next() メソッドや nextTag() メソッドを呼び出すと、XMLStreamReader 自体の状態が変わります。 XML 文書の解析時に要素名やテキストの内容を取得したい場合は、XMLStreamReader に定義されている getter メソッドなどを呼び出します。
状態遷移に関連するメソッド
XMLStreamReader の状態遷移は状態の確認に使用するメソッドには以下のようなものがあります:
メソッド名 | 備考 |
---|---|
hasNext() | 次の XML イベントがあるかどうかを判定します。 |
next() | XMLStreamReader の状態を次の XML イベントに遷移させます。 |
nextTag() | XMLStreamReader の状態を次の開始タグまたは終了タグまで遷移させます。 |
require() | XMLStreamReader の現在の状態が指定されたものに一致するかどうかを判定します。 |
XML ノードの情報を取得するメソッド
XMLStreamReader の各状態に対して、XML ノードの情報を取得するメソッドが多数定義されています。 基本的には XML イベントに定義されているメソッドと同じですが、それらが XMLStreamReader 自身に定義されている事に注意しましょう。
XMLStreamReader の状態 | 情報取得メソッド |
---|---|
START_DOCUMENT | getEncoding(), getVersion(), isStandalone(), standaloneSet(), getCharacterEncodingScheme() |
START_ELEMENT | getName(), getLocalName(), hasName(), getPrefix(), getAttributeXxx(), isAttributeSpecified(), getNamespaceXxx(), getElementText() |
END_ELEMENT | getName(), getLocalName(), hasName(), getPrefix(), getNamespaceXxx() |
CHARACTERS | getTextXxx() |
CDATA | getTextXxx() |
SPACE | getTextXxx() |
COMMENT | getTextXxx() |
PROCESSING_INSTRUCTION | getPITarget(), getPIData() |
ENTITY_REFERENCE | getLocalName(), getText() |
DTD | getText() |
- getNamespaceXxx() には getNamespaceContext(), getNamespaceCount(), getNamespacePrefix(), getNamespaceURI() があります。
- getAttributeXxx() には getAttributeCount(), getAttributeName(), getAttributePrefix(), getAttributeNamespace(), getAttributeLocalName(), getAttributeType(), getAttributeValue() があります。
- getTextXxx() には getText(), getTextCharacters(), getStart(), getLength() があります。
プロパティ風 XML ファイルの解析
XMLEventReader 同様、nextTag() や getElementText() は、プロパティ風の XML ファイルに対して用いることができます。 次のような XML ファイルがあったとしましょう:
<book> <title>イラスト西洋哲学史下</title> <author>小阪修平</author> <price>610</price> <isbn>978-4-7966-6598</isbn> </book>
この XML ファイルを解析して、プロパティを表示する簡単なサンプルコードは例えば次のようになります:
public void iterateProperties()throws Exception{ XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("book.xml")); // <book> 要素まで処理を飛ばす reader.nextTag(); while (reader.hasNext()) { // 次のタグへ状態を遷移 reader.nextTag(); // 終了タグの場合はループから抜ける if(reader.isEndElement()) break; // 要素名と子テキストを表示 System.out.println(start.getName()+"="+reader.getElementText()); } reader.close(); }
getElementText() メソッドを呼び出した後、XMLStreamReader の状態は要素下のテキストの次の終了要素に移るのに注意しましょう。
これを実行すると次のように表示されます:
title=イラスト西洋哲学史下 author=小阪修平 price=610 isbn=978-4-7966-6598
XMLEventReader を閉じる
XMLEventReader の場合と同じなので省略します。