倭マン's BLOG

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

5. SAX とのブリッジ

プッシュ・パースを行う API としてすでに SAX があるので、SAX 解析を行う際に作成したクラスを利用できるようにしておいた方がよいでしょう。 今回は、前回までに作成したクラスで org.xml.sax.InputSource と org.xml.sax.ContentHandler を使用する方法を考えます。

org.xml.sax.InputSource から読み込む


これは特に新しくクラスなどを作成する必要はなく、javax.xml.transform.sax.SAXSource クラスを使用するだけで OK です:

import org.xml.sax.InputSource;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource

public void parse(InputSource input){
    Source src = new SAXSource(input);
    ...
}

org.xml.sax.ContentHandler へ書き出す


SAX を使用する際に手作りするクラスは org.xml.sax.ContentHandler を実装するクラスでしょう。 これを使用できるようにしておけば、SAX を使用していたときの成果物がだいたい再利用できるのではないでしょうか?

必要なクラスは、XMLEventHandler インターフェースを実装していて、各コールバック・メソッドが呼び出された際に、その処理を既存の org.xml.sax.ContentHandler オブジェクトへ委譲するようなクラスです。

ここではイベントの種類を限定しているので、あまり複雑にはなりません:

package xmlparsing.sax;

import org.xml.sax.*;
import org.xml.sax.helpers.AttributesImpl;

import xmlparsing.XMLEventHandler;
import xmlparsing.events.*;

public class SAXEventHandler implements XMLEventHandler {
    
    private final ContentHandler ch;
    
    public SAXEventHandler(ContentHandler ch){
        this.ch = ch;
    }

    public void startDocument(StartDocument event) {
        try{
            this.ch.startDocument();
            
        }catch(SAXException ex){
            throw new RuntimeException(ex);
        }
    }

    public void endDocument(EndDocument event) {
        try{
            this.ch.endDocument();
            
        }catch(SAXException ex){
            throw new RuntimeException(ex);
        }
    }
    
    private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl(); 

    public void startElement(StartElement event) {
        try{
            this.ch.startElement("", event.getName(), event.getName(), EMPTY_ATTRIBUTES);
            
        }catch(SAXException ex){
            throw new RuntimeException(ex);
        }
    }

    public void endElement(EndElement event) {
        try{
            this.ch.endElement("", event.getName(), event.getName());
            
        }catch(SAXException ex){
            throw new RuntimeException(ex);
        }
    }

    public void text(Text event) {
        try{
            String text = event.getText();
            this.ch.characters(text.toCharArray(), 0, text.length());
            
        }catch(SAXException ex){
            throw new RuntimeException(ex);
        }
    }
}

これを使用する Java コードは次のような感じです:

import org.xml.sax.ContentHandler;
import javax.xml.transform.Source;

public void parse(Source src, ContentHandler ch){
    XMLEventParser parser = new XMLEventParser();
    XMLEventHandler handler = new SAXEventHandler(ch);

    parser.pushparse(src, handler);
}

まぁ、なんてことはないですね。