Search code examples
javaxmlxmlunit

XML file comparison in JAVA ignoring node order


I wanted to compare the xml files using JAVA and check if they are "equivalent". The below code works for me in 2 cases:

  1. When the xml files are exactly same.
  2. When the xml file has difference

But fails when:

  1. XML files contain the same nodes but they are not in the same order.

One file called Sample.xml having the content as:

<Employee>
    <FirstName>Jack</FirstName>
    <LastName>Dave</LastName>
    <Age>21</Age>
    <Professtion>Doctor</Professtion>
</Employee>

Another file called Sample1.xml having the content as:

<Employee>
    <Age>21</Age>
    <Professtion>Doctor</Professtion>
    <FirstName>Jack</FirstName>
    <LastName>Dave</LastName>
</Employee>

Note the content is the same but the order is not.

I tried [this1] but it didn't work for me.

The code I tried follows:

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.List;

import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;

public class CompareXML {

    public static void main(String[] args) {

        try (BufferedReader bufferedReaderExistingFile = new BufferedReader(new FileReader("C:\\Test\\Sample.xml"));
                BufferedReader bufferedReaderNewFile = new BufferedReader(new FileReader("C:\\Test\\Sample1.xml"))) {

            XMLUnit.setIgnoreWhitespace(true);
            XMLUnit.setIgnoreAttributeOrder(true);
            XMLUnit.setIgnoreComments(true);

            Diff d = new Diff(bufferedReaderExistingFile, bufferedReaderNewFile); 
            d.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
            DetailedDiff detailedDiff = new DetailedDiff(d);
            List<?> allDifferences1 = detailedDiff.getAllDifferences();

            System.out.println("  difference are :: " + allDifferences1.isEmpty());
            System.out.println("  difference are :: " + allDifferences1.size());
            System.out.println("  difference are :: " + allDifferences1.toString());

        }catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }

}

I have also tried the below code :

Diff diff = DiffBuilder.compare(bufferedReaderExistingFile)
    .withTest(bufferedReaderNewFile).ignoreComments()
    .ignoreWhitespace()
    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
    .checkForSimilar()
    .build();

System.out.println("  difference are :: " + diff.hasDifferences());

Solution

  • You can do this with DifferenceEvaluators:

    DifferenceEvaluator evaluator = DifferenceEvaluators
      .downgradeDifferencesToEquals(ComparisonType.CHILD_NODELIST_SEQUENCE);
    
    
    
    Diff diff = DiffBuilder.compare(bufferedReaderExistingFile)
        .withTest(bufferedReaderNewFile).ignoreComments()
        .ignoreWhitespace()
        .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
        .withDifferenceEvaluator(evaluator)
        .checkForSimilar()
        .build();