কোনও এক্সএমএল স্ট্রিংকে অভিধানে কীভাবে রূপান্তর করবেন?


125

আমার একটি প্রোগ্রাম রয়েছে যা সকেট থেকে একটি এক্সএমএল ডকুমেন্ট পড়ে। আমার কাছে এক্সএমএল ডকুমেন্টটি একটি স্ট্রিংয়ে সঞ্চিত আছে যা আমি সরাসরি পাইথন অভিধানে রূপান্তর করতে চাই, একইভাবে জাঙ্গোর simplejsonলাইব্রেরিতে এটি করা হয় ।

উদাহরণ হিসাবে ধরুন:

str ="<?xml version="1.0" ?><person><name>john</name><age>20</age></person"
dic_xml = convert_to_dic(str)

তাহলে দেখতে dic_xmlহবে{'person' : { 'name' : 'john', 'age' : 20 } }


str এর কয়েকটি সিনট্যাক্স ত্রুটি রয়েছে। চেষ্টা করে দেখুন: str = '<? xML version = "1.0"?> <پريس> <নাম> জন </ name> <age> 20 </age> </
কেয়ার

উত্তর:


58

এটি একটি দুর্দান্ত মডিউল যা কেউ তৈরি করেছে। আমি এটি বেশ কয়েকবার ব্যবহার করেছি। http://code.activestate.com/recipes/410469-xml-as-dictionary/

লিঙ্কটি খারাপ হওয়ার ক্ষেত্রে কেবল ওয়েবসাইট থেকে কোড এখানে দেওয়া হয়েছে।

from xml.etree import cElementTree as ElementTree

class XmlListConfig(list):
    def __init__(self, aList):
        for element in aList:
            if element:
                # treat like dict
                if len(element) == 1 or element[0].tag != element[1].tag:
                    self.append(XmlDictConfig(element))
                # treat like list
                elif element[0].tag == element[1].tag:
                    self.append(XmlListConfig(element))
            elif element.text:
                text = element.text.strip()
                if text:
                    self.append(text)


class XmlDictConfig(dict):
    '''
    Example usage:

    >>> tree = ElementTree.parse('your_file.xml')
    >>> root = tree.getroot()
    >>> xmldict = XmlDictConfig(root)

    Or, if you want to use an XML string:

    >>> root = ElementTree.XML(xml_string)
    >>> xmldict = XmlDictConfig(root)

    And then use xmldict for what it is... a dict.
    '''
    def __init__(self, parent_element):
        if parent_element.items():
            self.update(dict(parent_element.items()))
        for element in parent_element:
            if element:
                # treat like dict - we assume that if the first two tags
                # in a series are different, then they are all different.
                if len(element) == 1 or element[0].tag != element[1].tag:
                    aDict = XmlDictConfig(element)
                # treat like list - we assume that if the first two tags
                # in a series are the same, then the rest are the same.
                else:
                    # here, we put the list in dictionary; the key is the
                    # tag name the list elements all share in common, and
                    # the value is the list itself 
                    aDict = {element[0].tag: XmlListConfig(element)}
                # if the tag has attributes, add those to the dict
                if element.items():
                    aDict.update(dict(element.items()))
                self.update({element.tag: aDict})
            # this assumes that if you've got an attribute in a tag,
            # you won't be having any text. This may or may not be a 
            # good idea -- time will tell. It works for the way we are
            # currently doing XML configuration files...
            elif element.items():
                self.update({element.tag: dict(element.items())})
            # finally, if there are no child tags and no attributes, extract
            # the text
            else:
                self.update({element.tag: element.text})

ব্যবহারের উদাহরণ:

tree = ElementTree.parse('your_file.xml')
root = tree.getroot()
xmldict = XmlDictConfig(root)

// অথবা, আপনি যদি এক্সএমএল স্ট্রিং ব্যবহার করতে চান:

root = ElementTree.XML(xml_string)
xmldict = XmlDictConfig(root)

4
আপনি বিকল্পভাবে 'xmltodict' ব্যবহার করতে পারেন

7
আমি এটি চেষ্টা করেছি এবং এটি এক্সম্লটডিক্টিক্টের চেয়ে অনেক দ্রুত। ৮০ এমবি এক্সএমএল ফাইল বিশ্লেষণের জন্য এটি s সেকেন্ড নিয়েছিল, এক্সম্লটডিক্টিক্ট সহ এটি 90s নিয়েছিল
এডি 21

