अजगर का उपयोग करके एक सरल XML फ़ाइल बनाना


161

अगर मैं अजगर में एक सरल XML फ़ाइल बनाना चाहता हूं तो मेरे पास क्या विकल्प हैं? (पुस्तकालय वार)

जो xml मुझे चाहिए वह दिखता है:

<root>
 <doc>
     <field1 name="blah">some value1</field1>
     <field2 name="asdfasd">some vlaue2</field2>
 </doc>

</root>

जवाबों:


310

इन दिनों, सबसे लोकप्रिय (और बहुत सरल) विकल्प एलीमेंटट्री एपीआई है , जिसे पायथन 2.5 के बाद से मानक पुस्तकालय में शामिल किया गया है।

इसके लिए उपलब्ध विकल्प हैं:

  • एलीमेंटट्री (बेसिक, प्योर-पायथन इम्प्लीमेंट ऑफ़ ट्रीट्री। 2.5 से मानक लाइब्रेरी का हिस्सा)
  • cElementTree (ElementTree का ऑप्टिमाइज्ड C कार्यान्वयन। 2.5 से मानक पुस्तकालय में भी प्रस्तुत किया गया)
  • LXML (libxml2 के आधार पर। एलीमेंटट्री एपीआई के समृद्ध सुपरसेट के साथ-साथ XPath, CSS चयनकर्ता और भी बहुत कुछ प्रदान करता है)

इन-स्टडीलिब 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 कार्यान्वयन का उपयोग नहीं करता हूं)

आगे पढ़ने के लिए, यहां कुछ उपयोगी लिंक दिए गए हैं:

अंतिम नोट के रूप में, या तो क्लेमेंटट्री या एलएक्सएमएल आपकी सभी जरूरतों के लिए काफी तेज होना चाहिए (दोनों को अनुकूलित किया गया है सी कोड), लेकिन इस घटना में आप ऐसी स्थिति में हैं जहां आपको प्रदर्शन के हर अंतिम बिट को निचोड़ने की आवश्यकता होती है, पर बेंचमार्क LXML साइट इंगित करती है कि:

  • LXML स्पष्ट रूप से धारावाहिक निर्माण (निर्माण) XML के लिए जीतता है
  • उचित अभिभावक ट्रैवर्स को लागू करने के साइड-इफेक्ट के रूप में, एलएक्सएमएल पार्सिंग के लिए क्लेमेंटट्री की तुलना में थोड़ा धीमा है।

1
@ कैस्पर: मेरे पास मैक नहीं है इसलिए मैं इस समस्या की नकल करने की कोशिश नहीं कर सकता। मुझे पायथन संस्करण बताएं और मैं देखूंगा कि क्या मैं इसे लिनक्स पर दोहरा सकता हूं।
ssokolow

4
@nonsensickle आपको वास्तव में एक नया प्रश्न पूछना चाहिए था और फिर मुझे इसके लिए एक लिंक भेजा ताकि हर कोई इससे लाभ उठा सके। हालांकि, मैं आपको सही दिशा में इंगित करूंगा। DOM (डॉक्यूमेंट ऑब्जेक्ट मॉडल) लाइब्रेरीज़ हमेशा इन-मेमोरी मॉडल का निर्माण करती हैं ताकि आप इसके बजाय SAX (सिंपल API फॉर XML) कार्यान्वयन चाहते हैं। मैंने कभी SAX कार्यान्वयन में नहीं देखा है, लेकिन यहाँ इनपुट के बजाय आउटपुट के लिए इन-स्टडीलिब एक का उपयोग करने के लिए एक ट्यूटोरियल है
ssokolow

1
@YonatanSimson मुझे नहीं पता कि उस सटीक स्ट्रिंग को कैसे जोड़ा जाए , क्योंकि ElementTree केवल तभी मानता है xml_declaration=Trueयदि आप एन्कोडिंग निर्दिष्ट करते हैं ... लेकिन, समतुल्य व्यवहार प्राप्त करने के लिए, tree.write()इस तरह कॉल करें: tree.write("filename.xml", xml_declaration=True, encoding='utf-8')जब तक आप स्पष्ट रूप से निर्दिष्ट करते हैं, तब तक आप किसी भी एन्कोडिंग का उपयोग कर सकते हैं। एक। ( asciiयदि आप किसी वेब सर्वर को ठीक से कॉन्फ़िगर करने के लिए भरोसा नहीं करते हैं, तो 7-बिट ASCII सेट के बाहर सभी यूनिकोड वर्णों को बलपूर्वक एनकोड किया जाएगा।)
ssokolow

