Python Function For Xml List
I have parsed XML file looking like this. Maybe I just didn't copy well,but it's ok, so, here it is:
Solution 1:
Here is a solution that parse the XML file, and compares each managedObject with all others, and print out the resulting diff object.
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'))
defpkv(o):
"""Return dict with name:text of p elements"""return {k.attrib['name']: k.text for k in o.iter(nsP)}
defparse(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
defdiff_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
defdiff_lists(l1, l2):
"""Return dict with differences between lists of dicts provided as arguments"""
diff = {}
# note: assumes that lists are of same lengthfor i, (d1, d2) inenumerate(zip(l1, l2)):
d = diff_dicts(d1, d2)
if d:
diff[i] = d
return diff
defdiff_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 ifisinstance(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
defcompare_objects(objs):
diffs = []
keys = list(objs)
for k1, k2 inzip(keys[:-1], keys[1:]):
o1, o2 = objs[k1], objs[k2]
diff = diff_objects(o1, o2)
if diff:
diffs.append((k1, k2, diff))
return diffs
res = compare_objects(parse(tree))
print(json.dumps(res, indent=2))
I've tested with the following raml20.xml
file:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ramlSYSTEM'raml20.dtd'><ramlversion="2.0"xmlns="raml20.xsd"><cmDatatype="actual"><managedObjectclass="LN"distName="PTR"id="2425"><pname="aak">220</p><pname="orp">05</p><pname="name">Portro</p><pname="optres">false</p><pname="optblu">false</p><pname="aoptdet">false</p><pname="advcell">false</p><listname="sibList"><item><pname="sibcity">177</p><pname="sibrep">2</p></item><item><pname="sibcity">177</p><pname="sibrep">1</p></item></list></managedObject><managedObjectclass="LN"distName="KRNS"id="93886"><pname="aak">150</p><pname="orp">05</p><pname="name">Portro</p><pname="optres">false</p><pname="optblu">tru</p><pname="aoptdet">false</p><pname="advcell">true</p><listname="sibList"><item><pname="sibcity">177</p><pname="sibrep">1</p></item><item><pname="sibcity">180</p><pname="sibrep">2</p></item></list></managedObject></cmData></raml>
The resulting diff object is:
[["PTR","KRNS",{"advcell":["false","true"],"optblu":["false","tru"],"sibcity":["177","180"],"aak":["220","150"],"sibrep":["1","2"],"sibList":{"0":{"sibrep":["2","1"]},"1":{"sibcity":["177","180"],"sibrep":["1","2"]}}}]]
Post a Comment for "Python Function For Xml List"