2016-10-20 4 views
1

Я разбираю некоторые очень большие XML-файлы, используя пакет xml2 в R. read_xml() успешно загружает большой файл, но когда я пытаюсь использовать xml_find_all() Я получаю «Ошибка: не удалось выделить память: увеличение предела набора узлов». Я предполагаю, что этот предел установлен в libxml2, возможно, в XPATH_MAX_NODESET_LENGTH var? так что, возможно, это не проблема с пакетом xml2 как таковой. Но возможно ли решение в xml2? Я экспериментировал с удалением узлов и освобождением памяти без везения. Благодарю.Получение памяти не удалось: увеличение предела набора узлов с пакетом xml2

ответ

3

Да, вы попадаете в пределы жесткого набора узлов libxml2 XPath engine. От 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 

Одним из вариантов является перекомпилировать libxml2 с другим значением. Или вы можете изменить выражения XPath, чтобы они никогда не сталкивались с узлами, превышающими 10 М узлов. Обратите внимание, что этот предел применяется также к промежуточным наборам узлов, созданным при оценке выражения. Так, к сожалению, сегментирование набора узлов с предикатами не работа:

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

В сущности, вы должны убедиться, что каждый NodeTest не возвращается больше, чем 10M узлов. Если вы не можете этого сделать, вам не повезло.

Вы также можете поднять эту проблему на libxml2 mailing list. Я предполагаю, что этот предел был введен для защиты от вредоносных выражений XPath, которые могут привести к атакам типа «отказ в обслуживании». Но, как я вижу, выражение никогда не сможет вернуть больше узлов, чем во входных документах. Таким образом, максимальный объем памяти, используемый для набора узлов, в любом случае ограничен размером входных документов.

+0

Спасибо. Похоже, что альтернатива - это анализ событий с использованием интерфейса SAX (который я могу увидеть, как это сделать, используя функцию xmlEventParse библиотеки XML R. Не уверен, что то же самое можно достичь, используя пакет xml2 в R. ... хотя read_xml функция включает аргумент «options», который принимает значение «SAX1» как значение ... TBD – litlogger

+0

@litlogger Также должно быть возможно использовать * read_xml * и пройти через дерево документов без использования XPath. Интерфейс SAX (или [* xmlTextReader *] (http://www.xmlsoft.org/html/libxml-xmlreader.html), если они связаны с привязками R), является наиболее эффективным с точки зрения памяти подходом. – nwellnhof

 Смежные вопросы

  • Нет связанных вопросов^_^