XQuery, una abbrevazione per XML Query Language, è un linguaggio di programmazione specificato dal W3C e destinato ad interrogare documenti e basi di dati XML. Questo perché XML si sta proponendo come la tecnologia per rimpiazzare i vecchi DBMS relazionali
Il w3c ha definito il linguaggio XQuery 1.0; usa la sintassi delle espressioni di XPath 2.0, con l’aggiunta delle cosiddette espressioni FLWOR per la formulazione di query complesse. Il risultato è un linguaggio di programmazione funzionale, dichiarativo, con somiglianze con il vecchio SQL.
Per effettuare delle query xquery su un file XML possiamo usare delle librerie come BaseX e Saxon. Purtroppo attualmente Saxon non è un prodotto del tutto gratuito, quindi scegliamo di usare BaseX, un processore Xquery-XPath open source.
In realtà BaseX, oltre ad essere utlilizzabile come libreria all’interno del linguaggio Java, ci mette a disposizione un’interfaccia grafica dalla quale possiamo effettuare query su file XML ben formati arbitrari.
Primo esempio di query
La prima cosa da fare è inserire i file jar di BaseX nel build path del nostro progetto; la seconda è assicurarsi di avere java 1.6 (non funziona con java 1.5) perché BaseX utilizza il package javax.xml.stream.
Questo è un sempio dove si esegue la query //li sul file ‘input‘:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import javax.xml.xquery.XQConnection; import javax.xml.xquery.XQDataSource; import javax.xml.xquery.XQPreparedExpression; import javax.xml.xquery.XQResultSequence; public final class XQueryAPIExample { /** Database Driver. */ static final String DRIVER = "org.basex.api.xqj.BXQDataSource"; public static void main(final String[] args) throws Exception { // Gets the XQDataSource for the specified Driver. XQDataSource source = (XQDataSource) Class.forName(DRIVER).newInstance(); // Creates an XQConnection XQConnection conn = source.getConnection(); // Prepares the Expressionwith the Document and the Query. XQPreparedExpression expr = conn.prepareExpression("doc('input')//li"); // Executes the XQuery query. XQResultSequence result = expr.executeQuery(); // Gets all results of the execution. while(result.next()) { // Prints the results to the console. System.out.println(result.getItemAsString(null)); } } } |
Questo esempio funziona solo se il file XML interrogato non dichiara nessun namespace.
Query in presenza di namespace
Supponiamo adesso di interrogare un file XML con namespace… ad esempio un file in formato XML Mpeg-7 che usa i seguenti namespace:
xmlns=”urn:mpeg:mpeg7:schema:2001″
xmlns:mpeg7=”urn:mpeg:mpeg7:schema:2001″
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
Per far riconoscere i namespace dobbiamo dichiararli nel prologo della xquery in questo modo:
declare default element namespace “urn:mpeg:mpeg7:schema:2001″
declare namespace mpeg7 = “urn:mpeg:mpeg7:schema:2001″
declare namespace xsi = “http://www.w3.org/2001/XMLSchema-instance”
Questo è il codice che esegue la query sul file file/video/extract.xml:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | String prologoQuery = "" + "declare default element namespace \"urn:mpeg:mpeg7:schema:2001\"; " + "declare namespace mpeg7 = \"urn:mpeg:mpeg7:schema:2001\"; " + "declare namespace xsi = \"http://www.w3.org/2001/XMLSchema-instance\"; "; // Gets the XQDataSource for the specified Driver. XQDataSource source = (XQDataSource) Class.forName(DRIVER).newInstance(); // Creates an XQConnection XQConnection conn = source.getConnection(); // Prepares the Expressionwith the Document and the Query. //XQPreparedExpression expr = conn.prepareExpression("<xml>1 + 2 = { 1+2 }</xml>/text()"); //XQPreparedExpression expr = conn.prepareExpression("doc('file/video/20090201_video_15213221.xml')//meta"); XQPreparedExpression expr = conn.prepareExpression(prologoQuery + " doc('file/video/extract.xml')//Name"); // Executes the XQuery query. XQResultSequence result = expr.executeQuery(); // Gets all results of the execution. while(result.next()) { //element = (org.w3c.dom.Element) result.getObject(); System.out.println(result.getItemAsString(null)); } |
Nella riga 18 è commentato un altro modo per usare gli oggetti restiuiti dalla query, che ci restituisce il risultato come elementi della struttura DOM del file XML.

ottobre 26th, 2009 alle 17:55
X Saverio
Cercando su internet info su Xquery ci siamo imbattute in un nome che ci ispirava fiducia….e siamo rimaste piacevolmente sorprese nel vedere che l’esempio era “casualmente” mooolto simile al nostro progetto
febbraio 3rd, 2010 alle 17:53
Ho un piccolo problema.
i package non me li fa importare???perchè??
grazie
febbraio 10th, 2010 alle 18:14
Ciao Franco,
i package me li fa importare senza problemi… sono solo un pò grandi
Per questo non ti posso aiutare perchè si tratta di configurare correttamente il tuo IDE.
febbraio 17th, 2010 alle 17:18
Grazie saverio ci sono riuscito…non avevo importato i package giusti….
Una cosa che non ho capito è:
static final String DRIVER = “org.basex.api.xqj.BXQDataSource”;
a cosa serve??
In jdbc il driver è relativo al database. Perchè qui uso una classe???
Grazie mille
febbraio 23rd, 2010 alle 23:20
Ciao Franco,
la stringa “org.basex.api.xqj.BXQDataSource” individua il driver da usare per eseguire le query.
Come tu hai detto la cosa è analoga a JDBC: ci possono essere più motori di interrogazione xquery, ognuno associato con un driver.
BaseX usa i file XML per creare un database semi-strutturato, e tutte le successive operazioni sono fatte su questo database. Stai attendo a non confonderti con i database relazionali!
febbraio 24th, 2010 alle 12:43
Grazie mille….
febbraio 25th, 2010 alle 11:15
Un’altra piccola cosa (scusa il disturbo).
Ma baseX ha solo un driver?? Oppure ne posso utilizzare altri??
Grazie mille ancora, mi stai dando una mano enorme!!!
marzo 9th, 2010 alle 08:44
Ciao Franco, scusa il ritardo
Penso che BaseX abbia solamente un driver, però c’è la possibilità di usare sia le API standard Java, sia direttamente le sue API.