获取内存分配失败:使用 xml2 包增加节点集达到限制

Getting Memory allocation failed : growing nodeset hit limit with xml2 package

我正在使用 R 中的 xml2 包解析一些非常大的 xml 文件。read_xml() 成功加载了大文件,但是当我尝试使用 xml_find_all(),我得到 "Error: Memory allocation failed : growing nodeset hit limit." 我假设这个限制是在 libxml2 中设置的,也许在 XPATH_MAX_NODESET_LENGTH var 中?所以也许这不是 xml2 包本身的问题。但是在 xml2 内是否有可能的解决方案?我尝试过删除节点和释放内存,但没有成功。谢谢。

是的,您正在达到 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

一个选项是用不同的值重新编译 libxml2。或者您可以更改 XPath 表达式,使它们永远不会遇到大于 10M 节点的节点集。请注意,此限制也适用于在计算表达式期间创建的中间节点集。所以,不幸的是,用谓词 分割节点集不会 工作:

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

本质上,你必须确保每个NodeTest不return超过10M的节点。如果你做不到,那你就不幸了。

您也可以在 libxml2 mailing list 上提出这个问题。我想引入此限制是为了防止可能导致拒绝服务攻击的恶意 XPath 表达式。但在我看来,一个表达式永远不会 return 比输入文档中存在的节点多。因此,用于节点集的最大内存量无论如何都受输入文档大小的限制。