我正在使用R中的xml2包解析一些非常大的xml文件.read_xml()成功加载了大文件,但是当我尝试使用xml_find_all()时,我得到了#34;错误:内存分配失败:增加节点集命中限制。"我假设这个限制是在libxml2中设置的,也许是在XPATH_MAX_NODESET_LENGTH var中?所以这可能不是xml2包本身的问题。但是在xml2中是否有可能的解决方案?我尝试删除节点并释放内存而没有运气。感谢。
答案 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表达而引入的。但是我看到它的方式,表达式永远不会返回比输入文档中存在的更多的节点。因此,用于节点集的最大内存量无论如何都受输入文档大小的限制。