2011-11-01 32 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