1
নিশ্চিত করা হয়েছে ... আমি প্রতিটি প্রান্তের মামলার বিরুদ্ধে এটি পরীক্ষা করেছি না তবে আমার বরং জটিল এক্সএমএল স্ট্রিংয়ের জন্য এটি বেশ দ্রুত ( xmltodictলাইব্রেরির চেয়ে প্রায় 8 গুণ বেশি দ্রুত )। অসুবিধা হ'ল এটি আপনাকে আপনার প্রকল্পের মধ্যেই হোস্ট করতে হবে।
ডার্ক

10
হাই, এটি নিখুঁতভাবে কাজ করে, যারা খুঁজে পাচ্ছেন না তাদের জন্য কেবল একটি স্নিপেট যুক্ত করবেন cElementTree, কেবল প্রথম লাইনটি এতে পরিবর্তন করুন: from xml.etree import cElementTree as ElementTree
রাফায়েল আগুইলর

2
ডাউন-ভোটিং যেহেতু নীচে আরও ভাল উত্তর পোস্ট করা হয়েছে, বিশেষত একই নামের সাথে একাধিক ট্যাগ হ্যান্ডেল করার ক্ষেত্রে।
ম্যাকসেম

280

xmltodict (সম্পূর্ণ প্রকাশ: আমি এটি লিখেছি) ঠিক তা করে:

xmltodict.parse("""
<?xml version="1.0" ?>
<person>
  <name>john</name>
  <age>20</age>
</person>""")
# {u'person': {u'age': u'20', u'name': u'john'}}

22
এটি একটি দুর্দান্ত মডিউল।
জেকেল

2
আপনি সবেমাত্র আমাকে প্রচুর পরিশ্রম বাঁচিয়েছেন। আমার দিন তৈরি।
এলআরই

3
এছাড়াও, ভবিষ্যতের গুগলনোটগুলির জন্য - আমি এটি অ্যাপ ইঞ্জিনে ব্যবহার করতে সক্ষম হয়েছি, যা আমি বিশ্বাস করি যে পাইথনের বেশিরভাগ এক্সএমএল লাইব্রেরি দিয়ে সুন্দরভাবে খেলেনি।
এলআরই

2
আপনি কেবল এটি ইউনিকোড স্ট্রিংটি সঞ্চিত করছেন। এটি কোনওভাবেই স্ট্রিংয়ের মানকে প্রভাবিত করে না।
জোশুয়া ওলসন

2
খুশী হলাম। এবং হ্যাঁ, @ টাইপ्यूब, বিপরীতে একটি xmldict.unparse () ফাংশন রয়েছে।
দুথার

47

নিম্নলিখিত এক্সএমএল-থেকে-পাইথন-ডিক স্নিপেট সত্ত্বাকে পাশাপাশি এই এক্সএমএল-জেএসওএন "স্পেসিফিকেশন" অনুসরণ করে এমন গুণাবলী । এটি এক্সএমএল এর সমস্ত ক্ষেত্রে পরিচালিত সবচেয়ে সাধারণ সমাধান।

from collections import defaultdict

def etree_to_dict(t):
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    if children:
        dd = defaultdict(list)
        for dc in map(etree_to_dict, children):
            for k, v in dc.items():
                dd[k].append(v)
        d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.items()}}
    if t.attrib:
        d[t.tag].update(('@' + k, v) for k, v in t.attrib.items())
    if t.text:
        text = t.text.strip()
        if children or t.attrib:
            if text:
              d[t.tag]['#text'] = text
        else:
            d[t.tag] = text
    return d

এটা ব্যবহার করা হয়:

from xml.etree import cElementTree as ET
e = ET.XML('''
<root>
  <e />
  <e>text</e>
  <e name="value" />
  <e name="value">text</e>
  <e> <a>text</a> <b>text</b> </e>
  <e> <a>text</a> <a>text</a> </e>
  <e> text <a>text</a> </e>
</root>
''')

from pprint import pprint
pprint(etree_to_dict(e))

এই উদাহরণটির আউটপুট (উপরের লিঙ্কযুক্ত "স্পেসিফিকেশন" অনুযায়ী) হওয়া উচিত:

{'root': {'e': [None,
                'text',
                {'@name': 'value'},
                {'#text': 'text', '@name': 'value'},
                {'a': 'text', 'b': 'text'},
                {'a': ['text', 'text']},
                {'#text': 'text', 'a': 'text'}]}}

