2011-03-21 88 views
3

有很多方法可以讀取XML,包括一次性(DOM)和一次一位(SAX)。我已經使用SAX或lxml來迭代讀取大型XML文件(例如,維基百科6.5GB的壓縮的)。在python中迭代編寫XML節點

但是,在對XML文件進行一些迭代處理(在使用ElementTree的python中)之後,我想將(新)XML數據寫出到另一個文件中。

是否有任何庫迭代地寫出XML數據?我可能創建XML樹,然後寫出來,但這是不可能的,沒有內存的RAM。無論如何要反覆地將XML樹寫入文件?一次一點?

我知道我可以用print "<%s>" % tag_name等自己生成XML,但這似乎有點... hacky

+0

可能重複[?什麼是最簡單的非內存密集型的方式從Python的輸出XML(http://stackoverflow.com/questions/93710/whats-the -easiest-non-memory-intensive-way-to-output-xml-from-python) – Mark 2012-01-06 15:40:13

回答

4

弗雷德裏克Lundh的elementtree.SimpleXMLWriter會讓你逐漸寫出XML。這裏是嵌入模塊中的演示代碼:的

from elementtree.SimpleXMLWriter import XMLWriter 
import sys 

w = XMLWriter(sys.stdout) 

html = w.start("html") 

w.start("head") 
w.element("title", "my document") 
w.element("meta", name="generator", value="my application 1.0") 
w.end() 

w.start("body") 
w.element("h1", "this is a heading") 
w.element("p", "this is a paragraph") 

w.start("p") 
w.data("this is ") 
w.element("b", "bold") 
w.data(" and ") 
w.element("i", "italic") 
w.data(".") 
w.end("p") 

w.close(html) 
0

使用lxml,可以使用etree.Element來創建新節點,並使用etree.tostring來寫出XML表示。例如,請參閱Liza Daly's article的「Listing 6. Serialize an element's children」「使用lxml在Python中進行高性能XML解析」。

+0

爲了使用''etree.tostring'',我需要在內存中使用整棵樹嗎?如果是這樣,這是一個非跑步者。 – Rory 2011-03-21 14:53:36

+0

@Rory:'fast_iter'函數遍歷節點而不生成整個DOM。然後,您可以一次一個地修改某些或全部這些節點,並用'etree.tostring'寫出它們。 – unutbu 2011-03-21 16:50:12

1

如果您正在使用XML dialect1進行閱讀並且必須編寫XML dialect2,使用xslt寫下轉換過程不是一個好主意嗎?你甚至可能不需要這樣的源代碼。

+0

我不介意編程或不編程。最重要的是內存消耗。我沒有空間將所有源文檔存儲在內存中。不是XSLT內存密集型? (這不就是爲什麼STX被髮明的原因嗎?) – Rory 2011-03-21 15:24:39

+0

@Rory:xslt允許你以聲明的方式指定轉換。然後,您可以使用手頭的工具來應用轉換。我必須承認,我並不需要擔心可擴展性。我建議你看看可用的XSLT處理器。第一次看起來告訴我,例如撒克遜人有一個'懶惰的建設'模式(http:// www。saxonica.com/documentation/javadoc/net/sf/saxon/lib/FeatureKeys.html#LAZY_CONSTRUCTION_MODE) – xtofl 2011-03-21 15:38:00

1

如果你沒有找到其他的東西,我想在這裏繼承ElementTree並創建一個「iteractiveElementTree」,並添加一個「文件」屬性。我將節點子集化以具有「start_tag_comitted」屬性和「提交」方法。一旦被調用,這個「提交」方法就會調用子樹的渲染方法 - 從fartest父項開始,其中e「start_tag_comitted」爲false。用手中的字符串,我會手動剝離當前節點父項的結束標記。有必要處理以前操作但未關閉的父母兄弟姐妹。

然後,我會從內存模型中刪除「提交」節點。 因爲ElementTree沒有這樣做,所以您還需要將節點父節點分配給每個節點。

(收件箱,如果沒有更好的答案的dyou卡住那裏,我可以實現這一點)