Compare XML snippets? Compare XML snippets? xml xml

Compare XML snippets?


You can use formencode.doctest_xml_compare -- the xml_compare function compares two ElementTree or lxml trees.


The order of the elements can be significant in XML, this may be why most other methods suggested will compare unequal if the order is different... even if the elements have same attributes and text content.

But I also wanted an order-insensitive comparison, so I came up with this:

from lxml import etreeimport xmltodict  # pip install xmltodictdef normalise_dict(d):    """    Recursively convert dict-like object (eg OrderedDict) into plain dict.    Sorts list values.    """    out = {}    for k, v in dict(d).iteritems():        if hasattr(v, 'iteritems'):            out[k] = normalise_dict(v)        elif isinstance(v, list):            out[k] = []            for item in sorted(v):                if hasattr(item, 'iteritems'):                    out[k].append(normalise_dict(item))                else:                    out[k].append(item)        else:            out[k] = v    return outdef xml_compare(a, b):    """    Compares two XML documents (as string or etree)    Does not care about element order    """    if not isinstance(a, basestring):        a = etree.tostring(a)    if not isinstance(b, basestring):        b = etree.tostring(b)    a = normalise_dict(xmltodict.parse(a))    b = normalise_dict(xmltodict.parse(b))    return a == b


Here a simple solution, convert XML into dictionaries (with xmltodict) and compare dictionaries together

import jsonimport xmltodictclass XmlDiff(object):    def __init__(self, xml1, xml2):        self.dict1 = json.loads(json.dumps((xmltodict.parse(xml1))))        self.dict2 = json.loads(json.dumps((xmltodict.parse(xml2))))    def equal(self):        return self.dict1 == self.dict2

unit test

import unittestclass XMLDiffTestCase(unittest.TestCase):    def test_xml_equal(self):        xml1 = """<?xml version='1.0' encoding='utf-8' standalone='yes'?>        <Stats start="1275955200" end="1276041599">        </Stats>"""        xml2 = """<?xml version='1.0' encoding='utf-8' standalone='yes'?>        <Stats end="1276041599" start="1275955200" >        </Stats>"""        self.assertTrue(XmlDiff(xml1, xml2).equal())    def test_xml_not_equal(self):        xml1 = """<?xml version='1.0' encoding='utf-8' standalone='yes'?>        <Stats start="1275955200">        </Stats>"""        xml2 = """<?xml version='1.0' encoding='utf-8' standalone='yes'?>        <Stats end="1276041599" start="1275955200" >        </Stats>"""        self.assertFalse(XmlDiff(xml1, xml2).equal())

or in simple python method :

import jsonimport xmltodictdef xml_equal(a, b):    """    Compares two XML documents (as string or etree)    Does not care about element order    """    return json.loads(json.dumps((xmltodict.parse(a)))) == json.loads(json.dumps((xmltodict.parse(b))))