XPath: dotazy do XML dokumentu

XPath je jazyk pro vyhledávání v XML dokumentu. Jedním krátkým výrazem vybereš konkrétní elementy, atributy nebo hodnoty. Používá ho XSLT, XSD, testovací nástroje i knihovny ve všech běžných jazycích.

Autor: Aktualizováno

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

knihovna.xml
<?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ápisVý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
@jmenoatribut
*libovolný element; @* libovolný atribut
text()textové uzly
[…]predikát — podmínka, která výsledek filtruje
|sjednocení dvou výsledků, např. //nazev | //autor
VýrazCo vybereVýsledekNástroj
/knihovna/kniha/nazevnázvy všech knih, cesta od kořeneSaturnin, Válka s mloky, R.U.R.Vyzkoušet
//autorvšechny elementy autor kdekoli v dokumentuZdeněk Jirotka, Karel Čapek, Karel ČapekVyzkoušet
//kniha/@idatribut id všech knihb1, b2, b3Vyzkoušet
/knihovna/*[1]/nazevnázev prvního potomka kořene (* = libovolný element)SaturninVyzkouš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ýrazCo vybereVýsledekNástroj
//kniha[2]/nazevdruhá kniha (pozice se číslují od 1)Válka s mlokyVyzkoušet
//kniha[last()]/nazevposlední knihaR.U.R.Vyzkoušet
//kniha[@jazyk='en']/nazevknihy s atributem jazyk rovným enR.U.R.Vyzkoušet
//kniha[autor='Karel Čapek']/nazevknihy, jejichž autor má danou hodnotuVálka s mloky, R.U.R.Vyzkoušet
//kniha[cena > 200]/nazevknihy dražší než 200 (porovnává se číselně)Saturnin, Válka s mlokyVyzkoušet
//kniha[rok < 1940][1]/nazevprvní z knih vydaných před rokem 1940Válka s mlokyVyzkoušet
//kniha[contains(nazev, 'mlok')]/autorautor knihy, jejíž název obsahuje „mlok“Karel ČapekVyzkouš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.

OsaZkratkaSmě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ýrazCo vybereVýsledekNástroj
//autor[.='Zdeněk Jirotka']/../nazev.. je rodič — název knihy od JirotkySaturninVyzkoušet
//nazev[.='R.U.R.']/following-sibling::roksourozenec rok za názvem R.U.R.1920Vyzkoušet
//rok[.='1936']/preceding-sibling::*[1]nejbližší předchozí sourozenec (osy dozadu počítají pozpátku)Karel ČapekVyzkoušet
//cena[.='199']/ancestor::kniha/@idid knihy, ve které je cena 199b3Vyzkouš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ýrazCo vybereVýsledekNástroj
count(//kniha)počet knih3Vyzkoušet
sum(//cena)součet cen747Vyzkoušet
count(//kniha[autor='Karel Čapek'])počet knih od Čapka2Vyzkoušet
string-length(//kniha[1]/nazev)délka názvu první knihy8Vyzkoušet
//kniha[starts-with(nazev, 'V')]/rokrok knihy, jejíž název začíná na V1936Vyzkoušet
//kniha[not(@jazyk='cs')]/nazevknihy, 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:

JavaScript
// 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ínky if … 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

Výrazy 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

Dvě sekce se dvěma knihami
<katalog><sekce><kniha id="a"/><kniha id="b"/></sekce><sekce><kniha id="c"/><kniha id="d"/></sekce></katalog>
XPath 1.0, vpravo očekávaný výsledek
//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

Elementy jsou v prostoru urn:knihy, atribut id nikoli
<katalog xmlns="urn:knihy"><kniha id="a"><nazev>XML</nazev></kniha></katalog>
XPath s prefixem k navázaným na urn:knihy
/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ů

Vstup pro XPath 1.0 i novější
<knihy><kniha id="k1" cena="199"/><kniha id="k2" cena="49"/></knihy>
Samostatné výrazy a očekávané výsledky; šipka není součást dotazu
/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.