#!/usr/bin/python import xml.etree.ElementTree from sys import argv, exit if len(argv) < 3: print 'Usage: xmldiff.py ' exit(1) # Helper functions to reduce duplication def ensureKey(dictionary, key, init): if key not in dictionary: dictionary[key] = init() def add(dictionary, key, value, index): ensureKey(dictionary, key, lambda: [None, None]) dictionary[key][index] = value ours = xml.etree.ElementTree.parse(argv[1]).getroot().find('events') theirs = xml.etree.ElementTree.parse(argv[2]).getroot().find('events') # Collect every event on either side byHandle = {} for e in ours: add(byHandle, e.find('handle').text, e, 0) for e in theirs: add(byHandle, e.find('handle').text, e, 1) # 0: only ours, 1: only theirs, 2: identical results = [[], [], []] differences = {} for key, value in byHandle.items(): # event exists only on one side if value[0] is None: results[0].append(key) continue elif value[1] is None: results[1].append(key) continue # event exists on both sides, compare each subelement subelements = {} for se in value[0]: add(subelements, se.tag, xml.etree.ElementTree.tostring(se), 0) for se in value[1]: add(subelements, se.tag, xml.etree.ElementTree.tostring(se), 1) match = True for sekey, sevalue in subelements.items(): ensureKey(differences, key, list) if sevalue[0] is None: differences[key].append(sekey + ' only in ' + argv[1]) match = False elif sevalue[1] is None: differences[key].append(sekey + ' only in ' + argv[2]) match = False elif sevalue[0] != sevalue[1]: differences[key].append(sekey + ' differs') match = False if match: results[2].append(key) # Print results in groups print 'Elements only in ' + argv[1] + ' (' + str(len(results[0])) + '):' for e in results[0]: print ' ' + e print print 'Elements only in ' + argv[2] + ' (' + str(len(results[1])) + '):' for e in results[1]: print ' ' + e print print 'Elements identical in both (' + str(len(results[2])) + '):' for e in results[2]: print ' ' + e print print 'Elements with differences (' + str(len([l for k, l in differences.items() if len(differences[k]) > 0])) + '):' for e, d in differences.items(): if len(d) < 1: continue print ' ' + e for s in d: print(' ' + s) print