2009-06-16 28 views
2

Im使用內置的XML解析器加載1.5 gig XML文件並需要一整天。顯示加載大文件時python的XML解析器的進度

from xml.dom import minidom 
xmldoc = minidom.parse('events.xml') 

我需要知道如何進入並測量其進度,以便我可以顯示進度條。 有什麼想法?

minidom有另一個名爲parseString()的方法,它返回一個DOM樹,假設你傳遞的字符串是有效的XML,如果我要將文件自己拆分成塊並將它們傳遞給parseString,可能最後將所有的DOM樹合併在一起?

回答

5

你的用例需要您使用SAX解析器而非DOM,DOM加載在內存中的一切,薩克斯,而不是將行解析做線和你寫的事件處理程序,因爲你需要 所以可能是有效的,你會能夠編寫進度指示器也

我還建議使用SAX試圖expat解析器有時它是非常有用 http://docs.python.org/library/pyexpat.html

進步:

隨着sax逐步讀取文件,您可以將自己傳遞的文件對象封裝起來,並跟蹤讀取了多少文件。

編輯: 我也做分裂文件你們自己不喜歡的想法,並在末端連接DOM,這樣可以幫助您更好地編寫自己的XML解析器,我建議不使用SAX解析器 我也想知道你的閱讀目的DOM樹中的1.5 gig文件? 看起來像薩克斯在這裏會更好

+0

這看起來像我所需要的,我絕對不需要在內存中的整個DOM。我會嘗試SAX – Nathan 2009-06-17 02:32:15

2

在最後合併樹會很容易。您可以創建一個新的DOM,並且基本上將逐個樹添加到它。這可以讓你很好地調整解析過程。如果你想通過產生不同的進程來解析每一部分,你甚至可以並行化它。你只需要確保你智能地分割它(而不是在標籤中間分割等等)。

5

您是否考慮過使用其他方式解析XML?構建這種大型XML文件的樹總是會很慢並且內存密集。如果你不需要內存中的整個樹,基於流的解析將會更快,更容易。如果你習慣了基於樹的XML操作,它會有點令人生畏,但它會以巨大的速度提高(幾分鐘而不是幾小時)的形式付出。

http://docs.python.org/library/xml.sax.html

3

我有PyGTK的非常類似的東西,不PyQt的,使用pulldom API。它使用Gtk空閒事件(所以GUI不鎖定)和Python生成器(保存解析狀態)一次調用一點點。

def idle_handler (fn): 
    fh = open (fn) # file handle 
    doc = xml.dom.pulldom.parse (fh) 
    fsize = os.stat (fn)[stat.ST_SIZE] 
    position = 0 

    for event, node in doc: 
    if position != fh.tell(): 
     position = fh.tell() 
     # update status: position * 100/fsize 

    if event == .... 

    yield True # idle handler stays until False is returned 

yield False 

def main: 
    add_idle_handler (idle_handler, filename)