অগত্যা সুন্দর নয়, তবে এটি দ্ব্যর্থহীন এবং সহজ এক্সএমএল ইনপুটগুলির ফলস্বরূপ সহজ জেএসএন। :)


হালনাগাদ

যদি আপনি বিপরীতটি করতে চান , একটি JSON / ডিক্ট থেকে এক্সএমএল স্ট্রিং নির্গত করুন , আপনি এটি ব্যবহার করতে পারেন:

try:
  basestring
except NameError:  # python3
  basestring = str

def dict_to_etree(d):
    def _to_etree(d, root):
        if not d:
            pass
        elif isinstance(d, basestring):
            root.text = d
        elif isinstance(d, dict):
            for k,v in d.items():
                assert isinstance(k, basestring)
                if k.startswith('#'):
                    assert k == '#text' and isinstance(v, basestring)
                    root.text = v
                elif k.startswith('@'):
                    assert isinstance(v, basestring)
                    root.set(k[1:], v)
                elif isinstance(v, list):
                    for e in v:
                        _to_etree(e, ET.SubElement(root, k))
                else:
                    _to_etree(v, ET.SubElement(root, k))
        else:
            raise TypeError('invalid type: ' + str(type(d)))
    assert isinstance(d, dict) and len(d) == 1
    tag, body = next(iter(d.items()))
    node = ET.Element(tag)
    _to_etree(body, node)
    return ET.tostring(node)

pprint(dict_to_etree(d))

1
এই কোডের জন্য থেক্স! অতিরিক্ত তথ্য: আপনি যদি অজগর 2.5 ব্যবহার করেন তবে আপনি অভিধানের বোধগম্যতা ব্যবহার করতে পারবেন না, তাই আপনাকে লাইনটি পরিবর্তন করতে d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}} হবে d = { t.tag: dict( (k, v[0] if len(v) == 1 else v) for k, v in dd.iteritems() ) }
এম

2
আমি এটির জন্য প্রায় 10 টি স্নিপেট / পাইথন মডিউল / ইত্যাদি পরীক্ষা করেছি। এটি আমি খুঁজে পেয়েছি সেরা। আমার পরীক্ষাগুলি অনুসারে, এটি হ'ল: 1) github.com/martinblech/xmltodict (XML SAX এপিআই ভিত্তিক) 2) github.com/mcspring/XML2 চিত্রের তুলনায় অনেক ভাল, যা বেশ কয়েকটি সন্তানের একই নাম 3 থাকলে কিছু সামান্য সমস্যা রয়েছে ) Code.activestate.com/recines/410469-xML-as-d অভিধান এর চেয়ে ভাল যা ছোট সমস্যাগুলিও ছিল এবং আরও গুরুত্বপূর্ণ: 4) পূর্ববর্তী সমস্তগুলির তুলনায় অনেক সংক্ষিপ্ত কোড! ধন্যবাদ @ কে 3 --- আরএনসি
বাসজ

এটি এখন পর্যন্ত সর্বাধিক বিস্তৃত উত্তর, এবং এটি> 2.6 এ কাজ করে এবং এটি বেশ নমনীয়। আমার একমাত্র সমস্যাটি হ'ল পাঠ্যটি পরিবর্তন করতে পারে যেখানে এটি কোনও বৈশিষ্ট্য আছে কিনা তা নির্ভর করে যেখানে থাকে) আমি আরও ছোট এবং আরও কঠোর সমাধান পোস্ট করেছি।
এরিক অ্যারোনস্টি

1
: আপনি একটি XML ফাইল থেকে একটি আদেশ অভি পেতে প্রয়োজন, তাহলে দয়া করে, আপনি (নীচের আমার প্রতিক্রিয়া দেখুন) কয়েক সংশোধনসহ এই একই উদাহরণ ব্যবহার করতে পারেন stackoverflow.com/questions/2148119/...
serfer2

এটি বেশ নিফটি এবং দ্রুত যখন cElementTreeবা সাথে ব্যবহৃত হয় lxml.etree। দ্রষ্টব্য যে পাইথন 3 ব্যবহার করার সময়, সমস্তগুলিতে .iteritems()পরিবর্তন করতে হবে .items()(একই আচরণ তবে মূল শব্দটি পাইথন 2 থেকে 3 এ পরিবর্তিত হয়েছে)।
শির্ক

25

