Základy jazyka XPath
XPath je jazykem, který stojí jaksi na pozadí téměř veškeré práce s XML. Znalost XPath není úplně triviální, přesto je často považován za samozřejmost. Pokud vám tento jazyk prozatím nic neříká a chcete to napravit, je tento článek určen právě vám.
Zjednodušeně řečeno, XPath především umožňuje vyjádřit relativní cestu od nějakého XML uzlu k jinému elementu nebo atributu. Umí toho mnohem více, ale toto je jeho nejdůležitější poslání. Může tedy připomínat například adresářové cesty v souborových systémech, ovšem je zde podstatný rozdíl – výsledek XPath výrazu (nebo jeho části) může obsahovat jeden, více nebo žádný XML element nebo atribut. Může dokonce obsahovat i jiné datové typy. Je tedy mnohem variabilnější, což je třeba si neustále uvědomovat. Pokud vám označení „jazyk“ pro XPath připadá přehnaný, snad změníte názor, až se dozvíte o všech možnostech, které nabízí.
XPath se využívá při práci s XML velmi hojně, vlastně všude, kde je třeba vyhledávat ve struktuře XML dokumentu určité data. Chceme-li vybrat určitou množinu dat, odpovídajících zadaným podmínkám, obvykle nám postačuje jediný XPath výraz a XML parser se o prohledání dokumentu a vyhodnocení podmínek postará sám. Takovéto vyhledávání dat je výborně využitelné také v XSL transformacích.
Velmi užitečný nástroj pro ladění XPath výrazů je XPath Expression Builder. Uložte si ho na disk (lokální kopie) a pak otevřete. Budete moci vyzkoušet XPath výrazy na libovolném vlastním XML dokumentu. Kliknutím na libovolný element si určíte výchozí pozici (budeme jí říkat aktuální element) a pak můžete zkoušet různé XPath výrazy. Výsledné uzly se vám budou zvýrazňovat. Můžeme testovat na tomto jednoduchém dokumentu:
<anketa>
<otazka>Kolik hodin strávíte denně u počítače?</otazka>
<moznosti>
<moznost hlasu=’12‘>12-15 hodin</moznost>
<moznost hlasu=’5′>15-20 hodin</moznost>
<moznost hlasu=’15‘>20-24 hodin</moznost>
<moznost hlasu=’10‘>Můj počítač nefunguje</moznost>
</moznosti>
</anketa>
Složky XPath výrazu
Nejdůležitější konstrukcí jazyka XPath je zřejmě cesta k XML uzlu (Location Path). Jejím vytvářením se zde budeme zabývat nejvíce. Cesta obsahuje několik kroků, přičemž každý z nich sestává z identifikátoru osy, testu uzlu a podmínky (predikátu). Povinný je ale pouze test uzlu. Jednotlivé kroky XPath výrazu se pak spojují lomítky, vyhodnocují se zleva doprava a vždy se vychází z předchozích výsledků. Na začátku zpracování celého výrazu se vychází z aktuálního uzlu. Výsledkem může být libovolný typ uzlu, tedy nejen element nebo atribut, ale třeba i textový uzel.
Vyhodnocení každého kroku si probereme nejdříve poněkud abstraktně, ale až uvidíte konkrétní příklady, princip snadno pochopíte. Nejdříve se podle identifikátoru osy určí uzly, které se budou v tomto kroku výrazu zpracovávat. Dle výchozí osy (child::
) jsou to podřízené uzly aktuálního uzlu, což je asi nejběžnější a nejlogičtější přístup. Množina vybraných uzlů se omezí podle testu uzlu, kterým může být třeba název elementu. A nakonec se ještě zohlední případné dodatečné podmínky. Uzly, které v tomto procesu obstály, postupují do dalšího kroku. Ten se pak bude vyhodnocovat postupně pro všechny uzly, které do něj postoupily. Zní to možná složitě, ale výrazy mohou být poměrně jednoduché a přitom velice silné.
Pojďme se tedy podívat na jednotlivé lexikální prvky cesty XPath. Výklad bude doprovázen tabulkami s ukázkami XPath výrazů, které si můžete ihned vyzkoušet. Občas je v některém výrazu použit prvek, který bude popsán až později, snad to nebude moc vadit.
Oddělování kroků
Nejdříve si ukážeme oddělování jednotlivých kroků cesty a způsob zápisu absolutních cest.
Lomítko (/)
Stejně jako u adresářové struktury, jednotlivé kroky v XPath cestě lze oddělovat lomítky. Pokud je lomítko na začátku výrazu, znamená to, že výraz není vztažen k aktuálnímu elementu, ale počítá se od kořene dokumentu.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
moznosti/moznost |
anketa |
Všechny elementy moznost , které jsou přímými potomky elementů moznosti , obsažených v elementu anketa . |
/anketa |
jakýkoli | Kořenový element dokumentu. |
Dvě lomítka (//)
Dvě lomítka bezprostředně za sebou slouží k překonání víceúrovňové struktury. Pokud jsou dvě lomítka na začátku výrazu, opět se jedná o absolutní cestu od kořene dokumentu, takže lze snadno vybrat libovolný element odkudkoli. Více vám vysvětlí příklady:
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
anketa//moznost |
kořen dokumentu | Funguje, i když elementy moznost nejsou přímými potomky elementu anketa . |
//moznost |
jakýkoli uzel | Vrací všechny elementy daného jména v jakémkoli kontextu. |
//* |
jakýkoli uzel | Všechny elementy XML dokumentu. |
Identifikátory osy
Testu uzlu může předcházet takzvaný identifikátor osy. Ten vlastně určuje směr procházení XML dokumentu, tedy říká, odkud se uzly k vyhodnocení budou vytahovat. Pokud identifikátor osy neuvedeme, použije se child::
, dále tedy postupují potomci aktuálního uzlu. Všechno ale může být úplně naopak a ještě k tomu naruby, jak se dozvíte v následujícím přehledu všech identifikátorů osy:
Identifikátor | Vyhodnocené uzly |
---|---|
child:: |
Přímí potomci aktuálního uzlu. |
descendand:: |
Všichni potomci aktuálního uzlu. |
descendand-or-self:: |
Aktuální uzel a všichni potomci. |
self:: |
Aktuální uzel. |
ancestor-or-self:: |
Aktuální uzel a všichni jeho předci. |
ancestor:: |
Všichni předci aktuálního uzlu. |
parent:: |
Rodič aktuálního uzlu. |
following:: |
Všechny uzly, které se v toku XML dokumentu nacházejí za aktuálním uzlem. |
preceding:: |
Všechny uzly, které se v toku XML dokumentu nacházejí před aktuálním uzlem. |
following-sibling:: |
Všichni následující sourozenci aktuálního uzlu. |
preceding-sibling:: |
Všichni předcházející sourozenci aktuálního uzlu. |
attribute:: |
Atributy aktuálního uzlu. |
namespace:: |
Deklarované jmenné prostory. |
Pokud vám to připadá složité, nic si z toho nedělejte a prozatím berte v úvahu pouze výchozí typ osy child
. Uvědomte si, že za postupné procházení strukturou dokumentu nemohou lomítka, ale právě osa. Pomůže vám to pochopit celou problematiku.
Testy uzlu
Jak již bylo řečeno, test uzlu dále vymezuje množinu uzlů, která byla určena identifikátorem osy. Jejich používání je velice jednoduché.
Uzel určený názvem
Je to jeden z nejzákladnějších testů uzlu. Vybere všechny XML elementy s daným názvem. Tento test zapíšeme jednoduchým zápisem testovaného názvu elementu.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
moznost |
moznosti |
Všechny podřízené elementy s daným názvem. |
anketa |
kořen dokumentu | Kořenový element dokumentu. |
Uzel určený typem
Tento test uzlu bere ohled na typ uzlu, a vybírá pouze určitý typ. Tento test se zapisuje typem uzlu následovaným prázdnými kulatými závorkami. Máme tyto možnosti: comment()
, text()
, processing-instruction()
a node()
.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
//text() |
jakýkoli element | Vybere všechny textové uzly v dokumentu. |
Podmínky ([])
Do hranatých závorek se zapisují další podmínky, které zužují výsledky předchozího vyhodnocení. Pokud místo podmínky napíšeme pouze číslo, vybere podmínka pouze uzel umístěný na pozici s daným pořadovým číslem.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
//moznost[@hlasu="5"] |
jakýkoli element | Všechny elementy moznost , jejichž atribut hlasu má hodnotu rovnou 5. |
*[2] |
jakýkoli element | V pořadí druhý element podřízený aktuálnímu. |
Zkracování syntaxe
Protože některé konstrukce se používají velice často, existují pro ně zkrácené tvary. Doporučuji je používat, mimo jiné zvyšují přehlednost celého výrazu.
Hvězdička (*)
Hvězdička použitá jako test uzlu vybírá všechny poskytnuté elementy.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
* |
kořen dokumentu | Kořenový element dokumentu. |
anketa/* |
kořen dokumentu | Všechny elementy podřízené kořenovému elementu anketa . |
Tečka (.)
Tečka nahrazuje odkaz na sebe sama, což se někdy může hodit. Je vlastně náhražkou celého kroku, takže k němu již nelze připojit podmínky.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
. |
jakýkoli uzel | Aktuální uzel. |
./* |
jakýkoli uzel | Má úplně stejný význam jako jen * , tedy vrací všechny podřízené elementy. |
Dvě tečky (..)
Dvě tečky (stejně jako v adresářové cestě) umožní pohyb o jednu úroveň výše. Opět nahrazuje jeden celý krok, který lze česky vyjádřit jako rodič aktuálního uzlu.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
.. |
anketa |
Vrací kořen dokumentu. |
../* |
jakýkoli uzel | Vybere všechny sourozence aktuálního elementu včetně jeho samotného. |
Zavináč (@)
Zavináč nahrazuje identifikátor osy attribute::
. Jako test uzlu pak obvykle poslouží název atributu.
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
@* |
jakýkoli element | Všechny atributy aktuálního elementu. |
//@hlasu |
jakýkoli element | Všechny atributy hlasu v celém dokumentu. |
//@hlasu/.. |
jakýkoli element | Všechny nadřízené elementy k těmto atributům. Lze tak zjistit všechny elementy obsahující daný atribut. |
Operátory
V XPath se používají operátory obvyklé snad ve všech programovacích jazycích. Využívají se především v podmínkách. Pořadí vyhodnocení je možné upravovat závorkami.
Operátory | Význam |
---|---|
| |
Sjednocuje výsledky více výrazů |
+ , - , * , div , mod |
Matematické operátory. Pro dělení se používá div , protože znaménko / slouží k jinému účelu (viz. výše). |
= , != , < , <= , > , >= |
Relační operátory. Význam je zřejmý. |
and , or |
Logické operátory. |
Funkce
XPath obsahuje celou řadu užitečných funkcí, které můžete využít hlavně při tvorbě podmínek. Pro přehled uvádím krátkou tabulku základních funkcí:
- position(), last(), count()
- Pořadové číslo aktuálního XML uzlu, pořadové číslo posledního uzlu a počet uzlů v daném kontextu.
- name(), namespace-uri(), local-name()
- Úplné kvalifikované jméno, název jmenného prostoru a lokální název aktuálního XML uzlu.
- string(), number(), boolean()
- Převede libovolný objekt na řetězcovou, číselnou a logickou hodnotu.
- concat()
- Spojí řetězce v parametrech.
- starts-with(), contains(), substring-before(), substring-after(), substring(), string-length(), normalize-space(), translate()
- Vysvětlení těchto řetězcových funkcí již přesahuje rozsah tohoto článku, zmiňuji se pouze proto, abyste věděli o jejich existenci.
- floor(), ceiling(), round()
- Zaokrouhlení čísla dolů, nahoru a na nejbližší celé číslo.
- sum()
- Objekty v parametru jsou zkonvertovány na čísla, a funkce vrátí jejich součet.
- not(), true(), false()
- Negace logického výrazu, logická jednička a logická nula.
V konkrétním prostředí (například XSLT) mohou být doplněny ještě další funkce, které zde uvedeny nejsou, popřípadě může existovat možnost si další funkce naprogramovat.
Složitější příklady
Výraz | Aktuální uzel | Vyhodnocení |
---|---|---|
//moznost[last()] |
jakýkoli element | Poslední možnost v pořadí. |
sum(*/@hlasu) |
moznosti |
Součet všech hlasů. |
moznost[number(@hlasu)>=10]/text() |
moznosti |
Texty možností, které mají alespoň 10 hlasů. |
Více příkladů uvádět nebudu, myslím, že časem v praxi narazíte na mnoho zajímavých případů. Pokud jste článek studovali pečlivě, máte velice slušný základ tohoto jazyka, který vám určitě nějakou dobu bude bohatě stačit. V opačném případě můžete své znalosti ještě doladit studiem z dalších zdrojů.
Odkazy, zdroje
- XML Path Language (XPath) (W3C)
- XSLT v příkladech – XPath – Kosek, Jiří
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Doména .io v ohrožení: Co přinese předání Čagoských ostrovů?
10. října 2024 -
Souboj na trhu s CPU pro servery: AMD vs. Intel
8. prosince 2023 -
Regulace digitálních služeb: Co přináší nové nařízení DSA?
20. února 2024
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024
Anonym
Srp 20, 2010 v 11:18chyba: descendant se pise s T nakonci