12

私は次の問題を抱えています:

私はXMLファイル(約1GB)を持っており、必要なデータを取得してそれに対していくつかの操作を行うために、上下に反復する必要があります(つまり、順次ではなく、次々に)。最初はDOMJavaパッケージを使用しましたが、明らかに、XMLファイルを解析しているときに、JVMが最大ヒープスペースに到達して停止しました。

この問題を克服するために、私が思いついた解決策の1つは、XMLの各要素を反復する別のパーサーを見つけ、その内容をハードディスク上の一時的なSQLiteデータベースに保存することでした。したがって、このようにして、JVMのヒープを超えることはなく、すべてのデータが入力されると、XMLファイルを無視して、一時的なSQLiteデータベースでの操作を続行します。

手元で問題に取り組む別の方法はありますか?

4

4 に答える 4

13

ここでは、SAX (Simple API for XML)が役に立ちます。

DOM パーサーとは異なり、SAX パーサーは XML ドキュメントのメモリ内表現を作成しないため、高速でメモリ使用量が少なくなります。org.xml.sax.helpers.DefaultHandler代わりに、SAX パーサーは、コールバックを呼び出すことによって、つまり、パーサーに提供されたインスタンスでメソッドを呼び出すことによって、クライアントに XML ドキュメント構造を通知します 。

実装例を次に示します。

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler handler = new MyHandler();
parser.parse("file.xml", handler);

MyHandlerドキュメント/要素の開始/終了などのイベントが生成されたときに実行するアクションを定義する場所。

class MyHandler extends DefaultHandler {

    @Override
    public void startDocument() throws SAXException {
    }

    @Override
    public void endDocument() throws SAXException {
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
    }

    // To take specific actions for each chunk of character data (such as
    // adding the data to a node or buffer, or printing it to a file).
    @Override
    public void characters(char ch[], int start, int length)
            throws SAXException {
    }

}
于 2013-02-28T10:02:27.137 に答える
3

メモリ制限に縛られたくない場合は、現在のアプローチを使用して、すべてをデータベースに保存することをお勧めします。

SAX parser誰もが (私を含めて) 推奨しているように、XML ファイルの解析は によって行われるべきです。このようにして、一度に 1 つのオブジェクトを作成し、すぐにデータベースに永続化できます。

後処理 (相互参照の解決) ではSELECT、データベースの s を使用して、主キー、インデックスなどを作成できます。慣れている場合は、ORM (Eclipselink、Hibernate) も使用できます。

実際には、SQLite はあまりお勧めしません。MySQL サーバーをセットアップして、そこにデータを保存する方が簡単です。後で XML データを再利用することもできます (削除しない場合)。

于 2013-02-28T11:30:53.537 に答える
1

プログラミングが非常に難しい SAX よりも高レベルのアプローチを使用したい場合は、最近の Saxon-EE リリースを使用して XSLT 変換をストリーミングする方法を検討できます。ただし、これが特定のケースで機能するかどうかを知るには、実行している正確な処理について漠然としすぎています。

于 2013-02-28T14:49:44.787 に答える