使用iterparse()解析大型XML会占用太多内存。还有其他选择

时间:2011-11-01 20:59:08

标签: python xml memory lxml

我正在使用python 2.7和最新的lxml库。我正在解析一个具有非常同质结构和数百万个元素的大型XML文件。我认为lxml的iterparse在解析时不会构建内部树,但显然它确实存在,因为内存使用量增加直到它崩溃(大约1GB)。有没有办法在不使用大量内存的情况下使用lxml解析大型XML文件?

我认为target parser interface是一种可能性,但我不确定这是否会更好。

2 个答案:

答案 0 :(得分:2)

尝试使用Liza Daly的fast_iter

def fast_iter(context, func, args=[], kwargs={}):
    # http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
    # Author: Liza Daly
    for event, elem in context:
        func(elem, *args, **kwargs)
        elem.clear()
        while elem.getprevious() is not None:
            del elem.getparent()[0]
    del context

fast_iter在解析后从树中删除元素,以及不再需要的前一个元素(可能带有其他标记)。

可以像这样使用:

import lxml.etree as ET
def process_element(elem):
    ...
context=ET.iterparse(filename, events=('end',), tag=...)        
fast_iter(context, process_element)

答案 1 :(得分:0)

我遇到了这个问题,并通过http://effbot.org/zone/element-iterparse.htm#incremental-parsing的提示解决了这个问题:

elems = ET.Element('MyElements')
for event, elem in ET.iterparse(filename):
    if is_needed(elem): # implement this condition however you like
        elems.append(elem)
    else:
        elem.clear()

这为您提供了只包含所需元素的树,而在解析过程中不需要不必要的内存。