2012-09-06 27 views
2

我有一個XML文件,大約30MB,其中大約有300000個元素。使用太多的RAM處理python中的XML文件

我使用下面的代碼來處理這個文件。

xmldoc=xml.dom.minidom.parse("badges.xml") 

csv_out=open("badge.csv","w") 

for badge in xmldoc.getElementsByTagName("row"): 
    some processing here 
    csv_out.write(line) 

的文件只有30MB,但是當我在我的MBP(10.7,8G RAM),運行此腳本,它幾乎使用3GB內存。爲什麼這麼簡單的腳本和這麼小的文件使用這麼多的內存?

最好的問候,

+1

您如何測量內存使用情況? – tMC

+0

用像lxml這樣的合理解析器來嘗試一下。 –

+0

minidom不是解析器,它是原型級廢話 –

回答

4

你需要切換到反覆解析器,它在處理大塊XML語句,讓你清理內存之間。 DOM解析器一次將整個文檔加載到內存中。

標準庫有一個SAX parserElementTree.iterparse選項可供您使用。

快速iterparse例如:

from xml.etree.ElementTree import iterparse 

with open("badge.csv","w") as csvout: 
    for event, elem in iterparse("badges.xml"): 
     if event == 'end' and elem.tag == 'row': # Complete row tag 
      # some processing here 
      csv_out.write(line) 
      elem.clear() 

.clear()通話;釋放元素並將其從內存中移除。

+0

SAX解析器具有有限的功能,例如不要爲xpath的嚴格處理經常需要的xpath提供支持。 SAX解析器在這裏不是一個通用的解決方案。 –

0

DOM類型的XML解析器可以使用大量內存,因爲它們加載整個文檔。對於一個30MB的文件來說,3GB似乎有點過分,所以可能還有其他的事情發生。

但是,您可能需要考慮SAX風格的XML解析器(Python中的xml.sax)。在這種類型的解析器中,您的代碼在解析器處理它時通過回調來查看每個元素(標記,文本等)。 SAX風格的解析器不保留文檔結構;的確,除了單一的XML元素以外,沒有任何事情可以考慮。出於這個原因,它是快速和高效的。如果您的解析需求很複雜,那麼處理起來可能會很痛苦,但看起來像您的解決方案非常簡單。

0

我在非常大的xml文件上使用lxml,從來沒有任何問題。

請參閱幫助安裝這個計算器的文章,因爲我不得不這樣做我的Ubuntu系統上:

pip install lxml error