I have a question regarding “Similar” and “Identical”. In the following example given on XMLUnit help page:
<author>Dan Brown</author>
<category></category>
And
<category></category>
<author>Dan Brown</author>
The output comes out to be:
Similar? true
Identical? false
***********************
Expected sequence of child nodes ’5′ but was ’7′ – comparing at /books[1]/book[1]/author[1] to at /books[1]/book[1]/author[1]
***********************
***********************
Expected sequence of child nodes ’7′ but was ’5′ – comparing at /books[1]/book[1]/category[1] to at /books[1]/book[1]/category[1]
***********************
My question how can we “NOT” include in the output such non-identical information? My problem is that I have a long xml documents to compare. There are cases, where the differences are related to orderring and in addition to others.
But when I get the total output, it gets kind of difficult to find the actual differences (non-orderring) related.
I have to manually skip the non-important information (orderring differences) from the actual differences for example if anything is missing in the reference documents or have different content etc.
Have said that, I read somewhere that such "orderring" problems can be solved with my own "custom DifferenceListener".
So I did the following, (the whole class):
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.util.List;
import org.w3c.dom.Node;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.custommonkey.xmlunit.DetailedDiff;
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.custommonkey.xmlunit.ElementNameAndTextQualifier;
import org.custommonkey.xmlunit.ElementNameQualifier;
import org.custommonkey.xmlunit.MatchTracker;
import org.custommonkey.xmlunit.NodeDetail;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.examples.MultiLevelElementNameAndTextQualifier;
import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
import org.xml.sax.SAXException;
public class XMLComparator {
public static void main(String[] args) {
URL url1 = XMLComparator.class.getResource("reference.xml");
URL url2 = XMLComparator.class.getResource("comparison.xml");
FileReader fr1 = null;
FileReader fr2 = null;
try {
fr1 = new FileReader(url1.getPath());
fr2 = new FileReader(url2.getPath());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
XMLUnit.setIgnoreComments(Boolean.TRUE);
XMLUnit.setIgnoreWhitespace(Boolean.TRUE);
XMLUnit.setNormalizeWhitespace(Boolean.TRUE);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(Boolean.TRUE);
XMLUnit.setIgnoreAttributeOrder(Boolean.TRUE);
XMLUnit.setCompareUnmatched(Boolean.FALSE);
try {
Diff diff = new Diff(fr1, fr2);
diff.overrideDifferenceListener(new DifferenceListener() {
@Override
public void skippedComparison(Node arg0, Node arg1) {
// TODO Auto-generated method stub
}
@Override
public int differenceFound(Difference diff) {
if (diff.getId() == DifferenceConstants.CHILD_NODELIST_SEQUENCE_ID)
{
return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
return RETURN_ACCEPT_DIFFERENCE;
}
});
System.out.println(" Similar ? " + diff.similar());
System.out.println(" Identical ? " + diff.identical());
DetailedDiff detDiff = new DetailedDiff(diff);
detDiff.overrideMatchTracker(new MatchTrackerImpl());
detDiff.overrideElementQualifier(new ElementNameAndTextQualifier());
List differences = detDiff.getAllDifferences();
for (Object object : differences) {
Difference difference = (Difference) object;
System.out.println("***********************");
System.out.println(difference);
System.out.println("***********************");
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MatchTrackerImpl implements MatchTracker {
public void matchFound(Difference difference) {
if (difference != null) {
NodeDetail controlNode = difference.getControlNodeDetail();
NodeDetail testNode = difference.getTestNodeDetail();
String controlNodeValue = printNode(controlNode.getNode());
String testNodeValue = printNode(testNode.getNode());
if (controlNodeValue != null) {
// System.out.println("####################");
// System.out.println("Control Node: " + controlNodeValue);
}
if (testNodeValue != null) {
// System.out.println("Test Node: " + testNodeValue);
// System.out.println("####################");
}
}
}
private static String printNode(Node node) {
if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
StringWriter sw = new StringWriter();
try {
Transformer t = TransformerFactory.newInstance()
.newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
} catch (TransformerException te) {
System.out.println("nodeToString Transformer Exception");
}
return sw.toString();
}
return null;
}
}
reference.xml
<?xml version="1.0" encoding="UTF-8"?>
<UsernameToken>
<OtherSrvcName>EXCURSION_AND_TICKETS</OtherSrvcName>
<OtherSrvcName>TRAVELGUIDE</OtherSrvcName>
</UsernameToken>
comparison.xml
<?xml version="1.0" encoding="UTF-8"?>
<UsernameToken>
<OtherSrvcName>TRAVELGUIDE</OtherSrvcName>
<OtherSrvcName>EXCURSION_AND_TICKETS</OtherSrvcName>
</UsernameToken>
The output:
Similar ? false
Identical ? false
This to some degree resolved my original problem, but my question is why Similar is false? Shouldn't it be 'true' ?
Secondly, on my slightly changing the XMLs, the entire output then yielded the same original response, which i am not interested in.
reference.xml
<?xml version="1.0" encoding="UTF-8"?>
<UsernameToken>
<OtherSrvcPref>
<OtherSrvcName>EXCURSION_AND_TICKETS</OtherSrvcName>
</OtherSrvcPref>
<OtherSrvcPref>
<OtherSrvcName>TRAVELGUIDE</OtherSrvcName>
</OtherSrvcPref>
</UsernameToken>
comparision.xml
<?xml version="1.0" encoding="UTF-8"?>
<UsernameToken>
<OtherSrvcPref>
<OtherSrvcName>TRAVELGUIDE</OtherSrvcName>
</OtherSrvcPref>
<OtherSrvcPref>
<OtherSrvcName>EXCURSION_AND_TICKETS</OtherSrvcName>
</OtherSrvcPref>
</UsernameToken>
Output:
Similar ? false
Identical ? false
***********************
Expected presence of child node 'OtherSrvcName' but was 'null' - comparing <OtherSrvcName...> at /UsernameToken[1]/OtherSrvcPref[1]/OtherSrvcName[1] to at null
***********************
***********************
Expected presence of child node 'null' but was 'OtherSrvcName' - comparing at null to <OtherSrvcName...> at /UsernameToken[1]/OtherSrvcPref[1]/OtherSrvcName[1]
***********************
***********************
Expected presence of child node 'OtherSrvcName' but was 'null' - comparing <OtherSrvcName...> at /UsernameToken[1]/OtherSrvcPref[2]/OtherSrvcName[1] to at null
***********************
***********************
Expected presence of child node 'null' but was 'OtherSrvcName' - comparing at null to <OtherSrvcName...> at /UsernameToken[1]/OtherSrvcPref[2]/OtherSrvcName[1]
***********************
Now why am i getting the 'Expected presence...' messages in the output? Shouldn't it just produce the same output as in the previous case, i.e.
Similar ? false
Identical ? false
I don't understand this difference in the behaviour of the output? Could someone please help me out here..
Thanks.