倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

Result

今回は javax.xml.transform.Result インターフェースとその実装クラスを見ていきます。

Result インターフェースを実装したクラスには、以下のようなものがあります*1

  • javax.xml.transform.stream.StreamResult
  • javax.xml.transform.sax.SAXResult
  • javax.xml.transform.stax.StAXResult
  • javax.xml.transform.dom.DOMResult
  • org.jdom.transform.JDOMResult
  • org.dom4j.io.DocumentResult




それぞれ簡単に使い方を見ていきましょう。

javax.xml.transform.stream.StreamResult★


StreamResult はファイルや java.io.Writer へ XML 文書を書き出す際に使用します。

Result result = new StreamResult("output.xml");

コンストラクタに指定できる型には以下のようなものがあります:

  • java.lang.String(ファイル名もしくは URI
  • java.io.File
  • java.io.OutputStream
  • java.io.Writer

javax.xml.transform.sax.SAXResult★


SAXResult は org.xml.sax パッケージに定義されている ContentHandler クラスに変換結果を渡したい時に使用します。

ContentHandler ch = ...;
Result result = new SAXResult(ch);

org.xml.sax.ext.LexicalHandler を使用したい場合は、SAXResult に別途指定します:

ContentHandler ch = ...;
LexicalHandler lh = ...;

SAXResult result = new SAXResult(ch);
result.setLexicalHandler(lh);

javax.xml.transform.stax.StAXResult★


StAXResult は XML イベント(の列)を入力にしたい場合に使用します。

XMLEventWriter writer = ...;
Result result = new StAXResult(writer);

コンストラクタとして使用できるクラスは以下の2つ:

  • javax.xml.stream.XMLStreamReader
  • javax.xml.stream.XMLEventReader

ただし、通常 XMLStreamReader や XMLEventWriter のインスタンスを取得するには java.io.InputStream もしくは java.io.Writer を用いるので、StAXResult よりは StreamResult を用いる方が簡単です。

XMLStreamReader や XMLEventWriter で扱えるプロパティ「javax.xml.stream.isRepairingNamespaces」(雑な説明はこちらを参照)を使用するか、これらの独自の実装を使用する場合以外には StAXResult は使わないと思います*2

javax.xml.transform.dom.DOMResult★


DOMResult の使用方法は2通りあります。

変換後に Document オブジェクトを取得する

この方法は JDOM (JDOMResult) や dom4j (DocumentResult) と同じような方法です。 使用手順は次の通り:

  1. DOMResult オブジェクトを生成する
  2. 変換を実行する
  3. Document オブジェクトを取得する

サンプルコードは以下の通り:

public void Document getDOMDocument(Transformer transform, Source src)
        throws TransformerException{

    // 1. DOMResult オブジェクトを生成する
    DOMResult result = new DOMResult();

    // 2. 変換を実行する
    transformer.transform(src, result);

    // 3. Document オブジェクトを取得する
    return (Document)result.getNode();
}

変換結果となる Document オブジェクトを事前に生成しておく

もう1つの使用方法は次の通り:

  1. (空の)Document オブジェクトを生成する*3
  2. DOMResult オブジェクトを生成する
  3. 変換を実行する

サンプルコードは以下のようになります:

public void Document getDOMDocument(Transformer transform, Source src)
        throws TransformerException{

    // 1. Document オブジェクトを生成する
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.newDocument();

    // 2. DOMResult オブジェクトを生成する
    Result result = new DOMResult(doc);

    // 3. 変換を実行する
    transformer.transform(src, result);

    return doc;
}

org.jdom.transform.JDOMResult★


JDOMResult の使用手順は DOMResult の1つ目の手順とほとんど同じです:

  1. JDOMResult オブジェクトを生成する
  2. 変換を実行する
  3. Document オブジェクトを取得する

サンプルコードは以下の通り:

import org.jdom.Document;
import org.jdom4j.transform.JDOMResult;

public void Document getJDOMDocument(Transformer transform, Source src)
        throws TransformerException, JDOMException{

    // 1. JDOMResult オブジェクトを生成する
    JDOMResult result = new DocumentResult();

    // 2. 変換を実行する
    transformer.transform(src, result);

    // 3. Document オブジェクトを取得する
    return result.getDocument();
}

org.dom4j.io.DocumentResult★


使用手順は JDOMResult とほとんど同じです:

  1. DocumentResult オブジェクトを生成する
  2. 変換を実行する
  3. Document オブジェクトを取得する

サンプルコードは以下の通り:

import org.dom4j.Document;
import org.dom4j.io.DocumentResult;

public void Document getDom4jDocument(Transformer transform, Source src)
        throws TransformerException{

    // 1. DocumentResult オブジェクトを生成する
    DocumentResult result = new DocumentResult();

    // 2. 変換を実行する
    transformer.transform(src, result);

    // 3. Document オブジェクトを取得する
    return result.getDocument();
}

*1:今回も javax.xml.bind.util.JAXBResult は無視。

*2:StAXResult に渡せるクラスが XMLEventWriter ではなく XMLEventConsumer ならまだ少しは使いようがありそうですが。

*3:空でない Document オブジェクトを用いることもできるようですが、どの程度意味があるのか。 詳しくは JavaDoc を参照のこと。