এই লাইটওয়েট ভার্সনটি কনফিগারযোগ্য না হলেও এটি প্রয়োজনীয় অনুসারে দর্জি করা বেশ সহজ এবং পুরানো অজগরগুলিতে কাজ করে। এছাড়াও এটি অনমনীয় - মানে গুণাবলীর অস্তিত্ব নির্বিশেষে ফলাফলগুলি একই।

import xml.etree.ElementTree as ET

from copy import copy

def dictify(r,root=True):
    if root:
        return {r.tag : dictify(r, False)}
    d=copy(r.attrib)
    if r.text:
        d["_text"]=r.text
    for x in r.findall("./*"):
        if x.tag not in d:
            d[x.tag]=[]
        d[x.tag].append(dictify(x,False))
    return d

তাই:

root = ET.fromstring("<erik><a x='1'>v</a><a y='2'>w</a></erik>")

dictify(root)

ফলাফল স্বরূপ:

{'erik': {'a': [{'x': '1', '_text': 'v'}, {'y': '2', '_text': 'w'}]}}

2
আমি এই সমাধানটি পছন্দ করি। সহজ এবং বাহ্যিক libs প্রয়োজন হয় না।
ম্যাটকে

6

এক্সএমএল থেকে পাইথন ডিকে রূপান্তর করার জন্য পিকলিংটুলস লাইব্রেরিগুলির সর্বশেষতম সংস্করণগুলি (1.3.0 এবং 1.3.1) সমর্থন করে।

ডাউনলোডটি এখানে উপলভ্য: পিকলিংটুলস ১.৩.১

রূপান্তরকারীদের জন্য এখানে বেশ কয়েকটি নথিপত্র রয়েছে : ডকুমেন্টেশনটি এক্সএমএল এবং পাইথন অভিধানের মধ্যে রূপান্তর করার সময় উত্থাপিত হওয়া সমস্ত সিদ্ধান্ত এবং ইস্যুগুলির বিশদ বিবরণ দিয়ে বর্ণনা করে (বেশ কয়েকটি প্রান্তের কেস রয়েছে: বৈশিষ্ট্য, তালিকা, বেনাম তালিকা, বেনামে ডিকটস, ইভাল ইত্যাদি যা বেশিরভাগ রূপান্তরকারীরা পরিচালনা করে না)। সাধারণভাবে, যদিও, রূপান্তরকারীগুলি ব্যবহার করা সহজ। যদি একটি 'উদাহরণ.xml' থাকে:

<top>
  <a>1</a>
  <b>2.2</b>
  <c>three</c>
</top>

তারপরে এটিকে অভিধানে রূপান্তর করতে:

>>> from xmlloader import *
>>> example = file('example.xml', 'r')   # A document containing XML
>>> xl = StreamXMLLoader(example, 0)     # 0 = all defaults on operation
>>> result = xl.expect XML()
>>> print result
{'top': {'a': '1', 'c': 'three', 'b': '2.2'}}

সি ++ এবং পাইথন উভয় ক্ষেত্রে রূপান্তর করার জন্য সরঞ্জাম রয়েছে: সি ++ এবং পাইথন ইনডেন্টিকাল রূপান্তর করে তবে সি ++ প্রায় 60x দ্রুত


অবশ্যই, যদি 2 টি এর হয় তবে এটি ভাল ফর্ম্যাট নয়।
এরিক অ্যারোনস্টি

1
আকর্ষণীয় দেখায়, তবে পিক্লিংটুলগুলি কীভাবে ব্যবহার করা হয় তা আমি এখনও বুঝতে পারি নি - এটি কি কেবল সোর্স কোড ফাইলগুলির একটি টারবাল যা থেকে আমার কাজের জন্য আমাকে সঠিকগুলি খুঁজে পেতে এবং তারপরে সেগুলি আমার প্রকল্পে অনুলিপি করতে হবে? কোনও মডিউল লোড করার জন্য বা সহজ কিছু না?
শির্ক

আমি পেয়েছি: peekIntoNextNWSChar c = self.is। Read (1) AttributeError: 'str' অবজেক্টটির 'পড়ুন' এর কোনও বৈশিষ্ট্য নেই
sqp_125

5

আপনি lxml এর সাহায্যে এটি বেশ সহজেই করতে পারেন। প্রথমে এটি ইনস্টল করুন:

[sudo] pip install lxml

এখানে আমি একটি পুনরাবৃত্ত ফাংশন লিখেছি যা আপনার জন্য ভারী উত্তোলন করে:

