最好的方法来生成XML?

我正在创build一个web api,需要一个很好的方法来快速生成一些格式良好的xml。 我找不到在python中这样做的好方法。

注意:有些库看起来很有前途,但缺less文档或仅输出到文件。

使用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> 

有关更多信息,请参阅教程 。

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> 

有关更多详细信息以及如何打印,请参阅本教程 。

或者,如果你的XML很简单,不要低估string格式化的力量:)

 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库。 我认为这是最pythonic的方式:

 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()) 

如果你想使用纯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> 

我已经尝试了一些在这个线程中的解决scheme,不幸的是,我发现其中一些是繁琐的(即在做一些不重要的事情时需要过多的努力)和不雅的。 因此,我想我会把我的首选解决scheme, web2py的HTML帮手对象 ,混合。

首先,安装独立的web2py模块 :

 pip install web2py 

不幸的是,上面安装了一个非常陈旧的web2py版本,但这个例子足够好了。 更新的来源在这里 。

导入此处logging的web2py HTML帮助程序对象。

 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>