XPath

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 8 september 2017; kontroller kräver 14 redigeringar .

XPath (XML Path Language) är ett frågespråk för delar av ett XML- dokument. Designad för att komma åt delar av ett XML-dokument i XSLT- transformationsfiler och är en W3C-standard . XPath syftar till att implementera DOM- navigering i XML . XPath använder en kompakt syntax som skiljer sig från XML. Version 2.0 färdigställdes 2007 och är nu en del av språket XQuery 1.0. I december 2009 började utvecklingen av version 2.1, som använder XQuery 1.1.

För tillfället är den mest populära versionen XPath 1.0. Detta beror på bristen på XPath 2.0-stöd från bibliotek med öppen källkod. I synnerhet talar vi om libxml2 , på vilket språkstöd i webbläsare å ena sidan och stöd från servertolkare å andra sidan beror på.

Grunderna

XML har en trädstruktur. Ett fristående XML-dokument har alltid ett rotelement (instruktionen <?xml version="1.0"?> har inget att göra med elementträdet), där ett antal kapslade element är tillåtna, varav några också kan innehålla kapslade element . Du kan också se textnoder, kommentarer och instruktioner. Du kan tänka dig att ett XML-element innehåller en array av kapslade element och en array av attribut.

Trädelement har förfäderelement och efterkommande element (rotelementet har inga förfäder, och stubbelement (trädets blad) har inga barn). Varje element i trädet är på en viss häckningsnivå (hädanefter kallad "nivån"). Elementen är ordnade i XML-texten, så vi kan prata om deras tidigare och nästa element. Detta är mycket likt att organisera kataloger i ett filsystem.

XPath-raden beskriver hur man väljer de önskade elementen från en array av element, som kan innehålla kapslade element. Urvalet börjar med den passerade uppsättningen av element, vid varje steg i sökvägen väljs de element som motsvarar steguttrycket, och som ett resultat väljs en delmängd av element som motsvarar den givna sökvägen.

Ta till exempel följande XHTML- dokument:

< html > < body > < div > Första lagret < span > textblock i första lagret </ span > </ div > < div > Andra lagret </ div > < div > Tredje lagret < span class = "text" > första blocket i tredje lagret </ span > < span class = "text" > andra blocket i tredje lagret </ span > < span > tredje blocket i tredje lagret </ span > </ div > < span > fjärde lagret </ span > < img /> </ body > </ html >

XPath-sökvägen /html/body/*/span[@class] kommer att matcha två delar av källdokumentet i den - <span class="text">первый блок в третьем слое</span>och <span class="text">второй блок в третьем слое</span>.

Sökvägselement skrivs huvudsakligen i XPath i kort form. Den fullständiga formen av ovanstående sökväg är /child::html/child::body/child::*/child::span[attribut::class]

Sökvägen består av adresseringssteg, som är åtskilda av ett snedstreck /.

Varje adresseringssteg består av tre delar:

  • axel (default child::, elementaxel). Förutom att filtrera längs axeln för kapslade element, kan du välja längs olika andra axlar av element och längs attributaxeln (attribut::, det betecknas också med symbolen @) (se nedan).
  • ett uttryck som definierar de element som ska väljas (i exemplet görs valet genom att matcha dokumentelementen med namnen html, body, span och symbolen används *, vilket kommer att välja alla element på axeln)
  • predikat (i det här exemplet är det attribut::class) — ytterligare urvalsvillkor. Det kan finnas flera. Varje predikat omges av hakparenteser och innebär ett logiskt uttryck för att testa de valda elementen. Om det inte finns något predikat väljs alla matchande element.

Sökvägen analyseras från vänster till höger och startar antingen i kontexten av det första elementet i rotnoden (i det här exemplet är detta html-elementet), och sedan längs axeln under:: kommer det att finnas element kapslade i den (i det här exemplet är detta ett body-element), vilket är praktiskt vid ärendebearbetning av ett vanligt XML-dokument med en enda rotnod, eller, om tecknet anges i början av XPath /, i sammanhang med alla rotelementen av den skickade XML-en längs den underordnade::-axeln (i det här exemplet kommer detta att vara ett enda html-element). Vid varje adresseringssteg i det aktuella sammanhanget väljs element som matchar de villkor som anges i steget, och deras lista tas som kontext för nästa steg eller som ett returresultat.

