0

いくつかの異なるタグを持つXMLファイルを解析するためのSAXパーサーを作成しました。パフォーマンス上の理由から、DOMではなくSAXを選択しました。そして、それが速くて良いので、私がやったことをうれしく思います。私が現在抱えている唯一の問題は、メインクラス(DefaultHandlerを拡張する)が少し大きく、目にはあまり簡単ではないということです。タグ名をチェックする巨大なif/elseifブロックと、特定の属性を読み取るためのネストされたifが含まれています。このブロックはStartElementメソッドにあります。

これを分割するためのきれいな方法はありますか?ファイルを読み取るメインクラスと、すべてのタグのハンドラーが必要です。このタグハンドラーでは、そのタグの属性を読み取り、それらを使用して何かを実行してから、メインハンドラーに戻って、適切なハンドラーにリダイレクトされる次のタグを読み取ります。

メインハンドラーには、解析するすべてのドキュメントに関する情報を収集するグローバルコレクション変数もいくつかあります。理想的には、タグハンドラーからそれらのコレクションに何かを追加できるでしょう。

可能であれば、コード例が非常に役立ちます。このサイトでハンドラスタックについて何か読んだのですが、コード例がないと再現できませんでした。

前もって感謝します :)

4

1 に答える 1

3

SAXフィルターのチェーンを設定することをお勧めします。SAXフィルターは、他のSAXハンドラーと同じですが、完了時にイベントを渡すための別のSAXハンドラーがある点が異なります。これらは、XMLストリームへの一連の変換を実行するために頻繁に使用されますが、必要に応じて物事を因数分解するためにも使用できます。

使用している言語については言及していませんが、DefaultHandlerについて言及しているので、Javaを想定します。最初に行うことは、フィルターをコーディングすることです。Javaでは、これを行うには、XMLFilterを実装します(または、より簡単に言えば、XMLFilterImplをサブクラス化します)。

import java.util.Collection;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;

public class TagOneFilter extends XMLFilterImpl {

    private Collection<Object> collectionOfStuff;

    public TagOneFilter(Collection<Object> collectionOfStuff) {
        this.collectionOfStuff = collectionOfStuff;
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        if ("tagOne".equals(qName)) {
            // Interrogate the parameters and update collectionOfStuff
        }

        // Pass the event to downstream filters.
        if (getContentHandler() != null)
            getContentHandler().startElement(uri, localName, qName, atts);
    }
}

次に、すべてのフィルターをインスタンス化し、それらをチェーン化するメインクラス。

import java.util.ArrayList;
import java.util.Collection;

import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class Driver {

    public static void main(String[] args) throws Exception {
        Collection<Object> collectionOfStuff = new ArrayList<Object>();
        XMLReader parser = XMLReaderFactory.createXMLReader();

        TagOneFilter tagOneFilter = new TagOneFilter(collectionOfStuff);
        tagOneFilter.setParent(parser);

        TagTwoFilter tagTwoFilter = new TagTwoFilter(collectionOfStuff);
        tagTwoFilter.setParent(tagOneFilter);

        // Call parse() on the tail of the filter chain. This will finish
        // tying the filters together before executing the parse at the
        // XMLReader at the beginning.
        tagTwoFilter.parse(args[0]);

        // Now do something interesting with your collectionOfStuff.
    }
}
于 2013-03-18T16:10:03.763 に答える