2009-02-12 20 views
13

Desidero utilizzare JDOM per leggere in un file XML, quindi utilizzare XPath per estrarre i dati dal documento JDOM. Crea l'oggetto Document bene, ma quando uso XPath per interrogare il documento per un elenco di elementi, non ottengo nulla.Spazio nomi XML predefinito, JDOM e XPath

Il mio documento XML ha uno spazio dei nomi predefinito definito nell'elemento radice. La cosa divertente è che quando rimuovo lo spazio dei nomi predefinito, esegue correttamente la query XPath e restituisce gli elementi che voglio. Cos'altro devo fare per ottenere la query XPath per restituire i risultati?

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

risposta

26

XPath 1.0 non supporta il concetto di uno spazio dei nomi di default (XPath 2.0 fa). Si presume sempre che ogni tag non prefisso faccia parte dello spazio dei nomi senza nome.

Quando si utilizza XPath 1.0 avete bisogno di qualcosa di simile:

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

Ha fatto il trucco, grazie! – Michael

+0

Questo è eccellente, ho passato le ultime 3 ore a chiedermi perché il mio XPath improvvisamente non funzioni ed è stato questo. Pffh! :) – Esko

+0

a cosa serve la x? – Meinkraft

6

ho avuto un problema simile, ma la mia era che avevo una miscela di input XML, alcune delle quali aveva un namespace definito e altri quello no. Per semplificare il mio problema ho eseguito il seguente snippet JDOM dopo aver caricato il documento.

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

Dopo aver rimosso tutti gli spazi dei nomi sono stato in grado di utilizzare semplici getChild ("elname") di navigazione stile o query XPath semplici.

Non consiglierei questa tecnica come soluzione generale, ma nel mio caso è stata sicuramente utile.

+0

Grazie per il suggerimento. Ho pensato di fare qualcosa di simile, ma come hai fatto allusione, rimuovere gli spazi dei nomi significa che c'è la possibilità che ti imbatti in collisioni di nomi, a seconda di come sono i tuoi dati XML. – Michael

1

È possibile anche effettuare le seguenti operazioni

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

Here è elenco di query XPath utili.

Problemi correlati