Det första steget /child::htmlgör alltså explicit den aktuella kontexten för nästa steg till en lista med ett html-element, vilket skulle ha gjorts implicit om detta steg inte hade specificerats.

I det andra adresseringssteget i det här exemplet (barnet::kroppssteget) är kontexten en lista med ett html-element. The child:: axis säger att du måste titta på namnen på kapslade element i det aktuella sammanhanget, och body check-villkoret säger att de noder som har namnet body måste inkluderas i den genererade uppsättningen av element. Under det andra adresseringssteget får vi alltså en uppsättning noder som består av endast ett kroppselement, vilket blir sammanhanget för det tredje steget.

Tredje steget i adresseringen: child::* . Den underordnade::-axeln innehåller alla direkta barn till body-elementet, och testvillkoret * säger att element av huvudtypen med vilket namn som helst ska inkluderas i den genererade listan. Under detta steg får vi en lista bestående av tre div-element, ett span och ett img-element - totalt fem element.

Fjärde adresseringssteget: child::span/@class. Dess kontext är en lista med fem poster, så den utgående listan skapas i fem omgångar (fem iterationer). Vid den första iterationen blir den första div kontextnoden. Med tanke på barnet::-axeln och spantestregeln måste uppsättningen inkludera de omedelbara barnen till denna div, vars namn är lika med span. Det finns en där. Vid den andra iterationen kommer ingenting att läggas till uppsättningen, eftersom den andra div inte har några barn. Den tredje iterationen kommer att se tre span-element samtidigt. Den fjärde kommer inte att se någonting, eftersom span-elementet inte har några span-avkomlingar, och det faktum att det är ett span i sig spelar ingen roll, eftersom det är ättlingarna som ses. Den femte kommer inte att se något heller, img-elementet har heller inga span-barn. Så under testet kunde en noduppsättning bestående av fyra spännelement erhållas. Detta skulle vara sammanhanget för vidare bearbetning om inget predikat specificerades i detta steg.

Men eftersom det finns ett predikat vid det fjärde steget, när var och en av de fem övergångarna utförs, kommer ytterligare filtrering av de valda elementen att utföras. I det här fallet indikerar attributet:: axeln för predikatet behovet av att kontrollera om den valda noden har attribut, och klassvillkoret kräver att endast de noder som har ett attribut som heter klass lämnas kvar. Och därför, vid den första iterationen, kommer det enda hittade spannet inte att passera filtreringen av predikatet, vid den tredje iterationen kommer två av tre element att passera filtreringen, och som ett resultat, trots det faktum att filtreringen sker över fem iterationer, bara två span-element kommer in i den sista uppsättningen.

Axes

Axlar är basen för XPath-språket. Det finns förkortningar för vissa axlar.

  • child::  - innehåller en uppsättning underordnade element (element som finns en nivå under). Detta namn förkortas helt, det vill säga det kan utelämnas helt.
  • descendant::  - innehåller hela uppsättningen av descendant element (det vill säga både de närmaste efterkommande elementen och alla deras underliggande element). Uttrycket /descendant::node()/kan förkortas till //.
  • descendant-or-self::  innehåller hela uppsättningen av descendant-element och det aktuella elementet. Med hjälp av denna axel, till exempel, är det möjligt att organisera urvalet av element från vilken nod som helst, och inte bara från rotnoden, som det andra steget: det räcker att ta alla ättlingar till rotnoden som första steget. Till exempel kommer en sökväg //spanatt välja alla noder i spandokumentet, oavsett deras position i hierarkin, titta på både namnet på rotelementet och namnen på alla dess underordnade, till hela djupet av deras kapsling.
  • förfader::  - innehåller många förfaderelement.
  • ancestor-or-self::  innehåller uppsättningen förfaderelement och det aktuella elementet.
  • parent::  - innehåller förfaderelementet en nivå tillbaka. Detta samtal kan ersättas av..
  • self::  - innehåller det aktuella elementet. Detta samtal kan ersättas av.
  • följande::  - innehåller en uppsättning element som ligger under det aktuella elementet i trädet (på alla nivåer och lager), exklusive deras egna avkomlingar.
  • following-sibling::  innehåller en uppsättning syskonelement som följer det aktuella lagret.
  • föregående::  - innehåller uppsättningen element ovanför det aktuella elementet i trädet (på alla nivåer och lager), exklusive uppsättningen av egna förfäder.
  • preceding-sibling::  innehåller en uppsättning syskonelement som föregår det aktuella lagret.
  • attribut::  - innehåller en uppsättning attribut för det aktuella elementet. Denna anrop kan ersättas med symbolen@
  • namespace::  - innehåller en uppsättning element relaterade till ett visst namnområde (det vill säga det finns ett attribut xmlns).

