0

Androidでアプリを開発していますが、xmlファイルをトラバースする必要があります。

xmlをトラバースする必要があります-指定された位置から前後に移動します。これは、ファイルの解析を開始することを意味しますが、各瞬間に停止して逆方向に進むか、続行することができます。

私はDOMを使用することを考えていました。そのサイクルで、DOMを制御し、やりたいことを実行できました。しかし、私が解析したいxmlファイルには少なくとも8 Mbがあり、DOMは非常にメモリを消費するため、良い解決策ではないようです。

この問題の解決策は、解析のためにドキュメント全体をロードしないことでした。ドキュメントをいくつかの部分に分割し、1つの部分だけをメモリにロードして解析するのが好きです。このパートの終わりに来たら、別のパートをロードします。巻き戻したいときも同じです。

私の質問は、ファイルをいくつかの部分に分割する方法を教えてください。それはxmlファイルであり、子はすべて同じサイズではないので?

例えば:

<root>
   <child time="A">
     <sub1>1</sub1>
     <sub2>2</sub2>
   </child>

   <child time="B">
     <sub1>3</sub1>
   </child>

   <child time="C">
     <sub2>4</sub2>
   </child>
</root>

ご覧のとおり、子のサイズはさまざまであり、このようなファイルを効率的な方法でいくつかの部分に分割する方法がわかりません。

誰かが私に手がかりを与えることができますか?

よろしくお願いします。

4

1 に答える 1

2

XML では、通常、選択を行う必要があります。DOM は大量のメモリを消費し、SAX は後戻りできず、手作りのパーサーは作成と保守が面倒です。

数十 MB のメモリを消費する余裕がある場合は、単純に DOM を使用してください。

SAX と手動解析のどちらを使用するかの決定は、実際に逆戻りする必要がある頻度と、この時点で遅延を許容できるかどうかによって異なります。

それができない場合は、事前計算を行う手作りのパーサーを実装する必要があります。事前計算は、たとえば SAX を使用するか、 CountingInputStreamと組み合わせて使用​​するか、または手動で行うことができます。n各要素の開始オフセットと終了オフセットを事前に計算しchild、次のような間隔の配列として保存します。

public class Interval {
    public int startOffset;
    public int endOffset;
}

Interval[] precomputedOffsets;

ページ サイズであるの値はn20 のようになります。メモリ消費量と戻るパフォーマンスのトレードオフを制御するために、そのバランスをとってください。

iここで、実行時に item に移動する必要があることがわかっている場合は、入力ストリームで and を呼び出し、そこから残りの要素を解析resetします。skip(precomputedOffsets[i / n])i % nchild

于 2012-06-17T08:17:53.647 に答える