Skip to content Skip to sidebar Skip to footer

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"