XQuery - Guida rapida
Cos'è XQuery
XQuery è un linguaggio funzionale utilizzato per recuperare le informazioni archiviate in formato XML. XQuery può essere utilizzato su documenti XML, database relazionali contenenti dati in formati XML o database XML. XQuery 3.0 è una raccomandazione del W3C dell'8 aprile 2014.
La definizione di XQuery data dalla sua documentazione ufficiale è la seguente:
XQuery è un linguaggio standardizzato per combinare documenti, database, pagine Web e quasi qualsiasi altra cosa. È molto ampiamente implementato. È potente e facile da imparare. XQuery sta sostituendo i linguaggi middleware proprietari e i linguaggi di sviluppo di applicazioni Web. XQuery sta sostituendo i programmi Java o C ++ complessi con poche righe di codice. XQuery è più semplice da utilizzare e più facile da mantenere rispetto a molte altre alternative.
Caratteristiche
Functional Language - XQuery è un linguaggio per recuperare / interrogare dati basati su XML.
Analogous to SQL - XQuery sta a XML come SQL sta ai database.
XPath based - XQuery utilizza espressioni XPath per navigare nei documenti XML.
Universally accepted - XQuery è supportato da tutti i principali database.
W3C Standard - XQuery è uno standard W3C.
Vantaggi di XQuery
Utilizzando XQuery, è possibile recuperare dati sia gerarchici che tabulari.
XQuery può essere utilizzato per interrogare strutture ad albero e grafiche.
XQuery può essere utilizzato direttamente per interrogare le pagine web.
XQuery può essere utilizzato direttamente per creare pagine web.
XQuery può essere utilizzato per trasformare documenti xml.
XQuery è ideale per database basati su XML e database basati su oggetti. I database degli oggetti sono molto più flessibili e potenti dei database puramente tabulari.
Questo capitolo elabora come impostare la libreria XQuery in un ambiente di sviluppo locale.
Stiamo utilizzando un processore XQuery autonomo open source Saxon Home Edition (Saxon-HE) che è ampiamente utilizzato. Questo processore supporta XSLT 2.0, XQuery 3.0 e XPath 3.0 ed è altamente ottimizzato per le prestazioni. Il processore Saxon XQuery può essere utilizzato senza avere alcun database XML. Useremo un semplice documento XML come nostro database nei nostri esempi.
Per utilizzare il processore Saxon XQuery, dovresti avere saxon9he.jar, saxon9-test.jar, saxon9-unpack, saxon9-xqj.jar nel classpath dell'applicazione. Questi file jar sono disponibili nel file di downloadSaxonHE9-6-0-1J.zipScarica SaxonHE9-6-0-1J.zip .
Esempio
Useremo il processore Saxon XQuery basato su Java per testare books.xqy, un file contenente l'espressione XQuery rispetto al nostro documento XML di esempio, ovvero books.xml.
In questo esempio, vedremo come scrivere ed elaborare una query per ottenere gli elementi del titolo dei libri il cui prezzo è maggiore di 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
books.xqy
for $x in doc("books.xml")/books/book where $x/price>30
return $x/title
XQueryTester.java
package com.tutorialspoint.xquery;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import com.saxonica.xqj.SaxonXQDataSource;
public class XQueryTester {
public static void main(String[] args){
try {
execute();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (XQException e) {
e.printStackTrace();
}
}
private static void execute() throws FileNotFoundException, XQException{
InputStream inputStream = new FileInputStream(new File("books.xqy"));
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression exp = conn.prepareExpression(inputStream);
XQResultSequence result = exp.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
}
Passaggi per eseguire XQuery su XML
Step 1 - Copia XQueryTester.java in qualsiasi posizione, ad esempio, E: > java
Step 2 - Copia books.xml nella stessa posizione, E: > java
Step 3 - Copia books.xqy nella stessa posizione, E: > java
Step 4- Compila XQueryTester.java usando la console. Assicurati di avere JDK 1.5 o successivo installato sulla tua macchina e che i classpath siano configurati. Per i dettagli su come utilizzare JAVA, vedere il nostro Tutorial su JAVA
E:\java\javac XQueryTester.java
Step 5 - Esegui XQueryTester
E:\java\java XQueryTester
Produzione
Otterrai il seguente risultato:
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Comprendere l'esempio
books.xml rappresenta i dati di esempio.
books.xqy rappresenta l'espressione XQuery che deve essere eseguita su books.xml. Capiremo l'espressione in dettaglio nel prossimo capitolo.
XQueryTester, un programma esecutore XQuery basato su Java, legge books.xqy, lo passa al processore di espressioni XQuery ed esegue l'espressione. Quindi il risultato viene stampato.
Esempio
Di seguito è riportato un documento XML di esempio contenente i record di una libreria di vari libri.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
Di seguito è riportato un documento Xquery di esempio contenente l'espressione di query da eseguire sul documento XML precedente. Lo scopo è ottenere gli elementi del titolo di quei nodi XML in cui il prezzo è maggiore di 30.
books.xqy
for $x in doc("books.xml")/books/book
where $x/price>30 return $x/title
Risultato
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Verifica risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.
Espressioni XQuery
Cerchiamo di capire ogni parte dell'espressione XQuery sopra.
Uso delle funzioni
doc("books.xml")
doc () è una delle funzioni XQuery utilizzata per individuare l'origine XML. Qui abbiamo passato "books.xml". Considerando il percorso relativo, books.xml dovrebbe trovarsi nello stesso percorso in cui è presente books.xqy.
Uso di espressioni XPath
doc("books.xml")/books/book
XQuery utilizza pesantemente le espressioni XPath per individuare la parte richiesta di XML su cui eseguire la ricerca. Qui abbiamo scelto tutti i nodi del libro disponibili nel nodo libri.
Itera gli oggetti
for $x in doc("books.xml")/books/book
XQuery tratta i dati xml come oggetti. Nell'esempio precedente, $ x rappresenta il nodo selezionato, mentre il ciclo for itera sulla raccolta di nodi.
Applica la condizione
where $x/price>30
Poiché $ x rappresenta il nodo selezionato, "/" viene utilizzato per ottenere il valore dell'elemento richiesto; La clausola "where" viene utilizzata per porre una condizione sui risultati della ricerca.
Restituisci il risultato
return $x/title
Poiché $ x rappresenta il nodo selezionato, "/" viene utilizzato per ottenere il valore dell'elemento richiesto, prezzo, titolo; La clausola "return" viene utilizzata per restituire gli elementi dai risultati della ricerca.
FLWOR è un acronimo che sta per "For, Let, Where, Order by, Return". Il seguente elenco mostra ciò che rappresentano in un'espressione FLWOR:
F - Per: seleziona una raccolta di tutti i nodi.
L - Let - Inserisce il risultato in una variabile XQuery.
W - Dove: seleziona i nodi specificati dalla condizione.
O - Ordina per: ordina i nodi specificati secondo i criteri.
R - Return - Restituisce il risultato finale.
Esempio
Di seguito è riportato un documento XML di esempio che contiene informazioni su una raccolta di libri. Useremo un'espressione FLWOR per recuperare i titoli di quei libri con un prezzo maggiore di 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
Il seguente documento Xquery contiene l'espressione di query da eseguire sul documento XML precedente.
books.xqy
let $books := (doc("books.xml")/books/book) return <results> { for $x in $books where $x/price>30
order by $x/price return $x/title
}
</results>
Risultato
<title lang="en">Learn XQuery in 24 hours</title>
<title lang="en">Learn .Net in 24 hours</title>
Verifica risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.
XQuery può anche essere facilmente utilizzato per trasformare un documento XML in una pagina HTML. Dai un'occhiata al seguente esempio per capire come lo fa XQuery.
Esempio
Useremo lo stesso file books.xml. Il seguente esempio utilizza XQuery estrae i dati da books.xml e crea una tabella HTML contenente i titoli di tutti i libri insieme ai rispettivi prezzi.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
Di seguito è riportata l'espressione Xquery che deve essere eseguita sul documento XML precedente.
books.xqy
let $books := (doc("books.xml")/books/book) return <table><tr><th>Title</th><th>Price</th></tr> { for $x in $books order by $x/price
return <tr><td>{data($x/title)}</td><td>{data($x/price)}</td></tr>
}
</table>
</results>
Risultato
<table>
<tr>
<th>Title</th>
<th>Price</th>
</tr>
<tr>
<td>Learn XPath in 24 hours</td>
<td>16.50</td>
</tr>
<tr>
<td>Learn Java in 24 Hours</td>
<td>30.00</td>
</tr>
<tr>
<td>Learn XQuery in 24 hours</td>
<td>50.00</td>
</tr>
<tr>
<td>Learn .Net in 24 hours</td>
<td>70.50</td>
</tr>
</table>
Verifica risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.
Espressioni XQuery
Qui abbiamo usato le seguenti espressioni XQuery:
funzione data () per valutare il valore dell'elemento title e
{} operatore per dire al processore XQuery di considerare data () come una funzione. Se l'operatore {} non viene utilizzato, data () verrà trattato come testo normale.
XQuery è compatibile con XPath. Utilizza espressioni XPath per limitare i risultati della ricerca sulle raccolte XML. Per ulteriori dettagli su come utilizzare XPath, vedere il nostro tutorial su XPath .
Ricorda la seguente espressione XPath che abbiamo usato in precedenza per ottenere l'elenco dei libri.
doc("books.xml")/books/book
Esempi XPath
Useremo il file books.xml e vi applicheremo XQuery.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
Abbiamo fornito qui tre versioni di un'istruzione XQuery che soddisfano lo stesso obiettivo di visualizzare i titoli dei libri con un valore di prezzo maggiore di 30.
XQuery - Versione 1
(: read the entire xml document :)
let $books := doc("books.xml") for $x in $books/books/book where $x/price > 30
return $x/title
Produzione
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
XQuery - Versione 2
(: read all books :)
let $books := doc("books.xml")/books/book
for $x in $books
where $x/price > 30 return $x/title
Produzione
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
XQuery - Versione 3
(: read books with price > 30 :)
let $books := doc("books.xml")/books/book[price > 30] for $x in $books return $x/title
Produzione
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Verifica il risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.
Le sequenze rappresentano una raccolta ordinata di elementi in cui gli elementi possono essere di tipo simile o diverso.
Creazione di una sequenza
Le sequenze vengono create utilizzando parentesi con stringhe all'interno di virgolette o virgolette doppie e numeri in quanto tali. Gli elementi XML possono essere utilizzati anche come elementi di una sequenza.
XQuery Expression
let $items := ('orange', <apple/>, <fruit type="juicy"/>, <vehicle type="car">sentro</vehicle>, 1,2,3,'a','b',"abc") let $count := count($items) return <result> <count>{$count}</count>
<items>
{
for $item in $items
return <item>{$item}</item>
}
</items>
</result>
Produzione
<result>
<count>10</count>
<items>
<item>orange</item>
<item>
<apple/>
</item>
<item>
<fruit type="juicy"/>
</item>
<item>
<vehicle type="car">Sentro</vehicle>
</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>a</item>
<item>b</item>
<item>abc</item>
</items>
</result>
Visualizzazione degli elementi di una sequenza
Gli elementi di una sequenza possono essere iterati uno per uno, utilizzando l'indice o il valore. L'esempio sopra ha iterato gli elementi di una sequenza uno per uno. Vediamo gli altri due modi in azione.
Espressione XQuery (indice)
let $items := (1,2,3,4,5,6)
let $count := count($items)
return
<result>
<count>{$count}</count> <items> { for $item in $items[2] return <item>{$item}</item>
}
</items>
</result>
Produzione
<result>
<count>6</count>
<items>
<item>2</item>
</items>
</result>
Espressione XQuery (valore)
let $items := (1,2,3,4,5,6) let $count := count($items) return <result> <count>{$count}</count>
<items>
{
for $item in $items[. = (1,2,3)]
return <item>{$item}</item>
}
</items>
</result>
Produzione
<result>
<count>6</count>
<items>
<item>1</item>
<item>2</item>
<item>3</item>
</items>
</result>
La tabella seguente elenca le funzioni di sequenza comunemente utilizzate fornite da XQuery.
Suor n | Nome e descrizione |
---|---|
1 | Conta gli elementi in una sequenza. |
2 | Restituisce la somma degli elementi in una sequenza. |
3 | Restituisce la media degli elementi in una sequenza. |
4 | min ($ seq come elemento () *) Restituisce l'articolo con valore minimo in una sequenza. |
5 | max ($ seq come elemento () *) Restituisce l'elemento con valore massimo in una sequenza. |
6 | valori-distinti ($ seq come elemento () *) Restituisce selezionare elementi distinti da una sequenza. |
7 | sottosequenza ($ seq as item () *, $startingLoc as xs:double, $lunghezza come xs: doppia) Restituisce un sottoinsieme della sequenza fornita. |
8 | inserire prima ($seq as item()*, $posizione come xs: intero, $ inserisce come elemento () *) Inserisce un elemento in una sequenza. |
9 | remove ($ seq as item () *, $ position as xs: integer) Rimuove un elemento da una sequenza. |
10 | Restituisce la sequenza inversa. |
11 | indice di($seq as anyAtomicType()*, $target come anyAtomicType ()) Restituisce gli indici come numeri interi per indicare la disponibilità di un elemento all'interno di una sequenza. |
12 | Restituisce l'ultimo elemento di una sequenza quando utilizzato nell'espressione del predicato. |
13 | Utilizzato nelle espressioni FLOWR per ottenere la posizione di un elemento in una sequenza. |
La tabella seguente elenca le funzioni di manipolazione delle stringhe comunemente usate fornite da XQuery.
Suor n | Nome e descrizione |
---|---|
1 | string-length ($ string as xs: string) as xs: integer Restituisce la lunghezza della stringa. |
2 | concat ($ input as xs: anyAtomicType?) as xs: string Restituisce la stringa concatenata come output. |
3 | string-join ($sequence as xs:string*, $delimitatore come xs: string) come xs: string Restituisce la combinazione di elementi in una sequenza separata da un delimitatore. |
La tabella seguente elenca le funzioni di data comunemente utilizzate fornite da XQuery.
Suor n | Nome e descrizione |
---|---|
1 | Restituisce la data corrente. |
2 | Restituisce l'ora corrente. |
3 | Restituisce sia la data corrente che l'ora corrente. |
Di seguito è riportato l'elenco delle funzioni di espressioni regolari comunemente utilizzate fornite da XQuery
Suor n | Nome e descrizione |
---|---|
1 | Restituisce vero se l'input corrisponde all'espressione regolare fornita. |
2 | sostituire($input, $regex, $ string) Sostituisce la stringa di input corrispondente con la stringa data. |
3 | Restituisce una sequenza di elementi che corrispondono all'espressione regolare. |
XQuery fornisce un costrutto if-then-else molto utile per verificare la validità dei valori di input passati. Di seguito è riportata la sintassi del costrutto if-then-else.
Sintassi
if (condition) then
...
else
...
Esempio
Useremo il seguente file books.xml e applicheremo ad esso un'espressione XQuery contenente un costrutto if-then-else per recuperare i titoli di quei libri con un valore di prezzo maggiore di 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
La seguente espressione XQuery deve essere applicata al documento XML precedente.
books.xqy
<result>
{
if(not(doc("books.xml"))) then (
<error>
<message>books.xml does not exist</message>
</error>
)
else (
for $x in doc("books.xml")/books/book
where $x/price>30 return $x/title
)
}
</result>
Produzione
<result>
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
</result>
Verifica il risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.
XQuery fornisce la capacità di scrivere funzioni personalizzate. Di seguito sono elencate le linee guida per creare una funzione personalizzata.
Usa la parola chiave declare function per definire una funzione.
Utilizza i tipi di dati definiti nello schema XML corrente
Racchiudere il corpo della funzione all'interno di parentesi graffe.
Prefisso il nome della funzione con uno spazio dei nomi XML.
La seguente sintassi viene utilizzata durante la creazione di una funzione personalizzata.
Sintassi
declare function prefix:function_name($parameter as datatype?...)
as returnDatatype?
{
function body...
};
Esempio
Il seguente esempio mostra come creare una funzione definita dall'utente in XQuery.
XQuery Expression
declare function local:discount($price as xs:decimal?,$percentDiscount as xs:decimal?) as xs:decimal? { let $discount := $price - ($price * $percentDiscount div 100) return $discount
};
let $originalPrice := 100 let $discountAvailed := 10
return ( local:discount($originalPrice, $discountAvailed))
Produzione
90
Verifica il risultato
Per verificare il risultato, sostituire il contenuto di books.xqy (fornito nel capitolo Configurazione dell'ambiente ) con l'espressione XQuery sopra ed eseguire il programma java XQueryTester.