Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中解析大型(~40GB)XML文本文件_Python_Xml_Xml Parsing_Large Files - Fatal编程技术网

在python中解析大型(~40GB)XML文本文件

在python中解析大型(~40GB)XML文本文件,python,xml,xml-parsing,large-files,Python,Xml,Xml Parsing,Large Files,我有一个XML文件要用python解析。最好的方法是什么?把整个文档放到内存中是灾难性的,我需要一次只读取一个节点 我所知道的现有XML解决方案: 元素树 迷你XML 但我担心,由于我提到的问题,它们不会起作用。此外,我无法在文本编辑器中打开它-在generao中有没有处理巨型文本文件的好技巧?首先,您是否尝试过ElementTree(内置纯Python或C版本,或者更好的是lxml版本)?我敢肯定他们中没有人真的把整个文件读入了内存 当然,问题是,无论它是否将整个文件读入内存,最终解析的树

我有一个XML文件要用python解析。最好的方法是什么?把整个文档放到内存中是灾难性的,我需要一次只读取一个节点

我所知道的现有XML解决方案:

  • 元素树
  • 迷你XML

但我担心,由于我提到的问题,它们不会起作用。此外,我无法在文本编辑器中打开它-在generao中有没有处理巨型文本文件的好技巧?

首先,您是否尝试过
ElementTree
(内置纯Python或C版本,或者更好的是
lxml
版本)?我敢肯定他们中没有人真的把整个文件读入了内存

当然,问题是,无论它是否将整个文件读入内存,最终解析的树都会出现在内存中

ElementTree有一个很好的解决方案,非常简单,而且通常已经足够了:

这里的关键是,您可以在构建树时修改树(通过将内容替换为仅包含父节点所需内容的摘要)。通过在输入时扔掉所有不需要保存在内存中的东西,您可以坚持按常规顺序解析,而不会耗尽内存

链接页面提供了更多详细信息,包括一些在处理XML-RPC和plist时修改它们的示例。(在这些情况下,这是为了使生成的对象更易于使用,而不是为了节省内存,但它们应该足以让人明白这一点。)

这只有在你能想出一个方法来总结的时候才有帮助。(在最简单的情况下,如果父对象不需要来自其子对象的任何信息,则这只是
elem.clear()
)否则,这将不适用于您

标准的解决方案是,这是一个基于回调的API,允许您在树上一次操作一个节点。您不必像使用iterparse那样担心截断节点,因为解析节点后,节点就不存在了

大多数最好的SAX示例都是针对Java或Javascript的,但它们并不难理解。例如,如果您看一看,您应该能够找出如何用Python编写它(只要您知道在哪里可以找到)


也有一些基于DOM的库可以在不将所有内容读入内存的情况下工作,但据我所知,没有任何库可以以合理的效率处理40GB文件。

最佳解决方案部分取决于您正在尝试做什么,以及您的系统资源有多空闲。将其转换为postgresql或类似的数据库可能是一个不错的首要目标;另一方面,如果只需要提取一次数据,则可能不需要。当我必须解析大型XML文件时,特别是当我的目标是处理图形等的数据时,我通常会将XML转换为S表达式,然后使用S表达式解释器(用python实现)按顺序分析标记并构建列表数据。因为它可以一次读取一行中的文件,所以文件的长度无关紧要,只要生成的表格数据适合内存。

您打算如何处理此文件?它是如何构造的?你熟悉SAX解析器吗?@FrankieTheKneeMan-这是维基百科的垃圾堆。我想做一些图表分析。我不知道这是否意味着我想先把它全部放在SQL数据库中。@Gabe-不,我不知道。这种解析器的优点是什么?SAX是一个标准的XML解析器接口,用于在文件读入时解析文件,而不是一个DOM接口,它需要将整个tihng一次放入内存中。s表达式-有点像python中的pickling?这真的有用吗?以前从未听说过,听起来更像是理论上的精确:。对于搜索、分组等,似乎mysql或postgre会更好?这取决于需要解析数据的次数。如果您需要多次解析它,像sqlite这样的东西将是更好的选择,因为它将数据转换为压缩格式,并允许您对其运行查询。s-exp是lisp语言家族背后的语法,理论上很好,但实际上缺乏一个好的公共库。但是,作为一种数据结构,它们与xml相同,只是更容易解析(没有闭合标记语法)。基本上,执行xml(有点像ANT)。我以前做过这样的工作,将xml加载到sqlite数据库中。我发现最好的解释是:如果对我使用的lisp解释器感兴趣,它是基于lis.py的,你可以在网上找到它,但是有一些扩展可以将它集成到python代码中,我可以让它可用。我最终使用了cElementTree,它速度非常快。看看本页底部的基准测试:,它也比大多数SAX解析器(无论如何,对于python来说)要好,这是一个有点旧的基准测试。另外,这是在内存中进行字符串解析,而不是iterparse。根据我的经验,cElementTree和lxml.etree几乎总是足够快,而且比其他任何东西都快。lxml通常更快,但并不总是如此。lxml在cET受限制的一些领域与ET的兼容性不是100%;最近,我为一个项目选择了cET,因为lxml的iterparse只允许您将
elem.data
设置为字符串或无字符串,我的摘要是int,lxml在解析过程中节省的时间比花在str和int上的时间要少……但无论如何,很高兴您发现ER是正确的。
for event, elem in ET.iterparse(xmlfile, events=('end')):
  ...