Skip to content

Instantly share code, notes, and snippets.

@jcbsv
Last active March 16, 2017 09:34
Show Gist options
  • Save jcbsv/1a7f37e93e9f3d25470f27e15c365817 to your computer and use it in GitHub Desktop.
Save jcbsv/1a7f37e93e9f3d25470f27e15c365817 to your computer and use it in GitHub Desktop.
import json
from xml.etree import ElementTree
tree = ElementTree.parse('raml20.xml')
ns = {'ns': 'raml20.xsd'}
nsP, nsList, nsItem = ('{%s}%s' % (ns['ns'], i) for i in ('p', 'list', 'item'))
def pkv(o):
"""Return dict with name:text of p elements"""
return {k.attrib['name']: k.text for k in o.iter(nsP)}
def parse(tree):
root = tree.getroot()
objs = {}
for mo in root.findall('./ns:cmData/ns:managedObject', ns):
obj = pkv(mo)
for i in mo.iter(nsList):
obj[i.attrib['name']] = [pkv(j) for j in i.iter(nsItem)]
objs[mo.attrib['distName']] = obj
return objs
def diff_dicts(d1, d2, ignore_keys=set()):
"""Return dict with differences between the dicts provided as arguments"""
k1 = set(d1.keys())
k2 = set(d2.keys())
diff = {}
diff.update(
{i: (d1[i], d2[i]) for i in (k1 & k2) - ignore_keys if d1[i] != d2[i]})
diff.update({i: (d1.get(i), d2.get(i)) for i in (k1 ^ k2) - ignore_keys})
return diff
def diff_lists(l1, l2):
"""Return dict with differences between lists of dicts provided as arguments"""
diff = {}
# note: assumes that lists are of same length
for i, (d1, d2) in enumerate(zip(l1, l2)):
d = diff_dicts(d1, d2)
if d:
diff[i] = d
return diff
def diff_objects(o1, o2):
"""Return dict with differences between two objects (dicts) provided as arguments"""
listkeys = set(
i for o in (o1, o2) for i in o if isinstance(o.get(i), list))
diff = diff_dicts(o1, o2, listkeys)
for i in listkeys:
if i in o1 and i in o2:
diff.update({i: diff_lists(o1[i], o2[i])})
else:
diff.update({i: (o1.get(i), o2.get(i))})
return diff
def compare_objects(reference, objs):
diffs = []
for k, o in objs.items():
diff = diff_objects(reference, o)
if diff:
diffs.append((k, diff))
return diffs
reference = ... # set your reference object here
res = compare_objects(reference, parse(tree))
print(json.dumps(res, indent=2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment