Python で解析したい XML ファイルがあります。これを行う最善の方法は何ですか?ドキュメント全体をメモリに取り込むのは悲惨なことです。何らかの方法で一度に 1 つのノードを読み取る必要があります。
私が知っている既存の XML ソリューション:
- 要素ツリー
- minixml
しかし、私が言及した問題のために、それらはうまく機能しないのではないかと心配しています. また、テキスト エディターで開くこともできません。巨大なテキスト ファイルを操作するための一般的なヒントはありますか?
Python で解析したい XML ファイルがあります。これを行う最善の方法は何ですか?ドキュメント全体をメモリに取り込むのは悲惨なことです。何らかの方法で一度に 1 つのノードを読み取る必要があります。
私が知っている既存の XML ソリューション:
しかし、私が言及した問題のために、それらはうまく機能しないのではないかと心配しています. また、テキスト エディターで開くこともできません。巨大なテキスト ファイルを操作するための一般的なヒントはありますか?
まず、試してみElementTree
ましたか(組み込みの純粋なPythonまたはCバージョン、あるいはより良いlxml
バージョン)?実際にファイル全体をメモリに読み込むものはないと確信しています。
もちろん、問題は、ファイル全体をメモリに読み込むかどうかに関係なく、結果として解析されるツリーがメモリに保存されることです。
ElementTreeには、非常にシンプルで、多くの場合十分な、気の利いたソリューションがあります。iterparseです。
for event, elem in ET.iterparse(xmlfile, events=('end')):
...
ここで重要なのは、ツリーを構築しながら変更できることです(コンテンツを、親ノードに必要なものだけを含む要約に置き換えることによって)。入ってくるときにメモリに保持する必要のないものをすべて捨てることで、メモリを使い果たすことなく、通常の順序で物事を解析することに固執することができます。
リンク先のページには、XML-RPCとplistを処理中に変更する例など、詳細が記載されています。(そのような場合、メモリを節約するためではなく、結果のオブジェクトを使いやすくするためですが、アイデアを理解するには十分なはずです。)
これは、要約する方法を考えられる場合にのみ役立ちます。(親が子からの情報を必要としない最も些細なケースでは、これはただelem.clear()
のことです。)そうでなければ、これはあなたのために機能しません。
標準ソリューションはSAXです。これは、一度に1つのノードでツリーを操作できるコールバックベースのAPIです。iterparseの場合のようにノードを切り捨てることについて心配する必要はありません。これは、ノードを解析した後はノードが存在しないためです。
そこにある最高のSAXの例のほとんどは、JavaまたはJavascript用ですが、理解するのはそれほど難しくありません。たとえば、http://cs.au.dk/~amoeller/XML/programming/saxexample.htmlを見ると、Pythonでの記述方法を理解できるはずです(どこにあるかを知っている限り)xml.saxのドキュメント)。
すべてをメモリに読み込まずに動作するDOMベースのライブラリもいくつかありますが、40GBのファイルを妥当な効率で処理できると私が確信しているものはありません。
最善の解決策は、何をしようとしているか、およびシステム リソースがどれだけ空いているかによって部分的に異なります。それをpostgresqlまたは同様のデータベースに変換することは、最初の目標としては悪くないかもしれません。一方、データを 1 回だけ取り出す必要がある場合は、おそらく必要ありません。大きな XML ファイルを解析する必要がある場合、特にグラフなどのデータを処理することが目的の場合は、通常、xml を S 式に変換し、S 式インタープリター (Python で実装) を使用して分析します。順番にタグ付けして、表形式のデータを構築します。一度に 1 行ずつファイルを読み取ることができるため、結果の表形式のデータがすべてメモリに収まる限り、ファイルの長さは問題になりません。