3

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

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

  • 元素树
  • 迷你xml

但我担心由于我提到的问题,它们不会完全正常工作。我也无法在文本编辑器中打开它——generao 中有什么好的技巧来处理巨大的文本文件吗?

4

2 回答 2

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 编写它(只要您知道在哪里可以找到xml.sax 的文档)。

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

于 2012-09-27T00:16:11.550 回答
2

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

于 2012-09-27T02:02:03.483 回答