2

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());
Lluís Suñol
  • 3,466
  • 3
  • 22
  • 33
Abhijit Bashetti
  • 8,518
  • 7
  • 35
  • 47
  • convert them to Java objects and run the equals method – Stultuske Sep 18 '19 at 12:55
  • take the two object into the hashmap and compare both – Ganesh Gudghe Sep 18 '19 at 13:41
  • @stultuske this won't work. First of all, you don't need to convert nothing to Object in java as all non-primitive data types always inherit from Object, so you can always call the equals method. In any case, the equals returns true only when the two values refer to the same object. – Lluís Suñol Sep 18 '19 at 13:52
  • @LluísSuñol I said nothing about converting to Object. Neither did I say this was the best way to go, it was an option, which is why I posted it as a comment, not as an answer. – Stultuske Sep 19 '19 at 05:41

2 Answers2

2

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();


kutschkem
  • 7,826
  • 3
  • 21
  • 56
1

You can use the similar() method from Diff, as said in the documentation:

Return the result of a comparison. Two documents are considered to be "similar" if they contain the same elements and attributes regardless of order.

Your code could be something like this:

Diff diff = XMLUnit.compareXML(bufferedReaderExistingFile, bufferedReaderNewFile);
System.out.println("Both documents are similar: " + diff.similar());

Note though that order in XML matters, so the two XML samples you presented are essentially different XML.

Lluís Suñol
  • 3,466
  • 3
  • 22
  • 33
  • It's perfectly reasonable to design an XML vocabulary in which order of elements is deemed to have no semantic significance, and therefore to attempt a comparison that ignores element order. – Michael Kay Sep 18 '19 at 14:04