I am using XMLUnit to compare two XMLs to detect the updates. My pom is as :
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.6</version>
</dependency>
For most of the scenarios, XMLUnit is working fine except few where the given differences are wrong or unexpected. Lets take first the positive scenario where the XMLUnit is working correct :
Case-1:
XML-Original:
<ClassHours>
<Hours close="11:10" day="27" classname="sec-1" open="17:20" noOfStudent="23"/>
<Hours close="11:10" day="28" classname="sec-2" open="17:20" noOfStudent="43"/>
<Hours close="11:10" day="21" classname="sec-3" open="17:20" noOfStudent="12"/>
<Hours close="11:10" day="1" classname="sec-4" open="17:20" noOfStudent="54"/>
<Hours close="11:10" day="25" classname="sec-5" open="17:20" noOfStudent="22"/>
<Hours close="11:10" day="1" classname="sec-6" open="17:20" noOfStudent="10"/> s
</ClassHours>
XML-Updated:
<ClassHours>
<Hours close="18:00" day="27" classname="sec-1" open="10:00" noOfStudent="23"/>
<Hours close="18:00" day="28" classname="sec-2" open="10:00" noOfStudent="43"/>
<Hours close="18:00" day="21" classname="sec-3" open="10:00" noOfStudent="12"/>
<Hours close="18:00" day="1" classname="sec-4" open="10:00" noOfStudent="54"/>
<Hours close="18:00" day="25" classname="sec-5" open="10:00" noOfStudent="22"/>
<Hours close="18:00" day="1" classname="sec-6" open="10:00" noOfStudent="10"/> s
</ClassHours>
as you can notice, the parent node contains multiple child nodes . For all the child nodes, the name and attribute is same and the only difference is in Open and Close attributes value. In this case the output is :
2019-12-24 19:53:28,093 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,093 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:53:28,093 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,093 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:53:28,093 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,095 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:53:28,096 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,096 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:53:28,096 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,096 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:53:28,097 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:53:28,097 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
Case-2:
XML-Original:
<ClassHours>
<Hours close="11:10" day="27" classname="sec-1" open="17:20" noOfStudent="23"/>
<Hours close="11:10" day="28" classname="sec-2" open="17:20" noOfStudent="43"/>
<Hours close="11:10" day="21" classname="sec-3" open="17:20" noOfStudent="12"/>
<Hours close="11:10" day="1" classname="sec-4" open="17:20" noOfStudent="54"/>
<Hours close="11:10" day="25" classname="sec-5" open="17:20" noOfStudent="22"/>
<Hours close="11:10" day="1" classname="sec-6" open="17:20" noOfStudent="10"/> s
</ClassHours>
XML-Updated:
<ClassHours>
<Hours close="18:00" day="28" classname="sec-2" open="10:00" noOfStudent="43"/>
<Hours close="18:00" day="21" classname="sec-3" open="10:00" noOfStudent="12"/>
<Hours close="18:00" day="27" classname="sec-1" open="10:00" noOfStudent="23"/>
<Hours close="18:00" day="1" classname="sec-4" open="10:00" noOfStudent="54"/>
<Hours close="18:00" day="25" classname="sec-5" open="10:00" noOfStudent="22"/>
<Hours close="18:00" day="1" classname="sec-6" open="10:00" noOfStudent="10"/> s
</ClassHours>
Here, again for all the child nodes, the name and attribute is same and the difference is in Open and Close attributes value. This time the sequence of the nodes is also updated as classname sec-3 row is shifted after sec-2. In this case the output is :
2019-12-24 19:54:31,737 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [classname], Before value : [sec-1], After value : [sec-2]]
2019-12-24 19:54:31,738 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,738 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [day], Before value : [27], After value : [28]]
2019-12-24 19:54:31,738 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [noOfStudent], Before value : [23], After value : [43]]
2019-12-24 19:54:31,738 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:54:31,740 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [classname], Before value : [sec-2], After value : [sec-3]]
2019-12-24 19:54:31,740 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,740 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [day], Before value : [28], After value : [21]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [noOfStudent], Before value : [43], After value : [12]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [classname], Before value : [sec-3], After value : [sec-1]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [day], Before value : [21], After value : [27]]
2019-12-24 19:54:31,741 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [noOfStudent], Before value : [12], After value : [23]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [close], Before value : [11:10], After value : [18:00]]
2019-12-24 19:54:31,742 INFO [main] (XMLDiffMain.java:107) - Node [/ClassHours/Hours, node attribute : [open], Before value : [17:20], After value : [10:00]]
here the output is wrong as the difference is in only in values, but XMLUnit is considering the sequence of the nodes as well and giving such output.
My code is :
LOGGER.debug("Comparing Actual and Expected XMLs");
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreAttributeOrder(true);
XMLUnit.setIgnoreComments(true);
DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML));
diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
return diff.getAllDifferences();
Can somebody tell me how I can fix this? I have also tried adding
diff.overrideDifferenceListener(new IgnoreTextAndAttributeValuesDifferenceListener());
diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
and still getting same results. Also I cannot control the sequence of the XML nodes as it is coming from some other external system. I need to get the fix to ignore sequence while comparing the nodes attributes.
Also, I already mentioned that this is the only case where XMLUnit is not working. For all other cases it is working as expected.
You are using the no-arg constructor of ElementNameAndAttributeQualifier
which means two elements are eligible to being compared if their names are the same and all their attributes have the same values. This is not true for any pair of elements in your example as the close
attributes are all different. So there are no matches at all.
In XMLUnit 1.x the default behavior is to match elements that haven't got a matching partner to match them in document order with those without partners from the test document. So in effect you are comparing elements in order.
One thing you can do is make the ElementNameAndAttributeQualifier
more specific by listing the attributes that you expect to keep the same values in the constructor. You probably also want to set XMLUnit.setCompareUnmatched
to false
so you won't trip over the bad default - or better, yet, switch to XMLUnit 2.x which unlike 1.x is actively maintained and will never compare unmatched nodes to each other.