from lxml import objectify as xml_objectify


def xml_to_dict(xml_str):
    """ Convert xml to dict, using lxml v3.4.2 xml processing library """
    def xml_to_dict_recursion(xml_object):
        dict_object = xml_object.__dict__
        if not dict_object:
            return xml_object
        for key, value in dict_object.items():
            dict_object[key] = xml_to_dict_recursion(value)
        return dict_object
    return xml_to_dict_recursion(xml_objectify.fromstring(xml_str))

xml_string = """<?xml version="1.0" encoding="UTF-8"?><Response><NewOrderResp>
<IndustryType>Test</IndustryType><SomeData><SomeNestedData1>1234</SomeNestedData1>
<SomeNestedData2>3455</SomeNestedData2></SomeData></NewOrderResp></Response>"""

print xml_to_dict(xml_string)

নীচের বৈকল্পিকটি মূল কী / উপাদান সংরক্ষণ করে:

def xml_to_dict(xml_str):
    """ Convert xml to dict, using lxml v3.4.2 xml processing library, see http://lxml.de/ """
    def xml_to_dict_recursion(xml_object):
        dict_object = xml_object.__dict__
        if not dict_object:  # if empty dict returned
            return xml_object
        for key, value in dict_object.items():
            dict_object[key] = xml_to_dict_recursion(value)
        return dict_object
    xml_obj = objectify.fromstring(xml_str)
    return {xml_obj.tag: xml_to_dict_recursion(xml_obj)}

আপনি যদি কেবল একটি সাবট্রিটি ফিরিয়ে দিতে এবং ডাকে রূপান্তর করতে চান তবে সাবট্রিটি পেতে আপনি এলিমেন্ট.ফাইন্ড () ব্যবহার করতে পারেন এবং তারপরে এটি রূপান্তর করতে পারেন:

xml_obj.find('.//')  # lxml.objectify.ObjectifiedElement instance

এখানে lxML ডক্স দেখুন । আশা করি এটা কাজে লাগবে!


5

দাবি অস্বীকার: এই পরিবর্তিত এক্সএমএল পার্সার অ্যাডাম ক্লার্ক দ্বারা অনুপ্রাণিত হয়েছিল মূল এক্সএমএল পার্সার বেশিরভাগ সাধারণ ক্ষেত্রে কাজ করে। তবে এটি কিছু জটিল এক্সএমএল ফাইলের জন্য কাজ করে নি। আমি লাইন দিয়ে কোড লাইনটি ডিবাগ করেছি এবং শেষ পর্যন্ত কিছু সমস্যা সমাধান করেছি। যদি আপনি কিছু বাগ খুঁজে পান তবে দয়া করে আমাকে জানান। আমি এটি ঠিক করতে পেরে খুশি।

class XmlDictConfig(dict):  
    '''   
    Note: need to add a root into if no exising    
    Example usage:
    >>> tree = ElementTree.parse('your_file.xml')
    >>> root = tree.getroot()
    >>> xmldict = XmlDictConfig(root)
    Or, if you want to use an XML string:
    >>> root = ElementTree.XML(xml_string)
    >>> xmldict = XmlDictConfig(root)
    And then use xmldict for what it is... a dict.
    '''
    def __init__(self, parent_element):
        if parent_element.items():
            self.updateShim( dict(parent_element.items()) )
        for element in parent_element:
            if len(element):
                aDict = XmlDictConfig(element)
            #   if element.items():
            #   aDict.updateShim(dict(element.items()))
                self.updateShim({element.tag: aDict})
            elif element.items():    # items() is specialy for attribtes
                elementattrib= element.items()
                if element.text:           
                    elementattrib.append((element.tag,element.text ))     # add tag:text if there exist
                self.updateShim({element.tag: dict(elementattrib)})
            else:
                self.updateShim({element.tag: element.text})

    def updateShim (self, aDict ):
        for key in aDict.keys():   # keys() includes tag and attributes
            if key in self:
                value = self.pop(key)
                if type(value) is not list:
                    listOfDicts = []
                    listOfDicts.append(value)
                    listOfDicts.append(aDict[key])
                    self.update({key: listOfDicts})
                else:
                    value.append(aDict[key])
                    self.update({key: value})
            else:
                self.update({key:aDict[key]})  # it was self.update(aDict)    

