2011-11-01 71 views
1

我使用Python 2.7与最新的lxml库。我正在解析一个非常均匀的结构和数百万个元素的大型XML文件。我认为lxml的iterparse在解析时不会构建内部树,但显然它会自内存使用增长到崩溃(大约1GB)。有没有办法使用lxml解析大型XML文件而不使用大量内存?使用iterparse()解析大型XML消耗太多内存。任何选择?

我看到target parser interface是一种可能性,但我不确定这是否会奏效。使用

回答

2

尝试丽莎达利的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

好文章的链接。 +1 –

+0

Liza的代码有一个问题;它期望唯一的标签名称。如果你有相同的标签嵌套,那么内部的将是空的。 (http://www.willmer.com/kb/2012/02/minor-gotcha-with-liza-dalys-fast_iter/有一个稍长的答案,不能解决如何在这个评论中做一个代码示例) – Rachel

+0

Rachel,我认为如果你在呼叫 中使用'events =('start',)''ET.iterparse'并将该'context'传递给'fast_iter',就会出现“gotcha”。在这种情况下,到达起始标签时将删除元素 ,而不是在达到末尾标签 后删除。这可能会导致错误(逻辑或语法)。 [This code](http://paste.ubuntu.com/829989/)演示了这个问题。如果这是您看到的 错误,则解决方法是将“开始”更改为“结束”。 – unutbu