XPath

ohjelmointikieli

XPath (lyhenne sanoista XML Path Language) on ei-XML-pohjainen kieli XML-dokumenttien osien osoittamiseen ja XML-dokumentin rakenteeseen perustuvan tiedon luontiin[1]. 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 muokkaa

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 muokkaa

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 muokkaa

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 muokkaa

Valinnan tyyppi Lyhennetty syntaksi Täysi syntaksi
Valitse kontekstisolmun lapsielementti nimeltä "nimi" nimi
(lapsi on oletussuunta)
child::nimi
Valitse nykyisen puun juuri ja kaikki sen jälkeläiset // /descendant-or-self::node()/
Valitse nykyinen solmu . self::node()
Valitse ylemmän tason solmu .. parent::node()
Valitse attribuutti nimeltä "nimi" @nimi attribute::nimi

Akselimäärittelyt muokkaa

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

Nimi Selitys
ancestor Esivanhempi
ancestor-or-self Esivanhempi tai nykyinen
attribute Attribuutti
child Lapsi
descendant Jälkeläinen
descendant-or-self Jälkeläinen tai nykyinen
following Tuleva
following-sibling Tuleva sisar
namespace Nimiavaruus
parent Vanhempi
preceding Edeltävä
preceding-sibling Edeltävä sisar
self Nykyinen solmu

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 muokkaa

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 <k>terve</k>.
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 muokkaa

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 muokkaa

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 muokkaa

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 muokkaa

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 muokkaa

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 muokkaa

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 muokkaa

Lähteet muokkaa

Aiheesta muualla muokkaa