2011-08-14 12 views
13

Alcuni nodi di un documento XML hanno spazi dei nomi, specificati con un prefisso definito.Perché non esiste una sintassi XPath per i nodi qualificati per lo spazio dei nomi?

È possibile specificare nome locale() in XPath 1.0 e quindi ignorare i namespace.

Tuttavia, voglio consentire al writer dell'XPath di trovare i nodi utilizzando il loro nome completo dello spazio dei nomi come identificatore.

Il modo consigliato è aggiungere dichiarazioni di namespace nel codice di richiamo (nel mio caso, Java). Ma questo significa che la persona che scrive Xpath non ha la capacità di lavorare con i namespace!

Come troviamo i nodi con i nomi completi con XPath puro?

+2

Se ho capito bene la domanda, mi chiedi perché c'è bisogno di dichiarare uno spazio dei nomi usando un'istruzione come 'addNamespace (" abc "," http://example.com ")' che quindi permette di fare un Query Xpath come '/ abc: node', invece di usare in qualche modo' http: // example.com' direttamente nella query. Ho interpretato correttamente la domanda? –

+1

@Jong Bor Sì, è tutto. Sarebbe bene usare il prefisso abc direttamente nella query XPath dopo aver dichiarato che abc = http: //example.com in qualche modo all'interno dell'XPath. Capisco che le espressioni XPath siano brevi e non sarebbe usuale inserire definizioni, ma non c'è nulla che tecnicamente impedisca di essere possibile in XPath. –

+1

Buona domanda, +1. Poiché i prefissi devono essere semplicemente sintattici, mentre gli URI dello spazio dei nomi sono ciò che è significativo, si potrebbe pensare che potrebbe essere utile associare su un nome nodo l'URI dello spazio dei nomi senza dover confondere con un prefisso - specialmente se XPath stesso fornisce nessun modo per dichiarare un prefisso. – LarsH

risposta

13

Non sei sicuro di cosa intendessi con "come identificatore".

Come troviamo i nodi con i nomi completi utilizzando XPath puro?

In XPath 1.0, utilizzando il nome locale() e namespace-uri(), ad es.

"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']" 

In XPath 2.0, v'è un insieme più ricco di funzioni relative a namespace, ad esempio namespace-uri-from-QName(). Ma non sono sicuro che migliorino quanto sopra per quello che vuoi.

+1

Bene, questo ha senso. Un po 'goffo - preferisco scrivere qualcosa come http://my.org/ns/2.0|foo senza questi nomi di funzioni, e ancora meglio usare in qualche modo i prefissi, dichiarandoli in XPath piuttosto che in Java - ma questo soddisfa il requisito. –

+1

Tramite "l'uso del loro nome completo dello spazio dei nomi come identificatore" intendevo solo che dovresti essere in grado di fare riferimento ai nodi con precisione, con namespace + nome-locale. La tua risposta mostra come. –

+0

@JoshuaFox: Sono d'accordo, sarebbe molto utile poter dichiarare prefissi in XPath stesso. Immagino ci siano alcune ragioni per cui "loro" hanno deciso di non includerlo in XPath, ma sembra un grosso gap, dal momento che la soluzione è così prolissa. – LarsH

1

È possibile utilizzare namespace durante le query XPath. In Java, ciò che è necessario fornire è un'implementazione di NamespaceContext se si desidera utilizzare anche prefissi in tali query anziché lo spazio dei nomi completo in ogni momento. Basta aggiungere un'istanza di NamespaceContext al tuo XPath - Suppongo che tu usi l'implementazione JDK standard - ma il concetto è applicabile anche a Jaxen o ad altri.

Quindi è possibile eseguire query quali //customns:Element.

Se non si vuole o non può utilizzare un NamespaceContext (per qualsiasi motivo), allora l'unica soluzione sembra essere utilizzando i local-name e namespace-uri funzioni:

Document doc = ...; 
XPath xp = XPathFactory.newInstance().newXPath(); 
String name = "Element"; 
String ns = "http://www.custom.org/#"; 
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']"; 
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0); 
+1

Grazie. Cosa succede se sono disposto a utilizzare nomi di domini completi e non prefissi? In altre parole, qualcosa di simile. Posso evitare di dichiarare gli spazi dei nomi in Java? Il mio obiettivo è leggere le espressioni XPath da una fonte esterna, quindi preferirei non doverle specificare separatamente. –

+0

Dipende da come appare la sorgente - se hai solo un'espressione // abc: Element e nessuna dichiarazione dello spazio dei nomi, in teoria, sei bloccato - non c'è modo di sapere a cosa punta abc. Ma se puoi essere assolutamente sicuro che quelle espressioni esterne hanno gli stessi prefissi del tuo documento di lavoro, allora puoi ancora cercare gli spazi dei nomi corrispondenti nel tuo documento e poi creare un NamespaceContext o non usarlo affatto. Aggiornerò la mia risposta spiegando come farlo. – emboss

+0

Sfortunatamente, sembra esserci [nessun'altra soluzione] (http://www.jguru.com/forums/view.jsp?EID=1073634) di una combinazione di local-name() e namespace-uri(). – emboss

4

XPath 3.0, che è attualmente in lavorazione stato di bozza, includerà un'espressione letterale per URI qualified QNames che consente di specificare direttamente lo spazio dei nomi uri.

Ecco alcuni esempi di EQNames:

  • pi greco è un QName lessicale senza prefisso dello spazio dei nomi.
  • matematica: pi è un QName lessicale con un prefisso di namespace.
  • "http://www.w3.org/2005/xpath-functions/math":pi specifica l'URI dello spazio dei nomi utilizzando un URILiteral; non è un QName lessicale.

Penso Saxon 9.3 include un'implementazione anteprima di XPath 3.0, che dovrebbe essere utilizzabile tramite l'API Java.

+3

Corretto, sebbene le funzionalità 3.0 possano essere abilitate solo nelle edizioni commerciali del prodotto. Domande come "perché questa caratteristica non era nelle versioni precedenti" sono sempre difficili da rispondere - o nessuno le ha proposte o non hanno spinto abbastanza, o hanno dovuto competere con proposte rivali per risolvere lo stesso problema. –

0

Le specifiche per XPath 3.0 dice:

Q{http://www.w3.org/2005/xpath-functions/math}pi 

Questo funziona in questo momento (ottobre 2015), per esempio in esiste, db.

+0

@ e4c5: a XML piace utilizzare gli URI per le cose nella sua sintassi letterale. Dovresti leggere la risposta con più attenzione. –

+0

@NathanTuggy sì hai ragione, mentre la moderazione che appariva come una risposta solo link (il commento è auto inserito dal sistema) ho ora cancellato quel commento. – e4c5

Problemi correlati