Ett uttryck som anger de element som ska väljas

Inom innehållet i axeln utförs valet enligt uttrycket som definierar de element som ska väljas.

Som ett uttryck kan det vara

  • ett specifikt namn anges, sedan väljs de axelelement som motsvarar detta namn
  • symbolen anges *, vilket kommer att välja alla element på axeln
  • ett uttryck som består av funktioner anges, och sedan kommer resultaten av uttrycksberäkningen att väljas i sammanhanget för varje element på axeln

Funktionerna är indelade i 5 grupper:

Fungerar över uppsättningar av knop

Fungera Beskrivning
node-set node() Returnerar själva noden. Istället för denna funktion används ofta ersättaren *, men till skillnad från asterisken returnerar funktionen node()även textnoder
string text() Returnerar noden om det är text
node-set current() Returnerar en uppsättning av ett element, vilket är det nuvarande. Om vi ​​ställer in bearbetning med predikat, kommer det enda sättet att nå det aktuella elementet från detta predikat att vara denna funktion
number position() Returnerar positionen för ett element i uppsättningen av axelelement. Fungerar korrekt endast i en slinga<xsl:for-each/>
number last() Returnerar numret på det sista elementet i uppsättningen av axelelement. Fungerar korrekt endast i en slinga<xsl:for-each/>
number count(node-set) Returnerar antalet element i node-set.
string name(node-set?) Returnerar det fullständiga namnet på den första taggen i uppsättningen
string namespace-url(node-set?) Returnerar en länk till en URL som anger ett namnområde
string local-name(node-set?) Returnerar namnet på den första taggen i uppsättningen, utan ett namnområde
node-set id(object) Hittar ett element med ett unikt id

Strängfunktioner

Fungera Beskrivning
string string(object?) Returnerar textinnehållet i elementet. Returnerar i huvudsak den sammanslagna uppsättningen textelement en nivå ner
string concat(string, string, string*) Sammanfogar strängarna som anges i argumenten
number string-length(string?) Returnerar längden på strängen
boolean contains(string, string) Returnerar trueom den första raden innehåller den andra, annars -false
string substring(string, number, number?) Returnerar en sträng utskuren från en sträng, med början på det angivna numret och, om ett andra nummer anges, antalet tecken
string substring-before(string, string) Om den andra strängen hittas inom den första, returnerar strängen till den första förekomsten av den andra strängen
string substring-after(string, string) Om den andra strängen hittas inom den första, returneras strängen efter den första förekomsten av den andra strängen
boolean starts-with(string, string) Returnerar trueom den andra raden är i början av den första, annars -false
boolean ends-with(string, string) Returnerar trueom den andra raden är i slutet av den första, annars -false
string normalize-space(string?) Tar bort extra och upprepade mellanslag, samt kontrolltecken, och ersätter dem med mellanslag
string translate(string, string, string) Ersätter tecknen i den första strängen som förekommer i den andra strängen med tecknen i den tredje strängen som motsvarar positionerna för tecknen i den andra strängen. Till exempel kommer den translate("bar", "abc", "ABC")att returnera BAr.

Booleska funktioner och operatorer

