2011-03-21 53 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卡住那里,我可以实现这一点)