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());
4
  • convert them to Java objects and run the equals method Commented Sep 18, 2019 at 12:55
  • take the two object into the hashmap and compare both Commented Sep 18, 2019 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. Commented Sep 18, 2019 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. Commented Sep 19, 2019 at 5:41

2 Answers 2

4

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


Sign up to request clarification or add additional context in comments.

1 Comment

Unfortunately it wouldn't work if the node that proves equality is deeply nested.
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.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.