使用python解析非常大的xml文件时遇到的问题

使用python解析非常大的xml文件时遇到的问题,python,xml-parsing,Python,Xml Parsing,我有一个大的xml文件(大约84MB),其格式如下: <books> <book>...</book> .... <book>...</book> </books> 但是代码在解析指令中似乎失败了。为什么会发生这种情况?我该如何解决 我要指出,该文件可能包含希腊、西班牙和阿拉伯字符 这是我在ipython中得到的输出: In [2]: fd = "myfile.xml" In [3]: parse

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

<books>
    <book>...</book>
    ....
    <book>...</book>
</books>
但是代码在解析指令中似乎失败了。为什么会发生这种情况?我该如何解决

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

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

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

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

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

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

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

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

  • 一般来说,DOM比SAX更容易,因为许多棘手的细节都是由其本机方法处理的

    SAX是一个更大的挑战,因为您必须编写SAX解析在遍历XML文档期间“运行”的方法。

    尝试使用哪种方法更易于使用

    #!/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
    

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

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

    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
    子类将覆盖中的各种方法(例如
    startElement
    startelements
    endElement
    endelements
    字符)。这些方法在SAX解析器读取XML文档时处理SAX解析器生成的事件

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

    我还没有尝试过在这种大小的XML文档上使用其他DOM解析器,比如lxml,但我怀疑lxml解析XML文档仍然需要相当长的时间和相当大的内存。如果每次运行代码时都必须等待它读入84MB的XML文档,这可能会减慢开发速度


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

    您能在这里提供堆栈跟踪吗?执行python myparser.py时,shell被终止。我忘了说我有非ascii字符……这会是个问题吗?@user601836:提供失败消息。@akira:我怀疑它的内存不足。我我见过
    minidom
    使用~400MB的内存解析~10MB的XML文档。如果
    minidom
    s的内存使用量与XML文档的大小成线性关系,那么我预计
    minidom
    将尝试在这里使用~3.5GB。我的输出现在有问题。
    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)