3
def xml_to_dict(node):
    u''' 
    @param node:lxml_node
    @return: dict 
    '''

    return {'tag': node.tag, 'text': node.text, 'attrib': node.attrib, 'children': {child.tag: xml_to_dict(child) for child in node}}

2

পাইথনের জন্য এক্সএমএল পার্সার ব্যবহার করা সবচেয়ে সহজ হ'ল এলিমেন্ট্রি (এটি 2.5x এবং উপরে এটি স্ট্যান্ডার্ড লাইব্রেরি xML.etree.ElementTree এ রয়েছে)। আমি মনে করি না এমন কিছু আছে যা বাক্স থেকে বেরিয়ে আপনি যা চান ঠিক তেমন করে। আপনি এলিমেট্রি ব্যবহার করে যা করতে চান তা করতে কিছু লিখলে তা খুব নগণ্য হবে, তবে কেন একটি অভিধানে রূপান্তর করুন এবং কেন কেবল এলিমেট্রি সরাসরি ব্যবহার করবেন না।


2

Http://code.activestate.com/recines/410469-xML-as-d অভিধান/ থেকে কোডটি কার্যকরভাবে কাজ করে তবে শ্রেণিবদ্ধের একটি নির্দিষ্ট জায়গায় একই রকম একাধিক উপাদান থাকলে এটি কেবল তাদের ওভাররাইড করে।

আমি এটির মধ্যে একটি শিম যুক্ত করেছি যা দেখে মনে হচ্ছে যে সেল.অ্যাপডেট () এর আগে উপাদানটি ইতিমধ্যে বিদ্যমান কিনা। যদি তা হয় তবে বিদ্যমান এন্ট্রিটিকে পপ করে এবং বিদ্যমান এবং নতুনটির বাইরে একটি তালিকা তৈরি করে। পরবর্তী যে কোনও সদৃশ তালিকাতে যুক্ত করা হয়।

এটি আরও কৌতূহলীভাবে পরিচালনা করা যায় কিনা তা নিশ্চিত নয়, তবে এটি কাজ করে:

import xml.etree.ElementTree as ElementTree

class XmlDictConfig(dict):
    def __init__(self, parent_element):
        if parent_element.items():
            self.updateShim(dict(parent_element.items()))
        for element in parent_element:
            if len(element):
                aDict = XmlDictConfig(element)
                if element.items():
                    aDict.updateShim(dict(element.items()))
                self.updateShim({element.tag: aDict})
            elif element.items():
                self.updateShim({element.tag: dict(element.items())})
            else:
                self.updateShim({element.tag: element.text.strip()})

    def updateShim (self, aDict ):
        for key in aDict.keys():
            if key in self:
                value = self.pop(key)
                if type(value) is not list:
                    listOfDicts = []
                    listOfDicts.append(value)
                    listOfDicts.append(aDict[key])
                    self.update({key: listOfDicts})

                else:
                    value.append(aDict[key])
                    self.update({key: value})
            else:
                self.update(aDict)

2

@ কে 3 --- আরএনসি প্রতিক্রিয়া থেকে (আমার পক্ষে সেরা) আমি এক্সএমএল পাঠ্য থেকে অর্ডারডিক্ট পেতে একটি ছোট পরিবর্তন সংযোজন করেছি (কিছু সময় বিষয়গুলি অর্ডার করে):

def etree_to_ordereddict(t):
d = OrderedDict()
d[t.tag] = OrderedDict() if t.attrib else None
children = list(t)
if children:
    dd = OrderedDict()
    for dc in map(etree_to_ordereddict, children):
        for k, v in dc.iteritems():
            if k not in dd:
                dd[k] = list()
            dd[k].append(v)
    d = OrderedDict()
    d[t.tag] = OrderedDict()
    for k, v in dd.iteritems():
        if len(v) == 1:
            d[t.tag][k] = v[0]
        else:
            d[t.tag][k] = v
if t.attrib:
    d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems())
if t.text:
    text = t.text.strip()
    if children or t.attrib:
        if text:
            d[t.tag]['#text'] = text
    else:
        d[t.tag] = text
return d

@ কে 3 --- আরএনসি উদাহরণ অনুসরণ করে আপনি এটি ব্যবহার করতে পারেন:

from xml.etree import cElementTree as ET
e = ET.XML('''
<root>
  <e />
  <e>text</e>
  <e name="value" />
  <e name="value">text</e>
  <e> <a>text</a> <b>text</b> </e>
  <e> <a>text</a> <a>text</a> </e>
  <e> text <a>text</a> </e>
</root>
''')

