Standardy służące przetwarzaniu dokumentów XML: XSLT, XPath i XQuery, są ze sobą związane i występują ogólnie rzecz biorąc w dwóch wersjach.
Starsza i prostsza:
Nowsza i bogatsza:
Obecnie jest to też na wykładzie, ale zostało kiedyś napisane, więc niech sobie wisi...
$foo
jest odwołaniem do zmiennej o nazwie foo
. Zmienna musi być dostępna w kontekście w momencie ewaluacji wyrażenia.
Poprawnymi wyrażeniami XPath są literały różnych typów.
Typ wartości | Przykładowe literały |
---|---|
string | '12.5' "He said, ""I don't like it.""" |
integer | 123 5 |
decimal | 12.3 5.0 .23 |
double | 125E2 1.13e-8 |
xs:date("2001-08-25")
(o ile prefiks xs
odnosi się do przestrzeni nazw XML Schema)string(2 + 2)
To samo można uzyskać dzięki rzutowaniu typów:
"2001-08-25" cast as xs:date
Sekwencje można jawnie tworzyć poprzez wyliczenie ich elementów lub podanie przedziałów (dla liczb całkowitych). Całą sekwencję obejmuje się nawiasami, a poszczególne elementy i przedziały rozdziela przecinkami.
Przykłady:
()
– sekwencja pusta("ala")
– singleton równoważny wartości atomowej "ala"
(1, 2,3, 4 ,6, 7, -3)
(1 to 4, 6 to 7, -3)
("ala", 20.5, 2 + 5, //obiekt/opis)
(10, (1, 2), (), (3, 4))
– jest równe (10, 1, 2, 3, 4)
Wyrażeniami XPath są "normalne" wyrażenia arytmetyczne z operatorami
+
-
*
div
idiv
mod
.
Dodawanie i odejmowanie działają także na typach daty i czasu (tzn. do daty można dodać duration itp.).
Poza operatorami arytmetycznymi, są dostępne także logiczne or
i and
.
Przykłady:
2 + 2
12.5 div 3
13 idiv 3
14 mod 3 = 2 and 3 > 2
Istnieją także specjalne operatory dla sekwencji węzłów (w wersji 1.0 "zbiorów węzłów"). Wyniki tych operatorów to sekwencje bez powtórzeń, uporządkowane według porządku dokumentu (nawet jeśli argumenty tego nie spełniały):
union
lub |
– suma zbiorówintersect
– przecięcie zbiorówexcept
– różnica zbiorów
Do porównywania wartości atomowych służą operatory porównania atomowego: eq
, ne
, lt
, le
, gt
i ge
.
Argumenty są rzutowane sa najwęższy wspólny typ, a jeśli takiego nie ma lub jest nim xs:untypedAtomic
, rzutowane na xs:string
.
Dla pewnych kombinacji typów niektóre operatory mogą nie być zdefiniowane, wówczas pojawia się błąd.
Do porównywania sekwencji służą operatory porównania ogólnego: =
!=
<
<=
>
>=
.
Porównanie dla dwóch sekwencji L i R zwraca prawdę wtedy i tylko wtedy, gdy dla chociaż jednej pary:
l (elementu L po atomizacji) oraz r (elementu R po atomizacji) zachodzi porównanie atomowe odpowiadające
zadanemu porównaniu ogólnemu.
Poza tym istnieją operatory porównania specyficzne dla węzłów: is
(identyczność węzłów),
<<
i >>
(porównywanie względem porządku dokumentu).
Przykłady:
5 gt 3
(3) eq 2
() eq 2
(2, 3) eq 2
(2) = (2)
2 = 2
() = 2
(2, 3) = 2
(1, 2) = (2, 3)
(2, 3) = (3, 4)
(1, 2) = (3, 4)
(1, 2) != (1, 2)
//obiekt[9]/opis/text() = //obiekt[10]/opis/text()
//obiekt[9]/opis/text() is //obiekt[10]/opis/text()
//obiekt is //obiekt
W XPath można wywoływać funkcje. Wiele funkcji zdefiniowanych jest w tej rekomendacji.
Funkcje te znajdują się w przestrzeni nazw http://www.w3.org/2005/xpath-functions
. W ewaluatorze XML Spy nie trzeba używać prefiksów,
w XSLT 2.0 zalecane jest używanie prefiksów.
Standardy XSLT i XQuery przewidują definiowanie własnych funkcji. Definiowanie własnych funkcji dostępne jest także poprzez specjalne interfejsy programistyczne (np. EXSLT).
Przykłady:
not(false()) eq true()
concat("Ala ", "ma", " kota")
sum(//obiekt/@parzysty)
moje:moja_funkcja(12, //jakieś_elementy)
for
Wyrażenie for $x in E1 return E2
może być obliczone w następujący (lub równoważny) sposób:
W jednym forze można związać wiele zmiennych.
Przykłady:
for $n in (10, 20, 30.5) return $n + 5
for $x in //obiekt return concat("Obiekt o nazwie: ", $x/@nazwa)
for $x in (1 to 5), $y in (3 to 5) return 10 * $x + $y
Obliczenie wyrażenia if (W) then E1 else E2
sprowadza się
do obliczenia W, a następnie, w zależności od wyniku, E1 lub E2.
Przykład:
for $x in //obiekt return
if($x/@nazwa) then concat("Obiekt ma nazwę: ", $x/@nazwa)
else "Obiekt nie ma nazwy"
Wyrażenie some $var in E1 satisfies E2
zwraca prawdę gdy przynajmniej
jeden element sekwencji obliczonej z E1 spełnia wyrażnie E2, tzn. E2
w kontekście wzbogaconym o zmienną var z wartością równą elementowi sekwencji wylicza się do prawdy.
Analogicznie every $var in E1 satisfies E2
zwraca prawdę gdy każdy
element sekwencji obliczonej z E1 spełnia wyrażenie E2.
Obliczanie wyrażeń kwantyfikowanych może odbywać się w dowolnej kolejności, może być leniwe i może zostać przerwane po wystąpieniu dynamicznego błędu.
Przykłady:
some $x in (1,2,3) satisfies $x = 3
(prawda)every $x in (1,2,3) satisfies $x = 3
(fałsz)some $x in (//obiekt, 'aaa') satisfies $x is //obiekt[2]
(prawda lub błąd w zależności od kierunku ewaluacji,
spróbujcie zmienić kolejność w sekwencji)To wyrażenia najbardziej charakterystyczne dla XPath. Służą do odczytywania (adresowania) fragmentów dokumentu.
Ścieżka względna ma następującą postać:
krok/krok ...
gdzie krok to:
oś::test-węzłów [predykat] [predykat] ...
Ścieżka bezwzględna dodatkowo zaczyna się od /
lub //
.
Obliczenie wyrażenia zaczyna się od węzła konktekstowego (ścieżka względna) lub węzła dokumentu (ścieżka bezwzględna). W każdym kroku na wejściu ("z lewej strony") mamy jakąś sekwencję węzłów. Dla każdego węzła z tej sekwencji krok prowadzi do jakiejś sekwencji węzłów (np. dzieci). Wszystkie uzyskane w ten sposób węzły tworzą sekwencję, która jest wynikiem kroku i "przechodzi na prawą stronę".
Wynikiem całej ścieżki jest sekwencja węzłów, która jest wynikiem ostatniego kroku.
Oś wskazuje "kierunek", w którym podążamy w danym kroku (tak naprawdę określa jakąś sekwencję węzłów). Test węzłów pozwala na proste wybranie tylko niektórych węzłów z danej osi. Predykaty to dowolne wyrażenia dodatkowo filtrujące węzły.
Zasadniczo są dwa rodzaje testów: po rodzaju węzła i po nazwie. Oto reprezentatywne przykłady:
node()
– dowolne węzły,element()
– dowolne elementy,text()
– dowolne węzły tekstowe,processing-instruction()
– dowolne instrukcje przetwarzania,comment()
– dowolne komentarze,attribute()
– dowolne atrybuty,element(obiekt)
– elementy o nazwie obiekt
,element(*, TGość)
– elementy o dowolnej nazwie, o typie TGość
(ustalonym na podstawie załączonej schemy),attribute(licznik, xs:integer)
– atrybuty o nazwielicznik
i typie xs:integer
(ustalonym na podstawie załączonej schemy),obiekt
– węzły o nazwie obiekt
w przestrzeni nazw o pustym identyfikatorze (albo domyślnej przestrzeni nazw?),pre:obiekt
– węzły o nazwie obiekt
w przestrzeni nazw wskazanej prefiksem pre
,*:obiekt
– węzły o lokalnej nazwie obiekt
,pre:*
– węzły w przestrzeni nazw o prefiksie pre
.Każda oś wskazuje sekwencję (ew. pustą) węzłów. Kolejność węzłów w sekwencji jest zgodna lub przeciwna do ich wystąpienia w dokumencie (w zależności od tego czy oś jest w przód czy w tył).
fn:get-in-scope-prefixes
i fn:get-namespace-uri-for-prefix
.
Przykłady:
/child::lista/child::obiekt
– sekwencja wszystkich elementów obiekt
z dokumentuchild::obiekt
– sekwencja wszystkich elementów obiekt
, które są dziećmi "węzła konktekstowego",
jest sens obliczać z elementu lista
attribute::*
– wszystkie atrybuty węzła konktekstowego (sprawdź w obiekcie)preceding-sibling::obiekt
– sprawdź w obiekcie w środku dokumentu oraz w dzieciach obiektupreceding::obiekt
– sprawdź w obiekcie w środku dokumentu oraz w dzieciach obiektuchild::attribute()
– czy są to atrybuty bieżącego węzła?attribute::node()
– a to?/child::lista/child::obiekt/attribute::node()
/descendant-or-self::node()
/descendant-or-self::element()/attribute::attribute()
Można stosować różne skróty notacyjne.
Domyślną osią jest child
, rozpoczęcie nazwy węzła od @
oznacza przejście na oś atrybutów.
//
oznacza wszystkich potomków (nie tylko dzieci jak /
),
..
oznacza rodzica (parent::node()
), natomiast .
(kropka) węzeł kontekstowy (self::node()
).
Przykłady:
/lista/obiekt
obiekt
@*
//node()
//*
(czym się różnią?)Predykaty pozwalają na sprawdzanie własności, których nie da się wyrazić w samych testach węzłów. Predykat jest obliczany dla każdego węzła z sekwencji (wyniku wyrażenia z lewej strony predykatu), tzn. kolejne węzły są ustawiane jako węzły kontekstowe. Jeśli dla danego węzła test zachodzi, węzeł znajdzie się w wynikowej sekwencji („przejdzie na prawą stronę”). Jeśli test nie zachodzi, węzeł zostanie „zatrzymany”.
Predykatem może być dowolne wyrażenie XPath. Jeśli jego wynikiem jest wartość numeryczna, wówczas
predykat zachodzi wtw gdy pozycja testowanego węzła jest równa tej liczbie.
Jeśli jego wynikiem nie jest wartość numeryczna, wówczas wynik jest rzutowany na xs:boolean
.
W szczególności pusta sekwencja jest rzutowana na fałsz, a sekwencja z jakimkolwiek węzłem na początku na prawdę.
Przykłady:
//obiekt[2]
– drugi obiekt//obiekt[position() > 5]
– obiekty o pozycji > 5//obiekt[length()]
– ostatni obiekt//obiekt[@nazwa='drugi']
– obiekt z atrybutem nazwa równym drugi
//obiekt[@nazwa]
– obiekt z jakimkolwiek atrybutem nazwa//obiekt[@nazwa and position() = 6]
– ...//obiekt[@nazwa][position() = 6]
– ...//obiekt[@nazwa]/opis
– ...Take files example.xml and example.xsl.
Use appropriate XPaths to select and emphase the following elements (if possible):