Skip to content

Instantly share code, notes, and snippets.

@baverman
Forked from anonymous/xml2dict.py
Last active January 4, 2016 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baverman/8600221 to your computer and use it in GitHub Desktop.
Save baverman/8600221 to your computer and use it in GitHub Desktop.
# Simple xml to dict parser
#
# It's usable only for small documents due low performance
# comparing with lxml
from xml.etree import cElementTree as etree
from cStringIO import StringIO
def builder(ptag, attrib, pchild):
child = []
data = StringIO()
def start(tag, attrib):
if tag[0] == '{':
tag = tag.split('}', 1)[1]
return builder(tag, attrib, child)
def fdata(value):
data.write(value)
def end():
cdata = data.getvalue().strip()
if not child and not attrib:
pchild.append((ptag, cdata))
else:
result = {}
for name, value in child:
try:
vlist = result[name]
except KeyError:
vlist = result[name] = []
vlist.append(value)
for k, v in result.iteritems():
if len(v) == 1 and isinstance(v[0], basestring):
result[k] = v[0]
if cdata:
result['#'] = cdata
if attrib:
result['$'] = attrib
pchild.append((ptag, result))
return start, fdata, end
class DictBuilder:
def __init__(self):
self.result = []
self.stack = []
self.s, self.d, self.e = builder('root', {}, self.result)
def start(self, tag, attrib):
self.stack.append((self.s, self.d, self.e))
self.s, self.d, self.e = self.s(tag, attrib)
def data(self, data):
self.d(data)
def end(self, tag):
self.e()
self.s, self.d, self.e = self.stack.pop()
def close(self):
self.e()
root = self.result[0][1]
return root[root.keys()[0]][0]
def parsestring(xml):
parser = etree.XMLParser(target=DictBuilder())
parser.feed(xml)
return parser.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment