我正在创建一个web api,并且需要一个很好的方法来快速生成一些格式良好的xml。我找不到在Python中做这件事的好方法。生成XML的最佳方法?
注意:某些库看起来很有前途,但缺少文档或仅输出到文件。
我正在创建一个web api,并且需要一个很好的方法来快速生成一些格式良好的xml。我找不到在Python中做这件事的好方法。生成XML的最佳方法?
注意:某些库看起来很有前途,但缺少文档或仅输出到文件。
使用lxml:
from lxml import etree
# create XML
root = etree.Element('root')
root.append(etree.Element('child'))
# another child with text
child = etree.Element('child')
child.text = 'some text'
root.append(child)
# pretty string
s = etree.tostring(root, pretty_print=True)
print s
输出:
<root>
<child/>
<child>some text</child>
</root>
更多信息,请参见tutorial。
ElementTree是一个很好的模块,可以读取xml并写入太多内容。
from xml.etree.ElementTree import Element, SubElement, tostring
root = Element('root')
child = SubElement(root, "child")
child.text = "I am a child"
print tostring(root)
输出:
<root><child>I am a child</child></root>
更多细节,以及如何漂亮打印看到这个tutorial。
或者,如果你的XML是简单的,不要小看串的功率格式:)
xmlTemplate = """<root>
<person>
<name>%(name)s</name>
<address>%(address)s</address>
</person>
</root>"""
data = {'name':'anurag', 'address':'Pune, india'}
print xmlTemplate%data
输出:
<root>
<person>
<name>anurag</name>
<address>Pune, india</address>
</person>
</root>
您可以使用string.Template或一些模板引擎也为复杂的格式。
使用lxml.builder类,从:http://lxml.de/tutorial.html#the-e-factory
import lxml.builder as lb
from lxml import etree
nstext = "new story"
story = lb.E.Asset(
lb.E.Attribute(nstext, name="Name", act="set"),
lb.E.Relation(lb.E.Asset(idref="Scope:767"),
name="Scope", act="set")
)
print 'story:\n', etree.tostring(story, pretty_print=True)
输出:
story:
<Asset>
<Attribute name="Name" act="set">new story</Attribute>
<Relation name="Scope" act="set">
<Asset idref="Scope:767"/>
</Relation>
</Asset>
我会使用yattag库。我认为这是最Python的方式:
from yattag import Doc
doc, tag, text = Doc().tagtext()
with tag('food'):
with tag('name'):
text('French Breakfast')
with tag('price', currency='USD'):
text('6.95')
with tag('ingredients'):
for ingredient in ('baguettes', 'jam', 'butter', 'croissants'):
with tag('ingredient'):
text(ingredient)
print(doc.getvalue())
我不确定,如果我认为它实际上很美很难看。我已经使用'with'语句打开了文件,我认为这有助于“清理”或“关闭”我在'with'语句后直接写入的任何内容。因此,在这种情况下,它会关闭标签?或者当它打开文件时,它会像文件句柄一样扔掉它们?如果它把它扔掉了,为什么它仍然在最终的输出中?必须是因为那个'text()'函数。但是,这是不是绕过了“附带”声明的性质? – Zelphir 2015-07-27 23:13:24
,如果你想使用纯Python的可选方式:
ElementTree是适合大多数情况下,但它不能CData的和漂亮打印。
所以,如果你需要CData的和漂亮的打印你应该使用minidom:
minidom_example.py:
from xml.dom import minidom
doc = minidom.Document()
root = doc.createElement('root')
doc.appendChild(root)
leaf = doc.createElement('leaf')
text = doc.createTextNode('Text element with attributes')
leaf.appendChild(text)
leaf.setAttribute('color', 'white')
root.appendChild(leaf)
leaf_cdata = doc.createElement('leaf_cdata')
cdata = doc.createCDATASection('<em>CData</em> can contain <strong>HTML tags</strong> without encoding')
leaf_cdata.appendChild(cdata)
root.appendChild(leaf_cdata)
branch = doc.createElement('branch')
branch.appendChild(leaf.cloneNode(True))
root.appendChild(branch)
mixed = doc.createElement('mixed')
mixed_leaf = leaf.cloneNode(True)
mixed_leaf.setAttribute('color', 'black')
mixed_leaf.setAttribute('state', 'modified')
mixed.appendChild(mixed_leaf)
mixed_text = doc.createTextNode('Do not use mixed elements if it possible.')
mixed.appendChild(mixed_text)
root.appendChild(mixed)
xml_str = doc.toprettyxml(indent=" ")
with open("minidom_example.xml", "w") as f:
f.write(xml_str)
minidom_example。XML:
<?xml version="1.0" ?>
<root>
<leaf color="white">Text element with attributes</leaf>
<leaf_cdata>
<![CDATA[<em>CData</em> can contain <strong>HTML tags</strong> without encoding]]> </leaf_cdata>
<branch>
<leaf color="white">Text element with attributes</leaf>
</branch>
<mixed>
<leaf color="black" state="modified">Text element with attributes</leaf>
Do not use mixed elements if it possible.
</mixed>
</root>
我已经尝试了一些解决方案,在此线程,不幸的是,我发现他们中的一些繁琐和不雅(即做一些不平凡的时候需要过多的精力)。因此,我认为我会把我的首选解决方案web2py HTML helper objects纳入混合。
首先,安装了standalone web2py module:
pip install web2py
不幸的是,上面安装的web2py的一个非常陈旧的版本,但它会是不够好这个例子。更新的来源是here。
导入web2py记录的HTML帮助对象here。
from gluon.html import *
现在,您可以使用web2py助手来生成XML/HTML。
words = ['this', 'is', 'my', 'item', 'list']
# helper function
create_item = lambda idx, word: LI(word, _id = 'item_%s' % idx, _class = 'item')
# create the HTML
items = [create_item(idx, word) for idx,word in enumerate(words)]
ul = UL(items, _id = 'my_item_list', _class = 'item_list')
my_div = DIV(ul, _class = 'container')
>>> my_div
<gluon.html.DIV object at 0x00000000039DEAC8>
>>> my_div.xml()
# I added the line breaks for clarity
<div class="container">
<ul class="item_list" id="my_item_list">
<li class="item" id="item_0">this</li>
<li class="item" id="item_1">is</li>
<li class="item" id="item_2">my</li>
<li class="item" id="item_3">item</li>
<li class="item" id="item_4">list</li>
</ul>
</div>
小心第二种方法,因为它不引用特殊字符,因此,如果您的数据中包含的字符,如'<>&'你可以用畸形XML结束。 – zch 2015-07-23 11:41:52