python - मैं पायथन में एक्सएमएल का विश्लेषण कैसे करूं?




xml (8)

आप BeautifulSoup उपयोग कर सकते हैं

from bs4 import BeautifulSoup

x="""<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>"""

y=BeautifulSoup(x)
>>> y.foo.bar.type["foobar"]
u'1'

>>> y.foo.bar.findAll("type")
[<type foobar="1"></type>, <type foobar="2"></type>]

>>> y.foo.bar.findAll("type")[0]["foobar"]
u'1'
>>> y.foo.bar.findAll("type")[1]["foobar"]
u'2'

मेरे पास डेटाबेस में कई पंक्तियां हैं जिनमें xml है और मैं एक पायथन स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो उन पंक्तियों के माध्यम से जायेगा और गिनती होगी कि किसी विशेष नोड विशेषता के कितने उदाहरण दिखाए जाते हैं। उदाहरण के लिए, मेरा पेड़ इस तरह दिखता है:

<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>

मैं पायथन का उपयोग कर एक्सएमएल में गुण 1 और 2 तक कैसे पहुंच सकता हूं?


पायथन में एक्सएमएल पार्सर एक्सपैट करने के लिए एक इंटरफ़ेस है।

xml.parsers.expat

यह एक गैर-मान्य पार्सर है, इसलिए खराब एक्सएमएल पकड़ा नहीं जाएगा। लेकिन अगर आपको पता है कि आपकी फाइल सही है, तो यह बहुत अच्छा है, और आपको शायद सटीक जानकारी मिल जाएगी जो आप चाहते हैं और आप बाकी को फ्लाई पर छोड़ सकते हैं।

stringofxml = """<foo>
    <bar>
        <type arg="value" />
        <type arg="value" />
        <type arg="value" />
    </bar>
    <bar>
        <type arg="value" />
    </bar>
</foo>"""
count = 0
def start(name, attr):
    global count
    if name == 'type':
        count += 1

p = expat.ParserCreate()
p.StartElementHandler = start
p.Parse(stringofxml)

print count # prints 4

मुझे पाइथन xml.dom और xml.dom.minidom काफी आसान लगता है। ध्यान रखें कि डीओएम बड़ी मात्रा में एक्सएमएल के लिए अच्छा नहीं है, लेकिन यदि आपका इनपुट काफी छोटा है तो यह ठीक काम करेगा।


मैं declxml सुझाव दे सकता declxml

पूर्ण प्रकटीकरण: मैंने इस पुस्तकालय को लिखा क्योंकि मैं एलीमेंट ट्री के साथ अनिवार्य पार्सिंग / क्रमबद्धता कोड के दर्जनों लाइनों को लिखने के बिना एक्सएमएल और पायथन डेटा संरचनाओं के बीच परिवर्तित करने का एक तरीका ढूंढ रहा था।

Declxml के साथ, आप प्रोसेसर का उपयोग अपने एक्सएमएल दस्तावेज़ की संरचना को परिभाषित करने और एक्सएमएल और पायथन डेटा संरचनाओं के बीच मैप करने के लिए कैसे करते हैं। प्रोसेसर का उपयोग सीरियलाइजेशन और पार्सिंग के साथ-साथ सत्यापन के बुनियादी स्तर के लिए किया जाता है।

पायथन डेटा संरचनाओं में पार्सिंग सरल है:

import declxml as xml

xml_string = """
<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>
"""

processor = xml.dictionary('foo', [
    xml.dictionary('bar', [
        xml.array(xml.integer('type', attribute='foobar'))
    ])
])

xml.parse_from_string(processor, xml_string)

जो उत्पादन का उत्पादन करता है:

{'bar': {'foobar': [1, 2]}}

आप एक्सएमएल में डेटा क्रमबद्ध करने के लिए एक ही प्रोसेसर का भी उपयोग कर सकते हैं

data = {'bar': {
    'foobar': [7, 3, 21, 16, 11]
}}

xml.serialize_to_string(processor, data, indent='    ')

जो निम्नलिखित आउटपुट उत्पन्न करता है

<?xml version="1.0" ?>
<foo>
    <bar>
        <type foobar="7"/>
        <type foobar="3"/>
        <type foobar="21"/>
        <type foobar="16"/>
        <type foobar="11"/>
    </bar>
</foo>

यदि आप शब्दकोशों के बजाय ऑब्जेक्ट्स के साथ काम करना चाहते हैं, तो आप प्रोसेसर को ऑब्जेक्ट्स से डेटा को बदलने के लिए भी परिभाषित कर सकते हैं।

