0

I would like to compare 2 xml documents

d1.xml

<?xml version="1.0" encoding="UTF-8"?>
<test:process xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1 xsd/BPELProcess1.xsd" xmlns:test="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1">
    <test:input1>RAVI1</test:input1>
   <test:input2>RAVI2</test:input2>
</test:process>

d2.xml

<?xml version="1.0" encoding="UTF-8"?>
<test:process xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1 xsd/BPELProcess1.xsd" xmlns:test="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1">
    <test:input1>RAVI1</test:input1>
   <test:input2>RAVI2</test:input2>
</test:process>

Wrote a java code to do a diff on these XML files with the following code

 public static void main(String[] args) throws Exception {
              
       String sourceXml = new String(readAllBytes(get("c:\\temp\\d1.xml")));
       String targetXml = new String(readAllBytes(get("c:\\temp\\d2.xml")));
       
    XPathEngine engine = new JAXPXPathEngine(); 
    
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
            
        Document sourceDoc = Convert.toDocument(Input.fromString(sourceXml).build(), dbf);
       
        Document targetDoc = Convert.toDocument(Input.fromString(targetXml).build(), dbf);
        
        Diff myDiff = DiffBuilder.compare(sourceDoc).withTest(targetDoc)
                    .checkForSimilar()
                                 .checkForIdentical()
                    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes))
                    .ignoreWhitespace() 
                    .withNamespaceContext(null)
                    .build();
   
        Iterator<Difference> iter = myDiff.getDifferences().iterator();
           int size = 0;
           while (iter.hasNext()) {
             
              Difference d1 =  iter.next();
               System.out.println(d1);
             
            System.out.println(d1.getComparison().getControlDetails().getXPath()  +" (SOURCE) -->  "+d1.getComparison().getControlDetails().getValue());
            System.out.println(d1.getComparison().getTestDetails().getXPath()  +" (TARGET) -->  "+d1.getComparison().getTestDetails().getValue());
              
               System.out.println();
               size++;
           }
    }
    

This is the output , I am getting

Expected text value 'RAVI2' but was 'RAVI3' - comparing RAVI2 at /process[1]/input2[1]/text()[1] to RAVI3 at /process[1]/input2[1]/text()[1] (DIFFERENT) /process[1]/input2[1]/text()[1] (SOURCE) --> RAVI2 /process[1]/input2[1]/text()[1] (TARGET) --> RAVI3

Here the Xpath does not contain the namespaces /process[1]/input1[1]/text()[1] I exptect this to be as ,

/test:process[1]/test:input1[1]/text()

In my code I am trying to use this Xpath and it is not giving any results. If the XML contains no namespaces then this works fine.

XPathEngine engine = new JAXPXPathEngine();

String value = engine.evaluate(d1.getComparison().getTestDetails().getXPath(), Input.fromString(targetXml).build()); System.out.println("------------------ " +value);

RaviReddy
  • 31
  • 2

1 Answers1

0

I don't see RAVI3 in either of your examples.

Anyway, if you want XPaths with namespace prefixes you must specify a NamespaceContext (really a Map from prefix to uri) containing the desired mapping. See the Javadocs of DiffBuilder.

Stefan Bodewig
  • 3,260
  • 15
  • 22
  • I would like to pick up any random xml file so I may not be knowing the namespaces the xml file is using. Is there any way I can get all the namesspaces that an xml file containing. – RaviReddy Mar 15 '17 at 14:55
  • I'm not aware of anything simpler than parsing the document and inspecting each and every `Node` for its namespace URI. Note that you can have multiple URIs inside a document using the same prefix (at different contexts) as well as the same URI using different prefixes - so simply using the prefixes used inside the document won't work in general. That's why I decided to have the user of XMLUnit specify the mapping explicitly. It wouldn't help if XMLUnit created surrogate `ns1`, `ns2` ... prefixes that you wouldn't know how to match with real namespace URIs. – Stefan Bodewig Mar 15 '17 at 16:24