How to Convert an Xml String to a Dictionary

How to convert an XML string to a dictionary?

This is a great module that someone created. I've used it several times.
http://code.activestate.com/recipes/410469-xml-as-dictionary/

Here is the code from the website just in case the link goes bad.

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

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)

convert xml to python dict

You can make use of xmltodict module:

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']

which produces an OrderedDict:

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

which can be converted to dict if order doesn't matter:

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

Prints:

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

Converting an XML-document to a dictionary

You could use linq to xml to do what you want (if I understand what you want)

string data = "<data><test>foo</test><test>foobbbbb</test><bar>123</bar><username>foobar</username></data>";

XDocument doc = XDocument.Parse(data);
Dictionary<string, string> dataDictionary = new Dictionary<string, string>();

foreach (XElement element in doc.Descendants().Where(p => p.HasElements == false)) {
int keyInt = 0;
string keyName = element.Name.LocalName;

while (dataDictionary.ContainsKey(keyName)) {
keyName = element.Name.LocalName + "_" + keyInt++;
}

dataDictionary.Add(keyName, element.Value);
}

Convert XML into dictionary

I suggest you construct a list of dicts, instead of a dict of lists like:

result_list = []
for item in tree.findall("./node"):
dictionary = {}
dictionary['id'] = item.get('id')
dictionary['lat'] = item.get('lat')
dictionary['lon'] = item.get('lon')
result_list.append(dictionary)

Or as a couple of comprehensions like:

result_list = [{k: item.get(k) for k in ('id', 'lat', 'lon')}
for item in tree.findall("./node")]

And for the nested case:

result_list = [{k: (item.get(k) if k != 'tags' else
{i.get('k'): i.get('v') for i in item.iter('tag')})
for k in ('id', 'lat', 'lon', 'tags')}
for item in tree.findall("./node")]

Results:

{
'id': '2188497873',
'lat': '52.5053306',
'lon': '13.4360114',
'tags': {
'alt_name': 'Spreebalkon',
'name': 'Brommybalkon',
'tourism': 'viewpoint',
'wheelchair': 'yes'
}
}

Convert XML to dictionary in Python using lxml

Personally I like xmltodict from here. With pip you can install it like so pip install xmltodict.

Note that this actually creates OrderedDict objects. Example usage:

import xmltodict as xd

with open('test.xml','r') as f:
d = xd.parse(f)

Converting xml to dictionary using ElementTree

def etree_to_dict(t):
d = {t.tag : map(etree_to_dict, t.iterchildren())}
d.update(('@' + k, v) for k, v in t.attrib.iteritems())
d['text'] = t.text
return d

Call as

tree = etree.parse("some_file.xml")
etree_to_dict(tree.getroot())

This works as long as you don't actually have an attribute text; if you do, then change the third line in the function body to use a different key. Also, you can't handle mixed content with this.

(Tested on LXML.)

ASP.NET convert xml string to dictionary

I'm sure there is probably a more elegant solution but this would do it:

Function

IDictionary<string, string> XmlToDictionary(string data)
{
XElement rootElement = XElement.Parse(data);
var names = rootElement.Elements("Key").Elements("Name").Select(n => n.Value);
var values = rootElement.Elements("Key").Elements("Value").Select(v => v.Value);
var list = names.Zip(values, (k, v) => new { k, v }).ToDictionary(item => item.k, item => item.v);
return list;
}

Test

var xmlString = @"<Tags>
<Key>
<Name>Model</Name>
<Value>Raggae</Value>
</Key>
<Key>
<Name>Rate</Name>
<Value>21</Value>
</Key>
</Tags>";

Console.WriteLine(XmlToDictionary(xmlString));

How to convert an xml to a dictionary with some modifications?

I would say that the right way is to prepare the needed XML structure - then just convert it to dict and json string:

Complex approach:

import xml.etree.ElementTree as ET
import xmltodict
import json

tree = ET.parse('gardenlist.xml')
root = tree.getroot()

state_el = ET.Element('state') # prepare `state` node
state_el.text = '0'
root.insert(1, state_el)

def add_state(root, el_to_insert):
for el in root:
if len(list(el)): # check if element has child nodes
el.insert(1, el_to_insert)
add_state(el, el_to_insert)

add_state(root, state_el)
json_str = json.dumps(xmltodict.parse(ET.tostring(root, encoding="unicode")), indent=4)
print(json_str)

The actual output:

{
"Garden": {
"id": "97",
"state": "0",
"Flowers": {
"id": "98",
"state": "0",
"Type": {
"id": "99",
"state": "0",
"Level": {
"id": "100",
"state": "0"
}
}
}
}
}

Convert XML to python dictionary

This can be done using the BeautifulSoup module.

The code is self-explanatory:

  • Search for the tag by its name using the find_all() method.
  • Create a dictionary where the key is the name of the tag found, and the value is the text of the tag.


from bs4 import BeautifulSoup

xml = """<?xml version="1.0" encoding="UTF-8"?>
<flowSegmentData version="traffic-service 4.0.011">
<frc>FRC0</frc>
<currentSpeed>78</currentSpeed>
<freeFlowSpeed>78</freeFlowSpeed>
<currentTravelTime>19</currentTravelTime>
<freeFlowTravelTime>19</freeFlowTravelTime>
<confidence>0.980000</confidence>
<roadClosure>false</roadClosure>
<coordinates>
<coordinate>"""

soup = BeautifulSoup(xml, "html.parser")

print({tag.name: tag.text for tag in soup.find_all("currentspeed")})

Output:

{'currentspeed': '78'}


Related Topics



Leave a reply



Submit