Лучший способ для создания 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>