Каковы мои параметры, если я хочу создать простой XML файл в python? (библиотека мудрым)
xml, который я хочу, выглядит так:
<root>
 <doc>
     <field1 name="blah">some value1</field1>
     <field2 name="asdfasd">some vlaue2</field2>
 </doc>
</root>
Каковы мои параметры, если я хочу создать простой XML файл в python? (библиотека мудрым)
xml, который я хочу, выглядит так:
<root>
 <doc>
     <field1 name="blah">some value1</field1>
     <field2 name="asdfasd">some vlaue2</field2>
 </doc>
</root>
В наши дни самым популярным (и очень простым) вариантом является ElementTree API, который был включен в стандартную библиотеку с 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 показывают, что:
библиотека 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>
Он также поддерживает добавление уже сделанного node, например. после вышесказанного вы могли бы сказать
the_doc.append(FIELD2('another value again', name='hithere'))
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>
Для простейшего выбора я бы пошел с минидомом: 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>
Недостатком подхода шаблона является то, что вы не получите escape-кода < и > бесплатно. Я танцевал вокруг этой проблемы, вытаскивая утилиту из xml.sax