comparing two xmls using xmlunit ignorng their order

1.2k views Asked by At

I have two xml files which I need to compare using xmlunit

content of these xml files are always same except their order

ex:

 <report>
     <component name = "a">
         <component name = "b"/>
         <component name = "c"/>
     </component>
</report>

Here the order of the inside component may be different like below

<report>
     <component name = "a">
         <component name = "c"/>
         <component name = "b"/>
     </component>
</report>

When I compare these two xml I want diff.similar() to be true.

What I tried so far is

try(FileInputStream fileStream1 = new FileInputStream(expXMLPath)) {
        try(FileInputStream fileStream2 = new FileInputStream(genXMLPath)) {
            InputSource inputSource1 = new InputSource(fileStream1);
            InputSource inputSource2 = new InputSource(fileStream2);
            diff = new Diff(inputSource1, inputSource2);
            RegDiffListener ignorableElementsListener = new RegDiffListener(
                    ignorableXPathsRegex);
            diff.overrideDifferenceListener(ignorableElementsListener);
            diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
            diff.overrideElementQualifier(new MultiLevelElementNameAndTextQualifier(1, true));
            diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
            // diff.overrideElementQualifier(new
            // ElementNameAndTextQualifier());
            return diff;
        }

I tried with different option of overrideElementQualifier and nothing is working. Please let me know the solution.

1

There are 1 answers

0
SubOptimal On

Using the solution mentioned by RC XMLUnit treat the documents as similar.

If you want them to be treated as identical one solution could be to implement an DifferenceListener which ignores attribute differences at those nodes. Finde below a snippet for demonstration.

import java.io.FileInputStream;
import java.io.IOException;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.DifferenceConstants;
import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class IgnoreOrder {

    public static void main(String[] args) throws IOException, SAXException {
        try (FileInputStream fileStream1 = new FileInputStream("file1.xml");
                FileInputStream fileStream2 = new FileInputStream("file2.xml")) {
            InputSource inputSource1 = new InputSource(fileStream1);
            InputSource inputSource2 = new InputSource(fileStream2);
            Diff diff = new Diff(inputSource1, inputSource2);
            // to treat the files as identical
            diff.overrideDifferenceListener(new IgnoreAttributeDifference());
            // to treat the files as similar
            // diff.overrideElementQualifier(
            //     new ElementNameAndAttributeQualifier());
            System.out.println("identical: " + diff.identical());
            System.out.println("similar  : " + diff.similar());
        }
    }

    /**
     * Ignores attribute differences on node
     * "/report[\d+]/component[\d+]/component[\d+]/@name"
     */
    private static class IgnoreAttributeDifference 
        implements DifferenceListener {

        @Override
        public int differenceFound(Difference difference) {
            String xpathPattern = 
               "/report\\[\\d+\\]/component\\[\\d+\\]/component\\[\\d+\\]/@name";
            String controlXpath = difference.getControlNodeDetail()
                .getXpathLocation();
            String testXpath = difference.getTestNodeDetail()
                .getXpathLocation();
            if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID
                    && controlXpath.matches(xpathPattern)
                    && testXpath.matches(xpathPattern)) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            } else {
                return RETURN_ACCEPT_DIFFERENCE;
            }
        }

        @Override
        public void skippedComparison(Node node, Node node1) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}

output using diff.overrideElementQualifier(new ElementNameAndAttributeQualifier())

identical: false
similar  : true

output using diff.overrideDifferenceListener(new IgnoreAttributeDifference())

identical: true
similar  : true