51 votes

Exécution de XPath sur le nœud enfant

Les XPaths exécutés sur les noeuds enfants d'un document semblent être exécutés contre le noeud racine du document (dans l'exemple, la balise d'inventaire.), au lieu de la racine du noeud fourni.

Est-ce que quelque chose m'échappe ici ? Je suis novice en matière de XPath.

Aussi, s'il vous plaît, ne répondez pas "faites simplement //book[author='Neal Stephenson'/title". J'ai un cas d'utilisation légitime, et c'est un exemple simplifié.

Extrait de code

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("src/main/java/books.xml");

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

Node book = (Node) xpath.evaluate("//book[author='Neal Stephenson']", doc, XPathConstants.NODE);
Node title = (Node) xpath.evaluate("/title", book, XPathConstants.NODE); // I get null here.
Node inventory = (Node) xpath.evaluate("/inventory", book, XPathConstants.NODE); // this returns a node.

book.xml

<inventory>
<book year="2000">
    <title>Snow Crash</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553380958</isbn>
    <price>14.95</price>
</book>

<book year="2005">
    <title>Burning Tower</title>
    <author>Larry Niven</author>
    <author>Jerry Pournelle</author>
    <publisher>Pocket</publisher>
    <isbn>0743416910</isbn>
    <price>5.99</price>
</book>

<book year="1995">
    <title>Zodiac</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553573862</isbn>
    <price>7.50</price>
</book>

<!-- more books... -->

</inventory>

50voto

Pete Hodgson Points 5147

/foo sélectionnera en fonction du nœud racine, en ignorant le contexte dans lequel vous évaluez le xpath. foo (sans la barre oblique) est ce que vous voulez ; cela sélectionne sur la base du nœud actuel.

http://www.w3schools.com/Xpath/xpath_syntax.asp donne un peu plus d'informations.

26voto

Salman Points 81

Dans Xpath, "." (Point) représente le document actuel. Ainsi, écrivez votre chaîne XPATH après un "." (point) .

ex :

"./title"

ou

".//title"

Tout ce que vous voulez....

La suppression de la barre oblique ne fonctionne que si elle est un enfant du nœud. Que faire si vous voulez utiliser la fonctionnalité // (où que ce soit dans le document actuel) ?

Donc, utilisez le point (.)

Merci beaucoup pour les réponses ci-dessus aussi :) .

7voto

Corey Porter Points 1016

Enlevez juste la barre oblique de vos sous-requêtes et ça devrait aller. Donc vous obtenez vos livres via "//book" et à partir de là, c'est juste "title" , "inventory" etc. pour obtenir les bits enfants.

4voto

mauhiz Points 136

Ce qui est en fait bizarre dans l'implémentation Java, c'est qu'un nœud extrait d'un document continue à faire référence au document parent (cf. Node.getOwnerDocument() ) et xpath l'utilise pour trouver la racine.

D'autres ont mentionné un moyen de modifier le xpath pour qu'il soit effectivement pas commencer à partir de la racine en supprimant les barres obliques.

J'ai eu un problème similaire mais je voulais que le xpath gère à la fois les documents Root et les noeuds enfants (avec un xpath du type /title ). La solution était à clone le nœud : Node.cloneNode(true) . Notez le true qui fait en sorte que le nœud secoue son document parent.

...Finalement, cela nuit trop aux performances et il est préférable d'avoir des xpaths séparés pour gérer Node et Document.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X