Skip to content

Instantly share code, notes, and snippets.

Created January 24, 2014 16:02
Show Gist options
  • Save anonymous/8600215 to your computer and use it in GitHub Desktop.
Save anonymous/8600215 to your computer and use it in GitHub Desktop.

Revisions

  1. @invalid-email-address Anonymous created this gist Jan 24, 2014.
    68 changes: 68 additions & 0 deletions xml2dict.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    from functools import wraps
    from xml.etree import cElementTree as etree

    def coroutine(func):
    @wraps(func)
    def start(*args, **kwargs):
    cr = func(*args, **kwargs)
    cr.next()
    return cr

    return start


    @coroutine
    def builder(root):
    def process(parent, current, ctag, event, v1, v2):
    if event == 'start':
    tag = v1
    if tag[0] == '{':
    tag = tag.split('}', 1)[1]

    newnode = {}
    try:
    child = current[ctag]
    except KeyError:
    child = current[ctag] = []

    child.append(newnode)
    return (parent, current, ctag), newnode, tag
    elif event == 'data':
    print ctag, v1
    current[ctag] = v1
    return parent, current, ctag
    elif event == 'end':
    return parent

    parent, node, tag = (None, None, None), root, 'root'
    while node:
    event, v1, v2 = (yield)
    try:
    parent, node, tag = process(parent, node, tag, event, v1, v2)
    except Exception as e:
    import traceback
    traceback.print_exc()


    class DictBuilder:
    def __init__(self):
    self.result = {}
    self.builder = builder(self.result)

    def start(self, tag, attrib):
    self.builder.send(('start', tag, attrib))

    def data(self, data):
    self.builder.send(('data', data, None))

    def end(self, tag):
    self.builder.send(('end', tag, None))

    def close(self):
    return self.result


    def parsestring(xml):
    parser = etree.XMLParser(target=DictBuilder())
    parser.feed(xml)
    return parser.close()