Skip to content

Instantly share code, notes, and snippets.

@ifduyue
Last active February 5, 2021 14:05
Show Gist options
  • Save ifduyue/602af57a623c1b38bb89d83fd6fb81ab to your computer and use it in GitHub Desktop.
Save ifduyue/602af57a623c1b38bb89d83fd6fb81ab to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
#coding: utf8
#
#
# xml2dict
# ============
#
# Convert XML to dict.
#
from xml.etree import cElementTree as ElementTree
from collections import OrderedDict
def xml2dict(xmlstring, strip=True, dict_constructor=OrderedDict):
'''Convert XML to JSON
<foo /> => {'foo': None}
<foo>bar</foo> => {'foo': 'bar'}
<foo id="1">bar</foo> => {'foo': {'#text': 'bar', '@id': '1'}}
<foo id="1"> {'foo': {'a': '1',
foo '#text': 'foo',
<a>1</a> => 'b': {'#tail': 'bar',
<b>2</b> '#text': '2'},
bar '@id': '1'}}
</foo>
'''
def parse_item(item, strip, dict_constructor):
'''Parse every single XML item'''
d = dict_constructor()
for k, v in item.attrib.items():
d['@'+k] = v
for child in item:
cd = parse_item(child, strip=strip, dict_constructor=dict_constructor)
tag = child.tag
v = cd[tag]
if tag in d:
try:
d[tag].append(v)
except AttributeError:
d[tag] = [d[tag], v]
else:
d[tag] = v
if strip:
if item.tail:
item.tail = item.tail.strip()
if item.text:
item.text = item.text.strip()
if item.tail:
d['#tail'] = item.tail
if d and item.text:
d['#text'] = item.text
if not d:
d = item.text
return {item.tag: d}
try:
xml = ElementTree.fromstring(xmlstring)
return parse_item(xml, strip=strip, dict_constructor=dict_constructor)
except ElementTree.ParseError:
return None
if __name__ == '__main__':
import sys, json
xmlstring = sys.stdin.read()
d = xml2dict(xmlstring)
json.dump(d, sys.stdout, indent=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment