Skip to content

Instantly share code, notes, and snippets.

@walkermatt
Forked from aisipos/objectifiedJson.py
Last active December 20, 2016 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save walkermatt/f747c666b42e787d9371 to your computer and use it in GitHub Desktop.
Save walkermatt/f747c666b42e787d9371 to your computer and use it in GitHub Desktop.
JSON encoder that can handle simple lxml objectify types, based on the original: https://gist.github.com/aisipos/345559, extended to accommodate encoding child nodes with the same tag name as a list.
import json
import lxml
from lxml import objectify
class ObjectifyJSONEncoder(json.JSONEncoder):
""" JSON encoder that can handle simple lxml objectify types,
based on the original: https://gist.github.com/aisipos/345559, extended
to accommodate encoding child nodes with the same tag name as a list.
Usage:
>>> import json
>>> import lxml
>>> from lxml import objectify
>>> obj = objectify.fromstring("<author><name>W. Shakespeare</name><play>Twelfth Night</play><play>As You Like It</play></author>")
>>> json.dumps(obj, cls=ObjectifyJSONEncoder)
'{"play": ["Twelfth Night", "As You Like It"], "name": "W. Shakespeare"}'
"""
def default(self, o):
if isinstance(o, lxml.objectify.IntElement):
return int(o)
if isinstance(o, lxml.objectify.NumberElement) or isinstance(o, lxml.objectify.FloatElement):
return float(o)
if isinstance(o, lxml.objectify.ObjectifiedDataElement):
return str(o)
if hasattr(o, '__dict__'):
# objectify elements act like dicts to allow access to child nodes
# via their tag name. If an element has more than one child of the
# same name the dict only contains the first value against the tag
# name; to ensure all children are encoded create a list of child
# node values and assign it to the key that matches their tag name.
d = o.__dict__.copy()
for k in d.keys():
if len(d[k]) > 1:
d[k] = [i for i in d[k]]
return d
return json.JSONEncoder.default(self, o)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment