Лучший способ для создания xml? [дубликат]
этот вопрос уже есть ответ здесь:
Я создаю веб-API и нужен хороший способ быстро создать хорошо сформированный XML. Я не могу найти хороший способ сделать это в Python.
Примечание: некоторые библиотеки выглядят многообещающе, но либо отсутствие документации или только вывод в файлы.
6 ответов:
используя 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 прост, не стоит недооценивать силу форматирования строк:)
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.Шаблон или какой-то шаблонный движок тоже, для сложного форматирования.
использовать lxml.класс строителя, от: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 библиотека. Я думаю, что это самый питонический способ:
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_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, в миксе.
во-первых, установите the автономный модуль web2py:
pip install web2pyк сожалению, выше устанавливается чрезвычайно устаревшая версия web2py, но это будет достаточно хорошо для этого примера. Обновленный источник здесь.
импорт 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>