ตัวเลือกของฉันคืออะไรหากฉันต้องการสร้างไฟล์ 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")
ฉันทดสอบแล้วและใช้งานได้ แต่ฉันคิดว่าช่องว่างไม่สำคัญ หากคุณต้องการการเยื้อง "สวย" แจ้งให้เราทราบและฉันจะค้นหาวิธีการทำ (อาจเป็นตัวเลือกเฉพาะ LXML ฉันไม่ได้ใช้ stdlib มาก)
สำหรับการอ่านเพิ่มเติมนี่คือลิงค์ที่มีประโยชน์:
ในฐานะโน้ตสุดท้าย cElementTree หรือ LXML ควรเร็วพอสำหรับทุกความต้องการของคุณ (ทั้งคู่เป็นรหัส C ที่ปรับให้เหมาะสมที่สุด) แต่ในกรณีที่คุณอยู่ในสถานการณ์ที่คุณจำเป็นต้องบีบประสิทธิภาพทุกบิตให้เป็นมาตรฐาน ไซต์ LXML ระบุว่า:
xml_declaration=True
ถ้าคุณระบุการเข้ารหัส ... แต่เพื่อให้ได้พฤติกรรมที่เทียบเท่าโทรtree.write()
เช่นนี้: tree.write("filename.xml", xml_declaration=True, encoding='utf-8')
คุณสามารถใช้การเข้ารหัสใด ๆ ตราบเท่าที่คุณระบุอย่างชัดเจน หนึ่ง. ( ascii
จะบังคับให้อักขระ Unicode ทั้งหมดที่อยู่นอกชุด ASCII 7 บิตถูกเข้ารหัสเป็นเอนทิตีหากคุณไม่เชื่อถือเว็บเซิร์ฟเวอร์ที่จะกำหนดค่าอย่างถูกต้อง)
vlaue2
เพื่อvalue2
การพิมพ์ผิดอยู่ในการส่งออก XML ร้องขอในคำถามเดิม จนกระทั่งมีการเปลี่ยนแปลงที่พิมพ์ผิดจริงที่นี่เป็นที่ถูกต้อง
cElementTree
ถูกตัดค่าเสื่อมราคาในหลาม 3.3
ห้องสมุด lxmlรวมถึงไวยากรณ์สะดวกมากสำหรับการสร้าง XML ที่เรียกว่าE-โรงงาน นี่คือวิธีที่ฉันทำตัวอย่างที่คุณให้:
#!/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 มันถูกสร้างขึ้นในไลบรารีมาตรฐานหลามและตรงไปตรงมาเพื่อใช้ในกรณีง่าย ๆ
ต่อไปนี้เป็นบทแนะนำที่ใช้งานง่าย: http://www.boddie.org.uk/python/XML_intro.html
สำหรับโครงสร้าง XML อย่างง่ายคุณอาจไม่ต้องการเกี่ยวข้องกับโมดูล XML แบบเต็ม พิจารณาเทมเพลตสตริงสำหรับโครงสร้างที่ง่ายที่สุดหรือ Jinja สำหรับบางสิ่งที่ซับซ้อนกว่าเล็กน้อย Jinja สามารถจัดการวนรอบรายการข้อมูลเพื่อสร้าง XML ภายในของรายการเอกสารของคุณ นั่นเป็นเรื่องยุ่งยากเล็กน้อยกับแม่แบบสตริงหลามดิบ
สำหรับตัวอย่างที่ 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) ที่สอดคล้องกันซึ่งข้อมูลจะถูกนำมาจาก ด้วยวิธีนี้หากมีการเปลี่ยนแปลงตำแหน่งของข้อมูลที่เข้ามาจากไฟล์อินพุตโปรแกรมจะไม่เปลี่ยนแปลง มันทำงานออกจากตำแหน่งของเขตข้อมูลจากแท็กที่เหมาะสมในไฟล์พารามิเตอร์แบบไดนามิก