Skip to content

Instantly share code, notes, and snippets.

@danielkec
Last active December 30, 2015 19:19
Show Gist options
  • Save danielkec/7873305 to your computer and use it in GitHub Desktop.
Save danielkec/7873305 to your computer and use it in GitHub Desktop.
package xmldiff;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLDiff {
static final XPathFactory xPathfactory = XPathFactory.newInstance();
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = fac.newDocumentBuilder();
Document dom1 = docBuilder.parse(new File(args[0]));
Document dom2 = docBuilder.parse(new File(args[1]));
System.out.format("Rovnost dokumentů je %s\n",compare(dom1.getDocumentElement(), dom2.getDocumentElement()));
}
public static boolean compare(Element e1,Element e2) throws XPathExpressionException{
// porovnani jmena
System.out.println(String.format("Porovnavam %1$5s %3$40s",nodeToXpath(e1),"-",nodeToXpath(e1)));
if(!e1.getNodeName().equals(e2.getNodeName())){
return false;
}
// porovnani atributu
NamedNodeMap amap = e1.getAttributes();
for (int i = 0; i < amap.getLength(); i++) {
Attr a = (Attr) amap.item(i);
if(!e2.hasAttribute(a.getName())){
System.err.format("Chyba: Element %3s nema attribut %1s\n",nodeToXpath(e2),a);
return false;
}
if(!e2.getAttribute(a.getName()).equals(a.getValue())){
System.err.format("Chyba: Attribut %s nema hodnotu %s\n",nodeToXpath(a),a,nodeToXpath(e2));
return false;
}
}
// porovnani deticek
NodeList childNodes = e1.getChildNodes();
deticky:
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if(node.getNodeType()==Node.ELEMENT_NODE){
Element chEl1 = (Element)node;
ArrayList<Element> chEl2List = xpathEl(e2,"./"+chEl1.getTagName());
for (Element chEl2 : chEl2List) {
if(compare(chEl1, chEl2))continue deticky;
}
System.out.println(nodeToXpath(chEl1)+" nema kandidata mezi "+nodeToXpath(e2) +"/"+chEl1.getTagName());
return false;
}
if(node.getNodeType()==Node.ATTRIBUTE_NODE){
}
}
return true;
}
public static ArrayList<Element> xpathEl(Element e,String pathS) throws XPathExpressionException{
ArrayList<Element> resultList= new ArrayList<Element>();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(pathS);
NodeList nl = (NodeList)expr.evaluate(e,XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); i++) {
if(nl.item(i).getNodeType()==Node.ELEMENT_NODE){
resultList.add((Element)nl.item(i));
}
}
return resultList;
}
public static ArrayList<Node> xpathNode(Element e,String pathS) throws XPathExpressionException{
ArrayList<Node> resultList= new ArrayList<Node>();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(pathS);
NodeList nl = (NodeList)expr.evaluate(e,XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); i++) {
resultList.add((Node)nl.item(i));
}
return resultList;
}
public static String xpathStr(Element e,String pathS) throws XPathExpressionException{
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(pathS);
return ""+expr.evaluate(e,XPathConstants.STRING);
}
public static String nodeToXpath(Node n){
String sb = n.getNodeName();
if(n.getNodeType()==Node.ATTRIBUTE_NODE)sb='@'+sb;
Node n1 = n.getParentNode();
if(n.getNodeType()==Node.ATTRIBUTE_NODE)n1 = ((Attr)n).getOwnerElement();
if(n1.getNodeType()==Node.DOCUMENT_NODE){
return '/'+sb;
}
while(true){
if(n1.getNodeType()==Node.DOCUMENT_NODE)return '/'+sb;
sb=n1.getNodeName()+'/'+sb;
n1 = n1.getParentNode();
if(n1==null)return sb;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment