1

現在、libxml2のDOMインターフェイス以外のものを使用するように既存のアプリケーションを修正する必要があります。これは、XMLファイルが非常に大きく、メモリにロードできないことが判明したためです。

データの読み込みを、DOMツリーの反復から、ほとんどの部分でxmlTextReaderを使用するように書き直しましたが、それほど問題はありません。(私xmlNewTextReaderFilenameはローカルファイルを開くために使用します。)

ただし、大きなデータが存在するサブツリーは順番に読み取る必要はありませんが、いくつかの(少量の)データを他のデータよりも先に収集する必要があります。(問題は、大量のデータが含まれているのはこのサブツリーであるため、このサブツリーのみをメモリにロードしてもあまり意味がないということです。)

最も簡単な方法は、現在のリーダーを「複製」/「コピー」し、先読みしてから元のインスタンスに戻って、そこで読み続けることです。(私は最初の人ではないようです... C#側に実装されているものもあります:ブックマーク付きのXMLリーダー。)

ただし、xmlTextReaderの状態を「コピー」する方法はないようです。

ファイルの一部を再読み込みできない場合は、ファイル全体を再読み込みすることもできます。これは無駄ですが、ここでは問題ありませんが、事前にどこにいたかを覚えておく必要がありますか?

xmlTextReaderが現在のドキュメント内にあることを覚えておく簡単な方法があるので、後でドキュメント/ファイルをもう一度読むときにその位置をもう一度見つけることができますか?

問題の例を次に示します。

<root>
  <cat1>
    <data attrib="x1">
      ... here goes up to one GB in stuff ...
    </data>
    <data attrib="y2"> <!-- <<< Want to remember this position without having to re-read the stuff before -->
      ... even more stuff ...
    </data>
    <data attrib="z3">
       <!-- I need (part of) the data here to meaningfully interpret the data in [y2] that 
            came before. The best approach would seem to first skip all that data
            and then start back there at <data attrib="y2"> ... not having to re-read
            the whole [x1] data would be a big plus! -->
    </data>
  </cat1>
  ...
</root>
4

1 に答える 1

1

XMLメーリングリストで学んだことから回避策を回答したいと思います。

xmlReaderで状態を「複製」する簡単な方法はありませんが、可能であり、非常に簡単である必要があるのは、ドキュメントで行った読み取りをカウントすることです。

つまり、xmlReaderを使用してドキュメントを読み取るには、おそらく次のコマンドを呼び出す必要があります。

// looping ...
status = ::xmlTextReaderRead(pReader);

構造化された方法でそれを行う場合(たとえば、xmlReaderの使用パターンをカプセル化する小さなラッパークラスを作成することになりました)、カウンターを追加するのは比較的簡単です。

// looping ...
status = ::xmlTextReaderRead(pReader);
if (1 == status) { // success
  ++m_ReadCounter;
}

ドキュメントを再読み込みする(特定の位置に到達する)場合は、何度も呼び出すだけxmlTextReaderReadm_ReadCounter、最初からやり直したい位置に到達するまで結果を破棄します。

はい、ドキュメント全体を再解析する必要がありますが、それで十分な速度である可能性があります。(実際には、ドキュメントの非常に大量の部分をキャッシュするよりも優れている/高速である可能性があります。)

于 2013-04-04T11:42:14.823 に答える