XPath

XPath (lyhenne sanoista XML Path Language) on ei-XML-pohjainen kieli XML-dokumenttien osien osoittamiseen ja XML-dokumentin rakenteeseen perustuvan tiedon luontiin. XPath-kieli perustuu XML-dokumentin puumuotoiseen esitystapaan ja antaa siten mahdollisuuden poimia eri osia dokumentista tietyillä valintakriteereillä. XPath kehitettiin halusta saada yhtenäinen syntaksi ja käyttäytymismalli XPointerin ja XSL:n välille. Kehittäjät ovat nopeasti ottaneet XPathin käyttöönsä pienenä kyselykielenä.

Merkintätapa 

Yleisin XPath-lauseke on polkulauseke, josta kieli on saanut nimensä. Polkulauseke koostuu peräkkäisistä askeleista, joilla päästään XML-solmusta yhteen tai useampaan toiseen solmuun. Askeleet erotetaan toisistaan vinoviivalla, ”/”. Jokaisessa askeleessa on vähintään kaksi osaa:

 Akselimäärittely (axis specifier)
 Solmutesti (node test)
 Predikaatti (predicate)

Näistä viimeinen eli predikaatti on vapaaehtoinen osa, mutta niitä voi olla useita peräkkäin. Komponentit esiintyvät yllä luetellussa järjestyksessä. Akselimäärittely ja solmutesti erotetaan tosistaan kahdella kaksoispisteellä ::, predikaatit erotetaan kirjoittamalla kukin niistä hakasulkeiden [] sisään.

Tarjolla on kaksi eri merkintätapaa. Lyhennetty syntaksi on tiiviimpi ja usein helpompi lukea ja kirjoittaa – usein tutuilla merkeillä ja rakenteilla. Täysi syntaksi on monisanaisempi, mutta sen avulla voi määritellä enemmän asetuksia.

Lyhennetty syntaksi 

Tiivis merkintätapa sallii joitain oletuksia ja lyhenteitä. Yksinkertaisin XPath-lauseke on muotoa /A/B/C, joka valitsee XML-juurielementin A lapsielementtien B lapsielementit C. XPathin syntaksi on suunniteltu muistuttamaan URI:n ja tiedostopolkujen syntaksia.

Monimutkaisempia lausekkeita voi muodostaa muun muassa määrittelemällä:
akselin, joka on jokin muu kuin oletusarvoinen lapsiakseli,
solmutestin, jossa testataan jotain muuta kuin nimeä tai
predikaatin, jonka voi kirjoittaa minkä tahansa askeleen perään hakasuluissa ”[]”.

Esimerkiksi lauseke A//B/*[1] valitsee ensimmäisen ([1]) minkä tahansa nimisen elementin (*), joka on lapsi (/) elementille B, joka taas itsessään on elementin A jälkeläinen (//), joka on nykyisen kontekstisolmun lapsi, koska koko lauseke ei ala merkillä / tai muulla akselimäärittelyllä.

Täysi syntaksi 

