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ドキュメントを作成していくことができます。

この先は会員の登録が必要です。有料会員(月額プラン)は初月無料!

日経 xTECHには有料記事(有料会員向けまたは定期購読者向け)、無料記事(登録会員向け)、フリー記事(誰でも閲覧可能)があります。有料記事でも、登録会員向け配信期間は登録会員への登録が必要な場合があります。有料会員と登録会員に関するFAQはこちら