Question

Je veux utiliser JDOM lire dans un fichier XML, puis utilisez XPath pour extraire des données du document JDOM. Il crée l'objet document très bien, mais quand je l'utilise XPath pour interroger le document pour une liste d'éléments, je reçois rien.

Mon document XML a un espace de noms par défaut défini dans l'élément racine. La chose drôle est, quand je supprimer l'espace de noms par défaut, il fonctionne avec succès la requête XPath et renvoie les éléments que je veux. Que dois-je faire pour obtenir ma requête XPath pour retourner des résultats?

XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection xmlns="http://www.foo.com">
<dvd id="A">
  <title>Lord of the Rings: The Fellowship of the Ring</title>
  <length>178</length>
  <actor>Ian Holm</actor>
  <actor>Elijah Wood</actor>
  <actor>Ian McKellen</actor>
</dvd>
<dvd id="B">
  <title>The Matrix</title>
  <length>136</length>
  <actor>Keanu Reeves</actor>
  <actor>Laurence Fishburne</actor>
</dvd>
</collection>

Java:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("collection/dvd");
    xpath.addNamespace(d.getRootElement().getNamespace());
    System.out.println(xpath.selectNodes(d));
}
Était-ce utile?

La solution

XPath 1.0 ne supporte pas le concept d'un espace de noms par défaut ( XPath 2.0 t).  Toute étiquette est toujours sans préfixe supposé faire partie de l'espace de noms sans nom.

Lors de l'utilisation XPath 1.0 vous avez besoin quelque chose comme ceci:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("x:collection/x:dvd");
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI());
    System.out.println(xpath.selectNodes(d));
}

Autres conseils

J'ai eu un problème similaire, mais le mien était que j'avais un mélange d'entrées XML, dont certains avaient un espace de nom défini et d'autres qui ne l'ont pas. Pour simplifier mon problème j'ai couru l'extrait JDOM après le chargement du document.

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) {
    if (el.getNamespace() != null) el.setNamespace(null);
}

Après avoir enlevé tous les espaces de noms, j'ai pu utiliser simplement getChild ( "elname") navigation style ou requêtes XPath simple.

Je ne recommanderais pas cette technique comme une solution générale, mais dans mon cas, il était certainement utile.

Vous pouvez également effectuer les opérations suivantes

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

est la liste des requêtes XPath utiles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top