1

巨大な XML ファイル 4G を処理する必要があります。私は dom4j SAX を使用しましたが、独自の DefaultElementHandler を作成しました。コード フレームワークは次のとおりです。

SAXParserFactory sf = SAXParserFactory.newInstance();   
SAXParser sax = sf.newSAXParser();   
sax.parse("english.xml", new DefaultElementHandler("page"){   
public void processElement(Element element) { 
// process the element
}
});    

巨大なファイル「ページ」を「ページ」ごとに処理していると思いました。しかし、私はいつもメモリ不足エラーを抱えていたので、そうではないようです。何か重要なことを見逃していませんか?ありがとう。XMLプロセスは初めてです。

4

3 に答える 3

0

ページごとに XML を実際に処理するわけではありませんが、DefaultElementHandler (それが何であれ) を使用する代わりに XMLFilterImpl を拡張すると、XML 要素をそのまま処理することができます。ストリーミングするため、ドキュメント全体がメモリ内にある場合はありません (実際問題として)。

基本的に、イベント要素、要素の開始時、属性、その中のテキスト、そして要素の最後で呼び出されます (ContentHandler インターフェイスのメソッドを見てください)。これらの呼び出しに基づいて、処理を行います (おそらく、「ページ」要素内に要素を蓄積するいくつかのデータ構造が必要になるでしょう。また、テキストの呼び出しが 1 回だけであるという保証はないことに注意してください (パーサーまで)。

これはより明確にするのに役立ちますか?

于 2009-12-16T10:05:34.173 に答える
0

あなたの DefaultElement 実装は私には混乱しているように見えます。すべてが sBuilder に積み上げられているように見え、ルート要素の最後が見つかるか、メモリが不足する可能性が高いまでクリアされません。

要素のテキストを読み取る方法は、解析する必要がある xml の種類によって異なります。各要素にはテキストを含めることができ、子要素を散在させることができます。一般に、Web サービスや構成ファイルで見られる種類の xml があり、すべての要素テキストがリーフ要素にあり、XHTML のように散在している場合があります。

xml のスキーマが、すべてのテキスト情報がリーフ要素にあるというものである場合、取得したテキストを startElement でバッファリングし、蓄積されたテキストを endElement で使用してから、バッファをクリアできます。

SAX に関する優れた記事は次のとおりです。 http://www.javaworld.com/javaworld/jw-08-2000/jw-0804-sax.html

于 2009-12-16T13:56:42.170 に答える
0

オンラインの例に従っただけなので、要素内のすべてのコンテンツのみを読み取ると思います...

public 抽象クラス DefaultElementHandler extends DefaultHandler{ private boolean begin; プライベート文字列タグ名; プライベート StringBuilder sBuilder;

public DefaultElementHandler(String tagName) {
    this.tagName = tagName;
    this.begin = false;
    this.sBuilder = new StringBuilder();
}

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if (qName.equals(tagName)||begin){
        sBuilder.append("<");
        sBuilder.append(qName);
        sBuilder.append(" ");
        int attrCount = attributes.getLength();
        for (int i=0; i<attrCount; i++) {
            sBuilder.append(attributes.getQName(i));
            sBuilder.append("=\"");
            sBuilder.append(attributes.getValue(i));
            sBuilder.append("\" ");
        }
        sBuilder.append(">");
        begin = true;
    }
}

public void characters(char[] ch, int start, int length) throws SAXException{       
    StringBuilder sb = new StringBuilder();
    for(int i=0; i < length; i++) {
        sb.append(convertSpecialChar(ch[start+i]));
    }

    String text = sb.toString().trim();      
    //String text = new String(convertSpecialChar(ch), start, length);
    if (text.trim().equals("")) return;
    if (begin) sBuilder.append(text);
}

public void endElement(String uri, String localName, String qName) throws SAXException {
    String stag = "</" + tagName + ">";   
    String ntag = "</" + qName + ">";   
    if (stag.equals(ntag) || begin) {   
        sBuilder.append(ntag);   
        if (stag.equals(ntag)) {   
            begin = false;   
            try {   
                Document doc = DocumentHelper.parseText(sBuilder.toString());   
                Element element = doc.getRootElement();   
                this.processElement(element);   
            } catch (DocumentException e) {   
                e.printStackTrace();  
                System.exit(1);
            }   
            sBuilder.setLength(0);   
        }   
    }   
}
于 2009-12-16T10:49:07.740 に答える