XQuery Wprowadzenie Procesory XQuery: wbudowane w systemy

Transkrypt

XQuery Wprowadzenie Procesory XQuery: wbudowane w systemy
XQuery
Wprowadzenie
Procesory XQuery: wbudowane w systemy baz danych oraz „wolnostojące”.
Saxon (w wersji 8 i wyższej) jest procesorem języków: XSLT i XQuery.
Wywołanie saxona w trybie xquery (-o plik.wy jest opcjonalne):
java -Xmx256M net.sf.saxon.Query -s plik.we -o plik.wy plik.xq
Model danych oparty jest o pojęcie: sekwencji. Sekwencja składa się z zero lub
więcej składowych (elementów). Składowa to albo wartość atomowa (zgodna
z jednym z typów okreśonych w XML Schema: liczba, napis, data, itp.), albo
węzeł (node, węzłów jest 7 typów).
XQuery to język funkcyjny, tj. składa się z wyrażeń zwracających wartość (no
side effects). Struktura programu: prolog (opcjonalny) oraz część główna. Część
główna składa się z wyrażenia. Składniki wyrażeń:
Przykładowe dane:
<?xml version=’1.0’ encoding=’iso-8859-1’?>
<classification stage=’5’>
<rider time=’5.28.01’ nat=’Ger’ team=’Gerolsteiner’><name>Fabian Wegmann</
<rider df=’0.00’ nat=’Ita’ team=’Quick Step’><name>Filippo Pozzato</name><
<rider df=’0.00’ nat=’Slo’ team=’Phonak Hearing Systems’><name>Uros Murn</
<rider df=’0.02’ nat=’Ita’ team=’Liquigas-Bianchi’><name>Danilo Di Luca</n
<rider df=’0.02’ nat=’Lux’ team=’Fassa Bortolo’><name>Kim Kirchen</name></
<rider df=’0.02’ nat=’Ned’ team=’Rabobank’><name>Michael Boogerd</name></r
...
<rider time=’DNF’ nat=’Bel’ team=’Davitamon-Lotto’><name>Bert Roesems</nam
<rider time=’DNS’ nat=’Bel’ team=’Davitamon-Lotto’><name>Peter Van Petegem
<rider time=’DNS’ nat=’Ita’ team=’Lampre-Caffita’><name>Alessandro Ballan<
</classification>
Wyrażenia XPath:
(:-- wszyscy wlosi jadący w Domina-Vacanze :)
//rider[starts-with(@team, "Domina")][@nat=’Ita’]/name
albo
(:-- wszyscy wlosi jadący w Domina-Vacanze :)
for $name in //rider[starts-with(@team, "Domina")][@nat=’Ita’]
return $name/name
c TP: anything: 17 grudnia 2008
1
Konstruktory:
W najprostrzej postaci mają składnię identyczną jak obiekty, które definiują.
Jeżeli jakaś część elementu/atrybutu ma być wyliczona dynamicznie należy użyć
odpowiedniego wyrażenia wewnątrz nawiasów klamrowych
for $n in //rider[starts-with(@team, "Domina")][@nat=’Ita’]
return <r> {
$n/@team,
$n/@nat,
$n/name
}
</r>
Jeżeli także nazwa elementu/arybutu ma być wyliczana można wykorzystać
wariant konstruktora postaci:
element nazwa
{zawartość}
attribute nazwa {zawartość}
Wyrażenia FLWOR:
Od pierwszych liter słów kluczowych: for, let, where, order, return. Część for to
pętla po elementach sekwencji (lista). Let pozwala zadeklarować zmienną (także
może to być sekwencja). Return zawiera wyrażenie obliczane dla każdego
elementu sekwencji.
(: wypisz trzech pierwszych z kazdego etapu :)
for $i in (1,2,3) return //stage/rider[$i]
(: tytuły książek, które mają więcej niż jednego autora :)
for $b in doc("books.xml")//book
let $c := $b//author
where count($c) > 2
return $b/title
Cześć where określa warunek:
(: Wypisz tytuły książek tańsze niż 50 :)
for $b in doc ("plik.xml")//book
where $b/price < 50.0
return $b/title
Klauzule where oraz order są opcjonalne:
c TP: anything: 17 grudnia 2008
2
(: Wypisz tytuły książek posortowane tańsze niż 50 :)
for $b in doc ("plik.xml")//book
where $b/price < 50.0
order by $b/price descending
return $b/title
Część return wyrażenia FLWOR jest obowiązkowa i określa co ma być
zwrócone przez wyrażenie.
(: wypisz włochów :)
for $r in //rider
where $r/@nat=’Ita’
return $r/name
(: źle :-)
let $authors := for $a in doc("books.xml")//author
order by $a/last, $a/first (: sortowanie wg last i first :-)
return $a
return $authors/last
(: dobrze :)
for $a in doc("books.xml")//author
order by $a/last, $a/first (: sortowanie wg last i first :-)
return $a/last
Klauzula for może zawierać wielokrotne związania zmiennych, często z różnych
źródeł danych:
for $t in doc("books.xml")/isbn
$e in doc("sellers.xml")/book
where $t = $e/@isbn
return <b>$t</b>
Różne
Klauzula at określa pozycję elementu w sekwencji:
(: wypisz cały etap dodając explicite miejsce :)
for $r at $p in //stage/rider return <r p=’{$p}’> $r </r>
Klauzula distinc-values usuwa duplikaty z sekwencji:
distinct-values(doc("books.xml)//author/last)
c TP: anything: 17 grudnia 2008
3
Definiowanie własnych funkcji
W XQuery istnieje możliwość definiowania własnych funkcji, których następnie
można używać w wyrażeniach (także w innych funkcjach). Funkcje powinny być
zadeklarowane w prologu dokumentu XQuery (przed ciałem zapytania, obok
innych deklaracji).
Własne funkcje powinno się definiować we własnych przestrzeniach nazw lub w
predefiniowanej przestrzeni nazw o prefiksie local.
(: reverse(1 to 5)
:)
define function reverse($items)
{
let $count := count($items)
for $i in 0 to $count
return $items[$count - $i]
}
z podaniem typów argumentów i zwracanej wartości:
(: reverse(1 to 5)
:)
define function is-document-ele ($e as element())
as xs:boolean
{
if ($e/.. instance of document-node())
then true ()
else false ()
}
albo
define function day-of-week ($e as xs:date) as xs:string
{ ... }
Odczyt zewnętrznych dokumentów
doc(URI) zwraca węzeł dokumentu identyfikowny przez URI
collection(URL) zwraca zbiór węzłów identyfikowny przez URI
c TP: anything: 17 grudnia 2008
4