from pprint import pprint
pprint(etree_to_ordereddict(e))

আশা করি এটা সাহায্য করবে ;)


1

এখানে একটি অ্যাক্টিস্টেট সমাধানের একটি লিঙ্ক রয়েছে - এবং কোডটি যদি আবার অদৃশ্য হয়ে যায়।

==================================================
xmlreader.py:
==================================================
from xml.dom.minidom import parse


class NotTextNodeError:
    pass


def getTextFromNode(node):
    """
    scans through all children of node and gathers the
    text. if node has non-text child-nodes, then
    NotTextNodeError is raised.
    """
    t = ""
    for n in node.childNodes:
    if n.nodeType == n.TEXT_NODE:
        t += n.nodeValue
    else:
        raise NotTextNodeError
    return t


def nodeToDic(node):
    """
    nodeToDic() scans through the children of node and makes a
    dictionary from the content.
    three cases are differentiated:
    - if the node contains no other nodes, it is a text-node
    and {nodeName:text} is merged into the dictionary.
    - if the node has the attribute "method" set to "true",
    then it's children will be appended to a list and this
    list is merged to the dictionary in the form: {nodeName:list}.
    - else, nodeToDic() will call itself recursively on
    the nodes children (merging {nodeName:nodeToDic()} to
    the dictionary).
    """
    dic = {} 
    for n in node.childNodes:
    if n.nodeType != n.ELEMENT_NODE:
        continue
    if n.getAttribute("multiple") == "true":
        # node with multiple children:
        # put them in a list
        l = []
        for c in n.childNodes:
            if c.nodeType != n.ELEMENT_NODE:
            continue
        l.append(nodeToDic(c))
            dic.update({n.nodeName:l})
        continue

    try:
        text = getTextFromNode(n)
    except NotTextNodeError:
            # 'normal' node
            dic.update({n.nodeName:nodeToDic(n)})
            continue

        # text node
        dic.update({n.nodeName:text})
    continue
    return dic


def readConfig(filename):
    dom = parse(filename)
    return nodeToDic(dom)





def test():
    dic = readConfig("sample.xml")

    print dic["Config"]["Name"]
    print
    for item in dic["Config"]["Items"]:
    print "Item's Name:", item["Name"]
    print "Item's Value:", item["Value"]

test()



==================================================
sample.xml:
==================================================
<?xml version="1.0" encoding="UTF-8"?>

<Config>
    <Name>My Config File</Name>

    <Items multiple="true">
    <Item>
        <Name>First Item</Name>
        <Value>Value 1</Value>
    </Item>
    <Item>
        <Name>Second Item</Name>
        <Value>Value 2</Value>
    </Item>
    </Items>

</Config>



==================================================
output:
==================================================
My Config File

Item's Name: First Item
Item's Value: Value 1
Item's Name: Second Item
Item's Value: Value 2

হ্যাঁ তাই হয়। কোডটি আবার চলে যাওয়ার ক্ষেত্রে এখানে পুনরুত্পাদন করেছেন।
জেমি বুল

0

এক পর্যায়ে আমাকে এক্সএমএল বিশ্লেষণ এবং লিখতে হয়েছিল যা কেবলমাত্র বৈশিষ্ট্য ছাড়াই উপাদানগুলির সমন্বয়ে গঠিত হয়েছিল তাই এক্সএমএল থেকে ডিকটিতে 1: 1 ম্যাপিং সহজেই সম্ভব হয়েছিল। অন্য কারও জন্যও গুণাবলীর প্রয়োজন না পড়লে এটিই আমি নিয়ে এসেছি:

def xmltodict(element):
    if not isinstance(element, ElementTree.Element):
        raise ValueError("must pass xml.etree.ElementTree.Element object")

    def xmltodict_handler(parent_element):
        result = dict()
        for element in parent_element:
            if len(element):
                obj = xmltodict_handler(element)
            else:
                obj = element.text

            if result.get(element.tag):
                if hasattr(result[element.tag], "append"):
                    result[element.tag].append(obj)
                else:
                    result[element.tag] = [result[element.tag], obj]
            else:
                result[element.tag] = obj
        return result

    return {element.tag: xmltodict_handler(element)}


