2017-09-25 3 views
0

J'essaie de comparer deux xml seulement partiellement en utilisant XMLUnit2. J'ai essayé ci-dessous Xpath pour comparer l'élément int seul. Mais mon test a échoué, car il vérifie également le tag boolean.Comment utiliser XMLUnit2 pour comparer des xml par XPATH?

Comment faire passer ce test?

@Test 
    public void diff_through_xPath(){ 
     String myControlXML = "<struct><boolean>false</boolean><int>3</int></struct>"; 
     String myTestXML = "<struct><boolean>true</boolean><int>3</int></struct>"; 

     ElementSelector childSelector = selectorForElementNamed("int", byXPath("//int", byName)); 

     Diff myDiffSimilar = DiffBuilder.compare(myControlXML).withTest(myTestXML) 
       .withNodeMatcher(new DefaultNodeMatcher(childSelector, byName)) 
       .checkForSimilar() 
       .ignoreWhitespace() 
       .build(); 

     assertFalse("XML similar " + myDiffSimilar.toString(), 
       myDiffSimilar.hasDifferences()); 


    } 

Edit: Avec NodeFilter, j'ai enlevé les nœuds indésirables de la comparaison. Mais existe-t-il un moyen de donner Xpath, et de ne comparer que les nœuds évalués par XPath.

@Test 
    public void diff_through_xPath() { 
     String myControlXML = "<struct><boolean>false</boolean><int>3</int></struct>"; 
     String myTestXML = "<struct><boolean>true</boolean><int>3</int></struct>"; 

     Diff myDiffSimilar = DiffBuilder.compare(myControlXML).withTest(myTestXML) 
       .withNodeFilter(new Predicate<Node>() { 
        public boolean test(Node node) { 
         return !node.getNodeName().equals("boolean"); //ignores all child nodes from of 'a'. 
        } 
       }) 
       //.checkForSimilar() 
       .ignoreWhitespace() 
       .build(); 

     assertFalse("XML similar " + myDiffSimilar.toString(), 
       myDiffSimilar.hasDifferences()); 


    } 
+0

Je ne suis pas sûr de comprendre ce que vous voulez comparer. Voulez-vous comparer le 'struct' du tout ou simplement le' int's? 'NodeMatcher' est utilisé pour décider quels noeuds d'un ensemble de frères et sœurs comparer les uns avec les autres, il n'a aucun effet sur les noeuds qui sont admissibles à la comparaison du tout. Vous utiliseriez 'NodeFilter' pour enlever ceux que vous ne voulez pas. –

+0

Je veux comparer juste balise 'int' dans les deux xml. Je me fiche de savoir si les balises booléennes correspondent ou non. – Manoj

+0

Comme j'ai modifié, je pourrais utiliser Nodefilter pour supprimer les nœuds indésirables. Y at-il un moyen d'utiliser Xpath et comparer? – Manoj

Répondre

0

Je ne sais pas si c'est la bonne approche. Mais posté ici de toute façon pour obtenir des commentaires de votre part. De cette façon, je peux seulement comparer la liste de noeuds XML évaluée XPath.

@Test 
    public void testXpath() throws Exception { 

     File controlFile = new File("src/test/resources/myControlXML.xml"); 
     File testFile = new File("src/test/resources/myTest.xml"); 


     Diff myDiff = DiffBuilder.compare(Input.fromDocument(getDocument("src/test/resources/myControlXML.xml", "/struct/int"))) 
       .withTest(Input.fromDocument(getDocument("src/test/resources/myTest.xml", "/struct/int"))) 
       .checkForSimilar().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)) 
       .ignoreWhitespace() 
       .build(); 

     assertFalse("XML similar " + myDiff.toString(), 
       myDiff.hasDifferences()); 
    } 

    public Document getDocument(String fileName, String xpathExpression) throws Exception { 
     File controlFile = new File(fileName); 
     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder dBuilder; 

     dBuilder = dbFactory.newDocumentBuilder(); 

     Document controlDoc = dBuilder.parse(controlFile); 
     controlDoc.getDocumentElement().normalize(); 

     XPath xPath = XPathFactory.newInstance().newXPath(); 

     NodeList nodes = (NodeList) xPath.compile(xpathExpression).evaluate(
       controlDoc, XPathConstants.NODESET); 

     Document newXmlDocument = DocumentBuilderFactory.newInstance() 
       .newDocumentBuilder().newDocument(); 
     Element root = newXmlDocument.createElement("root"); 
     newXmlDocument.appendChild(root); 
     for (int i = 0; i < nodes.getLength(); i++) { 
      Node node = nodes.item(i); 
      Node copyNode = newXmlDocument.importNode(node, true); 
      root.appendChild(copyNode); 
     } 

     return newXmlDocument; 
    } 
+0

Vous pourriez avoir sauvegardé quelques lignes en utilisant XMLUnit [XPath abstractions] (https://github.com/xmlunit/user-guide/wiki/XPath-Support) mais oui, c'est probablement la meilleure façon de le faire maintenant . Dans les prochaines versions, le constructeur 'Input' pourrait probablement être modifié pour accepter un' NodeList' comme source ou même une 'Source' et une expression XPath pour effectuer les mêmes tâches sous les couvertures. –