|
以下の節では、Streaming API for XML により XML ドキュメントの解析と生成を行う方法について説明します。
Java Community Process の JSR-173 で定義されている Streaming API for XML (StAX) を使用すると、XML ドキュメントを簡単かつ直感的に解析および生成できます。SAX API と似ていますが、XML ドキュメントに対する手続き的なストリーム ベースの処理が可能であり、SAX イベント ハンドラを作成する必要はありません。SAX イベント ハンドラで複雑な XML ドキュメントを扱うと、ハンドラ自体が複雑になる場合があります。つまり、StAX を利用すれば、SAX よりきめ細かく解析を制御できます。
SAX を使用して XML ドキュメントを解析する場合、プログラムでは、イベント発生時に解析をリスンするイベント リスナを作成し、特定のイベントを請求するのではなくイベントに対して対応する必要があります。一方、StAX を使用する場合は、XML ドキュメントを手順の流れに沿って処理すること、特定のタイプのイベント (要素の開始など) を請求すること、要素の属性を繰り返し処理すること、ドキュメントの先頭をスキップすること、任意の時点で処理を停止すること、特定の要素の下位要素を取得すること、指定どおりに要素をフィルタ処理することができます。イベントに対応するのではなく、イベントを請求するので、StAX を使用する方法は、「プル解析」と呼ばれることもあります。
StAX には、カーソル API とイベント イテレータ API という 2 つの API があり、どちらでも XML を読み書きできます。以下の節では、各 API およびそれぞれの利点について説明します。
カーソル API の基本機能は、できる限り簡単かつ効率的に XML を解析および生成できるようにするためのものです。StAX の 2 つの API のうち、ほとんどのプログラマが使用すると思われるのは、こちらの方です。
カーソル API は、開始要素、コメント、属性などの一連のイベントを、発生していないものも含めて繰り返し処理します。カーソル API には、XML 解析用の XMLStreamReader
と XML 生成用の XMLStreamWriter
という 2 つの主要なインタフェースがあります。
カーソル API は、XMLStreamReader
インタフェースを使用して仮想カーソルを XML ドキュメント上に移動し、hasNext()
、next()
、getEventType()
、および getText()
などのメソッドを呼び出してデータおよび基底の状態にアクセスできるようにします。XMLStreamReader
インタフェースでは、XML に対して読み込み専用の前方アクセスのみが可能です。
XMLStreamReader
の新しいインスタンスを作成するには、XMLInputFactory
クラスを使用します。新しいリーダーを取得すると、さまざまなプロパティを設定できます。詳細については、「XMLInputFactory インタフェース用に定義されたプロパティ」を参照してください。
XMLStreamReader
インタフェースの next()
メソッドを使用して XML を解析すると、リーダーは次の解析イベントを取得し、読み込んだイベントの種類を識別する整数を返します。解析イベントは、XML 宣言、開始要素タグ、終了要素タグ、ホワイトスペース、コメント、処理手順などの XML ドキュメントの各セクションに対応します。XMLStreamConstant
インタフェースは、next()
メソッドによって返された整数に対応するイベントを指定します。XMLStreamReader
の getEventType()
メソッドを使用して、イベントの種類を判別することもできます。
XMLStreamReader
インタフェースには、XML ドキュメントの特定のデータを取得するためのさまざまなメソッドがあります。そのメソッドの一部を次に示します。
有効なメソッドは、イベントの種類ごとに決まっています。無効なイベントの種類でメソッドを呼び出そうとすると、StAX プロセッサから java.lang.IllegalStateException
が送出されます。たとえば、ネームスペース イベントで getAttributeXXX()
メソッドを呼び出すとエラーになります。イベントの詳細なリストとそのイベントで有効な XMLStreamReader
メソッドについては、StAX 仕様を参照してください。
カーソル API は、XMLStreamWriter
インタフェースを使用して、XML の生成方法を指定します。
XMLStreamWriter
の新しいインスタンスを作成するには、XMLOutputFactory
クラスを使用します。新しいライターを取得すると、ネームスペースおよびプレフィックスを修正するためのプロパティを設定できます。詳細については、「XMLOutputFactory インタフェース用に定義されたプロパティ」を参照してください。
XMLStreamWriter
インタフェースには、XML ドキュメントの標準的な部分に書き込みを行う一連の writeXXX()
メソッドが定義されています。以下に、そのメソッドを示します。
属性とネームスペースを含む XML ドキュメントの各部分は、これらのメソッドによって明示的に書き込まれます。
キャッシュされたデータを出力に書き込むには flush()
メソッド、ライターを閉じてリソースを解放するには close()
メソッドを使用します。
XMLStreamWriter
は、XML の生成時に、生成されたドキュメントが整形式かどうかをチェックしません。整形式の XML ドキュメントを作成するのは、プログラマの役目です。特殊文字 &
、<
、および >
を出力するには、writeCharacters()
メソッドを使用します。
イベント イテレータ API は、カーソル API のすぐ上のレイヤです。パイプライニングの拡張および促進を簡単に行うことができます。パイプライニングとは、複数の XML 間の変換のことです。イベント イテレータ API を使用すると、パイプラインの各ステージで XML をデシリアライズおよびシリアライズする必要はなくなり、パイプラインの両端でのみ nextEvent()
などの API メソッドを使用して中間ステージで通信します。イベント イテレータ API には、XML 解析用の XMLEventReader
と XML 生成用の XMLEventWriter
という 2 つの主要なインタフェースがあります。
カーソル API が StAX で最も頻繁に使用される API なので、このセクションではイベント イテレータ API の詳細な使い方については例を挙げる他には説明しません。この API の詳細な使い方については、StAX 仕様を参照してください。
次の例では、StAX の XMLEventReader
インタフェースを使用して XML ドキュメントを解析する単純なプログラムを示します。このプログラムは、XML ファイルを表す 1 つのパラメータを取り、それを使用して XMLEventReader
オブジェクトを作成します。次に、リーダーを使用して、イベントのストリームを繰り返し処理して出力します。
package examples.event;
import java.io.FileReader;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.util.*;
import javax.xml.namespace.QName;
/**
* イベントを反復処理する単純なサンプル プログラム
*
* @author Copyright (c) 2002 by BEA Systems.All Rights Reserved.
*/
public class Parse {
private static String filename = null;
private static void printUsage() {
System.out.println("usage: java examples.event.Parse <xmlfile>");
}
public static void main(String[] args) throws Exception {
try {
filename = args[0];
} catch (ArrayIndexOutOfBoundsException aioobe){
printUsage();
System.exit(0);
}
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader r =
factory.createXMLEventReader(new FileReader(filename));
while(r.hasNext()) {
XMLEvent e = r.nextEvent();
System.out.println("ID:"+e.hashCode()+"["+e+"]");
}
}
}
次の表で、Streaming API for XML の主なインタフェースとクラスについて説明します。
以下の手順は、StAX カーソル API の XMLStreamReader
インタフェースにより XML ドキュメントの解析を行う一般的手順について説明したものです。この手順では、「StAX を使用した XML 解析の例」で示すサンプル コードを用います。
javax.xml.stream.*
クラスをインポートします。XMLInputFactory.newInstance()
メソッドを使用して XMLInputFactory
をインスタンス化します。XMLInputFactory xmlif = XMLInputFactory.newInstance();
設定可能なプロパティのリストについては、「XMLInputFactory インタフェース用に定義されたプロパティ」を参照してください。
XMLInputFactory.createXMLStreamReader()
メソッドを使用して XMLStreamReader
オブジェクトをインスタンス化します。
詳細については、「XMLStreamReader オブジェクトの取得」を参照してください。
hasNext()
メソッドと next()
メソッドで各 XML イベントを順番に処理して XML ドキュメントを解析します。while(xmlr.hasNext()){
printEvent(xmlr);
xmlr.next();
この例では、xmlr
が XMLStreamReader
インスタンスに当たり、ローカル メソッド printEvent()
(StAX API の一部ではありません) が、次の手順に示すように特定のイベント タイプを判別します。
「特定の XML イベント タイプの判別」を参照してください。
「要素の属性の取得」を参照してください。
「要素のネームスペースの取得」を参照してください。
「テキスト データの取得」を参照してください。
「場所の情報の取得」を参照してください。
「入力ストリームのクローズ」を参照してください。
次の例では、StAX の XMLStreamReader
インタフェースを使用して XML ドキュメントを解析する単純なプログラムを示します。
このプログラムは、XML ファイルを表す 1 つのパラメータを取り、それを使用して XMLStreamReader オブジェクトを作成します。次に、リーダーを使用してイベントのストリームを繰り返し処理し、XML 要素の開始、要素の属性のリスト、処理手順など、各イベントのタイプを判別します。このサンプル プログラムは、内部メソッドを使用して、適切な場合は属性およびネームスペースのリストを出力し、これらのイベントに関する情報を出力します。
package examples.basic;
import java.io.FileReader;
import java.util.Iterator;import javax.xml.stream.*;
import javax.xml.namespace.QName;
/**
* これは、XMLStreamReader クラスを示す
* 単純な解析例
*
* @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
*/
public class Parse {
private static String filename = null;
private static void printUsage() {
System.out.println("usage: java examples.basic.Parse <xmlfile>");
}
public static void main(String[] args) throws Exception {
try {
filename = args[0];
} catch (ArrayIndexOutOfBoundsException aioobe){
printUsage();
System.exit(0);
}
//
// 入力ファクトリを取得する
//XMLInputFactory xmlif = XMLInputFactory.newInstance();
System.out.println("FACTORY: " + xmlif);
//
// リーダーをインスタンス化する
//XMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(filename));
System.out.println("READER: " + xmlr + "\n");
//
// XML を解析する
//while(xmlr.hasNext()){
printEvent(xmlr);
xmlr.next();
}
//
// リーダーをクローズする
//xmlr.close();
}
private static void printEvent(XMLStreamReader xmlr) {
System.out.print("EVENT:["+xmlr.getLocation().getLineNumber()+"]["+
xmlr.getLocation().getColumnNumber()+"] ");
System.out.print(" [");
switch (xmlr.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;
case XMLStreamConstants.END_ELEMENT:
System.out.print("</");
printName(xmlr);
System.out.print(">");
break;
case XMLStreamConstants.SPACE:
case XMLStreamConstants.CHARACTERS:
int start = xmlr.getTextStart();
int length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION:
System.out.print("<?");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("?>");
break;
case XMLStreamConstants.CDATA:
System.out.print("<![CDATA[");
start = xmlr.getTextStart();
length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
System.out.print("]]>");
break;
case XMLStreamConstants.COMMENT:
System.out.print("<!--");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("-->");
break;
case XMLStreamConstants.ENTITY_REFERENCE:
System.out.print(xmlr.getLocalName()+"=");
if (xmlr.hasText())
System.out.print("["+xmlr.getText()+"]");
break;
case XMLStreamConstants.START_DOCUMENT:
System.out.print("<?xml");
System.out.print(" version='"+xmlr.getVersion()+"'");
System.out.print(" encoding='"+xmlr.getCharacterEncodingScheme()+"'");
if (xmlr.isStandalone())
System.out.print(" standalone='yes'");
else
System.out.print(" standalone='no'");
System.out.print("?>");
break;
}
System.out.println("]");
}
private static void printName(XMLStreamReader xmlr){if(xmlr.hasName()){
printName(prefix,uri,localName);
String prefix = xmlr.getPrefix();
String uri = xmlr.getNamespaceURI();
String localName = xmlr.getLocalName();
}
}
private static void printName(String prefix,
String uri,
String localName) {
if (uri != null && !("".equals(uri)) ) System.out.print("['"+uri+"']:");
if (prefix != null) System.out.print(prefix+":");
if (localName != null) System.out.print(localName);
}
private static void printAttributes(XMLStreamReader xmlr){for (int i=0; i < xmlr.getAttributeCount(); i++) {
}
printAttribute(xmlr,i);
}
private static void printAttribute(XMLStreamReader xmlr, int index) {String prefix = xmlr.getAttributePrefix(index);
System.out.print(" ");
String namespace = xmlr.getAttributeNamespace(index);
String localName = xmlr.getAttributeLocalName(index);
String value = xmlr.getAttributeValue(index);
printName(prefix,namespace,localName);
System.out.print("='"+value+"'");
}
private static void printNamespaces(XMLStreamReader xmlr){for (int i=0; i < xmlr.getNamespaceCount(); i++) {
}
printNamespace(xmlr,i);
}
private static void printNamespace(XMLStreamReader xmlr, int index) {String prefix = xmlr.getNamespacePrefix(index);
System.out.print(" ");
String uri = xmlr.getNamespaceURI(index);
if (prefix == null)
System.out.print("xmlns='"+uri+"'");
else
System.out.print("xmlns:"+prefix+"='"+uri+"'");
}
}
次のコードの抜粋で示すように、XMLInputFactory.createXMLStreamReader()
メソッドを使用し、XML ドキュメントに基づいて XMLStreamReader
オブジェクトをインスタンス化します。
XMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(filename));
この例では、xmlif
が XMLInputFactory
インスタンスに当たります。
createXMLStreamReader()
メソッドのさまざまなシグネチャにより、以下の XML ドキュメント フォーマットをパラメータとして扱うことができます。
java.io.InputStream
java.io.Reader
(例で示します)javax.xml.transform.Source
(JAXP API で指定されています)
XML ドキュメントの解析中に特定のイベント タイプを判別するには、XMLStreamReader.next()
メソッドまたは XMLStreamReader.getEventType()
メソッドを使用します。next()
メソッドは、次のイベントを読み込んで、そのイベント タイプを示す整数を返し、getEventType()
メソッドは、現在のイベント タイプを示す整数を単純に返します。XMLStreamReader
の XMLStreamConstants
上位インタフェースには、以下のリストに示すイベント タイプ定数が定義されています。
XMLStreamConstants.ATTRIBUTE
XMLStreamConstants.CDATA
XMLStreamConstants.CHARACTERS
XMLStreamConstants.COMMENT
XMLStreamConstants.DTD
XMLStreamConstants.END_DOCUMENT
XMLStreamConstants.END_ELEMENT
XMLStreamConstants.ENTITY_DECLARATION
XMLStreamConstants.ENTITY_REFERENCE
XMLStreamConstants.NAMESPACE
XMLStreamConstants.NOTATION_DECLARATION
XMLStreamConstants.PROCESSING_INSTRUCTION
XMLStreamConstants.SPACE
XMLStreamConstants.START_DOCUMENT
XMLStreamConstants.START_ELEMENT
次の例では、Java case
文を使用して、XMLStreamReader.next()
メソッドから返されたイベントのタイプを判別する方法を示します。この例では、XMLStreamReader.getEventType()
メソッドを使用して、next()
メソッドから返された整数値を基に現在のイベント タイプを判別します。簡単にするため、この例では、見つかったイベントをそのまま出力します。イベントをさらに処理する方法は、その後の節で示します。
switch (xmlr.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
System.out.print("Start Element\n");
break;
case XMLStreamConstants.END_ELEMENT:
System.out.print("End Element\n");
break;
case XMLStreamConstants.SPACE:
System.out.print("Space\n");
break;
case XMLStreamConstants.CHARACTERS:
System.out.print("Characters\n");
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION:
System.out.print("Processing Instrcutions\n");
break;
case XMLStreamConstants.CDATA:
System.out.print("CDATA\n");
break;
case XMLStreamConstants.COMMENT:
System.out.print("Comment\n");
break;
case XMLStreamConstants.DTD:
System.out.print("DTD\n");
break;
case XMLStreamConstants.ENTITY_REFERENCE:
System.out.print("Entity Reference\n");
break;
case XMLStreamConstants.ENTITY_DECLARATION:
System.out.print("Entity Declaration\n");
break;
case XMLStreamConstants.START_DOCUMENT:
System.out.print("Start Document\n");
break;
case XMLStreamConstants.END_DOCUMENT:
System.out.print("End Document\n");
break;
}
完全な要素名には、プレフィックス、ネームスペース URI、ローカル名が含まれます。現在のイベントが開始要素または終了要素であることを判別したら、XMLStreamReader
インタフェースの getPrefix()
メソッド、getNamespaceURI()
メソッド、および getLocalName()
メソッドをそれぞれ使用して、この情報を取得します。
たとえば、サンプル プログラムで、開始イベント要素の case
文が次のようになっているとします。
case XMLStreamConstants.START_ELEMENT:
System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;
注意 : | printNamespaces() メソッドと printAttributes() メソッドについては、別の節で説明します。 |
2 つの printName()
ローカル メソッドは、次のように getXXX()
メソッドを使用できます。
private static void printName(XMLStreamReader xmlr){
if(xmlr.hasName()){
String prefix = xmlr.getPrefix();
String uri = xmlr.getNamespaceURI();
String localName = xmlr.getLocalName();
printName(prefix,uri,localName);
}
}
private static void printName(String prefix,
String uri,
String localName) {
if (uri != null && !("".equals(uri)) ) System.out.print("['"+uri+"']:");
if (prefix != null) System.out.print(prefix+":");
if (localName != null) System.out.print(localName);
}
現在のイベントが開始要素、終了要素、または属性であることを判別したら、XMLStreamReader
インタフェースの getAttributeXXX()
メソッドを使用して、属性とその値のリストを取得します。
警告 : | getAttributeXXX() メソッドを使用できるのは、開始要素、終了要素、属性イベントに対してのみです。それ以外のタイプのイベントでこのメソッドを実行しようとすると、java.lang.IllegalStateException が送出されます。 |
getAttributeCount()
メソッドを使用すると、現在の要素の属性数を取得し、属性のリストに対して反復処理を行うループでその属性数を使用することができます。メソッドは、ネームスペースをこの数には含みません。追加の getAttributeXXX()
メソッドは、特定の属性のプレフィックス、ネームスペース URI、ローカル名、および値を返します。
たとえば、サンプル プログラムで、開始イベント要素の case
文が次のようになっているとします。
case XMLStreamConstants.START_ELEMENT:
System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;
注意 : | printName() メソッドと printNamespaces() メソッドについては、別の節で説明します。 |
次のローカル メソッド printAttributes()
では、属性のリストに対して反復処理を行う方法を示します。属性インデックスはゼロベースなので、for
ループは 0 から始まります。
private static void printAttributes(XMLStreamReader xmlr){
for (int i=0; i < xmlr.getAttributeCount(); i++) {
printAttribute(xmlr,i);
}
}
次のローカル メソッド printAttribute()
では、特定の属性の全情報を出力する方法を示します。
private static void printAttribute(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getAttributePrefix(index);
String namespace = xmlr.getAttributeNamespace(index);
String localName = xmlr.getAttributeLocalName(index);
String value = xmlr.getAttributeValue(index);
System.out.print(" ");
printName(prefix,namespace,localName);
System.out.print("='"+value+"'");
}
printName()
メソッドについては、「完全な要素名の取得」で説明しています。
現在のイベントが開始要素、終了要素、またはネームスペースであることを判別したら、XMLStreamReader
インタフェースの getNamespaceXXX()
メソッドを使用して、イベント用に宣言されたネームスペースのリストを取得します。
警告 : | getNamespaceXXX() メソッドを使用できるのは、開始要素、終了要素、ネームスペース イベントに対してのみです。それ以外のタイプのイベントでこのメソッドを実行しようとすると、java.lang.IllegalStateException が送出されます。 |
getNamespaceCount()
メソッドを使用すると、現在のイベント用に宣言されているネームスペースの数を返し、そのリストに対して反復処理を行うループでそのネームスペース数を使用することができます。現在のイベントが終了要素の場合、この数は、スコープ外になるネームスペースの数を示します。追加の getNamespaceXXX()
メソッドは、特定のネームスペースのプレフィックスとネームスペース URI を返します。
たとえば、サンプル プログラムで、開始イベント要素の case
文が次のようになっているとします。
case XMLStreamConstants.START_ELEMENT:
System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;
注意 : | printName() メソッドと printAttributes() メソッドについては、別の節で説明します。 |
次のローカル メソッド printNamespaces()
では、開始要素のネームスペースのリストに対して反復処理を行う方法を示します。ネームスペース インデックスはゼロベースなので、for
ループは 0 から始まります。
private static void printNamespaces(XMLStreamReader xmlr){
for (int i=0; i < xmlr.getNamespaceCount(); i++) {
printNamespace(xmlr,i);
}
}
次のローカル メソッド printNamespace()
では、特定のネームスペースの全情報を出力する方法を示します。
private static void printNamespace(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getNamespacePrefix(index);
String uri = xmlr.getNamespaceURI(index);
System.out.print(" ");
if (prefix == null)
System.out.print("xmlns='"+uri+"'");
else
System.out.print("xmlns:"+prefix+"='"+uri+"'");
}
デフォルトのネームスペース宣言の場合、getNamespacePrefix()
メソッドは null を返します。
XMLStreamReader
インタフェースには、コメントや CDATA などのイベントからテキスト データを取得するためのさまざまな getTextXXX()
メソッドが用意されています。
getTextStart()
メソッドを使用して、現在のテキスト イベントの最初の文字が格納されているテキスト文字配列内にオフセットを取得します。getTextLength()
メソッドを使用して、テキスト文字配列内の文字列の長さを取得します。最後に、getTextCharacters()
メソッドを使用して、現在のイベントのこの文字配列を返します。文字配列には、現在のイベントのみに関するテキスト情報が含まれています。next()
メソッドを呼び出すと、入力ストリームの次のイベントがすぐに読み込まれ、文字配列に新しい情報が格納されます。
次の例では、CDATA イベントのテキスト データを出力する方法を示します。
case XMLStreamConstants.CDATA:
System.out.print("<![CDATA[");
start = xmlr.getTextStart();
length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
System.out.print("]]>");
break;
文字イベントに実際にテキストがあることを最初にチェックする場合は、次の例に示すように hasText()
メソッドを使用します。
case XMLStreamConstants.COMMENT:
System.out.print("<!--");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("-->");
break;
StAX API の Location
インタフェースでは、解析対象の XML のパブリック ID やシステム ID とともに、行番号や列番号などイベントに関する場所の情報を取得するためのメソッドを利用できます。次の例に示すように、XMLStreamReader
インタフェースの getLocation()
メソッドを使用して、現在のイベントの Location
オブジェクトを返します。
System.out.print("EVENT:["+xmlr.getLocation().getLineNumber()+"]["+
xmlr.getLocation().getColumnNumber()+"] ");
プログラミング慣行として、作業終了時に XMLStreamReader
を明示的にクローズしてリソースを解放します。リーダーをクローズするには、XMLStreamReader.close()
メソッドを使用します。以下に例を示します。
//
// リーダーをクローズする
//
xmlr.close();
以下の手順は、StAX カーソル API の XMLStreamWriter
インタフェースにより、新しい XML ドキュメントの生成を行う一般的手順について説明したものです。
javax.xml.stream.*
クラスをインポートします。XMLOutputFactory.newInstance()
メソッドを使用して XMLOutputFactory
をインスタンス化します。次に例を示します。XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
設定可能なプロパティのリストについては、「XMLOutputFactory インタフェース用に定義されたプロパティ」を参照してください。
XMLOutputFactory.createXMLStreamWriter()
メソッドを使用して、XML を含むファイルまたはオブジェクトの名前を渡し、XMLStreamWriter
オブジェクトをインスタンス化します。
詳細については、「XMLStreamWriter オブジェクトの取得」を参照してください。
次の例では、StAX の XMLStreamWriter
インタフェースを使用して XML ドキュメントを生成する単純なプログラムを示します。
このサンプル プログラムではまず、カレント ディレクトリにある outFile.xml
ファイルに出力が書き込まれるように指定して、XMLStreamWriter
のインスタンスを作成します。次に、さまざまな writeXXX()
メソッドを使用して、次のような XML ファイルをビルドします。
<?xml version='1.0' encoding='utf-8'?>
<!-- ここはコメント -->
<person xmlns:one="http://namespaceOne" gender="f">
<one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
</person>
XMLStreamWriter
インタフェースは、XML ドキュメントが整形式かどうかをチェックしません。各開始要素と終了要素が対応しているかどうかなどを確認するのは、プログラマの役目です。この例では、writeCharacters("\n")
メソッドを使用して、テキスト ファイルへの書き込み時に XML を読みやすくするために新しい行を出力に追加する方法についても示します。
package examples.basic;
import java.io.FileOutputStream;
import java.util.Iterator;import javax.xml.stream.*;
import javax.xml.namespace.QName;
/**
* これは、XMLStreamWriter クラスを使用して
* XML を生成する方法を示す単純なサンプル コード
*
* 生成された XML ファイルは、以下のようになる
*
* <?xml version='1.0' encoding='utf-8'?>
*
* <!-- ここはコメント -->
* <person xmlns:one="http://namespaceOne" gender="f">
* <one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
* </person>
*
*
* @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
*/
public class Generate {
public static void main(String args[]) throws Exception {
//
// 出力ファクトリを取得する
//XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
System.out.println("FACTORY: " + xmlof);
//
// ライターをインスタンス化する
//XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(new FileOutputStream ("outFile.xml"));
System.out.println("READER: " + xmlw + "\n");
//
// XML を生成する
//
// デフォルト XML 宣言を記述するxmlw.writeStartDocument();
xmlw.writeCharacters("\n");
xmlw.writeCharacters("\n");
// コメントを記述するxmlw.writeComment("this is a comment");
xmlw.writeCharacters("\n");
// 単一の属性「gender」を持つルート要素「person」を記述するxmlw.writeStartElement("person");
xmlw.writeNamespace("one", "http://namespaceOne");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");
// 内容と 2 つの属性を持つ「name」要素を記述するxmlw.writeCharacters(" ");
xmlw.writeStartElement("one", "name", "http://namespaceOne");
xmlw.writeAttribute("hair","pigtails");
xmlw.writeAttribute("freckles","yes");
xmlw.writeCharacters("Pippi Longstocking");
// 「name」要素を終了するxmlw.writeEndElement();
xmlw.writeCharacters("\n");
// 「person」要素を終了するxmlw.writeEndElement();
// XML ドキュメントを終了するxmlw.writeEndDocument();
// XMLStreamWriter をクローズしてリソースを解放するxmlw.close();
}
}
次のコードの抜粋で示すように、XMLOutputFactory.createXMLStreamWriter()
メソッドを使用し、XML ドキュメントに基づいて XMLStreamWriter
オブジェクトをインスタンス化します。
XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(new FileOutputStream ("outFile.xml"));
この例では、xmlof
が XMLOutputFactory
インスタンスに当たります。
createXMLStreamWriter()
メソッドのさまざまなシグネチャにより、以下の XML ドキュメント フォーマットをパラメータとして扱うことができます。
java.io.OutputStream
(例で示します)java.io.Writer
javax.xml.transform.Result
(JAXP API で指定されています)
次のコードの抜粋で示すように、XMLStreamWriter.writeStartDocument()
メソッドを使用し、XML ドキュメントの 1 行目として XML 宣言を追加します。
xmlw.writeStartDocument();
引数を指定しない場合、このメソッドは次のデフォルト XML 宣言を記述します。
<?xml version='1.0' encoding='utf-8'?>
別のエンコーディングまたは XML バージョンを指定する場合は、引数を次のように指定した writeStartDocument()
メソッドを使用します。
writeStartDocument()
メソッドでエンコーディングを設定しても、基底の出力の実際のエンコーディングは設定されません。このエンコーディング設定用の引数は、XML 宣言の encoding
属性に対してどの値が書き込まれるかを指定するものです。出力のエンコーディングを実際に設定するには、対応する XMLOutputFactory.createXMLStreamWriter()
メソッドで XMLStreamWriter
のインスタンスを作成する際に encoding
パラメータを指定する必要があります。
XMLStreamWriter.write
XXX
()
メソッドを使用すると、開始要素、終了要素、コメント、CDATA、エンティティ参照などの標準的な XML イベントを出力ストリームに追加できます。XXX
は、writeStartElement()
、writeEndElement()
、writeComment()
、writeCData()
などの特定のイベントを指します。テキスト データまたは名前を String
として渡すことにより、大部分の要素を作成できます。
XMLStreamWriter
インタフェースでは、データの検証や、ドキュメントが整形式かどうかのチェックは行われません。各開始要素と終了要素が対応しているかどうかなどの確認は、プログラマの役目です。また、開始要素と終了要素のイベントが正しくネストされているかどうかを確認することも、プログラマに任されています。テキスト ファイルへの書き込み時に出力 XML を読みやすくするには、writeCharacters("\n")
メソッドを使用して、適切な場所に新しい行を追加します。
<!-- ここはコメント -->
<name>Jane Doe</name>
出力ストリームにこの要素を追加する Java コードは次のようになります。
xmlw.writeComment("This is a comment");
xmlw.writeCharacters("\n");
xmlw.writeStartElement("name");
xmlw.writeCharacters("Jane Doe");
xmlw.writeEndElement();
xmlw.writeCharacters("\n");
開始要素イベントの直後に writeAttribute()
メソッドを使用して、属性を要素に追加できます。バインド対象の URI とともに属性のプレフィックスを指定することも、属性をまったく指定しないことも可能です。
<person gender="f">
この XML を作成する Java コードは次のとおりです。
xmlw.writeStartElement("person");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");
writeNamespace()
メソッドを使用すると、出力ストリームにネームスペースを記述できます。現在のイベントで開始要素などのネームスペースの記述を有効にするのはプログラマの役目です。現在のイベントでネームスペースの記述が無効になっている場合は、javax.xml.stream.XMLStreamException
が送出されます。イベントのプレフィックスやそのバインド対象となる URI を指定するには、それに応じた形式の writeXXX()
メソッドを使用します。
たとえば、次の XML 出力では、<person>
要素のネームスペース宣言、および <one>
子要素用に指定した one
プレフィックスを示します。
<person xmlns:one="http://namespaceOne" gender="f">
<one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
</person>
この XML を作成する Java コードは次のとおりです。
// 単一の属性「gender」を持つルート要素「person」を記述する
xmlw.writeStartElement("person");
xmlw.writeNamespace("one", "http://namespaceOne");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");
// 内容と 2 つの属性を持つ「name」要素を記述する
xmlw.writeCharacters(" ");
xmlw.writeStartElement("one", "name", "http://namespaceOne");
xmlw.writeAttribute("hair","pigtails");
xmlw.writeAttribute("freckles","yes");
xmlw.writeCharacters("Pippi Longstocking");
// 「name」要素を終了する
xmlw.writeEndElement();
xmlw.writeCharacters("\n");
// 「person」要素を終了する
xmlw.writeEndElement();
プログラミング慣行として、作業終了時に XMLStreamWriter
を明示的にクローズしてリソースを解放します。ライターをクローズするには、XMLStreamWriter.close()
メソッドを使用します。以下に例を示します。
// XMLStreamWriter をクローズしてリソースを解放する
xmlw.close();
以下の表では、XMLInputFactory
を使用して XMLStreamReader
オブジェクトまたは XMLEventReader
オブジェクトを生成する際に設定可能な標準プロパティを示します。
注意 : | 以下の表のプロパティには、たとえば javax.xml.stream.isValidating のように、いずれも先頭に javax.xml.stream が付きます。
|
以下の表では、XMLOutputFactory
を使用して XMLStreamWriter
オブジェクトまたは XMLEventWriter
オブジェクトを生成する際に設定可能な標準プロパティを示します。
注意 : | 以下の表のプロパティには、たとえば javax.xml.stream.isValidating のように、いずれも先頭に javax.xml.stream が付きます。
|