ヒント: DOMからの変換

DOMからSAXまたはJDOMへ変換する必要があるときは...

Comments

W3CのDOM (Document Object Model) に満足しており、SAXでは不十分だと考える方も、いずれはDOMからアプリケーション開発者が使用する他の形式へ移行する方法を探さなければならなくなります。ここで言う他の形式とは、もちろんSAXとJDOMです。DOMを入力として受け入れ、それを他の何かへ変換しなければならない場合、どうすればよいのでしょうか?これは、もっともな疑問です。完ぺきな文書表現を提供するDOMを他の形式に変換することには大きな意味があります。このヒントでは、DOMをSAXまたはJDOMへ変換する方法について学びます。

DOMからSAXへ

DOM Level 1および それより新しいLevel 2では、残念ながらDOMツリーをSAXまたはそれ以外の形式に出力する手段が提供されていません。その結果、おのおののパーサーを実装すると、出力用にカスタムAPIセットが提供され、実装の独立性は失われます。すなわち、ユーザーがそのパーサー向けに書いたコードは、そのパーサー (Crimson、Xerces、または Oracleなど) とだけ共同して動作します。独立性を持たせるという機能は、DOM Level 3で提供されると考えられていますが、DOM Level 3がどんな出力方式を提供するか、成り行きを見守る必要があります。そのときまでは、DOMツリーについて書かれた (連載の) ベンダーの資料で学習するようにしてください。たとえば、Apache Xercesを使用すると、リスト1に挙げるようなorg.apache.xml.serialize.XMLSerializer クラスを使う必要が出てきます。いずれの場合でも、多分DOMツリーをストリームへ出力し、順次処理するために、そのストリームをSAXに戻さなければなりません。リスト1では、DOMツリーをストリームに出力することだけを示しているので注意してください。その後で、そのストリームをSAXプロセッサーへの入力として使用できます。

リスト1. DOMから出力ストリーム (SAXにより使用される) への変換
import org.apache.xerces.parsers.DOMParser;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
public class PrintDOMTree {
    public static void main(String[] args) {
        try {
            InputSource source = new InputSource(args[0]);
            DOMParser parser = new DOMParser();
            parser.parse(source);
            Document doc = parser.getDocument();
            XMLSerializer serializer = new XMLSerializer();
            // Insert your PipedOutputStream here instead of System.out!
            serializer.setOutputByteStream(System.out);
            serializer.serialize(doc);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

DOMからJDOMへの変換

DOMからJDOMへの変換は、DOMからSAXへの変換と比べかなり楽です。これは、実際、理にかなっています。DOMツリーをいったん入手したということは、既にSAXを通じてデータを取得する機会があったということです。実際、DOM表現により、XMLを保管するためのメモリーが既に使い果たされているため、DOMツリーはSAXによって処理されるのが最善という状況はめったにありません。さらに一般的な作業は、DOMツリーとして入ってくるXML文書をJDOMツリーへ変換することです。これらの形式は、両方とも 文書表現ですが、その振る舞いと機能は、かなり異なるので、DOMツリーをJDOMに変換するのは他の人に頼みたくなるかもしれません。他の人の仕事であると思っても、(最低限) 自分の構造を他の人の構造へ変換する方法は理解しておく必要はあります。

DOMからJDOMへ変換するため、JDOM APIは、org.jdom.input.DOMBuilder というDOMNode をユーザーに提供しています。このクラスは、(Element およびAttr のような、他のDOM構造と同様) DOMDocument を取り込み、DOMツリーをJDOMDocument へ変換します。実際この処理だけでは十分ではないので、リスト2にコードを示して処理の過程を見ていただきます。

リスト2. DOMからJDOMへの変換
// Java imports
import java.io.IOException;
// JDOM imports
import org.jdom.JDOMException;
import org.jdom.input.DOMBuilder;  
import org.jdom.output.XMLOutputter;  
// SAX and DOM
import org.xml.sax.InputSource;
// Xerces
import org.apache.xerces.parsers.DOMParser;
public class DOMtoJDOM {
    // DOM tree of input document
    org.w3c.dom.Document domDoc;
    public DOMtoJDOM(String systemID) throws Exception {
        DOMParser parser = new DOMParser();
        parser.parse(new InputSource(systemID));
        domDoc = parser.getDocument();
    }
    public org.jdom.Document convert() throws JDOMException, IOException {
        // Create new DOMBuilder, using default parser
        DOMBuilder builder = new DOMBuilder();
        org.jdom.Document jdomDoc = builder.build(domDoc);
        return jdomDoc;
    }
    public static void main(String[] args) {
        try {
            DOMtoJDOM tester = new DOMtoJDOM(args[0]);
            org.jdom.Document jdomDoc = tester.convert();
            // Output the document to System.out
            XMLOutputter outputter = new XMLOutputter();
            outputter.output(jdomDoc, System.out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

これ以上説明することはありません。一度DOMからSAXへの変換法を覚えてしまえば、必要とするいかなる出力形式とも取り組むことができ、また、将来出会うどのようなXML表現とも対話できるようになります。DOM Level 3の仕様が、DOMツリーを出力するため、標準的な、ベンダーに依存しない方法へ変更されることを期待しましょう。それまでは、DOMを楽しんでください。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=242477
ArticleTitle=ヒント: DOMからの変換
publish-date=04012001