使用python非常大的xml文件解析时遇到麻烦

时间:2012-12-29 12:31:17

标签: python xml-parsing

我有一个大的xml文件(大约84MB),其格式为:

<books>
    <book>...</book>
    ....
    <book>...</book>
</books>

我的目标是提取每本书并获得其属性。我尝试解析它(就像我对其他xml文件所做的那样),如下所示:

from xml.dom.minidom import parse, parseString

fd = "myfile.xml"
parser = parse(fd)
## other python code here

但是代码似乎在解析指令中失败了。为什么会发生这种情况?我该如何解决这个问题?

我应该指出该文件可能包含希腊语,西班牙语和阿拉伯语字符。

这是我在ipython中得到的输出:

In [2]: fd = "myfile.xml"

In [3]: parser = parse(fd)
Killed

我想指出计算机在执行期间冻结,因此这可能与内存消耗有关,如下所述。

3 个答案:

答案 0 :(得分:7)

尝试使用更易于使用的lxml

#!/usr/bin/env python
from lxml import etree

with open("myfile.xml") as fp:
    tree = etree.parse(fp)
    root = tree.getroot()

    print root.tag

    for book in root:
        print book.text

答案 1 :(得分:6)

我强烈建议在这里使用SAX解析器。我不建议在任何大于几兆字节的XML文档上使用minidom;我已经看到它在大约10MB的XML文档中使用大约400MB的RAM读取。我怀疑你遇到的问题是由minidom请求太多内存引起的。

Python附带了一个XML SAX解析器。要使用它,请执行以下操作。

from xml.sax.handlers import ContentHandler
from xml.sax import parse

class MyContentHandler(ContentHandler):
    # override various ContentHandler methods as needed...


handler = MyContentHandler()
parse("mydata.xml", handler)

您的ContentHandler子类将覆盖ContentHandler中的各种方法(例如startElementstartElementNSendElementendElementNS或{{1这些处理SAX解析器在读取XML文档时生成的事件。

SAX是一种比DOM更“低级”的处理XML的方法;除了从文档中提取相关数据外,您的ContentHandler还需要开展工作,跟踪当前内部的元素。然而,从好处来看,由于SAX解析器不会将整个文档保留在内存中,因此它们可以处理任何大小的XML文档,包括那些比您大的文档。

我没有尝试过在这种大小的XML文档上使用lxml等DOM解析器,但我怀疑lxml仍然需要相当长的时间并使用大量内存来解析XML文档。如果每次运行代码时都需要等待它读取84MB XML文档,那么这可能会降低开发速度。

最后,我不相信你提到的希腊语,西班牙语和阿拉伯语字符会引起问题。

答案 2 :(得分:3)

有两种XML解析器(这适用于任何语言)。

  1. DOM解析(这是你正在使用的)。在这种类型中,整个XML文件被读入内存结构,然后通过方法访问。

  2. SAX解析。这是一种解析算法,它以逐步的方式读取每段XML。这种技术可以让您更好地检测和处理错误。

  3. 一般来说,DOM比SAX更容易,因为许多细节都是通过其原生方法来处理的。

    SAX有点挑战,因为你必须编写SAX解析&#34;运行的方法。在浏览XML文档时。