2週に渡ってStAXを使用したXMLドキュメントのパースについて紹介しました。今週は,XMLドキュメントを作成する方法を紹介しましょう。
StAXでXMLドキュメントを作成する
XMLドキュメントの作成でも,StAXは2種類の手法を持ちます。もちろん,パースと同様,カーソルAPIとイベントイテレータAPIです。
まずは,カーソルAPIでXMLドキュメントを作成しましてみます。
カーソルAPIを用いたXMLドキュメントの作成
作成するXMLドキュメントは次のような形式のものとしましょう。
<names> <name first="Bob" last="Dylan" /> <name first="John" last="Lennon" /> <name first="Chuck" last="Berry" /> </names>
names要素の中に,複数のname要素があります。name要素はfirst属性とlast属性を持ち,それぞれ文字列が入ります。
サンプルのソース | CursorWriterSample.java |
---|
このサンプルはカーソルAPIを使用して,上記のXMLドキュメントを生成するプログラムです。
public CursorWriterSample() { // ファクトリの生成 XMLOutputFactory factory = XMLOutputFactory.newInstance(); StringWriter stringWriter = new StringWriter(); XMLStreamWriter writer = null; try { // ライタの生成 writer = factory.createXMLStreamWriter(stringWriter); // XMLドキュメントの開始 writer.writeStartDocument(); // names要素 writer.writeStartElement("names"); // name要素 writer.writeStartElement("name"); // name要素の属性 writer.writeAttribute("first", "Bob"); writer.writeAttribute("last", "Dylan"); // name要素を閉じる writer.writeEndElement(); // names要素を閉じる writer.writeEndElement(); // ドキュメントを閉じる writer.writeEndDocument(); writer.flush(); // ドキュメントの表示 System.out.println(stringWriter); } catch (XMLStreamException ex) { System.err.println("出力に失敗しました"); } finally { // クローズ if (writer != null) { try { writer.close(); } catch (XMLStreamException ex) {} } if (stringWriter != null) { try { stringWriter.close(); } catch (IOException ex) {} } } }
カーソルAPIを用いて,XMLドキュメントを作成するにはjavax.xml.stream.XMLStreamWriterインタフェースを使用します。XMLStreamWriterオブジェクトはファクトリを用いて,生成します。ファクトリはjavax.xml.stream.XMLOutputFactoryクラスです。
ファクトリを生成し,XMLStreamWriterオブジェクトを生成する部分を青字で示しました。
ファクトリはXMLOutputWriterクラスのnewInstanceメソッドをコールして生成し,createXMLStreamWriterメソッドでXMLStreamWriterオブジェクトを生成します。
この処理はパースの時のXMLStreamReaderオブジェクトを生成する処理とほぼ同じです。
createXMLStreamWriterメソッドの引数はストリーム,ライタ,またはXSLTで使用するリザルトが使用できます。ここでは,文字列に対する出力を行なうStringWriterクラスを使用しました。
XMLStreamWriterオブジェクトが取得できれば,後はXMLドキュメントを出力していくだけです。
XMLStreamWriterインタフェースにはパース時のイベントに応じた出力メソッドが用意されています。たとえば,要素の開始であればwriteStartDocumentメソッド,属性であればwriteAttributeメソッドを使用します。
上記のコードでは赤字で示した部分がXMLドキュメントの出力処理を表しています。特に難しい処理をしているわけではないので,容易に理解できるはずです。
この例では名前空間を指定していませんが,もちろん含めることも可能です。
このサンプルの実行結果を次に示します。
C:\stax>java StreamWriterSample <?xml version="1.0" ?><names><name first="Bob" last="Dylan"></name></names>
内容は意図した通りですが,すべて1行に記述されてしまいました。
読みやすいように整形して出力するのであれば,適宜writeCharactersメソッドを使用して改行や空白を加えていきます。以下に,改行,空白を加えたコードを示します。
public CursorWriterSample() { // ファクトリの生成 XMLOutputFactory factory = XMLOutputFactory.newInstance(); StringWriter stringWriter = new StringWriter(); XMLStreamWriter writer = null; try { // ライタの生成 writer = factory.createXMLStreamWriter(stringWriter); // XMLドキュメントの開始 writer.writeStartDocument(); writer.writeCharacters("\n"); // names要素 writer.writeStartElement("names"); writer.writeCharacters("\n "); // name要素 writer.writeStartElement("name"); // name要素の属性 writer.writeAttribute("first", "Bob"); writer.writeAttribute("last", "Dylan"); // name要素を閉じる writer.writeEndElement(); writer.writeCharacters("\n"); // names要素を閉じる writer.writeEndElement(); // ドキュメントを閉じる writer.writeEndDocument(); writer.flush(); // ドキュメントの表示 System.out.println(stringWriter); } catch (XMLStreamException ex) { System.err.println("出力に失敗しました"); } finally { // クローズ if (writer != null) { try { writer.close(); } catch (XMLStreamException ex) {} } if (stringWriter != null) { try { stringWriter.close(); } catch (IOException ex) {} } } }
赤字の部分が改行もしくは空白を出力している部分です。これで実行すると次のようになります。
C:\stax>java StreamWriterSample <?xml version="1.0" ?> <names> <name first="Bob" last="Dylan"></name> </names>
このようにシーケンシャルに出力をしていくことで,XMLドキュメントを作成していくことができます。