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

Bla*_*man 141 python xml

什么是我的选择,如果我想在Python中创建简单的XML文件?(图书馆明智)

我想要的xml看起来像:

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

</root>
Run Code Online (Sandbox Code Playgroud)

sso*_*low 276

目前,最受欢迎(也非常简单)的选项是ElementTree API,它自Python 2.5以来就已包含在标准库中.

可用的选项是:

  • ElementTree(ElementTree的基本,纯Python实现.自2.5以来标准库的一部分)
  • cElementTree(ElementTree的优化C实现.自2.5以来也在标准库中提供)
  • 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")
Run Code Online (Sandbox Code Playgroud)

我测试了它并且它有效,但我假设空白并不重要.如果你需要"prettyprint"缩进,请告诉我,我会查看如何做到这一点.(它可能是特定于LXML的选项.我不使用stdlib实现很多)

如需进一步阅读,请参阅以下链接:

最后要注意的是,cElementTree或LXML应该足够快以满足您的所有需求(两者都是优化的C代码),但是如果您需要挤出最后一点性能,那么基准测试就是LXML网站表明:

  • LXML显然赢得了序列化(生成)XML
  • 作为实现正确父遍历的副作用,LXML比cElementTree慢一点用于解析.

  • @nonsensickle你真的应该问一个新问题,然后给我发一个链接,这样每个人都可以从中受益.但是,我会指出你正确的方向.DOM(文档对象模型)库总是构建一个内存模型,因此您需要一个SAX(简单API for XML)实现.我从未研究过SAX实现,但这里有[教程](http://www.xml.com/pub/a/2003/03/12/py-xml.html)使用[in-stdlib one] (https://docs.python.org/2/library/xml.sax.html)输出而不是输入. (4认同)
  • [根据文档](https://docs.python.org/3/library/xml.etree.elementtree.html),`cElementTree` 在 Python 3.3 中折旧 (4认同)
  • 只是提醒其他任何试图将 `vlaue2` 更正为 `value2` 的人:原始问题中请求的 XML 输出中存在错字。直到改变,这里的错字实际上*是*正确的。 (2认同)

res*_*dsk 61

LXML库包括XML生成一个非常方便的语法,叫做E-工厂.以下是我给出的例子:

#!/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)
Run Code Online (Sandbox Code Playgroud)

输出:

<root>
  <doc>
    <field1 name="blah">some value1</field1>
    <field2 name="asdfasd">some value2</field2>
  </doc>
</root>
Run Code Online (Sandbox Code Playgroud)

它还支持添加到已经建立的节点,例如在上面你可以说

the_doc.append(FIELD2('another value again', name='hithere'))
Run Code Online (Sandbox Code Playgroud)

  • 如果标签名称不符合Python标识符规则,则可以使用`getattr`,例如`getattr(E,“ some-tag”)`。 (2认同)

scl*_*cls 16

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

它使用上下文管理器with关键字.

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)
Run Code Online (Sandbox Code Playgroud)

所以你会得到:

<root>
    <doc>
        <field1 name="blah">some value1</field1>
        <field2 name="asdfasd">some value2</field2>
    </doc>
</root>
Run Code Online (Sandbox Code Playgroud)

  • 这是一种非常干净的标记生成方式。我敢说它比任何内置方式都更Pythonic。 (2认同)

wha*_*ley 6

对于最简单的选择,我会使用minidom:http://docs.python.org/library/xml.dom.minidom.html .它内置于python标准库中,在简单的情况下可以直接使用.

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

  • 这个答案应该包括一个使用minidom的例子. (3认同)

big*_*_29 5

对于如此简单的 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
Run Code Online (Sandbox Code Playgroud)

输出:

<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>
Run Code Online (Sandbox Code Playgroud)

模板方法的缺点是你无法免费摆脱<and 。>我通过引入一个 util 来解决这个问题xml.sax