通过它们具有的相同节点比较Java中的两个不同XML文件

时间:2017-05-30 14:59:13

标签: java xml

我有两个不同的XML文件要比较,

假设我想比较这些XML文件的具体内容,

例如:

这些XML文件中的每一个都有一个名为:

的公共节点
<BURAK>
   <burak1>
      <burak2>a<burak2>
<BURAK>
   <burak1>
      <burak2>c<burak2>

所以,我想在java中使用该节点,并比较这些节点的节点名称和内容名称并验证它们。

public static void main(String args[]) throws FileNotFoundException, SAXException, IOException {
        FileInputStream fis1 = new FileInputStream("/abc.xml");{
        FileInputStream fis2 = new FileInputStream("/def.xml");

        BufferedReader source = new BufferedReader(new InputStreamReader(fis1)); 
        BufferedReader target = new BufferedReader(new InputStreamReader(fis2));

        XMLUnit.setIgnoreWhitespace(true);
        List differences = compareXML(source, target);
        printDifferences(differences);
        }
        }
            public static List compareXML(Reader source, Reader target) throws SAXException, IOException{ 
            //creating Diff instance to compare two XML files 
            Diff xmlDiff = new Diff(source, target); 
            //for getting detailed differences between two xml files
            DetailedDiff detailXmlDiff = new DetailedDiff(xmlDiff); 
            return detailXmlDiff.getAllDifferences(); 
            } 
            public static void printDifferences(List differences){ 
            int totalDifferences = differences.size(); 
            System.out.println("==============================="); 
            System.out.println("Total differences : " + totalDifferences); 
            System.out.println("================================"); 

                System.out.println(differences); 

            } 
        }

我找到了一个有用的代码来创建这个结构,但是这段代码给了我两个文件之间的所有区别。 我想要的是转到特定节点并比较该节点中的特定子节点。 我怎样才能用Java编写那种代码?

关于“svasa”的建议,我改变了代码:

try
        {
            String firstValue = null;
            String secondValue = null;

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();

            Document doc = db.parse( new File( "/abc.xml" ) );

            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath xpath = xPathFactory.newXPath();

            XPathExpression expr = xpath.compile( "//TOC/STRUCTURE/TOC_NODE/NODE_NAME");

            Object exprValue = expr.evaluate( doc, XPathConstants.STRING );

            if ( exprValue != null )
            {
                firstValue = exprValue.toString();
            }

            Document doc1 = db.parse( new File( "/def.xml" ) );

            XPathFactory xPathFactory1 = XPathFactory.newInstance();
            XPath xpath1 = xPathFactory1.newXPath();

            XPathExpression expr1 = xpath1.compile( "//TOC/cac:STRUCTURE/cac:TOC_NODE/cac:NODE_NAME");

            Object exprValue1 = expr1.evaluate( doc1, XPathConstants.STRING );

            if ( exprValue1 != null )
            {
                secondValue = exprValue1.toString();


            }

            if ( firstValue != null && secondValue != null )
            {
                System.out.println( firstValue );
                System.out.println( secondValue );


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

     }
}

这不起作用,或者我不能使它工作。如果这是我想要的正确结构。代码对我来说是合乎逻辑的。正如我在评论中提到的,我需要第二条路径。结构看起来不太完全相同。

2 个答案:

答案 0 :(得分:0)

使用XPathFactory。它易于编码,编译xpath表达式并使用它从xml中提取所需的数据。

代码将是:

        try
        {
            String firstValue = null;
            String secondValue = null;

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();

            Document doc = db.parse( new File( "/abc.xml" ) );

            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath xpath = xPathFactory.newXPath();

            XPathExpression expr = xpath.compile( "//BURAK/burak1/burak2");

            Object exprValue = expr.evaluate( doc, XPathConstants.STRING );

            if ( exprValue != null )
            {
                firstValue = exprValue.toString();
            }

            doc = db.parse( new File( "/def.xml" ) );

            exprValue = expr.evaluate( doc, XPathConstants.STRING );

            if ( exprValue != null )
            {
                secondValue = exprValue.toString();
            }

            if ( firstValue != null && secondValue != null )
            {
                System.out.println( firstValue );
                System.out.println( secondValue );


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

当您将结果指定为//BURAK/burak1/burak2

时,xpath burak会转到STRING节点,并为XPathConstants.STRING获取值

因为你的两个xmls相似,所以相同的xpath表达式都可以。

尝试执行代码,您将获得值ac,然后您可以进行比较。

答案 1 :(得分:0)

 try
        {  File inputFile = new File("abc.xml");
         DocumentBuilderFactory dbFactory 
            = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();


        XPath xPath =  XPathFactory.newInstance().newXPath();
     String expression="NODE";

     NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);
     for (int i = 0; i < nodeList.getLength(); i++) {
           Node nNode = nodeList.item(i);
           System.out.println("\nCurrent Element :" 
                    + nNode.getNodeName());
          if (nNode.getNodeType() == Node.ELEMENT_NODE) {
              Element eElement = (Element) nNode;

              System.out.println("NODE_NAME: " 
                      + eElement
                         .getElementsByTagName("NODE")
                         .item(0)
                         .getTextContent());
              System.out.println("NODE: " 
                      + eElement
                         .getElementsByTagName("NODE")
                         .item(0)
                         .getTextContent());


              File inputFile1 = new File("def.xml");
             DocumentBuilderFactory dbFactory1 
                = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder1;

             dBuilder1 = dbFactory1.newDocumentBuilder();

             Document doc1 = dBuilder1.parse(inputFile1);
             doc1.getDocumentElement().normalize();


            XPath xPath1 =  XPathFactory.newInstance().newXPath();
          String expression1="NODE1";

          NodeList nodeList1 = (NodeList) xPath1.compile(expression1).evaluate(doc1, XPathConstants.NODESET);
          for (int j = 0; j < nodeList1.getLength(); j++) {
               Node nNode1 = nodeList1.item(j);
               System.out.println("\nCurrent Element :" 
                         + nNode1.getNodeName());
              if (nNode1.getNodeType() == Node.ELEMENT_NODE) {
                   Element eElement1 = (Element) nNode1;

                   System.out.println("NODE: " 
                           + eElement1
                              .getElementsByTagName("NODE_NAME")
                              .item(0)
                              .getTextContent());
                   System.out.println("NODE: " 
                           + eElement1
                              .getElementsByTagName("NODE_NAME")
                              .item(0)
                              .getTextContent());
        }

以下是我对这个问题的回答。谢谢你&#34; svasa&#34;为了这些想法。