import declxml as xml

class Bar:

    def __init__(self):
        self.foobars = []

    def __repr__(self):
        return 'Bar(foobars={})'.format(self.foobars)


xml_string = """
<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>
"""

processor = xml.dictionary('foo', [
    xml.user_object('bar', Bar, [
        xml.array(xml.integer('type', attribute='foobar'), alias='foobars')
    ])
])

xml.parse_from_string(processor, xml_string)

जो निम्नलिखित आउटपुट उत्पन्न करता है

{'bar': Bar(foobars=[1, 2])}

मैं सादगी के लिए xmltodict सुझाव है।

यह आपके एक्सएमएल को ऑर्डर्ड डिक्ट पर पार्स करता है;

>>> e = '<foo>
             <bar>
                 <type foobar="1"/>
                 <type foobar="2"/>
             </bar>
        </foo> '

>>> import xmltodict
>>> result = xmltodict.parse(e)
>>> result

OrderedDict([(u'foo', OrderedDict([(u'bar', OrderedDict([(u'type', [OrderedDict([(u'@foobar', u'1')]), OrderedDict([(u'@foobar', u'2')])])]))]))])

>>> result['foo']

OrderedDict([(u'bar', OrderedDict([(u'type', [OrderedDict([(u'@foobar', u'1')]), OrderedDict([(u'@foobar', u'2')])])]))])

>>> result['foo']['bar']

OrderedDict([(u'type', [OrderedDict([(u'@foobar', u'1')]), OrderedDict([(u'@foobar', u'2')])])])

वहां कई विकल्प हैं। अगर गति और स्मृति उपयोग एक मुद्दा है तो cElementTree उत्कृष्ट दिखता है। readlines का उपयोग कर फ़ाइल में पढ़ने की तुलना में यह बहुत कम ओवरहेड है।

प्रासंगिक मेट्रिक्स नीचे दी गई तालिका में पाया जा सकता है, cElementTree वेबसाइट से कॉपी किया गया है:

library                         time    space
xml.dom.minidom (Python 2.1)    6.3 s   80000K
gnosis.objectify                2.0 s   22000k
xml.dom.minidom (Python 2.4)    1.4 s   53000k
ElementTree 1.2                 1.6 s   14500k  
ElementTree 1.2.4/1.3           1.1 s   14500k  
cDomlette (C extension)         0.540 s 20500k
PyRXPU (C extension)            0.175 s 10850k
libxml2 (C extension)           0.098 s 16000k
readlines (read as utf-8)       0.093 s 8850k
cElementTree (C extension)  --> 0.047 s 4900K <--
readlines (read as ascii)       0.032 s 5050k   

जैसा कि @jfs द्वारा इंगित किया गया है, cElementTree पायथन के साथ बंडल आता है:

  • पायथन 2: from xml.etree import cElementTree as ElementTree
  • पायथन 3: from xml.etree import ElementTree (त्वरित सी संस्करण स्वचालित रूप से उपयोग किया जाता है)।

minidom सबसे तेज़ और सुंदर सीधे आगे है:

एक्सएमएल:

<data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
</data>

अजगर:

from xml.dom import minidom
xmldoc = minidom.parse('items.xml')
itemlist = xmldoc.getElementsByTagName('item')
print(len(itemlist))
print(itemlist[0].attributes['name'].value)
for s in itemlist:
    print(s.attributes['name'].value)

आउटपुट

4
item1
item1
item2
item3
item4

cElementTree का उपयोग करके यहां एक बहुत ही सरल लेकिन प्रभावी कोड है।

try:
    import cElementTree as ET
except ImportError:
  try:
    # Python 2.5 need to import a different module
    import xml.etree.cElementTree as ET
  except ImportError:
    exit_err("Failed to import cElementTree from any known place")      

def find_in_tree(tree, node):
    found = tree.find(node)
    if found == None:
        print "No %s in file" % node
        found = []
    return found  

# Parse a xml file (specify the path)
def_file = "xml_file_name.xml"
try:
    dom = ET.parse(open(def_file, "r"))
    root = dom.getroot()
except:
    exit_err("Unable to open and parse input definition file: " + def_file)

# Parse to find the child nodes list of node 'myNode'
fwdefs = find_in_tree(root,"myNode")

स्रोत:

http://www.snip2code.com/Snippet/991/python-xml-parse?fromPage=1





xml