#r #libxml2 #xml2
#r #libxml2 #xml2
Вопрос:
Я анализирую некоторые очень большие XML-файлы, используя пакет xml2 в R. read_xml () успешно загружает большой файл, но когда я пытаюсь использовать xml_find_all (), я получаю «Ошибка: сбой выделения памяти: увеличение лимита доступа к набору узлов». Я предполагаю, что этот предел установлен в libxml2, возможно, в переменной XPATH_MAX_NODESET_LENGTH? так что, возможно, это не проблема с пакетом xml2 как таковым. Но возможно ли решение в xml2? Я экспериментировал с удалением узлов и освобождением памяти, но безуспешно. Спасибо.
Ответ №1:
Да, вы достигли жестко заданного предела набора узлов в движке XPath libxml2. Из 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 возвращает не более 10 миллионов узлов. Если вы не можете этого сделать, вам, к сожалению, не повезло.
Вы также можете поднять эту проблему в списке рассылкиlibxml2. Я предполагаю, что это ограничение было введено для защиты от вредоносных выражений XPath, которые могут привести к атакам типа «отказ в обслуживании». Но, как я это вижу, выражение никогда не сможет вернуть больше узлов, чем присутствует во входных документах. Таким образом, максимальный объем памяти, используемый для набора узлов, в любом случае ограничен размером входных документов.
Комментарии:
1. Спасибо. Похоже, альтернативой является анализ событий с использованием интерфейса SAX (что я вижу, как сделать, используя функцию xmlEventParse библиотеки XML R). Не уверен, что то же самое может быть достигнуто с помощью пакета xml2 в R. . . хотя функция read_xml включает аргумент «options», который принимает «SAX1» в качестве значения . . . TBD
2. @litlogger Также должна быть возможность использовать read_xml и перемещаться по дереву документа без использования XPath. Интерфейс SAX (или XmlTextReader , если он доступен с помощью R-привязок) — это наиболее экономичный подход к использованию памяти.