Ukázkový dokument
Všechny výrazy v této kapitole se vyhodnocují nad stejnou malou knihovnou. Výsledky jsou ověřené v XPath 1.0, tedy v té verzi, kterou umí každý prohlížeč.
<?xml version="1.0" encoding="UTF-8"?>
<knihovna>
<kniha id="b1" jazyk="cs">
<nazev>Saturnin</nazev>
<autor>Zdeněk Jirotka</autor>
<rok>1942</rok>
<cena>249</cena>
</kniha>
<kniha id="b2" jazyk="cs">
<nazev>Válka s mloky</nazev>
<autor>Karel Čapek</autor>
<rok>1936</rok>
<cena>299</cena>
</kniha>
<kniha id="b3" jazyk="en">
<nazev>R.U.R.</nazev>
<autor>Karel Čapek</autor>
<rok>1920</rok>
<cena>199</cena>
</kniha>
</knihovna> Cesty
Výraz XPath připomíná cestu k souboru: jednotlivé kroky oddělené lomítkem sestupují stromem
dokumentu. Výraz začínající / je absolutní (od kořene), ostatní jsou relativní k
aktuálnímu uzlu.
| Zápis | Význam |
|---|---|
| / | na začátku výrazu kořen dokumentu, jinak krok o úroveň níž (na přímé potomky) |
| // | libovolná hloubka — všichni potomci, nejen přímí |
| . | aktuální uzel |
| .. | rodič aktuálního uzlu |
| @jmeno | atribut |
| * | libovolný element; @* libovolný atribut |
| text() | textové uzly |
| […] | predikát — podmínka, která výsledek filtruje |
| | | sjednocení dvou výsledků, např. //nazev | //autor |
| Výraz | Co vybere | Výsledek | Nástroj |
|---|---|---|---|
| /knihovna/kniha/nazev | názvy všech knih, cesta od kořene | Saturnin, Válka s mloky, R.U.R. | Vyzkoušet |
| //autor | všechny elementy autor kdekoli v dokumentu | Zdeněk Jirotka, Karel Čapek, Karel Čapek | Vyzkoušet |
| //kniha/@id | atribut id všech knih | b1, b2, b3 | Vyzkoušet |
| /knihovna/*[1]/nazev | název prvního potomka kořene (* = libovolný element) | Saturnin | Vyzkoušet |
// je pohodlné, ale prochází celý dokument. U velkých souborů je rychlejší a
přesnější napsat celou cestu.
Predikáty: filtrování výsledku
Podmínka v hranatých závorkách ponechá jen uzly, pro které platí. Číslo v predikátu je pozice
a počítá se od 1, ne od nuly. Predikáty lze řetězit a kombinovat operátory
and, or a funkcí not().
| Výraz | Co vybere | Výsledek | Nástroj |
|---|---|---|---|
| //kniha[2]/nazev | druhá kniha (pozice se číslují od 1) | Válka s mloky | Vyzkoušet |
| //kniha[last()]/nazev | poslední kniha | R.U.R. | Vyzkoušet |
| //kniha[@jazyk='en']/nazev | knihy s atributem jazyk rovným en | R.U.R. | Vyzkoušet |
| //kniha[autor='Karel Čapek']/nazev | knihy, jejichž autor má danou hodnotu | Válka s mloky, R.U.R. | Vyzkoušet |
| //kniha[cena > 200]/nazev | knihy dražší než 200 (porovnává se číselně) | Saturnin, Válka s mloky | Vyzkoušet |
| //kniha[rok < 1940][1]/nazev | první z knih vydaných před rokem 1940 | Válka s mloky | Vyzkoušet |
| //kniha[contains(nazev, 'mlok')]/autor | autor knihy, jejíž název obsahuje „mlok“ | Karel Čapek | Vyzkoušet |
Past s pozicí: //kniha[1] znamená „u každého rodiče jeho první
element kniha“, takže při knihách ve více oddílech vrátí víc výsledků. Pokud chceš úplně první knihu v dokumentu bez ohledu na strukturu,
použij závorky: (//kniha)[1].
Osy: pohyb ve všech směrech
Lomítko standardně sestupuje k potomkům. Osy (axes) umožňují jít i nahoru a do stran —
k rodičům, předkům nebo sourozencům. Zapisují se jako osa::test.
| Osa | Zkratka | Směr |
|---|---|---|
| child:: | (výchozí) | přímí potomci |
| descendant:: | — (// je zkratka pro /descendant-or-self::node()/) | všichni potomci |
| parent:: | .. | rodič |
| ancestor:: | — | rodič, prarodič… až ke kořeni |
| following-sibling:: | — | sourozenci za uzlem |
| preceding-sibling:: | — | sourozenci před uzlem |
| attribute:: | @ | atributy |
| self:: | . | uzel sám |
| Výraz | Co vybere | Výsledek | Nástroj |
|---|---|---|---|
| //autor[.='Zdeněk Jirotka']/../nazev | .. je rodič — název knihy od Jirotky | Saturnin | Vyzkoušet |
| //nazev[.='R.U.R.']/following-sibling::rok | sourozenec rok za názvem R.U.R. | 1920 | Vyzkoušet |
| //rok[.='1936']/preceding-sibling::*[1] | nejbližší předchozí sourozenec (osy dozadu počítají pozpátku) | Karel Čapek | Vyzkoušet |
| //cena[.='199']/ancestor::kniha/@id | id knihy, ve které je cena 199 | b3 | Vyzkoušet |
Nejpoužívanější funkce
XPath 1.0 má jen čtyři datové typy (množina uzlů, řetězec, číslo, logická hodnota) a zhruba
30 funkcí. Nejčastěji se hodí count(), sum(),
contains(), starts-with(), normalize-space(),
string-length(), not(), position() a
last().
| Výraz | Co vybere | Výsledek | Nástroj |
|---|---|---|---|
| count(//kniha) | počet knih | 3 | Vyzkoušet |
| sum(//cena) | součet cen | 747 | Vyzkoušet |
| count(//kniha[autor='Karel Čapek']) | počet knih od Čapka | 2 | Vyzkoušet |
| string-length(//kniha[1]/nazev) | délka názvu první knihy | 8 | Vyzkoušet |
| //kniha[starts-with(nazev, 'V')]/rok | rok knihy, jejíž název začíná na V | 1936 | Vyzkoušet |
| //kniha[not(@jazyk='cs')]/nazev | knihy, které nejsou v češtině | R.U.R. | Vyzkoušet |
Porovnání autor='Karel Čapek' je přesné — rozlišuje velikost písmen a bílé znaky.
Pokud v datech může být mezera navíc, pomůže normalize-space(autor)='Karel Čapek'.
XPath a jmenné prostory
Dokumenty s výchozím jmenným prostorem (sitemapy, XHTML, SOAP, faktury) jsou nejčastějším důvodem, proč výraz „nic nenajde“. V XPath 1.0 jméno bez prefixu vždy odpovídá jen elementu bez jmenného prostoru. Je potřeba prefix zaregistrovat v programu a použít ho ve výrazu:
// XPath 1.0 v prohlížeči: prefix s se přiřadí URI přes resolver
const resolver = (prefix) =>
prefix === 's' ? 'http://www.sitemaps.org/schemas/sitemap/0.9' : null;
const result = doc.evaluate('/s:urlset/s:url/s:loc', doc, resolver,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
Nouzové řešení bez registrace je //*[local-name()='loc'], které jmenný prostor
ignoruje. XPath 3.1 navíc zná zápis Q{URI}jmeno a zástupný prefix
*:loc. Registraci prefixu v C#, Javě, Pythonu, PHP a PostgreSQL ukazuje stránka
XPath nic nevrací: výchozí jmenný prostor.
Verze XPath
- XPath 1.0 (1999) — umí ho všechny prohlížeče (
document.evaluate), XSLT 1.0 a většina knihoven. Omezená sada funkcí, žádné regulární výrazy. - XPath 2.0 (2007) — typový systém podle XSD, sekvence, regulární výrazy
(
matches(),replace()), podmínkyif … then … else, práce s daty. - XPath 3.0 a 3.1 (2014, 2017) — funkce vyššího řádu, mapy a pole, operátor
=>a podpora JSON.
Záložka XPath v našem XML nástroji umí nativní XPath 1.0 prohlížeče i XPath 3.1 a XQuery 3.1, takže si rozdíly můžeš vyzkoušet na vlastním dokumentu. XPath se dál používá v XSLT, kde vybírá uzly pro šablony.
Sekvence, mapy a pole v XPath 3.1
(1, 2, 3) ! (. * 10)
map { "jmeno": "Jana", "vek": 20 }?jmeno
["Jana", 20]?2
parse-json('{"aktivni":true}')?aktivni Výsledky jsou postupně sekvence 10, 20, 30; řetězec Jana; číslo 20; true. Sekvence není pole: vnořené sekvence se zplošťují, pole může obsahovat člen, který je celou sekvencí. Index členu XPath pole začíná jedničkou, zatímco JSONPath index nulou.
XPath 2.0 přinesl sekvence a typový systém, 3.0 funkce jako hodnoty a 3.1 mapy a pole. Prohlížečové document.evaluate() zůstává u 1.0; novější zápis vyžaduje jiný procesor.
K 1. 10. 2026 publikuje QT4 Community Group návrhy XPath, XQuery a XSLT 4.0. Stabilní snapshot z ledna 2026 je stále návrh a práce pokračuje; není to doporučení W3C. Experimentální režim v nástroji XML.cz odpovídá podpoře konkrétní verze FontoXPath, nikoli záruce celé budoucí specifikace.
Pro tvorbu nových výsledných dokumentů a FLWOR pokračuj na XQuery.
Kontext a predikáty: proč závorky mění výsledek
<katalog><sekce><kniha id="a"/><kniha id="b"/></sekce><sekce><kniha id="c"/><kniha id="d"/></sekce></katalog> //kniha[1]/@id → a, c
(//kniha)[1]/@id → a
//kniha[@id="d"]/preceding-sibling::kniha[1]/@id → c
count(/katalog/sekce) → 2 Predikát u kroku vybírá první knihu každého rodiče. Závorky kolem celého výběru vytvoří jeden výsledek, z nějž vybereš první knihu. Na zpětné ose preceding-sibling je první nejbližší předchozí sourozenec. Číselný predikát pracuje s pozicí v daném kontextu; [1] není obecné omezení celé dotazové sady na jednu položku.
Počáteční / vychází z kořene dokumentu, . z aktuálního uzlu. Rozlišuj // jako průchod potomky a konkrétní cestu pro známý model: kratší zápis nemusí být přesnější ani levnější. Reference os a funkcí navazuje na tento příklad.
Namespace ve skutečném dotazu
<katalog xmlns="urn:knihy"><kniha id="a"><nazev>XML</nazev></kniha></katalog> /k:katalog/k:kniha/@id Ve svém XPath API přiřaď prefixu k URI urn:knihy. Funkci nebo nastavení, které převádí prefix na URI, knihovny obvykle nazývají resolver. Zdejší pokročilý tester přebírá vazby z kořenového elementu dokumentu; pro tento prefix mu přidej deklaraci xmlns:k="urn:knihy". Nemusí se vyskytovat ve vstupním XML. Dotaz /katalog/kniha v XPath 1.0 hledá elementy bez namespace a vrátí nic. @id naopak zůstává bez prefixu, protože výchozí namespace neplatí pro neprefixované atributy.
XPath 2.0/3.1 může podle prostředí mít výchozí elementový namespace pro výrazy; toto nastavení není automaticky převzaté z každého XML dokumentu. Pro přenositelný dotaz dej vazby prefixů výslovně. local-name() pomůže při diagnostice, ale bez kontroly namespace-uri může vybrat cizí element stejného jména.
Operátory: čísla, booleovské podmínky a množiny uzlů
<knihy><kniha id="k1" cena="199"/><kniha id="k2" cena="49"/></knihy> /knihy/kniha[@cena >= 100 and @id = 'k1'] → kniha k1
count(/knihy/kniha) = 2 → true
sum(/knihy/kniha/@cena) → 248
5 div 2 → 2.5
5 mod 2 → 1
/knihy/kniha[@id='k1'] | /knihy/kniha[@id='k2'] → oba uzly XPath 1.0 používá and, or, div, mod a znak | pro sjednocení množin uzlů. Hvězdička může podle kontextu znamenat násobení nebo výběr libovolného elementu. Porovnání množiny uzlů se může vyhodnocovat existenčně: /knihy/kniha/@cena = 199 je pravda, pokud alespoň jeden atribut odpovídá. Nevysvětluj je jako porovnání serializovaných seznamů.
XPath 2.0+ přidává sekvence, rozsahy to, typové operátory a value comparisons eq/ne/lt/le/gt/ge. Například (1, 2) = 2 je true, zatímco (1, 2) eq 2 selže, protože operátor eq dovoluje na každé straně nejvýše jednu hodnotu, ale vlevo jsou dvě. Operátor || pro spojení řetězců patří do 3.1, nikoli do 1.0. Vyber verzi podle skutečného procesoru; reference funkcí uvádí minimální verze.