2009-02-12 4 views
13

Ich möchte mit JDOM eine XML-Datei einlesen und dann mit XPath Daten aus dem JDOM-Dokument extrahieren. Es erstellt das Dokument-Objekt in Ordnung, aber wenn ich XPath verwende, um das Dokument nach einer Liste von Elementen abzufragen, bekomme ich nichts.Standard-XML-Namespace, JDOM und XPath

Mein XML-Dokument verfügt über einen Standard-Namespace, der im Stammelement definiert ist. Das Lustige ist, wenn ich den Standard-Namensraum entferne, führt er die XPath-Abfrage erfolgreich aus und gibt die gewünschten Elemente zurück. Was muss ich noch tun, damit meine XPath-Abfrage Ergebnisse zurückgibt?

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)); 
} 

Antwort

26

XPath 1.0 nicht das Konzept eines Standard-Namespace unterstützt (XPath 2.0 tut). Jedes nicht vordefinierte Tag wird immer als Teil des No-Name-Namespaces angenommen.

Wenn 1.0 XPath verwenden Sie so etwas wie dies benötigen:

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

Hat den Trick, danke! – Michael

+0

Das ist hervorragend, ich habe die letzten 3 Stunden damit verbracht, mich zu wundern, warum mein XPath plötzlich nicht funktioniert und das war es. Pffh! :) – Esko

+0

wofür ist das x? – Meinkraft

6

ich ein ähnliches Problem hatte, aber ich war, dass ich eine Mischung aus XML-Eingängen hatte, einen Namensraum definiert und andere, von denen einige hatten Das tat es nicht. Um mein Problem zu vereinfachen, habe ich das folgende JDOM-Snippet nach dem Laden des Dokuments ausgeführt.

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

Nachdem alle Namensräume zu entfernen ich einfach getChild ("ElName") Stil Navigation oder einfache XPath-Abfragen verwendet werden konnte.

Ich würde diese Technik nicht als allgemeine Lösung empfehlen, aber in meinem Fall war es definitiv nützlich.

+0

Danke für den Vorschlag. Ich dachte darüber nach, so etwas zu tun, aber wie du schon angedeutet hast, bedeutet das Entfernen der Namespaces, dass es zu Namenskonflikten kommen kann, abhängig davon, wie deine XML-Daten aussehen. – Michael

1

Sie können auch Folgendes tun

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

Here Liste nützlicher XPath-Abfragen ist.