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

时间:2016-10-20 16:33:25

标签: r libxml2 xml2

我正在使用R中的xml2包解析一些非常大的xml文件.read_xml()成功加载了大文件,但是当我尝试使用xml_find_all()时,我得到了#34;错误:内存分配失败:增加节点集命中限制。"我假设这个限制是在libxml2中设置的,也许是在XPATH_MAX_NODESET_LENGTH var中?所以这可能不是xml2包本身的问题。但是在xml2中是否有可能的解决方案?我尝试删除节点并释放内存而没有运气。感谢。

1 个答案:

答案 0 :(得分:5)

是的,您正在达到 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不会返回超过10M的节点。如果你不能这样做,那你很遗憾。

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