3

Python のビルトイン XML パーサーを使用して 1.5 ギガの XML ファイルをロードすると、1 日かかります。

from xml.dom import minidom
xmldoc = minidom.parse('events.xml')

進行状況バーを表示できるように、その内部に入り、進行状況を測定する方法を知る必要があります。何か案は?

minidom には parseString() という別のメソッドがあり、渡す文字列が有効な XML であると仮定して DOM ツリーを返します。ファイルを自分でチャンクに分割し、一度に parseString に 1 つずつ渡すとしたら、すべての最後に DOM ツリーを元に戻す?

4

4 に答える 4

5

ユースケースでは、dom の代わりに sax パーサーを使用する必要があり、dom はすべてをメモリにロードし、sax は代わりに行ごとの解析を行い、必要に応じてイベントのハンドラーを作成するので、効果的であり、進行状況インジケーターも作成できます。

また、非常に便利な時があれば、expat パーサーを試すこともお勧めし ます http://docs.python.org/library/pyexpat.html

サックスを使って上達するには:

sax はファイルをインクリメンタルに読み取るため、渡したファイル オブジェクトを独自のものでラップし、読み取った量を追跡できます。

編集: また、ファイルを自分で分割して最後に DOM に参加するという考えも好きではありません。そうすれば、独自の xml パーサーをより適切に作成できます。代わりに sax パーサーを使用することをお勧めします。 ? ここはサックスの方が良さそうです

于 2009-06-16T15:10:21.787 に答える
5

XML を解析する他の手段を使用することを検討しましたか? このような大きな XML ファイルのツリーを構築すると、常に時間がかかり、メモリを大量に消費します。メモリ内にツリー全体が必要ない場合は、ストリーム ベースの解析の方がはるかに高速です。ツリー ベースの XML 操作に慣れていると、少し気が遠くなるかもしれませんが、速度が大幅に向上するという形で見返りが得られます (数時間ではなく数分)。

http://docs.python.org/library/xml.sax.html

于 2009-06-16T14:57:35.883 に答える
3

pulldom APIを使用して、PyQtではなくPyGTKに非常に似たものがあります。Gtk アイドル イベント (GUI がロックアップしないようにするため) と Python ジェネレーター (解析状態を保存するため) を使用して、一度に少しずつ呼び出されます。

def idle_handler (fn):
  fh = open (fn)  # file handle
  doc = xml.dom.pulldom.parse (fh)
  fsize = os.stat (fn)[stat.ST_SIZE]
  position = 0

  for event, node in doc:
    if position != fh.tell ():
      position = fh.tell ()
      # update status: position * 100 / fsize

    if event == ....

    yield True   # idle handler stays until False is returned

 yield False

def main:
  add_idle_handler (idle_handler, filename)
于 2009-06-16T15:09:39.450 に答える
2

最後にツリーをマージするのは非常に簡単です。新しい DOM を作成し、基本的に個々のツリーを 1 つずつ追加することができます。これにより、解析の進行状況を細かく調整することもできます。必要に応じて、異なるプロセスを生成して各セクションを解析することで、並列化することもできます。インテリジェントに分割することを確認する必要があります(タグの途中で分割しないなど)。

于 2009-06-16T14:35:52.793 に答える