在python中解析一个大的(~40GB)XML文本文件

时间:2012-09-27 00:04:51

标签: python xml xml-parsing large-files

我有一个我想用python解析的XML文件。什么是最好的方法呢?考虑到内存整个文档将是灾难性的,我需要以某种方式一次读取一个节点。

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

  • 元素树
  • minixml
但是,由于我提到的问题,我担心他们不会上班。另外,我无法在文本编辑器中打开它 - 用于处理巨型文本文件的任何关于genrao的好技巧?

2 个答案:

答案 0 :(得分:5)

首先,你试过ElementTree(内置的纯Python或C版本,还是更好的lxml版本)?我很确定他们中没有人真正将整个文件读入内存。

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

ElementTree有一个非常简单且通常足够的漂亮解决方案:iterparse

for event, elem in ET.iterparse(xmlfile, events=('end')):
  ...

这里的关键是你可以在构建时修改树(通过用仅包含父节点所需内容的摘要替换内容)。通过丢弃所有你不需要保留在内存中的东西,你可以坚持以通常的顺序解析东西,而不会耗尽内存。

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

这只有在你能想到一种总结的方法时才有用。 (在最简单的情况下,父母不需要其子女的任何信息,这只是elem.clear()。)否则,这对你不起作用。

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

大多数最好的SAX示例都是针对Java或Javascript的,但它们并不难理解。例如,如果您查看http://cs.au.dk/~amoeller/XML/programming/saxexample.html,您应该能够弄清楚如何用Python编写它(只要您知道在哪里找到the documentation for xml.sax)。

还有一些基于DOM的库可以在不将所有内容读入内存的情况下工作,但是我所知道的并不是我所知道的,它可以合理地处理40GB文件。

答案 1 :(得分:2)

最佳解决方案部分取决于您尝试执行的操作以及系统资源的释放程度。将其转换为postgresql或类似的数据库可能不是一个糟糕的第一目标;另一方面,如果您只需要将数据拉出一次,则可能不需要。当我必须解析大型XML文件时,特别是当目标是处理图形的数据等时,我通常将xml转换为S表达式,然后使用S表达式解释器(在python中实现)来分析按顺序标记并构建列表数据。由于它可以一次读取一行中的文件,因此只要生成的列表数据全部适合内存,文件的长度就无关紧要了。