Potřebujete pomoci s XSLT?
Nabízím školení, konzultace, vývoj XSLT kódu na zakázku. Nevájte a kontaktujte mne.

Podpořte provoz stránek
Platba probíhá pomocí služby PayPal a je možné platit kartou nebo převodem z vašeho PayPal účtu.

2.2 Výrazy

2.2.1. Výrazy pro výběr části dokumentu pomocí cesty
Identifikátory osy
Testy uzlu
Zkrácený zápis
Predikáty
Příklady
2.2.2. Kontext pro vyhodnocování výrazů
2.2.3. Operátory
Operátory pro práci se seznamem uzlů
Logické spojky
Relační operátory
Matematické operátory
2.2.4. Funkce
Funkce pro práci s uzly
Řetězcové funkce
Logické funkce
Funkce pro práci s čísly
Rozšiřující funkce definované v XSLT

XPath výraz může vracet hodnotu jednoho z následujících typů:

V XSLT se XPath výrazy používají zejména pro:

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.

2.2.1 Výrazy pro výběr části dokumentu pomocí cesty

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:

od aktuálního uzlu

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ů.

od kořene

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.

z libovolného přesně určeného místa

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

Identifikátory osy

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.

Poznámka

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.

Testy uzlu

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(cíl) – vybere všechny instrukce pro zpracování s daným jménem;

  • comment() – vybere všechny komentáře;

  • text() – vybere všechny textové uzly;

  • node() – vybere všechny uzly bez ohledu na jejich typ.

Zkrácený zápis

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

Predikáty

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.

Příklady

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.

2.2.2 Kontext pro vyhodnocování výrazů

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]

Poznámka

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]

2.2.3 Operátory

XPath výrazy můžeme skládat pomocí několika operátorů.

Operátory pro práci se seznamem uzlů

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

Logické spojky

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]

Relační operátory

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 &lt;.

Matematické operátory

XPath obsahuje běžné operátory pro sčítání (+), odčítání (-) a násobení (*). Můžeme používat i dělení (div) a zbytek po dělení (mod).

2.2.4 Funkce

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.

Funkce pro práci s uzly

last()

Vrací pozici posledního uzlu mezi kontextovými uzly.

číslo last()

position()

Vrací pozici aktuálního uzlu mezi kontextovými uzly.

číslo position()

count()

Vrací počet uzlů v daném seznamu.

číslo count(seznam uzlů)

id()

Vrací uzel se zadaným ID.

seznam uzlů id(řetězec)

local-name()

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.

namespace-uri()

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.

name()

Vrací název uzlu.

řetězec 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.

Řetězcové funkce

string()

Převede libovolný objekt na řetězec.

řetězec string(objekt libovolného typu)

Poznámka

Pro formátování čísel je vhodnější použít funkci format-number().

concat()

Spojí několik řetězců do jednoho.

řetězec concat(řetězec, řetězec, ...)

starts-with

Otestuje, zda řetězec na svém začátku obsahuje hledaný řetězec.

boolean starts-with(řetězec, hledaný řetězec)

contains

Otestuje, zda řetězec obsahuje hledaný řetězec.

boolean contains(řetězec, hledaný řetězec)

substring-before

Vrací část řetězce, která se vyskytuje před zadaným řetězcem.

řetězec substring-before(řetězec, hledaný řetězec)

substring-after

Vrací část řetězce, která se vyskytuje za zadaným řetězcem.

řetězec substring-after(řetězec, hledaný řetězec)

substring

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.

string-length()

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.

normalize-space()

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.

translate()

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.

Logické funkce

boolean()

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.

not()

Vrací negaci výrazu.

boolean not(boolean)

true()

Funkce vrací hodnotu true.

false()

Funkce vrací hodnotu false.

lang()

Funkce zjistí, zda je u aktuálního uzlu nastaven určitý jazyk pomocí atributu xml:lang.

boolean lang(řetězec)

CVIČENÍ: Zjištění kódu aktuálního jazyka

  • Pokuste se vytvořit XPath výraz, který vrátí kód jazyka aktuálního uzlu. Jazykový kód je určen nejbližším atributem xml:lang přítomným na aktuálním uzlu nebo na jeho předcích. Pokusy můžete provádět na souboru xmllang.xml.

Funkce pro práci s čísly

number()

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.

sum()

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.

floor()

Zaokrouhlení čísla na celé číslo dolů.

číslo floor(číslo)

ceiling()

Zaokrouhlení čísla na celé číslo nahoru.

číslo ceiling(číslo)

round()

Zaokrouhlení čísla na nejbližší celé číslo.

číslo round(číslo)

Rozšiřující funkce definované v XSLT

XSLT definuje oproti XPath několik nových funkcí, které jsou pro použití ve stylech velice užitečné.

document()

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í.

key()

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.

format-number()

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

ZnakVý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 &#x2030;)
'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)
current()

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()

unparsed-entity-uri()

Vrací URI adresu deklarované externí binární entity.

řetězec unparsed-entity-uri(řetězec)

generate-id()

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.

system-property()

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

element-available()

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.

function-available()

Zjistí, zda je k dispozici určitá funkce.

boolean function-available(řetězec)

Zjistí, zda je k dispozici určitá funkce.



[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.

© Jiří Kosek 2014

Tento dokument je určen výhradně pro osobní potřebu seznámení s jazykem XSLT. Jakékoliv jiné použití, včetně dalšího šíření, pořizování kopií, použití při školeních a výuce apod. je výslovně zakázáno a bude považováno za porušení autorských práv.


Copyright © 2000-2014 Jiří Kosek