def dicttoxml(element):
    if not isinstance(element, dict):
        raise ValueError("must pass dict type")
    if len(element) != 1:
        raise ValueError("dict must have exactly one root key")

    def dicttoxml_handler(result, key, value):
        if isinstance(value, list):
            for e in value:
                dicttoxml_handler(result, key, e)
        elif isinstance(value, basestring):
            elem = ElementTree.Element(key)
            elem.text = value
            result.append(elem)
        elif isinstance(value, int) or isinstance(value, float):
            elem = ElementTree.Element(key)
            elem.text = str(value)
            result.append(elem)
        elif value is None:
            result.append(ElementTree.Element(key))
        else:
            res = ElementTree.Element(key)
            for k, v in value.items():
                dicttoxml_handler(res, k, v)
            result.append(res)

    result = ElementTree.Element(element.keys()[0])
    for key, value in element[element.keys()[0]].items():
        dicttoxml_handler(result, key, value)
    return result

def xmlfiletodict(filename):
    return xmltodict(ElementTree.parse(filename).getroot())

def dicttoxmlfile(element, filename):
    ElementTree.ElementTree(dicttoxml(element)).write(filename)

def xmlstringtodict(xmlstring):
    return xmltodict(ElementTree.fromstring(xmlstring).getroot())

def dicttoxmlstring(element):
    return ElementTree.tostring(dicttoxml(element))

0

@ ডিব্রোভসড: এক্সএমএলে একই নামের সাথে একাধিক ট্যাগ থাকলে সলিউশন কাজ করবে না

আপনার চিন্তার ধারায় আমি কোডটি কিছুটা পরিবর্তন করেছি এবং এটি মূলের পরিবর্তে সাধারণ নোডের জন্য লিখেছি:

from collections import defaultdict
def xml2dict(node):
    d, count = defaultdict(list), 1
    for i in node:
        d[i.tag + "_" + str(count)]['text'] = i.findtext('.')[0]
        d[i.tag + "_" + str(count)]['attrib'] = i.attrib # attrib gives the list
        d[i.tag + "_" + str(count)]['children'] = xml2dict(i) # it gives dict
     return d

0

আমি আমার রুচির উত্তরগুলির মধ্যে একটিতে সংশোধন করেছি এবং একই ট্যাগ সহ একাধিক মানের সাথে কাজ করতে উদাহরণস্বরূপ XML.xML ফাইলে সংরক্ষিত নিম্নলিখিত xML কোডটি বিবেচনা করুন

     <A>
        <B>
            <BB>inAB</BB>
            <C>
                <D>
                    <E>
                        inABCDE
                    </E>
                    <E>value2</E>
                    <E>value3</E>
                </D>
                <inCout-ofD>123</inCout-ofD>
            </C>
        </B>
        <B>abc</B>
        <F>F</F>
    </A>

অজগরে

import xml.etree.ElementTree as ET




class XMLToDictionary(dict):
    def __init__(self, parentElement):
        self.parentElement = parentElement
        for child in list(parentElement):
            child.text = child.text if (child.text != None) else  ' '
            if len(child) == 0:
                self.update(self._addToDict(key= child.tag, value = child.text.strip(), dict = self))
            else:
                innerChild = XMLToDictionary(parentElement=child)
                self.update(self._addToDict(key=innerChild.parentElement.tag, value=innerChild, dict=self))

    def getDict(self):
        return {self.parentElement.tag: self}

    class _addToDict(dict):
        def __init__(self, key, value, dict):
            if not key in dict:
                self.update({key: value})
            else:
                identical = dict[key] if type(dict[key]) == list else [dict[key]]
                self.update({key: identical + [value]})


tree = ET.parse('./XML.xml')
root = tree.getroot()
parseredDict = XMLToDictionary(root).getDict()
print(parseredDict)

আউটপুট হয়

{'A': {'B': [{'BB': 'inAB', 'C': {'D': {'E': ['inABCDE', 'value2', 'value3']}, 'inCout-ofD': '123'}}, 'abc'], 'F': 'F'}}

-2

আমার কাছে একটি এক্সএক্সএমএল উপাদান থেকে অভিধান পেতে একটি পুনরাবৃত্ত পদ্ধতি আছে

    def recursive_dict(element):
        return (element.tag.split('}')[1],
                dict(map(recursive_dict, element.getchildren()),
                     **element.attrib))

1
এই সমাধানটিতে কিছু কোড অনুপস্থিত, যেমন আমদানি এবং সেট আপ। আমি পেয়েছি বার্তাটি 'str' অবজেক্টের কোনও 'ট্যাগ' নেই
ক্রিস নিলসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.