Java Program To Compare Two XML's Ignoring Stanza Ordering
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLComparison {
public static void main(String s[]) throws ParserConfigurationException, SAXException, IOException{
compareTwoXMLS("<a><b>testb</b><c>testc</c></a>","<a><c>testc</c><b>testb</b></a>");
}
public static void compareTwoXMLS(String xml1, String xml2) throws ParserConfigurationException, SAXException, IOException {
//Convert the two xml's into two maps where each of the elements of XML along with the number of occurrences is listed
//key will be XPATH of element appended with its value and Value will be the number of occurrences of that element.
Map<String, Long> mapElementsOfXML1 = getMapOfElementsOfXML(xml1);
Map<String, Long> mapElementsOfXML2 = getMapOfElementsOfXML(xml2);
final Iterator<String> iteratorKeySet = mapElementsOfXML1.keySet().iterator();
//Now compare the two maps,clearing the elements which are there in both the maps.
while (iteratorKeySet.hasNext()) {
final String next = iteratorKeySet.next();
if (next != null)
if (mapElementsOfXML1.get(next).equals(mapElementsOfXML2.get(next))) {
mapElementsOfXML2.remove(next);
iteratorKeySet.remove();;
}
}
StringBuilder diffString = new StringBuilder();
diffString.append("Elements in XML1 but not found in XML2 ::");
for (String key : mapElementsOfXML1.keySet()) {
diffString.append(key + mapElementsOfXML1.get(key) + "\r\n");
}
diffString.append("Elements in XML2 but not found in XML1 ::" + "\r\n");
for (String key : mapElementsOfXML2.keySet()) {
diffString.append(key + mapElementsOfXML2.get(key) + "\r\n");
}
if (!mapElementsOfXML1.isEmpty() || !mapElementsOfXML2.isEmpty()) {
System.out.println("Difference between XML1 and XML2::" + diffString.toString());
}else{
System.out.println("Both XML's are identical ");
}
}
/**
* creates a map of elements with text values and no nested nodes.<br>
* Here Key of the map is XPATH of element concatenated with the text value of element, value of the element is number of occurrences of that element.<br>
*
* @param xmlContent
* @return
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
private static Map<String, Long> getMapOfElementsOfXML(String xmlContent)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc1 = db.parse(new ByteArrayInputStream(xmlContent.getBytes()));
NodeList entries = doc1.getElementsByTagName("*");
Map<String, Long> mapElements = new HashMap<>();
for (int i = 0; i < entries.getLength(); i++) {
Element element = (Element) entries.item(i);
if (element.getChildNodes().getLength() == 1&&element.getTextContent()!=null) {
final String elementWithXPathAndValue = getXPath(element.getParentNode())
+ "/"
+ element.getParentNode().getNodeName()
+ "/"
+ element.getTagName()
+ "/"
+ element.getTextContent();
Long countValue = mapElements.get(elementWithXPathAndValue);
if (countValue == null) {
countValue = Long.valueOf(0l);
} else {
++countValue;
}
mapElements.put(elementWithXPathAndValue, countValue);
}
}
return mapElements;
}
static String getXPath(Node node) {
Node parent = node.getParentNode();
if (parent == null) {
return "";
}
return getXPath(parent) + "/" + parent.getNodeName();
}
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLComparison {
public static void main(String s[]) throws ParserConfigurationException, SAXException, IOException{
compareTwoXMLS("<a><b>testb</b><c>testc</c></a>","<a><c>testc</c><b>testb</b></a>");
}
public static void compareTwoXMLS(String xml1, String xml2) throws ParserConfigurationException, SAXException, IOException {
//Convert the two xml's into two maps where each of the elements of XML along with the number of occurrences is listed
//key will be XPATH of element appended with its value and Value will be the number of occurrences of that element.
Map<String, Long> mapElementsOfXML1 = getMapOfElementsOfXML(xml1);
Map<String, Long> mapElementsOfXML2 = getMapOfElementsOfXML(xml2);
final Iterator<String> iteratorKeySet = mapElementsOfXML1.keySet().iterator();
//Now compare the two maps,clearing the elements which are there in both the maps.
while (iteratorKeySet.hasNext()) {
final String next = iteratorKeySet.next();
if (next != null)
if (mapElementsOfXML1.get(next).equals(mapElementsOfXML2.get(next))) {
mapElementsOfXML2.remove(next);
iteratorKeySet.remove();;
}
}
StringBuilder diffString = new StringBuilder();
diffString.append("Elements in XML1 but not found in XML2 ::");
for (String key : mapElementsOfXML1.keySet()) {
diffString.append(key + mapElementsOfXML1.get(key) + "\r\n");
}
diffString.append("Elements in XML2 but not found in XML1 ::" + "\r\n");
for (String key : mapElementsOfXML2.keySet()) {
diffString.append(key + mapElementsOfXML2.get(key) + "\r\n");
}
if (!mapElementsOfXML1.isEmpty() || !mapElementsOfXML2.isEmpty()) {
System.out.println("Difference between XML1 and XML2::" + diffString.toString());
}else{
System.out.println("Both XML's are identical ");
}
}
/**
* creates a map of elements with text values and no nested nodes.<br>
* Here Key of the map is XPATH of element concatenated with the text value of element, value of the element is number of occurrences of that element.<br>
*
* @param xmlContent
* @return
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
private static Map<String, Long> getMapOfElementsOfXML(String xmlContent)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc1 = db.parse(new ByteArrayInputStream(xmlContent.getBytes()));
NodeList entries = doc1.getElementsByTagName("*");
Map<String, Long> mapElements = new HashMap<>();
for (int i = 0; i < entries.getLength(); i++) {
Element element = (Element) entries.item(i);
if (element.getChildNodes().getLength() == 1&&element.getTextContent()!=null) {
final String elementWithXPathAndValue = getXPath(element.getParentNode())
+ "/"
+ element.getParentNode().getNodeName()
+ "/"
+ element.getTagName()
+ "/"
+ element.getTextContent();
Long countValue = mapElements.get(elementWithXPathAndValue);
if (countValue == null) {
countValue = Long.valueOf(0l);
} else {
++countValue;
}
mapElements.put(elementWithXPathAndValue, countValue);
}
}
return mapElements;
}
static String getXPath(Node node) {
Node parent = node.getParentNode();
if (parent == null) {
return "";
}
return getXPath(parent) + "/" + parent.getNodeName();
}
}
Comments
Post a Comment