XPath výraz může vracet hodnotu jednoho z následujících typů:
logická hodnota (true
nebo
false
)
číslo
textový řetězec
množina uzlů ze stromu vstupního dokumentu
část stromu výstupního dokumentu, kterou lze podle potřeby vložit do výstupu (tento typ přidává do XPathu až XSLT)
V XSLT se XPath výrazy používají zejména pro:
výběr uzlů, které chceme zpracovat
<xsl:apply-templates select="polozka[@cena='bomba']"/>
vytvoření vzoru pro porovnávání uzlu se šablonou (v tomto případě lze používat jen podmnožinu XPath výrazů, hovoří se proto o vzoru)
<xsl:template match="polozka">
vytvoření textu vkládaného do výstupního dokumentu
<xsl:value-of select="sum(polozka/cena[@dph='5'])*1.05 + sum(polozka/cena[@dph='22'])*1.22"/>
První dva případy zachycují další důležitou vlastnost XPath a
XSLT – XPath výraz může podle kontextu vracet buď seznam uzlů
(to v prvním případě) nebo je jen vyhodnocen a má hodnotu
true
, pokud existuje nějaký uzel
s danými kritérii.
Nyní se podrobněji podíváme právě na XPath konstrukce, které umožňují výběr nebo testování části dokumentu.
Uzly se ze stromu dokumentu vybírají na základě námi stanovených kritérií a vzájemné pozice uzlů. Výrazy přitom mohou strom dokumentu prohledávat z několika míst:
V tomto případě musíme použít relativní cestu (ta nezačíná
znakem `/
').
Aktuální uzel určuje XSLT. V rámci šablony je aktuálním uzlem uzel, pro který byla šablona aktivována. Uvnitř cyklů je aktuálním uzlem uzel právě vybraný z množiny zpracovávaných uzlů.
Musíme použít absolutní cestu (ta začíná znakem `/
'). Prohledávání dokumentu pak pokračuje od
kořene stromu dokumentu, bez ohledu na aktuální uzel.
XPath nabízí několik funkcí, které nám umožňují přesunout se na
určité místo ve stromu dokumentu. Takovou funkcí je například
id()
, která vybere uzel
s daným ID. Za takto začatou cestou můžeme používat již jen
relativní cesty.
Funkce jako id()
mohou být
použity jen na začátku cesty.
Cesta se může skládat z několika částí, které se oddělují
znakem `/
'. Kromě první části cesty
musíme používat relativní cesty.
Jednotlivé části cesty jsou procházeny zleva doprava a postupně se tak upřesňuje výsledek (snižuje se počet vyhovujících uzlů).
Každá část cesty se skládá z několika komponent:
identifikátoru osy – ten určuje, ve kterém směru se budeme od aktuálního uzlu pohybovat
testu uzlu – umožňuje vybírat jen některé uzly na základě jejich typu a názvu
predikátů – vybrané uzly můžeme dále filtrovat pomocí podmínek, které jsou testována pro každý uzel
Pohyb po určité ose stromu dokumentu se zapisuje pomocí identifikátoru osy následovaného dvěma dvojtečkami. Graficky je význam jednotlivých os zachycen na obrázku 2.2 – „Vztahy mezi uzly ve stromové reprezentaci XML dokumentu“. XPath definuje celkem třináct os.
ancestor::
Rodič aktuálního uzlu a všichni jeho další předci až ke kořenu stromu dokumentu. Uzly jsou uspořádány v opačném pořadí než v dokumentu.
ancestor-or-self::
Aktuální uzel a všichni jeho další předci až ke kořenu stromu dokumentu. Uzly jsou uspořádány v opačném pořadí než v dokumentu.
attribute::
Uzly odpovídající všem připojeným atributům, pořadí není nijak pevně definováno.
child::
Všechny děti aktuálního uzlu ve stejném pořadí jako v dokumentu.
descendant::
Všichni potomci aktuálního uzlu ve stejném pořadí jako v dokumentu.
descendant-or-self::
Aktuální uzel a všichni jeho potomci ve stejném pořadí jako v dokumentu.
following::
Všechny uzly následující za koncem aktuálního uzlu ve stejném pořadí jako v dokumentu.
following-sibling::
Všechny následující uzly, které jsou sourozenci aktuálního uzlu, ve stejném pořadí jako v dokumentu.
namespace::
Uzly odpovídající deklarovaným jmenným prostorům, pořadí není nijak pevně definováno.
parent::
Rodič aktuálního uzlu.
preceding::
Všechny uzly, jejichž všichni potomci jsou v dokumentu ještě před aktuálním uzlem, v opačném pořadí než v dokumentu.
preceding-sibling::
Všechny předcházející uzly, které jsou sourozencem aktuálního uzlu. Uzly jsou uspořádány v opačném pořadí než v dokumentu.
self::
Aktuální uzel.
Opačné uspořádání elementů na některých osách má vliv jen na testování pořadí uzlů. Výsledná množina uzlů je vždy uspořádána ve stejném pořadí jako se vyskytuje v dokumentu.
Test uzlu nám umožňuje vybrat si jen některé uzly na vybrané ose. Testovat můžeme název uzlu a jeho typ.
Při prohledávání elementů, atributů nebo jmenných prostorů můžeme použít přímo jejich název. Např.:
child::para attribute::lang
Můžeme rovněž použít znak `*
', který zastupuje uzel s libovolným
názvem.
Pokud chceme najít elementy nebo atributy, které patří do
určitého jmenného prostoru, můžeme použít test uzlu `
'.prefix
:*
Pokud chceme vybírat jiné uzly než elementy, atributy a jmenné prostory, můžeme použít ještě následující testy:
processing-instruction()
– vybere všechny uzly odpovídající instrukci pro
zpracování;
processing-instruction(
– vybere všechny instrukce pro zpracování s daným
jménem;cíl
)
comment()
– vybere
všechny komentáře;
text()
– vybere všechny
textové uzly;
node()
– vybere všechny
uzly bez ohledu na jejich typ.
Testy uzlů na různých osách se používají velice často. K nejčastěji používaným konstrukcím proto existují zkrácené zápisy.
Samotný název uzlu nebo test uzlu je považován jako pohyb po ose
dětí (child::
).
para child::para text() child::text() * child::*
Pokud se chceme pohybovat po atributech, můžeme místo attribute::
použít zavináč (`@
').
@id attribute::id
Na aktuální uzel se můžeme odkazovat zkráceným zápisem `.
' místo self::node()
.
Při použití tečky nemůžeme použít predikát v hranatých závorkách.
Na rodičovský uzel se můžeme odkazovat zkráceným zápisem
`..
' místo parent::node()
.
Při použití dvou teček nemůžeme použít predikát v hranatých závorkách.
Pokud potřebujeme prohledávat potomky do libovolné hloubky,
můžeme místo poněkud dlouhého /descendant-or-self::node()/
použít
`//
'.
//nadpis /descendant-or-self::node()/child::nadpis
V každé části cesty můžeme použít jeden nebo více predikátů, které sníží počet vyhovujících uzlů. Predikáty se zapisují do hranatých závorek a vyhodnocují se pro každý uzel, který zatím vyhovuje cestě. Pokud je pro uzel predikát pravdivý, uzel zůstává ve množině uzlů, které vyhovují cestě.
Při vyhodnocování predikátu se mění aktuální uzel na uzel, pro který se testuje predikát.
Predikát se vyhodnocuje jako logická hodnota, která filtruje uzly. Výraz použitý v predikátu může vracet různé typy a podle toho se pak vyhodnotí logická hodnota predikátu.
číselná hodnota – pokud predikát obsahuje výraz, který vrací číslo, chápe se jako pozice v množině uzlů na ose, po které se v dané části cesty pohybujeme.
Uzly jsou číslovány od jedničky. Pokud se pohybujeme po reverzních osách (ancestor, preceding), jsou uzly číslovány v opačném pořadí než v dokumentu. Číselná hodnota tak spíše odpovídá pojmu vzdálenost.
Pravdivou hodnotu má predikát pouze pro uzel s daným pořadím.
množina uzlů – jako výraz
v predikátu můžeme použít XPath výraz, který vrací množinu uzlů.
Pokud je množina uzlů neprázdná, má predikát hodnotu true
, v opačném případě false
.
ostatní výrazy – ostatní výrazy jsou převedeny na logickou hodnotu a jejich výsledek je i hodnotou predikátu pro daný uzel.
Pokud máme více predikátů za sebou, vyhodnocují se postupně zleva doprava.
Pro první pokusy s XPath je dobré využít nějaký nástroj,
který nám jednoduše a názorně zobrazí výsledky XPath výrazů. Jeden
takový nástroj je k dispozici na adrese http://www.pluralsight.com/toolcontent/xpath-expression-builder-4.zip.
Tato pomůcka umí vyhodnocovat výrazy, které vracejí seznam uzlů, a je
v ní možné podle potřeba měnit kontextový uzel. Spustit ji můžete
otevřením souboru src/xpathexpr/xpath.htm
.
Po spuštění programu si můžeme vybrat XML soubor, pro který chceme vytvářet XPath výrazy. Do dalšího vstupního pole můžeme zadávat XPath výrazy a sledovat, které části dokumentu jim vyhoví.
Pro zkoušení XPath výrazů použijeme následující ukázkový dokument XML.
Příklad 2.2. Ukázkový XML dokument s katalogem zboží – katalog.xml
<?xml version="1.0" encoding="utf-8"?> <katalog> <info> <firma>Sony</firma> <adresa>Nedůležitá, NěkdeTown</adresa> <obdobi>zima 2001</obdobi> </info> <polozka kod="mxd-d4"> <nazev>MiniDisc kombinovaný s CD přehrávačem</nazev> <kategorie>MiniDisc</kategorie> <cena>14990</cena> <popis>Kombinace MD a CD pro pohodlné nahrávání z CD<br/> přepis <b>vysokou rychlostí</b> z CD<br/> nahrávání v LP režimu (4x)<br/> 20 bitový A/D převodník<br/>funkce Time Machine Recording<br/> funkce sf Edit<br/> nízká spotřeba v pohotovostním režimu</popis> </polozka> <polozka kod="mds-ja555es_n"> <nazev>MiniDisc rekordér řady ES</nazev> <kategorie>MiniDisc</kategorie> <cena>34990</cena> <popis>plné editační možnosti<br/> zásuvková mechanika pro vkládání MD<br/> Pitch Control<br/> proudový pulsní D/A převodník<br/> 24bitový A/D převodník<br/> digitální filtr s proměnným koeficientem<br/> dvojitý transformátor s kruhovým jádrem (R-Core)<br/> systém DSP ATRAC typu R<br/> digitální ovládání záznamové úrovně<br/> dva optické digitální výstupy + koaxiální digitální vstup<br/> ovládání A1 (Control A1)<br/> provedení <b>ve zlaté barvě</b></popis> <foto href="MDSJA555ES_N.jpg"/> </polozka> <polozka kod="str-de135"> <nazev>Stereo receiver a zesilovač</nazev> <kategorie>Receiver</kategorie> <cena>5990</cena> <popis>2 x 60W (DIN 4 Ohm)<br/> 3 audiovstupy<br/>tuner RDS/EON<br/>30 předvoleb, korekce tónu a vyvážení<br/>digitální zpracování signálu - DSP<br/> systémový dálkový ovladač </popis> <foto href="STRDE135.jpg"/> </polozka> <polozka kod="mz-r90"> <nazev>MD Walkman</nazev> <kategorie>MiniDisc</kategorie> <cena>12990</cena> <popis>MD Walkman s možností záznamu<br/> <b>nejmenší na světě</b><br/> tělo přístroje z magnézia - výjimečně nízká hmotnost<br/> Pop Up Eject mechanismus<br/>až 14,5 hodin záznamu / 29 hodin reprodukce (Ni-MH + AA baterie)<br/> 40 sec. ESP, Mega Bass<br/> dálkové ovládání s podsvětleným LCD displejem (9 znaků) s editovacími funkcemi<br/>možnost pojmenování skladeb a disku během záznamu<br/> možnost monofonního záznamu v LP režimu (až 160 min.)<br/> LCD displej na přístroji<br/> paměť pro často užívaná slova (cca 40 výrazů po 10 znacích)<br/>možnost kopírování CD textu<br/>linkový vstup / výstup, optický vstup, vstup pro mikrofon<br/>zásuvka pro napájení ze sítě, AC adaptér, dobíjecí Ni-MH baterie</popis> <foto href="MZR90.jpg"/> </polozka> <polozka kod="ss-mb215"> <nazev>3pásmové reproduktory</nazev> <kategorie>Reproduktory</kategorie> <cena>3990</cena> <popis>párové, regálové, 3pásmové<br/> max. zatížitelnost 120W<br/>impedance 8 Ohm<br/> bassreflex<br/>magneticky stíněné<br/> odnímatelné mřížky<br/> rozměry: 220 x 518 x 230 mm</popis> </polozka> <polozka kod="ss-cr490"> <nazev>Sada AV reproduktorů</nazev> <kategorie>Reproduktory</kategorie> <cena>5990</cena> <popis>2 x zadní, 1 x centrální, 2 pásmové<br/> maximální zatížitelnost zadní: 120 W, centrální: 150 W<br/> impedance 8 Ohm</popis> </polozka> </katalog>
Pokud zapisujeme výrazy v XPath samostatně, je za aktuální uzel považován kořen stromu dokumentu. Následující přehled obsahuje ukázky nejpoužívanějších druhů výrazů pro výběr uzlů.
katalog
Vybere všechny elementy katalog
, které jsou dětmi aktuálního
uzlu.
./katalog
Vybere všechny elementy katalog
, které jsou dětmi aktuálního
uzlu.
/katalog
Vybere všechny elementy katalog
, které jsou dětmi kořenové uzlu.
Takový element může být v dokumentu maximálně jeden a je to
kořenový element.
*
Vybere všechny elementy, které jsou dětmi aktuálního uzlu.
katalog/*
Vybere všechny elementy, které jsou dětmi elementu katalog
, který je dítětem aktuálního
uzlu.
text()
Vybere všechny textové uzly, které jsou dětmi aktuálního uzlu.
//text()
Vybere všechny textové uzly v celém dokumentu.
id('mz-r90')
Vybere uzel, který má atribut typu ID nastaven na hodnotu
mz-r90
. Pokud chceme používat funkci id()
, musíme mít k dokumentu připojené
DTD, ve kterém mají některé z atributů typ ID.[1]
@href
Vybere atribut href
aktuálního uzlu.
foto/@href
Vybere atribut href
elementu foto
, který je dítětem
aktuálního uzlu.
@*
Vybere všechny atributy aktuálního uzlu.
//*[@*]
Vybere všechny elementy dokumentu, které mají alespoň jeden atribut.
polozka[1]
Vybere první element polozka
,
který je dítětem aktuálního uzlu.
/katalog/polozka[1]
Vybere první element polozka
,
který je dítětem elementu katalog
,
který je kořenovým elementem dokumentu.
polozka[last()]
Vybere poslední element polozka
, který je dítětem aktuálního
uzlu.
*/nazev
Vybere všechny elementy nazev
, které jsou vnoučaty (dětmi dětí)
aktuálního uzlu.
/katalog/polozka[4]/*[3]
Vybere třetí podelement, ve čtvrté položce katalogu. Výraz není
vztažen k aktuálnímu uzlu, ale ke kořenovému uzlu, protože jsme
na začátku výrazu použili znak `/
'. Kořenový uzel
má jen jediné dítě, a tím je kořenový element dokumentu.
katalog//cena
Vybere všechny elementy cena
,
které jsou potomky elementu katalog
, který je dítětem aktuálního
uzlu.
//cena
Vybere všechny elementy cena
,
které jsou potomky kořenového uzlu. To v praxi znamená, že jsou
vybrány všechny elementy cena
,
které se nacházejí ve stejném dokumentu jako aktuální uzel.
.
Vybere aktuální uzel.
.//br
Vybere všechny elementy para
,
které jsou potomky aktuálního uzlu.
..
Vybere rodiče aktuálního uzlu.
id('mz-r90')/../info/firma
Pomocí `..
' se lze velice
jednoduše pohybovat vzhůru ve struktuře dokumentu.
//polozka[kategorie='MiniDisc']/popis
Vybere všechny elementy popis
, které jsou dětmi elementu polozka
, v případě, že podelement kategorie
v položce má hodnotu ‚MiniDisc‘.
Lidsky řečeno vybere popis všech minidisků v katalogu.
/katalog/polozka[kategorie='MiniDisc']
Vybere element polozka
, který
je dítětem kořenového elementu katalog
, pokud obsahuje jako dítě element
kategorie
s textem
MiniDisc
.
//polozka[kategorie='MiniDisc'][3]
Vybere třetí element polozka
,
z celého dokumentu, který má podelement
kategorie
nastaven na hodnotu
MiniDisc
.
//polozka[3][kategorie='MiniDisc']
Vybere třetí element polozka
,
z celého dokumentu, pouze pokud má zároveň podelement
polozka
nastaven na hodnotu
MiniDisc
. Omezující podmínky v hranatých
závorkách jsou tedy vyhodnocovány postupně zleva doprava.
self::polozka
Vybere aktuální uzel, pokud je to element se
jménem polozka
.
preceding::*[1]
Vybere poslední element, který se nachází před aktuálním uzlem.
preceding-sibling::*[1]
Vybere poslední element, který se nachází před aktuálním uzlem a je na stejné úrovni (je to sourozenec).
following::*[1]
Vybere první element, který se nachází za aktuálním uzlem.
Vyhodnocování každého XPath výrazu probíhá v kontextu, který je charakterizován následujícími údaji:
aktuální uzel;
pozice aktuálního uzlu v seznamu kontextových uzlů;
velikost kontextu;
přiřazené proměnné;
dostupné funkce;
deklarace jmenných prostorů – použijí se pokud výraz používá prefixy jmenných prostorů.
Při vyhodnocování cesty v XPath výrazu se mění aktuální uzel a seznam kontextových uzlů.
Seznam kontextových uzlů je množina uzlů, se kterou se pracuje.
Na počátku vyhodnocování XPath výrazu je obvykle definována výrazem
v atributu select
u některého z XSLT příkazů (<xsl:apply-templates>
nebo <xsl:for-each>
). Postupně se seznam
kontextových uzlů mění, jak se prochází po jednotlivých částech
cesty a je tvořen vybranými uzly na dané ose.
Aktuální uzel je vždy součástí seznamu kontextových uzlů.
Kontextové uzly jsou číslovány od jedné a pozice aktuálního uzlu je
dostupná pomocí funkce position()
. Počet uzlů v kontextu je
dostupný pomocí funkce last()
.
Když zapisujeme pomocí predikátu pozici uzlu mezi v kontextu, používáme většinou zápis typu:
[3]
Ten je ve skutečnosti zkráceným zápisem složitějšího výrazu:
[position()=3]
Výše popsaný kontext pro vyhodnocování má některé důsledky, které nejsou na první pohled zřejmé. Například dotaz
//*[2]
Nevybere druhý element v celém dokumentu. Jedná se totiž o zkrácený zápis dotazu
/descendant-or-sef::node()/child::*[2]
který vybere všechny elementy, které jsou druhé dítě svého
rodiče. Pro výběr druhého elementu v celém dokumentu musíme použít
závorky, aby se výsledek výrazu //*
chápal jako
množina kontextových uzlů.
(//*)[2]
XPath výrazy můžeme skládat pomocí několika operátorů.
Do této kategorie patří operátor `|
', který se použije v případech, kdy
chceme aby jeden XPath výraz vracel výsledek jako sjednocení několika
dalších výrazů. Když budeme chtít z dokumentu vybrat všechny
elementy para
a title
, můžeme použít výraz:
//para | //title
V predikátech můžeme používat obvyklé logické spojky
and
a or
, které mají obvyklý význam. Složitější
výrazy můžeme podle potřeb doplnit závorkami. Pro výběr druhé a třetí
položky v nějakém dokumentu můžeme použít např. následující
výraz:
//polozka[position()=2 or position()=3]
Další ukázka vybírá ty položky faktury, které mají 5% sazbu DPH a jsou na více než 60000 Kč.
//polozka[cena/@dph=5 and cena>60000]
Pokud potřebujeme vytvořit negaci, musíme použít trošku
netypický funkcionální zápis využívající funkci
not()
.
//polozka[not(cena/@dph=5) and cena>60000]
V podmínkách můžeme používat běžné relační operátory, které známe z ostatních jazyků:
=
– porovnání dvou
výrazů;
!=
– nerovnost;
<=
– menší nebo
rovno;
<
– menší;
>=
– větší nebo
rovno;
>
– větší;
Vzhledem k tomu, že XPath výrazy se často zapisují
v XSLT stylech, které jsou samy o sobě XML dokumenty, musíme
znak <
zapisovat pomocí
odpovídající znakové entity <
.
Kromě cest, které vybírají množiny uzlů z dokumentu, můžeme v XPath používat několik funkcí. Ty se hodí v predikátech a v případech, kdy má XPath výraz vracet něco jiného než množinu uzlů.
S některými funkcemi jsme se již seznámili, zde si je pro přehlednost uvedeme všechny.
Vrací lokální část názvu uzlu (tj. pokud je uzel v určitém jmenném prostoru, vrací se jeho název bez prefixu).
řetězec local-name(
seznam uzlů)
Pokud je seznam uzlů prázdný nebo první uzel nemá název, vrací funkce prázdný řetězec. Pokud je funkce volána bez parametru, jako seznam uzlů se předá aktuální uzel.
Vrací URI adresu jmenného prostoru, do kterého patří uzel.
řetězec namespace-uri(
seznam uzlů)
Pokud je seznam uzlů prázdný nebo první uzel nemá název, vrací funkce prázdný řetězec. Pokud je funkce volána bez parametru, jako seznam uzlů se předá aktuální uzel.
Převede libovolný objekt na řetězec.
řetězec string(
objekt libovolného
typu)
Pro formátování čísel je vhodnější použít funkci format-number()
.
Otestuje, zda řetězec na svém začátku obsahuje hledaný řetězec.
boolean starts-with(
řetězec, hledaný řetězec)
Vrací část řetězce, která se vyskytuje před zadaným řetězcem.
řetězec substring-before(
řetězec, hledaný řetězec)
Vrací část řetězce, která se vyskytuje za zadaným řetězcem.
řetězec substring-after(
řetězec, hledaný řetězec)
Vrací část řetězce.
řetězec substring(
řetězec, začátek, počet znaků)
Znaky jsou v řetězci číslovány od jedničky. Pokud poslední parametr vynecháme, jsou vráceny všechny znaky od dané pozice až do konce.
Vrací délku (počet znaků) řetězce.
číslo string-length(
řetězec)
Pokud funkci zavoláme bez parametrů, převede se aktuální uzel na řetězec a funkce pak vrátí jeho délku.
Odstraní z řetězce přebytečné mezery.
řetězec normalize-space(
řetězec)
Pokud funkci zavoláme bez parametrů, převede se aktuální uzel na řetězec a použije jako parametr.
Funkce k slouží k jednoduchému překladu znaků v řetězci.
řetězec translate(
řetězec, původní znaky, náhrada znaků)
Všechny znaky prvního řetězce, které jsou obsaženy v druhém parametru funkce, jsou nahrazeny znakem na stejné pozici ve třetím řetězci. Lze tak vytvořit jednoduché konverzní funkce.
Př.: Volání
translate('ahoj boženo', 'abc', 'ABC')
vrátí hodnotu Ahoj Boženo
.
Tj. psímena `a', `b' a `c' jsou nahrazena písmeny `A', `B' a
`C'.
Pokud druhý parametr obsahuje více znaků než třetí, jsou znaky, které nemají náhradu ve třetím parametru, ze vstupního řetězce odstraněny. Př.:
translate('ahoj boženo', 'abc', 'A')
vrátí Ahoj oženo
.
Převod libovolné hodnoty na logickou hodnotu.
boolean boolean(
libovolný objekt)
Konverze jednotlivých typů se řídí následujícími pravidly:
čísla – 0 je převedena na false, ostatní hodnoty jsou převedeny na true;
seznam uzlů – pokud je seznam uzlů neprázdný, je převeden na true, jinak na false;
řetězec – prázdný řetězec je převeden na false, neprázdný na true.
Funkce zjistí, zda je u aktuálního uzlu nastaven určitý
jazyk pomocí atributu xml:lang
.
boolean lang(
řetězec)
Převede libovolný objekt na číselnou hodnotu.
číslo number(
libovolný objekt)
Konverze jednotlivých typů probíhá podle následujících pravidel:
řetězec – pokud je v řetězci za případnými mezerami číslo, vrátí se toto číslo, v opačném případě vrací funkce hodnotu NaN („not a number“);
logická hodnota (boolean) – true je převedeno na 1, false na 0;
množina uzlů – nejprve se převede na řetězec (stejně jako
ve funkci string()
), a pak se postupuje jako
při převodu řetězce.
Pokud funkci zavoláme bez parametru, použije se jako parametr aktuální uzel.
Funkce vrací součet hodnot uložených v množině uzlů.
číslo sum(
množina uzlů)
Ze všech uzlů v množině se nejprve získá jejich řetězcové vyjádření, to se převede na číslo a všechna takto získaná čísla se sečtou.
XSLT definuje oproti XPath několik nových funkcí, které jsou pro použití ve stylech velice užitečné.
Zpřístupnění uzlů z dalších dokumentů. Umožňuje v jednom stylu pracovat s více dokumenty.
seznam uzlů document(
seznam uzlů nebo
řetězec, seznam uzlů)
Nejčastěji se funkce volá pouze s jedním parametrem, který obsahuje jméno XML souboru, do kterého si potřebujeme pro něco sáhnout.
seznam uzlů document(
URI dokumentu)
Pokud použijeme pouze relativní URI souboru, vztahuje se k URI stylu. Pokud to chceme změnit, můžeme použít druhý parametr. Ten se chápe jako seznam uzlů. Relativní URI se pak bude vyhodnocovat od URI dokumentu, ve kterém leží první uzel ze seznamu uzlů. Nejčastěji chceme externí soubory hledat ve stejném adresáři, jako je vstupní dokument (ne styl), a použijeme proto zápis typu:
document("nějaký.xml",.) document("nějaký.xml",/)
Pokud použijeme pouze jeden parametr a je jím prázdný řetězec, odkazujeme se tím na soubor se stylem. Můžeme tak zjišťovat zajímavé věci uložené přímo ve stylu. Pokud chceme ve stylu zjistit, v jakém kódování se má uložit výstup, není nic snazšího:
document('')//xsl:output/@encoding
Pokud jako první parametr použijeme seznam uzlů, je každý uzel převeden na řetězec, který se chápe jako URI dokumentu. Všechny takto získané dokumenty jsou pak převedeny na stromovou reprezentaci a připojeny za sebe. Opět můžeme použít druhý parametr a změnit základní URI.
Praktické použití této funkce si ukážeme v průběhu školení.
Nalezení uzlů s určitou hodnotou předem definovaného klíče.
seznam uzlů key(
řetězec, seznam uzlů nebo
řetězec)
První parametr je název klíče definovaného pomocí xsl:key
. Druhý parametr je pak hodnota
klíče, kterou hledáme. Pokud je druhý parametr seznam uzlů, převedou
se na řetězce, funkce pak nalezne a vrátí všechny uzly
s odpovídajícími klíči.
Více si o funkci řekneme, až budeme probírat xsl:key
.
Funkce slouží k formátování čísel v uživatelem definovaném formátu.
řetězec format-number(
číslo, řetězec, řetězec)
Funkce naformátuje zadané číslo podle formátovacího řetězce v druhém parametru. Formátovací řetězec má následující strukturu:
[prefix
]celá část
[desetinná část
][suffix
] [;[prefix
]celá část
[desetinná část
][suffix
]]
Nepovinné části formátovacího řetězce jsou označeny hranatými závorkami. Druhá část řetězce je celá nepovinná, a použijeme ji v případech, kdy chceme odlišně formátovat záporná čísla.
prefix
a
suffix
umožňují definovat text, který se
doplní před a za formátované číslo. Ve specifikaci celé a desetinné
části čísla můžeme používat speciální znaky, které ovlivňují
formátování (viz tabulka 2.1 – „Význam speciálních znaků ve formátovacím řetězci“).
Tabulka 2.1. Význam speciálních znaků ve formátovacím řetězci
Znak | Význam |
---|---|
0 | číslice |
# | číslice – pokud je 0, nezobrazuje se |
. | znak oddělující specifikaci pro celou a desetinnou část čísla |
, | znak vyznačující pozici oddělovače řádu (nejčastěji tisíců) |
; | oddělovač specifikace pro kladná a záporná čísla |
- | znaménko |
% | číslo se vynásobí 100 a zobrazí jako procenta |
‰ | číslo se vynásobí 1000 a zobrazí jako promile (pro zápis můžeme
použít znakovou entitu ‰ ) |
'speciální znak ' | uzavření znaku mezi apostrofy vypne jeho speciální význam, pokud je použit v prefixu nebo suffixu |
Pokud chceme, aby se pro jednotlivé oddělovače použil jiný znak,
musíme si v XSLT nejprve definovat vlastní formát čísel, a v něm znaky
předefinovat. To si ukážeme u popisu XSLT instrukce xsl:decimal-format
.
Několik ukázek formátování čísla 123456789.87654:
Formátovací řetězec Výstup #.# 123456789.9 #.### 123456789.877 # 123456790 #,###.### 123,456,789.877 $#,###.### $123,456,789.877 #,###.## USD 123,456,789.88 USD '#'#,###.## #123,456,789.88
Několik ukázek formátování čísla 123.7:
Formátovací řetězec Výstup #.#% 12370% #.00 123.70 0,000.00 0,123.70
Několik ukázek formátování čísla -357.4:
Formátovací řetězec Výstup #.# -357.4 #.#;(#.#) (357.4)
Funkce vrací uzel, který byl aktuální v okamžiku začátku vyhodnocování výrazu. Tento uzel se tedy nemění s tím, jak se výraz postupně vyhodnocuje po jednotlivých částech cesty.
seznam uzlů current(
)
Vrací URI adresu deklarované externí binární entity.
řetězec unparsed-entity-uri(
řetězec)
Vygeneruje k danému uzlu jedinečný identifikátor.
řetězec generate-id(
seznam uzlů)
Funkce vygeneruje jedinečný identifikátor pro první uzel v seznamu. Platí přitom, že pro různé uzly se nikdy nevygeneruje stejný identifikátor, a pro stejné uzly musí během jednoho spuštění XSLT procesoru funkce generovat stejné identifikátory.
Pokud je seznam uzlů prázdný, vrací funkce prázdný řetězec. Pokud funkci zavoláme bez parametrů, vrací identifikátor aktuálního uzlu.
Funkce vrací různé informace o právě používaném XSLT procesoru.
objekt system-property(
řetězec)
Jako parametr můžeme předat jeden z následujících řetězců, které ovlivňují druh vrácené informace:
xsl:version
verze XSLT podporovaná procesorem
xsl:vendor
řetězec identifikující dodavatele procesoru
xsl:vendor-url
URL adresa stránek, kde jsou další informace o XSLT procesoru
Zjistí, zda je k dispozici určitý XSLT element (instrukce).
boolean element-available(
řetězec)
Ve stylu tak můžeme testovat, zda máme k dispozici nějaké rozšiřující elementy apod.
[1] Tato funkce proto nebude fungovat nad dokumentem
katalog.xml
, ale bude fungovat nad dokumentem
katalog-s-id.xml
, který obsahuje DTD
s požadovanou definicí typu atributu.