Adam Matan
Adam Matan

Reputation: 136351

Compare structure of two XML files

How can I compare to XML structures, ignoring the tag content?

For example, the following responses:

<note>
   <to>Adam</to>
   <from>Eve</from>
</note>

And:

<note>
   <to>John</to>
   <from>Joan</from>
</note>

Have the same XML structure, But:

<note>
   <from>Joan</from>
   <to>John</to>
</note>

Is not identical to the first examples, because the order of the tags differs.

How can I compare the XPath structure in Java?

Upvotes: 1

Views: 1493

Answers (2)

Alper
Alper

Reputation: 13220

You can compute the hash value for XML structure and compare two hash values. Simple example with StAX as below, example cares only for start and end elements, you may want to add other types. It prints the hash value to console rather than compare.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.MessageDigest;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;

public class ComputeXMLStructureHash {

    public static void main(String[] args)
    {
        try {
            FileInputStream in1 = new FileInputStream(new File("file1.xml"));
            FileInputStream in2 = new FileInputStream(new File("file2.xml"));
            FileInputStream in3 = new FileInputStream(new File("file3.xml"));

            System.out.println(digest(in1));
            System.out.println(digest(in2));
            System.out.println(digest(in3));                        

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static String digest(InputStream in) {
        MessageDigest messageDigest = null;

        // StAX for XML parsing
        XMLInputFactory inputFactory = XMLInputFactory.newFactory();

        try {
            messageDigest = MessageDigest.getInstance("MD5");
            XMLEventReader eventReader = inputFactory.createXMLEventReader(in);

            // Iterate over the XML elements and update hash
            while (eventReader.hasNext()) {
                XMLEvent event = eventReader.nextEvent();

                if (event.isStartElement()) {
                    messageDigest.update(event.asStartElement().getName().toString().getBytes());                   
                } else if (event.isEndElement()) {
                    messageDigest.update(event.asEndElement().getName().toString().getBytes());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        StringBuffer result = new StringBuffer();
        byte[] digest = messageDigest.digest();
        for (byte b : digest) 
            result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));

        return result.toString(); 
    }
}

Upvotes: 1

Muthukris Bala
Muthukris Bala

Reputation: 31

You can use JAVA DOM Parse or SAX parser

below one is example to access the element after that you need to do normal compare

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;

public class ReadXMLFile {

  public static void main(String argv[]) {

    try {

    File fXmlFile = new File("/Input.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fXmlFile);

    doc.getDocumentElement().normalize();

    System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

    NodeList nList = doc.getElementsByTagName("staff");

    System.out.println("----------------------------");

    for (int temp = 0; temp < nList.getLength(); temp++) {

        Node nNode = nList.item(temp);

        System.out.println("\nCurrent Element :" + nNode.getNodeName());

        if (nNode.getNodeType() == Node.ELEMENT_NODE) {

            Element eElement = (Element) nNode;

            System.out.println("Note: " + eElement.getAttribute("note"));
            System.out.println("From: " + eElement.getElementsByTagName("from").item(0).getTextContent());
            System.out.println("To : " + eElement.getElementsByTagName("to").item(0).getTextContent());

        }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
  }

}

Upvotes: 1

Related Questions