1
बस किसी और के लिए एक अनुस्मारक जो सही vlaue2करने की कोशिश करता है value2: टाइपो मूल प्रश्न में अनुरोधित XML आउटपुट में है। उस परिवर्तन तक, वास्तव में यहाँ टाइपो सही है।
ssokolow


63

Lxml पुस्तकालय एक्सएमएल पीढ़ी के लिए एक बहुत ही सुविधाजनक वाक्य रचना, कहा जाता है शामिल हैं ई-कारखाने । यहां बताया गया है कि मैं आपके द्वारा दिया गया उदाहरण बनाऊंगा:

#!/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'))

3
यदि टैग का नाम पायथन पहचानकर्ता नियमों के अनुरूप नहीं है, तो आप getattrउदाहरण के लिए उपयोग कर सकते हैं getattr(E, "some-tag")
हरदेसव

मेरे लिए lxml.etree.tostring प्रिंट कर रहा था, जिससे एट्रीब्यूट हो रहा था: 'lxml.etree._Element' ऑब्जेक्ट में कोई विशेषता 'etree' नहीं है। यह "lxml" शुरू किए बिना काम किया। जैसे: etree.tostring (the_doc, pretty_print = True)
kodlan

19

यटाग http://www.yattag.org/ या https://github.com/leforestier/yattag ऐसे XML दस्तावेज़ (और HTML दस्तावेज़) बनाने के लिए एक दिलचस्प API भी प्रदान करता है।

यह संदर्भ प्रबंधक और 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>

6

सबसे आसान विकल्प के लिए, मैं minidom के साथ जाऊंगा: http://docs.python.org/library/xml.dom..htmlidid.html । यह अजगर मानक पुस्तकालय के लिए बनाया गया है और सरल मामलों में उपयोग करने के लिए सीधा है।

यहाँ ट्यूटोरियल का पालन करना बहुत आसान है: http://www.boddie.org.uk/python/XML_intro.html


6
इस उत्तर में उपयोग में मिनीडोम का उदाहरण शामिल होना चाहिए।
स्टेविओसाक

4

इस तरह के एक सरल XML संरचना के लिए, आप एक पूर्ण विकसित XML मॉड्यूल को शामिल नहीं करना चाह सकते हैं। सरल संरचनाओं के लिए एक स्ट्रिंग टेम्पलेट पर विचार करें, या कुछ और जटिल के लिए जिंजा। जिंजा आपके दस्तावेज़ सूची के आंतरिक xml का उत्पादन करने के लिए डेटा की एक सूची पर लूपिंग को संभाल सकता है। कि कच्चे अजगर स्ट्रिंग टेम्पलेट्स के साथ थोड़ा मुश्किल है

एक जिन्जा उदाहरण के लिए, एक समान प्रश्न का मेरा उत्तर देखें ।

यहां स्ट्रिंग टेम्प्लेट के साथ अपना 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 &lt;value&gt; for the &lt;bar&gt; document</field2>
 </doc>
</root>

टेम्पलेट दृष्टिकोण के डाउनर कि आप में से बचने नहीं मिलेगा है <और >मुक्त करने के लिए। मैंने उस समस्या को एक प्रयोग से खींचकर उसके आसपास नृत्य कियाxml.sax


1

मैंने अभी अभी एक xml जनरेटर लिखना समाप्त किया है, टेम्पलेट के bigh_29 की विधि का उपयोग करते हुए ... यह नियंत्रित करने का एक अच्छा तरीका है कि आप बहुत सारे ऑब्जेक्ट्स के बिना 'जिस तरह से' प्राप्त कर रहे हैं।

टैग और मूल्य के लिए, मैंने दो सरणियों का उपयोग किया, एक जो आउटपुट xml में टैग का नाम और स्थिति देता था और दूसरा जिसमें टैग की समान सूची वाले पैरामीटर फ़ाइल का संदर्भ दिया गया था। हालाँकि, पैरामीटर फ़ाइल में संबंधित इनपुट (csv) फ़ाइल में स्थिति संख्या भी होती है जहाँ से डेटा लिया जाएगा। इस तरह, यदि इनपुट फ़ाइल से आने वाले डेटा की स्थिति में कोई परिवर्तन होता है, तो प्रोग्राम परिवर्तित नहीं होता है; यह पैरामीटर फ़ाइल में उपयुक्त टैग से डेटा फ़ील्ड स्थिति को गतिशील रूप से कार्य करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.