Відповіді:
В наші дні найпопулярнішим (і дуже простим) варіантом є API ElementTree , який включений у стандартну бібліотеку з Python 2.5.
Доступні варіанти для цього:
Ось приклад того, як генерувати свій прикладний документ за допомогою 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")
Я перевірив це, і він працює, але я припускаю, що пробіли не є істотними. Якщо вам потрібен відбіток «prettyprint», дайте мені знати, і я розберуся, як це зробити. (Це може бути специфічний для LXML варіант. Я не дуже використовую реалізацію stdlib)
Для подальшого читання, ось кілька корисних посилань:
На завершення, або cElementTree, або LXML повинні бути досить швидкими для всіх ваших потреб (обидва оптимізовані код C), але у випадку, якщо вам доведеться вичавити кожен останній шматочок продуктивності, орієнтири на сайт LXML вказує, що:
xml_declaration=True
тому, що ви вказали кодування ... але, щоб отримати еквівалентну поведінку, дзвоніть tree.write()
так: tree.write("filename.xml", xml_declaration=True, encoding='utf-8')
Ви можете використовувати будь-яке кодування до тих пір, поки ви чітко вказали один. ( ascii
змусить усіх символів Unicode поза 7-бітовим набором ASCII бути закодованим суттю, якщо ви не довіряєте веб-серверу правильно налаштованому.)
vlaue2
на value2
: помилка в запитуваній виведення XML в вихідному питанні. До цього зміни, помилка тут на самому ділі не є правильною.
cElementTree
було знецінено в Python 3.3
Бібліотека lxml включає дуже зручний синтаксис для генерації XML, який називається E-factory . Ось як я зробив приклад, який ви даєте:
#!/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)
Вихід:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some value2</field2>
</doc>
</root>
Він також підтримує додавання до вже зробленого вузла, наприклад після сказаного вище
the_doc.append(FIELD2('another value again', name='hithere'))
getattr
, наприклад, getattr(E, "some-tag")
.
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)
тож ви отримаєте:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some value2</field2>
</doc>
</root>
Для найпростішого вибору я б пішов з minidom: http://docs.python.org/library/xml.dom.minidom.html . Він вбудований у стандартну бібліотеку python і його легко використовувати у простих випадках.
Ось досить простий у виконанні підручник: http://www.boddie.org.uk/python/XML_intro.html
Для такої простої структури 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
Вихід:
<root>
<doc>
<field1 name="foo">The value for the foo document</field1>
<field2 name="bar">The <value> for the <bar> document</field2>
</doc>
</root>
Мінусом шаблонного підходу є те, що ви не зможете втекти <
і >
безкоштовно. Я танцював навколо цієї проблеми, потягнувши утиліту зxml.sax
Я щойно закінчив писати генератор XML, використовуючи метод bigh_29 Шаблони ... це приємний спосіб контролювати те, що ви виводите, не надто багато об'єктів стають «у дорогу».
Щодо тегу та значення, я використав два масиви, одному, який дав ім'я та положення тегу у вихідному xml, а іншому, на який посилався файл параметрів, що має той самий список тегів. Файл параметра, однак, також має номер позиції у відповідному вхідному (csv) файлі, з якого будуть взяті дані. Таким чином, якщо якісь зміни в положенні даних, що надходять із вхідного файлу, програма не змінюється; він динамічно опрацьовує позицію поля даних з відповідного тегу у файлі параметрів.