Some while ago a (now-ex) colleague introduced me to a Python class he called DictObject. Data stored in this object can be accessed via attributes or array suffixes, thus:
foo.bar is the same as foo["bar"].
I've taken this further, building in some support for nesting, and for parsing either JSON style objects or element tree XML that was itself parsed by LXML. Now, I can use LXML to parse this XML:
<foo> <bar a="123" b="223"> <baz>the end</baz> </bar> </foo>
and it will return an object such that:
foo.bar.a = "123" foo.bar.baz = "the end"
Likewise, this code:
a = {"a":{"b": 3, "c":4, "x":["aa", "bb", "cc"]}, "d":123}
b = DictObject(json = a)
print b.a.x[2]
produces "cc".
This makes working with restful web services much faster to code with, whether they return JSON or XML.
Here's the class itself.
from lxml import etree
class DictObject(dict):
def __init__(self, xml = None, json = None):
dict.__init__(self)
self.__dict__ = self
if json is not None:
for key, val in json.items():
if isinstance(val, dict):
val = DictObject(json=val)
self[key]=val
if xml is not None:
for attrib in xml.attrib:
self[attrib] = xml.attrib[attrib]
for child in xml.getchildren():
if len(child.attrib)==0 and len(child.getchildren())==0:
self[child.tag]=child.text
else:
self[child.tag] = DictObject(xml = child)