如果我想用python创建一个简单的XML文件,我有什么选择?(图书馆明智)
我想要的xml看起来像:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some vlaue2</field2>
</doc>
</root>
如果我想用python创建一个简单的XML文件,我有什么选择?(图书馆明智)
我想要的xml看起来像:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some vlaue2</field2>
</doc>
</root>
当前回答
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来创建这样的XML文档(以及HTML文档)。
它使用上下文管理器和带关键字。
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>
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'))
现在,最流行(也非常简单)的选项是ElementTree API, 它自Python 2.5起就被包含在标准库中。
可用的选项有:
ElementTree (ElementTree的基本、纯python实现。2.5以后的标准库的一部分) cElementTree (ElementTree的优化C实现。从2.5开始在标准库中也提供了。已弃用,并在3.3中将其折叠到常规的ElementTree中作为一个自动的东西。) LXML(基于libxml2。提供了丰富的ElementTree API超集以及XPath、CSS选择器等)
下面是如何使用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")
我已经测试过了,它是有效的,但我假设空白是不重要的。如果你需要“prettyprint”缩进,请告诉我,我会查找如何做到这一点。(它可能是特定于lxml的选项。我不太使用stdlib实现)
为了进一步阅读,这里有一些有用的链接:
在Python标准库中实现的API文档 入门教程(来自原作者的网站) LXML树教程。(带有从所有主要ElementTree实现中加载最佳可用选项的示例代码)
最后要注意的是,cElementTree或LXML都应该足够快来满足你的所有需求(两者都是优化的C代码),但如果你处于需要挤出最后一点性能的情况下,LXML站点上的基准测试表明:
LXML显然在序列化(生成)XML方面更胜一筹 作为实现适当的父遍历的副作用,LXML在解析时比cElementTree慢一些。
对于最简单的选择,我会选择minidom: http://docs.python.org/library/xml.dom.minidom.html。它内置在python标准库中,在简单的情况下可以直接使用。
这里有一个非常简单的教程:http://www.boddie.org.uk/python/XML_intro.html
对于这样一个简单的XML结构,您可能不希望涉及完整的XML模块。对于最简单的结构,可以考虑使用字符串模板,对于稍微复杂一点的结构,可以使用Jinja模板。Jinja可以处理数据列表的循环,以生成文档列表的内部xml。对于原始的python字符串模板来说,这有点棘手
关于Jinja的例子,请参阅我对类似问题的回答。
下面是一个用字符串模板生成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 <value> for the <bar> document</field2>
</doc>
</root>
模板方法的缺点是不能免费获得<和>的转义。我从xml.sax中引入了一个util,绕过了这个问题