使用python创build一个简单的XML文件

如果我想在Python中创build一个简单的XML文件,我有什么select? (图书馆明智)

我想要的XML看起来像:

<root> <doc> <field1 name="blah">some value1</field1> <field2 name="asdfasd">some vlaue2</field2> </doc> </root> 

现在,最stream行的(也是非常简单的)选项是ElementTree API ,自从Python 2.5以来,它已经被包含在标准库中。

可用的选项是:

  • ElementTree(ElementTree的基本,纯Python实现,自2.5开始,是标准库的一部分)
  • cElementTree(ElementTree的优化C实现,自2.5开始在标准库中提供)
  • LXML(基于libxml2提供了丰富的ElementTree API以及XPath,CSSselect器等等)

以下是如何使用in-stdlib cElementTree生成示例文档的示例:

 import xml.etree.cElementTree as ET root = ET.Element("root") doc = ET.SubElement(root, "doc") ET.SubElement(doc, "field1", name="blah").text = "some value1" ET.SubElement(doc, "field2", name="asdfasd").text = "some vlaue2" tree = ET.ElementTree(root) tree.write("filename.xml") 

我已经testing过它,它的工作原理,但我假设空白不重要。 如果你需要“漂亮”压痕,让我知道,我会看看如何做到这一点。 (这可能是一个特定于LXML的选项,我不使用stdlib实现)

为进一步阅读,这里有一些有用的链接:

  • 用于在Python标准库中实现的API文档
  • 入门教程 (来自原作者的网站)
  • LXML etree教程 。 (使用示例代码从所有主要ElementTree实现中加载最佳可用选项)

最后一点,cElementTree或LXML应该足够快,满足您的所有需求(都是优化的C代码),但是如果您需要排除性能的最后一点,那么基准LXML网站表明:

  • LXML显然赢得序列化(生成)的XML
  • 作为实现适当的父级遍历的一个副作用,LXML比parsing的cElementTree要慢一些。

lxml库包含一个用于生成XML的非常方便的语法,称为E-factory 。 下面是我如何做你给的例子:

 #!/usr/bin/python import lxml.etree import lxml.builder E = lxml.builder.ElementMaker() ROOT = E.root DOC = E.doc FIELD1 = E.field1 FIELD2 = E.field2 the_doc = ROOT( DOC( FIELD1('some value1', name='blah'), FIELD2('some value2', name='asdfasd'), ) ) print lxml.etree.tostring(the_doc, pretty_print=True) 

输出:

 <root> <doc> <field1 name="blah">some value1</field1> <field2 name="asdfasd">some value2</field2> </doc> </root> 

它也支持添加到已经完成的节点,例如在上面你可以说

 the_doc.append(FIELD2('another value again', name='hithere')) 

Yattag http://www.yattag.org/或https://github.com/leforestier/yattag提供了一个有趣的API来创build这样的XML文档(以及HTML文档)。;

它使用上下文pipe理器和关键字。

 from yattag import Doc, indent doc, tag, text = Doc().tagtext() with tag('root'): with tag('doc'): with tag('field1', name='blah'): text('some value1') with tag('field2', name='asdfasd'): text('some value2') result = indent( doc.getvalue(), indentation = ' '*4, newline = '\r\n' ) print(result) 

所以你会得到:

 <root> <doc> <field1 name="blah">some value1</field1> <field2 name="asdfasd">some value2</field2> </doc> </root> 

最简单的select,我会去minidom: http ://docs.python.org/library/xml.dom.minidom.html。 它是内置到python标准库中,在简单的情况下使用很简单。

这是一个非常容易遵循的教程: http : //www.boddie.org.uk/python/XML_intro.html

对于这样一个简单的XML结构,您可能不想涉及一个完整的XML模块。 考虑一个最简单结构的string模板,或者Jinja稍微复杂一些。 Jinja可以处理循环的数据列表,以生成文档列表的内部xml。 原始pythonstring模板有点棘手

对于Jinja的例子,请参阅我对类似问题的回答 。

这是一个用string模板生成xml的例子。

 import string from xml.sax.saxutils import escape inner_template = string.Template(' <field${id} name="${name}">${value}</field${id}>') outer_template = string.Template("""<root> <doc> ${document_list} </doc> </root> """) data = [ (1, 'foo', 'The value for the foo document'), (2, 'bar', 'The <value> for the <bar> document'), ] inner_contents = [inner_template.substitute(id=id, name=name, value=escape(value)) for (id, name, value) in data] result = outer_template.substitute(document_list='\n'.join(inner_contents)) print result 

输出:

 <root> <doc> <field1 name="foo">The value for the foo document</field1> <field2 name="bar">The &lt;value&gt; for the &lt;bar&gt; document</field2> </doc> </root> 

模板方法的不利之处在于,你不会逃避<>免费。 我通过从xml.sax提取一个util来解决这个问题