конвертировать xml в python dict

Я пытаюсь сделать класс dict для обработки xml, но застрял, у меня действительно заканчиваются идеи. Если бы кто-то мог вести по этому вопросу, было бы здорово.

код, разработанный до сих пор:

class XMLResponse(dict): def __init__(self, xml): self.result = True self.message = '' pass def __setattr__(self, name, val): self[name] = val def __getattr__(self, name): if name in self: return self[name] return None message="<?xml version="1.0"?><note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>" XMLResponse(message) 

4 Solutions collect form web for “конвертировать xml в python dict”

Вы можете использовать модуль xmltodict :

 import xmltodict message = """<?xml version="1.0"?><note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>""" print xmltodict.parse(message)['note'] 

который производит OrderedDict :

 OrderedDict([(u'to', u'Tove'), (u'from', u'Jani'), (u'heading', u'Reminder'), (u'body', u"Don't forget me this weekend!")]) 

который может быть преобразован в dict, если порядок не имеет значения:

 print dict(xmltodict.parse(message)['note']) 

Печать:

 {u'body': u"Don't forget me this weekend!", u'to': u'Tove', u'from': u'Jani', u'heading': u'Reminder'} 

Вы должны проверить

https://github.com/martinblech/xmltodict

Я думаю, что это один из лучших стандартных обработчиков для xml, который я видел.

Однако я должен предупредить вас, что xml и dict не являются абсолютно совместимыми структурами данных

Вы бы подумали, что к этому времени у нас будет хороший ответ на этот вопрос, но мы, очевидно, этого не сделали. Рассмотрев половину десятков подобных вопросов в stackoverflow, вот что сработало для меня:

 from lxml import etree # arrow is an awesome lib for dealing with dates in python import arrow # converts an etree to dict, useful to convert xml to dict def etree2dict(tree): root, contents = recursive_dict(tree) return {root: contents} def recursive_dict(element): if element.attrib and 'type' in element.attrib and element.attrib['type'] == "array": return element.tag, [(dict(map(recursive_dict, child)) or getElementValue(child)) for child in element] else: return element.tag, dict(map(recursive_dict, element)) or getElementValue(element) def getElementValue(element): if element.text: if element.attrib and 'type' in element.attrib: attr_type = element.attrib.get('type') if attr_type == 'integer': return int(element.text.strip()) if attr_type == 'float': return float(element.text.strip()) if attr_type == 'boolean': return element.text.lower().strip() == 'true' if attr_type == 'datetime': return arrow.get(element.text.strip()).timestamp else: return element.text elif element.attrib: if 'nil' in element.attrib: return None else: return element.attrib else: return None 

