XPath
Problemstillingen
Vi vet at XSLT hele tiden arbeider mot en trestruktur, som i all hovedsak er slik vi kjenner den fra DOM.
Når vi navigerer i et slikt tre må vi til en hver tid ha klart for oss hvor vi er, og vi må kunne få tak i elementer eller attributter som er andre steder i treet.
Form
Et XPath uttrykk kan bestå av inntil tre deler: Axis, nodetest og predicate. F.eks.:
child::bok[position()=1]
som angir "det første elementet av typen bok som er barn av kontekstnoden".
child | axis angir hva slags relasjon vi ønsker i forhold til kontekstnoden |
bok | nodetest angir hva slags type node vi er interesserte i |
position()=1 | predicate plukker ut et utvalg av de nodene vi har kvalifisert ved axis og nodetest |
Axes
Når vi ønsker å velge ut et sett med noder i en select-atributt i kommandoene: xsl:apply-templates, xsl:value-of, xsl:for-each, xsl:copy-of, xsl:variable, xsl:param, xsl:sort, så kan vi bruke følgende uttrykk for å navigere i treet i forhold til kontekstnoden:
ancestor | Forfedre til kontekstnoden |
ancestor-or-self | Forfedre til kontekstnoden og kontekstnoden selv |
attribute | Attributt til kontekstnoden |
child | Barn av konteksnoden |
descendant | Etterkommere av kontekstnoden |
descendant-or-self | Etterkommere av kontekstnoden og kontekstnoden selv |
following | Elementer som begynner etter konteksnoden |
following-sibling | Etterfølgende søsken til kontekstnoden |
namespace | Elementer som er i angitt namespace og er etterkommere av kontekstnoden |
parent | Far til kontekstnoden |
preceding | Elemeneter som er avsluttet før kontekstnoden |
preceding-sibling | Tidligere søsken til kontekstnoden |
self | Konteksnoden |
Eksempelliste
oversatt fra W3C.
Med kontekstnoden i oversikten nedenfor mener vi den noden vi "befinner oss på", altså den vi skal orientere oss i forhold til i dokumenttreet.
XPath-uttrykket: | velger ut: |
---|---|
child::para | alle elementer av typen para som er barn av kontekstnoden |
child::* | alle elementer som er barn av kontekstnoden |
child::text() | alle tekstnoder som er barn av kontekstnoden |
child::node() | alle barn av kontekstnoden, uansett type |
attribute::name | attributten name til kontekstnoden |
attribute::* | alle attributter til kontekstnoden |
descendant::para | alle elementene para som er etterkommere (barn, barnebarn etc) av kontekstnoden |
ancestor::div | alle elementene div som er forfedre (foreldre, besteforeldre etc.) til kontekstnoden |
ancestor-or-self::div | alle elementene div som er forfedre og kontekstnoden selv hvis den er av typen div |
descendant-or-self::para | alle elementer av typen para som er etterkommere og kontekstnoden selv hvis den er av typen para |
self::para | kontekstnoden dersom den er av typen para, ellers ikke noe |
child::chapter/descendant::para | alle elementene av typen para som er etterkommere av barn til kontekstnoden som er av typen chapter |
child::*/child::para | alle barnebarn av kontekstnoden som er av typen para |
/ | dokumentets rot |
/descendant::para | alle elementer av typen para i samme dokument som kontekstelementet |
/descendant::olist/child::item | alle elementer av typen item som har et element av typen olist som far, og som er i samme dokument som kontekstnoden |
child::para[position()=1] | det første elementet av typen para som er barn av kontekstnoden |
child::para[position()=last()] | det siste elementet av typen para som er barn av kontekstnoden |
child::para[position()=last()-1] | det nest siste elementet av typen para som er barn av kontekstnoden |
child::para[position()>1] | alle elementene av typen para som er barn av konteksnode, untatt det første |
following-sibling::chapter[position()=1] | det neste elementet av typen chapter som er søsken til kontekstnoden |
preceding-sibling::chapter[position()=1] | det forrige elementet av typen chapter som er søsken til kontekstnoden |
/descendant::figure[position()=42] | det 42. elementet av typen figure i dokumentet |
/child::doc/child::chapter[position()=5]/child::section[position()=2] | det andre elementet av typen section i det femte elementet av typen chapter i elementet av typen doc |
child::para[attribute::type="warning"] | alle elementer av typen para som er barn av kontekstnoden og som har attributt med navn type og med verdi warning |
child::para[attribute::type='warning'][position()=5] | det femte elementet av type para som er barn av kontekstnoden og som har en attributt med navn type og verdi warning |
child::para[position()=5][attribute::type="warning"] | det femte elementet av type para som er barn av kontekstnoden hvis det har en attributt med navn type og verdi warning |
child::chapter[child::title='Introduction'] | alle elementer av typen chapter som er barn av kontekstnoden og som har en eller fler barn av typen title med innholdet Introduction |
child::chapter[child::title] | alle barn av kontekstnoden som er av typen chapter og som har en eller flere barn av typen title. |
child::*[self::chapter or self::appendix] | alle barn av kontekstnoden som er elemenetr av typen chapter eller appendix |
child::*[self::chapter or self::appendix][position()=last()] | det siste elmentet av typen chapter eller appendix som er barn av kontekstnoden |
Kortformer
. | self::node() |
.. | parent::node() |
name | child::name |
@name | attribute::name |
// | /descendant-or-self::node()/ |
Noen XPathfunksjoner
Her finner du noen funksjoner som fungerer i XPath-uttrykk. Lista er ikke komplett. Jeg har tatt med de du trolig først vil ha behov for. En full liste finner du selvsagt hos W3C.
Disse opererer på node set, en gruppe noder | ||
---|---|---|
position() | number | Posisjonen til kontekstnoden i det aktuelle nodesettet |
last() | number | Antall noder i det aktuelle nodesettet |
count(nodeset) | number | Antall noder i parameter |
id(string) | nodeset | En node med element id lik string hvor som helst i det samme dokumentet. String kan også være en kommaseparert liste med id-verdier. |
String funksjoner | ||
concat() | string | Slår sammen stringer som angis som parametere. collect('hallo','der') |
contains() | boolean | Returnerer true hvis en a inneholder b. contains(a,b) |
normalize-space() | string | Trimmer en string for whitespace. |
starts-with() | boolean | Returnerer true hvis a begynner med b. starts-with(a,b) |
string() | string | Returnerer a som string. string(2) gir '2' |
string-length() | number | Returnerer lengden til en string |
substring() | string | Returnerer et utdrag fra en string. substring(hele,startix,lengde) |
substring-after() | string | Returnerer et utdrag fra en string. substring-after('kr10/kg','/') gir 'kg' |
substring-before() | string | Returnerer et utdrag fra en string. substringbefore('kr10/kg','/') gir 'kr10' |
translate() | string | Gjør en replace. translate('hello','e','a') gir 'hallo' |
Tall funksjoner | ||
ceiling() | number | Returnerer det det minste heltallet større enn argumentet. ceiling(2.1) gir 3 |
floor() | number | Returnerer det det største heltallet mindre enn argumentet. floor(2.1) gir 2 |
number() | number | Oversetter en string til et tall. |
round() | number | Avrunder et tall til nærmeste heltall. |
sum() | number | Summerer numeriske verdier i et nodesett. |
Noen Verktøy
Det finnes noen nyttige verktøy for å eksperimentere med XPath. Disse er nyttige både i opplæring og i utviklingsarbeid. Jeg har lastet ned og testet to av dem. Begge er gratis.
XPath Visualizer
Xpath Visualizer [1]
XPath Explorer
XPath Explorer [2] er skrevet i java og distribuert som jar. Kildekoden er også tilgjengelig. Kjøres slik: java -jar xpe.jar fra kommandolinja.