Symbol, operatör Menande
or logiskt "eller"
and logiskt "och"
= logiskt "lika"
<(<) logiskt "mindre än"
>(>) logiskt "större"
<=(<=) logiskt "mindre än eller lika med"
>=(>=) logiskt "större än eller lika"
Fungera Beskrivning
boolean boolean(object) Kastar ett objekt till en boolesk typ
boolean true() Returnerar sant
boolean false() Returnerar falskt
boolean not(boolean) Negation, returnerar sant om argumentet är falskt och vice versa

Numeriska funktioner och operatorer

Symbol, operatör Menande
+ tillägg
subtraktion
* multiplikation
div vanlig division ( inte heltal! )
mod resten av divisionen
Fungera Beskrivning
number number(object?) Konverterar ett objekt till ett tal
number sum(node-set) Returnerar summan av uppsättningen. Varje set-tagg kommer att konverteras till en sträng och ett nummer kommer att erhållas från den
number floor(number) Returnerar det största heltal som inte är större än argumentet (avrunda nedåt)
number ceiling(number) Returnerar det minsta heltal inte mindre än argumentet (avrundning uppåt)
number round(number) Avrundar ett tal enligt matematiska regler

Systemfunktioner

Fungera Beskrivning
node-set document(object, node-set?) Returnerar dokumentet som anges i parameternobject
string format-number(number, string, string?) Formaterar ett tal enligt mönstret som anges i den andra parametern. Den tredje parametern anger det namngivna talformatet som ska beaktas.
string generate-id(node-set?) Returnerar en sträng som är en unik identifierare
node-set key(string, object) Returnerar en uppsättning med den angivna nyckeln (liknande funktionen idför identifierare)
string unparsed-entity-uri(string) Returnerar den oparsade URI:en. Om det inte finns någon returnerar den en tom sträng
boolean element-available(string) Kontrollerar om elementet eller uppsättningen som anges i parametern är tillgänglig. Parametern behandlas som XPath
boolean function-available(string) Kontrollerar om funktionen som anges i parametern är tillgänglig. Parametern behandlas som XPath
object system-property(string) Parametrar som returnerar systemvariabler. Kan vara:
  • xsl: version - returnerar XSLT-versionen av processorn.
  • xsl: vendor - returnerar tillverkaren av XSLT-processorn.
  • xsl: vendor-url - returnerar en URL som identifierar tillverkaren.

Om en okänd parameter används returnerar funktionen en tom sträng

boolean lang(string) Returnerar trueom den aktuella taggen har ett attribut xml: langeller om taggens överordnade har ett attribut xml: langoch den innehåller tecknet som matchar strängen

Predikat

Predikat är logiska uttryck inom hakparenteser, byggda enligt samma principer som urvalsuttrycket. Uttryck som inte returnerar ett booleskt värde utan en tom uppsättning element anses vara falska. Ett uttryck som returnerar ett tal anses vara ett uttryck som jämför talet med position(). När det finns mer än ett predikat, filtrerar var och en av dem resultaten av filtreringen efter det föregående predikatet.

Andra notationer i XPath

Beteckning Beskrivning
* Indikerar alla namn eller teckenuppsättningar längs den angivna axeln, till exempel: * - valfri underordnad nod; @* - vilket attribut som helst
$name Få åtkomst till en variabel. name — variabel eller parameternamn
[] Ytterligare urvalsvillkor (eller adresseringsstegspredikat). Måste innehålla ett booleskt värde. Om det innehåller ett numeriskt värde, anses det vara nodens ordningsnummer, vilket motsvarar att prefixet detta nummer med uttrycketposition()=
{} Om den används inuti en tagg på ett annat språk (som HTML), behandlar XSLT-processorn innehållet i de lockiga hängslen som en XPath
/ Definierar nivån på trädet, d.v.s. separerar adresseringssteg
| Slår ihop resultatet. Det vill säga, inom en väg kan du skriva flera tolkningsvägar genom tecknet |, och resultatet av ett sådant uttryck kommer att inkludera allt som kommer att hittas av någon av dessa vägar

Länkar