2016-10-20 8 views
1

xml_find_all()を使用しようとすると、read_xml()は大きなファイルを正常に読み込みますが、私は「エラー:メモリ割り当てに失敗しました:ノードセットのヒット限界が増えています。私はこの制限がおそらくXPATH_MAX_NODESET_LENGTH varのlibxml2内に設定されていると仮定していますか?多分これはxml2パッケージ自体の問題ではないかもしれません。しかし、xml2には解決策がありますか?ノードを取り除き、運がないままメモリを解放することを実験しました。ありがとう。メモリ割り当ての取得に失敗しました:xml2パッケージでノードセットのヒットリミットが増加しています

答えて

3

はい、libxml2 XPathエンジンのハードコードされたノードセットの制限に達しています。 からxpath.c:

/* 
* XPATH_MAX_NODESET_LENGTH: 
* when evaluating an XPath expression nodesets are created and we 
* arbitrary limit the maximum length of those node set. 10000000 is 
* an insanely large value which should never be reached under normal 
* circumstances, one would first need to construct an in memory tree 
* with more than 10 millions nodes. 
*/ 
#define XPATH_MAX_NODESET_LENGTH 10000000 

1つのオプションは、別の値でlibxml2のを再コンパイルすることです。または、XPM式を変更して、10Mノードを超えるノードセットに遭遇しないようにすることもできます。この制限は、式の評価中に作成される中間ノードセットにも適用されます。だから、残念ながら、述語とノードセットを分割することは動作しません。

//element[position() < 5000000] 
//element[position() >= 5000000 and position() < 10000000] 
//element[position() >= 10000000 and position() < 15000000] 

本質的には、すべてのNodeTest以上10Mのノードを返さないことを確認する必要があります。あなたがそれをすることができないなら、あなたは悲しいかなか幸運ではありません。

libxml2 mailing listでこの問題を提起することもできます。この制限は、DoS攻撃につながる可能性のある悪意のあるXPath式から保護するために導入されたものだと思います。しかし、私が見ているように、式は入力文書に存在するノードより多くのノードを返すことはできません。とにかく、ノードセットに使用されるメモリの最大量は、入力ドキュメントのサイズによって制限されます。

+0

ありがとうございました。代わりに、SAXインターフェイスを使ってイベントを解析する方法があります(これは、RのXMLライブラリのxmlEventParse関数を使用する方法を見ることができます)。read_xmlではxml2パッケージを使用して同じことが達成できるかどうかはわかりません関数は "SAX1"を値として受け入れる "options"引数を含んでいます...。TBD – litlogger

+0

@litlogger * read_xml *を使用してXPathを使わずにドキュメントツリーを歩くことも可能です。 xmlTextReader *](http://www.xmlsoft.org/html/libxml-xmlreader.html)がRバインディングによって公開されている場合は、最もメモリ効率の良いアプローチです。 – nwellnhof

関連する問題