-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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