Source code for inkex.tester.xmldiff

#
# Copyright 2011 (c) Ian Bicking <ianb@colorstudy.com>
#           2019 (c) Martin Owens <doctormo@gmail.com>
#
# Taken from http://formencode.org under the GPL compatible PSF License.
# Modified to produce more output as a diff.
#
"""
Allow two xml files/lxml etrees to be compared, returning their differences.
"""

[docs]def text_compare(test1, test2): """ Compare two text strings while allowing for '*' to match anything on either lhs or rhs. """ if not test1 and not test2: return True if test1 == '*' or test2 == '*': return True return (test1 or '').strip() == (test2 or '').strip()
[docs]def xmldiff(xml1, xml2): """Create an xml difference, will modify the first xml structure with a diff""" clean = True #if reporter is None: # reporter = print_reporter if xml1.tag != xml2.tag: xml1.tag = '{}XXX{}'.format(xml1.tag, xml2.tag) clean = False #reporter('Tags do not match: %s and %s' % (xml1.tag, xml2.tag)) for name, value in xml1.attrib.items(): if name not in xml2.attrib: xml1.attrib[name] += "XXX" clean = False elif xml2.attrib.get(name) != value: xml1.attrib[name] = "{}XXX{}".format(xml1.attrib.get(name), xml2.attrib.get(name)) clean = False #return reporter('Attributes do not match: %s=%r, %s=%r' # % (name, value, name, xml2.attrib.get(name))) for name, value in xml2.attrib.items(): if name not in xml1.attrib: xml1.attrib[name] = "XXX" + value clean = False #return reporter('xml2 has an attribute xml1 is missing: %s' # % name) if not text_compare(xml1.text, xml2.text): xml1.text = "{}XXX{}".format(xml1.text, xml2.text) clean = False #return reporter('text: %r != %r' % (xml1.text, xml2.text)) if not text_compare(xml1.tail, xml2.tail): xml1.tail = "{}XXX{}".format(xml1.tail, xml2.tail) clean = False #return reporter('tail: %r != %r' % (xml1.tail, xml2.tail)) # Get children and pad with nulls children_a = list(xml1) children_b = list(xml2) children_a += [None] * (len(children_a) - len(children_b)) children_b += [None] * (len(children_b) - len(children_a)) for child_a, child_b in zip(children_a, children_b): if child_a is None: # child_b exists child_c = child_b.clone() child_c.tag = 'XXX' + child_c.tag xml1.append(child_c) clean = False elif child_b is None: # child_a exists child_a.tag += 'XXX' clean = False else: clean = xmldiff(child_a, child_b) and clean return clean
if __name__ == '__main__': import sys import xml.etree.ElementTree as xml XMLA = xml.parse(sys.argv[1]) XMLB = xml.parse(sys.argv[2]) xmldiff(XMLA.getroot(), XMLB.getroot()) print(xml.tostring(XMLA.getroot()).decode('utf-8'))