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 thevalue
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
How to Pass a Method as a Parameter in Python
How to Check a String for Specific Characters
How to Check If There Are Duplicates in a Flat List
Label Python Data Points on Plot
How to Get First Element in a List of Tuples
Python Sharing a Lock Between Processes
Cmd Opens Windows Store When I Type 'Python'
How to Decode Base64 Data in Python
Matplotlib Scatter Plot Legend
Run Python Script Without Windows Console Appearing
Sorting Columns in Pandas Dataframe Based on Column Name
How to Get a List of All Classes Within Current Module in Python
How to Build Multiple Submit Buttons Django Form
Converting Epoch Time into the Datetime