и вот как вы его используете:

 from lxml import etree message="""<?xml version="1.0"?><note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>"'' tree = etree.fromstring(message) etree2dict(tree) 

Надеюсь, поможет 🙂

Вы можете использовать библиотеку lxml . Преобразуйте строку в объект xml с помощью objectify.fromstring а затем найдите метод dir объектов. Например:

 from lxml import objectify xml_string = """<?xml version="1.0" encoding="UTF-8"?><NewOrderResp><IndustryType></IndustryType><MessageType>R</MessageType><MerchantID>700000005894</MerchantID><TerminalID>0031</TerminalID><CardBrand>AMEX</CardBrand><AccountNum>3456732800000010</AccountNum><OrderID>TESTORDER1</OrderID><TxRefNum>55A69B278025130CD36B3A95435AA84DC45363</TxRefNum><TxRefIdx>10</TxRefIdx><ProcStatus>0</ProcStatus><ApprovalStatus>1</ApprovalStatus><RespCode></RespCode><AVSRespCode></AVSRespCode><CVV2RespCode></CVV2RespCode><AuthCode></AuthCode><RecurringAdviceCd></RecurringAdviceCd><CAVVRespCode></CAVVRespCode><StatusMsg></StatusMsg><RespMsg></RespMsg><HostRespCode></HostRespCode><HostAVSRespCode></HostAVSRespCode><HostCVV2RespCode></HostCVV2RespCode><CustomerRefNum>A51C5B2B1811E5991208</CustomerRefNum><CustomerName>BOB STEVEN</CustomerName><ProfileProcStatus>0</ProfileProcStatus><CustomerProfileMessage>Profile Created</CustomerProfileMessage><RespTime>13055</RespTime><PartialAuthOccurred></PartialAuthOccurred><RequestedAmount></RequestedAmount><RedeemedAmount></RedeemedAmount><RemainingBalance></RemainingBalance><CountryFraudFilterStatus></CountryFraudFilterStatus><IsoCountryCode></IsoCountryCode></NewOrderResp>""" xml_object = objectify.fromstring(xml_string) print xml_object.__dict__ сумма from lxml import objectify xml_string = """<?xml version="1.0" encoding="UTF-8"?><NewOrderResp><IndustryType></IndustryType><MessageType>R</MessageType><MerchantID>700000005894</MerchantID><TerminalID>0031</TerminalID><CardBrand>AMEX</CardBrand><AccountNum>3456732800000010</AccountNum><OrderID>TESTORDER1</OrderID><TxRefNum>55A69B278025130CD36B3A95435AA84DC45363</TxRefNum><TxRefIdx>10</TxRefIdx><ProcStatus>0</ProcStatus><ApprovalStatus>1</ApprovalStatus><RespCode></RespCode><AVSRespCode></AVSRespCode><CVV2RespCode></CVV2RespCode><AuthCode></AuthCode><RecurringAdviceCd></RecurringAdviceCd><CAVVRespCode></CAVVRespCode><StatusMsg></StatusMsg><RespMsg></RespMsg><HostRespCode></HostRespCode><HostAVSRespCode></HostAVSRespCode><HostCVV2RespCode></HostCVV2RespCode><CustomerRefNum>A51C5B2B1811E5991208</CustomerRefNum><CustomerName>BOB STEVEN</CustomerName><ProfileProcStatus>0</ProfileProcStatus><CustomerProfileMessage>Profile Created</CustomerProfileMessage><RespTime>13055</RespTime><PartialAuthOccurred></PartialAuthOccurred><RequestedAmount></RequestedAmount><RedeemedAmount></RedeemedAmount><RemainingBalance></RemainingBalance><CountryFraudFilterStatus></CountryFraudFilterStatus><IsoCountryCode></IsoCountryCode></NewOrderResp>""" xml_object = objectify.fromstring(xml_string) print xml_object.__dict__ сумма from lxml import objectify xml_string = """<?xml version="1.0" encoding="UTF-8"?><NewOrderResp><IndustryType></IndustryType><MessageType>R</MessageType><MerchantID>700000005894</MerchantID><TerminalID>0031</TerminalID><CardBrand>AMEX</CardBrand><AccountNum>3456732800000010</AccountNum><OrderID>TESTORDER1</OrderID><TxRefNum>55A69B278025130CD36B3A95435AA84DC45363</TxRefNum><TxRefIdx>10</TxRefIdx><ProcStatus>0</ProcStatus><ApprovalStatus>1</ApprovalStatus><RespCode></RespCode><AVSRespCode></AVSRespCode><CVV2RespCode></CVV2RespCode><AuthCode></AuthCode><RecurringAdviceCd></RecurringAdviceCd><CAVVRespCode></CAVVRespCode><StatusMsg></StatusMsg><RespMsg></RespMsg><HostRespCode></HostRespCode><HostAVSRespCode></HostAVSRespCode><HostCVV2RespCode></HostCVV2RespCode><CustomerRefNum>A51C5B2B1811E5991208</CustomerRefNum><CustomerName>BOB STEVEN</CustomerName><ProfileProcStatus>0</ProfileProcStatus><CustomerProfileMessage>Profile Created</CustomerProfileMessage><RespTime>13055</RespTime><PartialAuthOccurred></PartialAuthOccurred><RequestedAmount></RequestedAmount><RedeemedAmount></RedeemedAmount><RemainingBalance></RemainingBalance><CountryFraudFilterStatus></CountryFraudFilterStatus><IsoCountryCode></IsoCountryCode></NewOrderResp>""" xml_object = objectify.fromstring(xml_string) print xml_object.__dict__ 

Преобразование объекта xml в dict приведет к возврату dict:

 {'RemainingBalance': u'', 'AVSRespCode': u'', 'RequestedAmount': u'', 'AccountNum': 3456732800000010, 'IsoCountryCode': u'', 'HostCVV2RespCode': u'', 'TerminalID': 31, 'CVV2RespCode': u'', 'RespMsg': u'', 'CardBrand': 'AMEX', 'MerchantID': 700000005894, 'RespCode': u'', 'ProfileProcStatus': 0, 'CustomerName': 'BOB STEVEN', 'PartialAuthOccurred': u'', 'MessageType': 'R', 'ProcStatus': 0, 'TxRefIdx': 10, 'RecurringAdviceCd': u'', 'IndustryType': u'', 'OrderID': 'TESTORDER1', 'StatusMsg': u'', 'ApprovalStatus': 1, 'RedeemedAmount': u'', 'CountryFraudFilterStatus': u'', 'TxRefNum': '55A69B278025130CD36B3A95435AA84DC45363', 'CustomerRefNum': 'A51C5B2B1811E5991208', 'CustomerProfileMessage': 'Profile Created', 'AuthCode': u'', 'RespTime': 13055, 'HostAVSRespCode': u'', 'CAVVRespCode': u'', 'HostRespCode': u''} 

Строка xml, которую я использовал, является ответом от шлюза платежей платежей, чтобы показать пример реального мира.

Также обратите внимание, что приведенный выше пример не является рекурсивным, поэтому, если в dicts есть dicts, вы должны сделать некоторую рекурсию. См. Рекурсивную функцию, которую я написал, которую вы можете использовать:

 from lxml import objectify 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 def xml_to_dict(xml_str): return xml_to_dict_recursion(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) 

Heres вариант, который сохраняет родительский ключ / элемент:

 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)} 

И если вы хотите только вернуть поддерево и преобразовать его в dict, вы можете использовать Element.find () :

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

Есть много вариантов для этого, но это здорово, если вы уже используете lxml. В этом примере использовался lxml-3.4.2.

  • Поиск нерекурсивной подузлы DOM в Python с использованием BeautifulSoup
  • Редактировать XML с помощью python
  • xml.sax парсер и номера строк и т. д.
  • Python - что быстрее разбирать Json или XML?
  • Анализ всех XML-файлов в каталоге и всех подкаталогах
  • разбор XML-файла для неизвестных элементов с помощью python ElementTree
  • lxml etree xmlparser удаляет ненужное пространство имен
  • Разбор XML для получения описания с использованием python с использованием minidom
  • Python - лучший язык программирования в мире.