2009-02-12 10 views
13

Je souhaite utiliser JDOM pour lire dans un fichier XML, puis utiliser XPath pour extraire des données du document JDOM. Il crée l'objet Document correctement, mais lorsque j'utilise XPath pour interroger le document pour une liste d'éléments, je n'ai rien.Espace de noms XML par défaut, JDOM et XPath

Mon document XML a un espace de noms par défaut défini dans l'élément racine. La chose amusante est, quand je supprime l'espace de noms par défaut, il exécute avec succès la requête XPath et renvoie les éléments que je veux. Que dois-je faire d'autre pour obtenir ma requête XPath pour retourner les 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)); 
} 

Répondre

26

XPath 1.0 ne supporte pas le concept d'un espace de noms par défaut (XPath 2.0 fait). Toute balise non préfixée est toujours supposée faire partie de l'espace de noms sans nom.

Lorsque vous utilisez XPath 1.0 vous besoin de 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)); 
} 
+0

A fait le tour, merci! – Michael

+0

C'est excellent, j'ai passé les 3 dernières heures à me demander pourquoi mon XPath ne fonctionne soudainement pas et c'est ainsi. Pffh! :) – Esko

+0

à quoi sert le x? – Meinkraft

6

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 ça n'a pas marché. Pour simplifier mon problème, j'ai exécuté l'extrait JDOM suivant après avoir chargé le 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 de simples getChild ("elname") de navigation de style ou des requêtes XPath simples.

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

+0

Merci pour la suggestion. J'ai pensé à faire quelque chose comme ça, mais comme vous l'avez fait, la suppression des espaces de noms signifie qu'il y a des chances que vous rencontriez des collisions de noms, en fonction de vos données XML. – Michael

1

Vous pouvez également effectuer les opérations suivantes

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

Here est la liste des requêtes XPath utiles.

Questions connexes