2011-06-07 6 views
0

J'ai des problèmes avec XPath. Pour une raison inconnue, le résultat que je reçois de mon expression est celui d'une autre exécution de la fonction.Xpath renvoyant la valeur du mauvais noeud

Voici le constructeur de ma classe:

Wine(Node ndWine){ 
    try{ 
    xpath = XPathFactory.newInstance().newXPath(); 
    } 
    catch(Exception e) 
    {} 

    Node ndName = null; 

    try{ 
     ndName = (Node)xpath.evaluate("//name", ndWine, XPathConstants.NODE); 
    } 
    catch(Exception e) 
    {} 
    if (ndName != null) 
     name = ndName.getTextContent(); 
} 

Et voici le XML:

<cellar> 
    <wine> 
    <name>Jasnières</name> 
    </wine> 
    <wine> 
    <name>Ballet d'Octobre</name> 
    </wine> 
</cellar> 

Dans la méthode d'appel que j'ai une autre expression XPath qui décompose le document à la liste des <wine> éléments . Le code ci-dessus est appelé pour chaque noeud.
Dans le débogueur, je vérifie qu'à la deuxième exécution, le nœud ndWine contient réellement des données du deuxième nœud du document, mais l'évaluation renvoie toujours la valeur Jasnieres au lieu de ballet d'octobre, ce que je ne comprends pas.

Une idée de la cause première?

Répondre

3

Le démarrage de l'expression XPath avec // en fait un chemin absolu. Même si vous transmettez l'élément <wine>, il l'ignore et commence à la racine du document. Ajouter un . devant pour en faire un chemin relatif:

.//name 

Ou mieux encore, éviter la syntaxe // si vous le pouvez. Il est préférable d'éviter de faire une recherche complète descendant-or-self si vous savez exactement où seront les éléments <name>. S'ils seront toujours directement à l'intérieur d'un élément <wine> utilisez cette XPath:

name 
+0

Merci, ce qu'il fait! Je n'étais pas au courant que même si la source de l'évaluation XPath est un nœud spécifique, elle va quand même parcourir tout le document. – Antoine

0

Essayez ce morceau de code

try {     
    expr = xpath.compile("/cellar/wine/name"); 
    nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
} catch (XPathExpressionException ignored) {} 

for (int i = 0; i < nodeList.getLength(); i++) { 
     Node node = nodeList.item(i); 
     if (node != null) { 
      NodeList childNodes = node.getChildNodes(); 
      for (int j = 0; j < childNodes.getLength(); j++) { 
       Node childNode = childNodes.item(j); 
       if (childNode.getNodeType() == Node.TEXT_NODE) { 
        System.out.println(childNode.getNodeValue()); 
       } 
      } 
     } 
} 
Questions connexes