Lyhentämättömässä syntaksissa yllä olevat esimerkit näyttävät tältä:
 /child::A/child::B/child::C ja
 child::A/descendant-or-self::node()/child::B/*[1] joka on sama kuin child::A/descendant::B/*[1].

Jokaisessa askeleessa akseli on määritelty eksplisiittisesti: child tai descendant-or-self). Akselia seuraa :: ja solmutesti, kuten A tai node() yllä olevissa esimerkeissä.

Lyhennetyn ja täyden syntaksin vastaavuudet

Akselimäärittelyt 

Akselimäärittely ilmaisee liikkumissuuntaa XML-dokumentin puumaisessa esitystavassa. Mahdolliset akselimäärittelyt ja niiden merkitykset ovat:

Esimerkkinä attribute-akselin käytöstä, //a/@href valitsee attribuutin nimeltä href dokumentin miltä tahansa a elementiltä. Suuntaa  self käytetään usein predikaatissa viittaamaan kontekstisolmuun. Esimerkiksi h3[.='Katso myös'] valitsee elementin nimeltä h3, jonka tekstisisältö on Katso myös.

Jos XML-dokumentti piirretään puumuotoon, akselit jakavat dokumentin neljään erilliseen lohkoon: vaakatasossa preceding–following -akselilla ja pystytasossa ancestor–descendant -akselilla. Syntaksin näkökulmasta preceding sisältää elementit, joiden lopputagi on jo tullut vastaan ja following elementit, joiden alkutagi ei ole vielä tullut vastaan (pois lukien jälkeläiset). Vastaavasti ancestor vastaa avoinna olevia elementtejä, ja descendant kontekstisolmusta avattavia elementtejä.

Solmutestit 

Elementtien, attribuuttien ja nimiavaruuksien kohdalla solmutesti muodostuu kohteen nimestä. Muilla tyypeillä se koostuu solmun tyyppiä vastaavasta solmutestistä.

Kun XPath-askeleessa solmutestinä on kohteen nimi, viittaa nimi oletuksena aina kohteeseen, jolle ei ole määritelty mitään nimiavaruutta. Haettaessa johonkin nimiavaruuteen kuuluvaa elementtiä tai attribuuttia, pitää solmutestissä aina käyttää nimiavaruusetuliitettä, joka erotetaan kaksoispisteellä nimestä. Tämä pätee vaikkei kohteella dokumentissa olisikaan etuliitettä vaan se kuuluisi oletusnimiavaruuteen. Nimiavaruusetuliitteen ei tarvitse olla sama, mitä dokumentissa mahdollisesti käytetty etuliite. Esimerkiksi jos nimiavaruudelle on määritelty etuliite gs, niin //gs:enquiry löytää kaikki enquiry-nimiset solmut siitä nimiavaruudesta. XPath-kieli ei ota kantaa miten nimiavaruus sidotaan etuliitteeseen vaan se riippuu käytettävästä ohjelmointiympäristöstä.

Solmun tyyppiä vastaavat testit ovat:
comment() löytää XML-kommenttisolmun: <!-- Comment -->.
text() löytää tekstisolmun terve.
processing-instruction() löytää XML-käsittelyohjeita, kuten <?php echo $a ?>. Tässä tapauksessa processing-instruction('php') olisi tarkempi lauseke mainitun solmun löytämiseen.
node() vastaa mitä tahansa solmutyyppiä.

Predikaatit 

Predikaatti on vapaaehtoinen osa XPath-askelta. Predikaatti on suodatusehdon tavoin toimiva hakasulkeiden sisällä oleva XPath-lauseke, jonka tulee olla tosi, jotta solmu tulee valituksi mukaan solmujoukkoon. Esimerkiksi //a[@href='apua.php'], poimii vain ne a elementit, jolla on href attribuutti ja sillä arvona apua.php. Valinta ei kuitenkaan osu itse attribuuttiin vaan elementtiin, koska tarkentava askel on predikaatissa.

Predikaattien määrälle ei ole rajoituksia eikä niiden tarvitse sijaita polkulausekkeen lopussa. Niitä voi sijoittaa myös sisäkkäin. Predikaatin sisällä käytettävä mahdollinen polku alkaa elementistä, jolle predikaatti alun perin määriteltiin eikä se vaikuta predikaatin ulkopuolella olevaan kontekstiin.

Esimerkki: //a[@href='apua.php'][../div/@luokka='otsikko']/@kohde poimii kohde attribuutin a elementiltä edellyttäen että sillä on  href attribuuttina arvo apua.php ja että a elementti on div elementin sisällä jolla puolestaan on luokka attribuuttina arvo otsikko.

Funktiot ja operaattorit 

XPath 1.0:ssa dokumentin rakenteet ovat olioita, jotka voidaan jakaa neljään eri tietotyyppiin: solmujoukko, merkkijono, numero sekä boolean-tyyppi.

Käytettävissä olevat operaattorit ovat:

 /, // ja [...] operaattorit, joita käytetään polkulausekkeissa edellä kuvatulla tavalla.
 Unioni, |, joka muodostaa kahden solmujoukon yhdistelmän.
 Boolean-operaattorit and ja or
 Aritmeettiset operaattorit +, -, *, div (jakolasku), ja mod (jakojäännös)
 Vertailuoperaattorit =, !=, <, >, <=, >=

Solmujoukkoja käsittelevät funktiot 

 count(solmujoukko)
 Palauttaa argumenttina annetun solmujoukon koon.
 id(olio)
 Palauttaa argumenttina annetun id-tunnisteen mukaisen elementin.
 last()
 Palauttaa kontekstijoukon koon.
 local-name(solmujoukko?)
 Palauttaa argumenttina annetun solmun paikallisen nimen. Mikäli argumenttia ei anneta, argumenttina käytetään kontekstijoukon ensimmäistä solmua.
 name(solmujoukko?)
 Palauttaa argumenttina annetun solmun tarkennetun nimen (QName). Mikäli argumenttia ei anneta, argumenttina käytetään kontekstijoukon ensimmäistä solmua.
 namespace-uri(solmujoukko?)
 Palauttaa argumenttina annetun solmun nimiavaruus URIn. Mikäli argumenttia ei anneta, argumenttina käytetään kontekstijoukon ensimmäistä solmua.
 position()
 Palauttaa konteksijoukossa solmun sijaintia vastaavan luvun.

Merkkijonofunktiot 

 concat(merkkijono, merkkijono, merkkijono*)
 Palauttaa argumenttinsa yhteenliitettyinä.
 contains(merkkijono, merkkijono)
 Palauttaa tosi, jos ensimmäinen argumentti sisältää jälkimmäisen, muuten palauttaa epätosi.
 normalize-space(merkkijono?)
 Palauttaa argumentin normalisoituna.
 starts-with(merkkijono, merkkijono)
 Palauttaa tosi, jos ensimmäinen argumentti alkaa jälkimmäisellä, muuten palauttaa epätosi.
 string(olio?)
 Palauttaa oliota vastaavan merkkijonon.
 string-length(merkkijono?)
 Palauttaa merkkijonon pituuden. Mikäli argumenttia ei anneta käytetään kontekstisolmun tekstiarvoa
 substring(merkkijono, numero, numero?)
 Palauttaa alimerkkijonon, joka alkaa toisen argumentin osoittamasta paikasta ja jonka pituus vastaa kolmatta argumenttia. Jos kolmatta argumenttia ei ole, pituus on ensimmäisen argumentin loppuun saakka. Huom! Merkkijonon kirjainten indeksointi alkaa luvusta 1.
 substring-after(merkkijono, merkkijono)
 Palauttaa alimerkkijonon, joka seuraa ensimmäisessä argumentissa jälkimmäistä
 substring-before(merkkijono, merkkijono)
 Palauttaa alimerkkijonon, joka edeltää ensimmäisessä argumentissa jälkimmäistä
 translate(merkkijono, merkkijono, merkkijono)
 Palauttaa ensimmäisen argumentin, jossa toisen argumentin osoittamat merkit ovat korvattu vastaavalla sijalla kolmannessa argumentissa olevilla merkeillä.

Totuusarvofunktiot 

 false()
 Palauttaa arvon epätosi.
 lang(merkkijono)
 Palauttaa tosi, mikäli kontekstisolmun kieli xml:lang-attribuutilla merkittynä vastaa argumenttina annettua merkkijonoa.
 not(totuusarvo)
 Palauttaa arvon tosi argumentin ollessa epätosi, muussa tapauksessa päinvastoin.
 true()
 Palauttaa arvon tosi.

Lukufunktiot 

 ceiling()
 Palauttaa argumentin pyöristettynä kattofunktiolla.
 floor(numero)
 Palauttaa argumentin pyöristettynä lattiafunktiolla.
 number(olio?)
 Palauttaa oliota muunnettuna numeroarvoksi.
 round()
 Palauttaa argumentin pyöristettynä lähimpään kokonaislukuun.
 sum(solmujoukko)
 Palauttaa solmujoukon solmuja vastaavien numeroarvojen summan

Katso myös 
XML
XSL, XSLT, XSL-FO
XQuery
XLink, XPointer
XML Schema
STXPath

Lähteet

Aiheesta muualla 

 XPath 1.0 -määrittely
 XPath 2.0 -kandidaatti
 ilmainen XPath-ohjelmisto
  XPath opetusohjelma
  XSLT ja XPath viite 

W3C-standardit
Kyselykielet

he:XSL#XPath