Yanıtlar:
Bu günlerde, en popüler (ve çok basit) seçenek Python 2.5'ten beri standart kütüphaneye dahil edilen ElementTree API'sıdır .
Bunun için mevcut seçenekler:
Aşağıda, in-stdlib cElementTree kullanarak örnek belgenizi nasıl oluşturacağınıza ilişkin bir örnek verilmiştir:
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")
Test ettim ve işe yarıyor, ama boşlukun önemli olmadığını varsayıyorum. "Prettyprint" girinti gerekiyorsa, bana bildirin, nasıl yapılacağına bakacağım. (LXML'ye özgü bir seçenek olabilir. Stdlib uygulamasını fazla kullanmıyorum)
Daha fazla okuma için, bazı yararlı bağlantılar şunlardır:
Son bir not olarak, cElementTree veya LXML tüm ihtiyaçlarınız için yeterince hızlı olmalıdır (her ikisi de optimize edilmiş C kodudur), ancak performansın her bir bitini sıkıştırmanız gereken bir durumdaysanız, LXML sitesi şunları belirtir:
xml_declaration=True... ancak, eşdeğer davranış elde etmek için şu şekilde çağırın tree.write(): tree.write("filename.xml", xml_declaration=True, encoding='utf-8')Açıkça belirttiğiniz sürece herhangi bir kodlamayı kullanabilirsiniz bir. ( asciidüzgün yapılandırılmış bir web sunucusuna güvenmiyorsanız 7 bit ASCII setinin dışındaki tüm Unicode karakterlerini varlık kodlu olmaya
vlaue2için value2yazım hatası asıl soruya istenilen XML çıktısında geçerli:. Bu değişikliklerin kadar yazım hatası burada aslında olduğu doğru.
cElementTreePython 3.3 değer kaybetmiş oldu
Lxml kütüphanesi denilen XML nesil için çok uygun bir sözdizimi içerir e-fabrika . Verdiğiniz örneği şu şekilde yapacağım:
#!/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)
Çıktı:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some value2</field2>
</doc>
</root>
Ayrıca, zaten yapılmış bir düğüme eklemeyi de destekler, örn.
the_doc.append(FIELD2('another value again', name='hithere'))
getattr, örneğin, kullanabilirsiniz getattr(E, "some-tag").
Yattag http://www.yattag.org/ veya https://github.com/leforestier/yattag , böyle bir XML belgesi (ve ayrıca HTML belgeleri) oluşturmak için ilginç bir API sağlar.
Bu kullanıyor bağlam yöneticisi ve withanahtar kelime.
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)
böylece alacaksınız:
<root>
<doc>
<field1 name="blah">some value1</field1>
<field2 name="asdfasd">some value2</field2>
</doc>
</root>
En basit seçim için minidom ile giderdim: http://docs.python.org/library/xml.dom.minidom.html . Python standart kütüphanesinde yerleşiktir ve basit durumlarda kullanımı kolaydır.
İzlenmesi oldukça kolay bir öğretici: http://www.boddie.org.uk/python/XML_intro.html
Böyle basit bir XML yapısı için tam bir XML modülü dahil etmek istemeyebilirsiniz. En basit yapılar için bir dize şablonu veya biraz daha karmaşık bir şey için Jinja'yı düşünün. Jinja, belge listenizin iç xml'sini oluşturmak için bir veri listesi üzerinde döngü gerçekleştirebilir. Ham python dize şablonları ile biraz daha zor
Bir Jinja örneği için benzer bir soruya verdiğim cevaba bakınız .
Dize şablonlarıyla xml'nizi oluşturmanın bir örneği.
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
Çıktı:
<root>
<doc>
<field1 name="foo">The value for the foo document</field1>
<field2 name="bar">The <value> for the <bar> document</field2>
</doc>
</root>
Şablon yaklaşımının altını çizmek, kaçmaktan <ve >ücretsiz olarak elde etmemenizdir . Bir sorun çekerek bu sorunun etrafında dans ettimxml.sax
Bigh_29'un Şablonlar yöntemini kullanarak bir xml oluşturucu yazmayı bitirdim ... çok fazla Nesne 'yoluna' girmeden çıktılarınızı kontrol etmenin güzel bir yolu.
Etiket ve değere gelince, biri çıktı xml'de etiket adını ve konumunu veren diğerini aynı etiket listesine sahip bir parametre dosyasına başvuran iki dizi kullandım. Bununla birlikte parametre dosyası, verilerin alınacağı karşılık gelen giriş (csv) dosyasında da konum numarasına sahiptir. Bu şekilde, giriş dosyasından gelen verilerin pozisyonunda herhangi bir değişiklik olursa, program değişmez; parametre dosyasındaki uygun etiketten veri alanı konumunu dinamik olarak çalıştırır.