You can use lxml library . Convert the string to an xml object using objectify.fromstring , and then find the dir method of the objects. For instance:
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__ / StatusMsg> <RespMsg> </ RespMsg> <HostRespCode> </ HostRespCode> <HostAVSRespCode> </ HostAVSRespCode> <HostCVV2RespCode> </ HostCVV2RespCode> <CustomerRefNum> A51C5B2B1811E5991208 </ CustomerRefNum> <CustomerName> 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__
Converting an xml object to a dict will return a 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''}
The xml line I used is a response from a payment payment gateway to show a real-world example.
Also note that the above example is not recursive, so if there are dicts in dicts, you should do some recursion. See the Recursive function I wrote that you can use:
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)
Here is an option that saves the parent key / element:
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:
And if you only want to return the subtree and convert it to a dict, you can use Element.find ():
xml_obj.find('.//')
There are many options for this, but this is great if you are already using lxml. In this example, lxml-3.4.2 was used. Thanks!