XPath

De la Wikipedia, enciclopedia liberă
Xpath expression applied to an XML file

XPath (XML Path Language) este un limbaj de expresii utilizat pentru a selecta porțiuni dintr-un document XML sau pentru a calcula valori (șiruri de caractere, numere, sau valori buleene) pe baza conținutului unui document XML. Versiunea actuală a limbajului este XPath 2.0, dar cea mai întâlnită versiune în prezent este versiunea 1.0.

Limbajul XPath este structurat pe reprezentarea sub formă de arbore a documentului XML, oferind posibilitatea de a naviga în acest arbore, prin selecția nodurilor XML care satisfac diferite criterii. În utilizarea frecventă (care nu este o specificație oficială), o expresie XPath este deseori numită un XPath.

Motivația apariției acestui limbaj a fost dorința de a folosi aceeași sintaxă și același model atât pentru XPointer ca și pentru XSLT, XPath s-a încetățenit printre programatori ca fiind un mic limbaj de interogare, iar anumite părți ale sale sunt folosite în specificațiile W3C pentru XML Schema și XForms.

Notație[modificare | modificare sursă]

Cea mai întâlnită metodă a expresiilor XPath (cea de la care provine și numele limbajului) este path expression. Un path expression este scrisă ca o secvență de pași pentru a ajunge dintr-un nod XML ('context node'-ul curent) la un alt nod sau un alt set de noduri. Pașii sunt separați de caracterul "/" (ex. path). Fiecare pas are trei componente:

  • Specificatorul de axe
  • Node Test
  • Predicat

Există două notații - prima, cunoscută ca sintaxa abreviată, este mai compactă și permite ca XPath-urile sa fie scrise și citite într-un mod mai intuitiv, și în multe cazuri, seturi de caractere și construcții mai intuitive. Sintaxa completă este mai complexă, dar permite specificarea mai multor opțiuni, și descrierea mai detaliată - în cazul în care se citește cu mai multă atenție.

Sintaxa abreviată[modificare | modificare sursă]

Notarea compactă permite mai multe notații implicite și abrevieri pentru cazurile cele mai comune. Cel mai simplu XPath are următoarea formă

  • /A/B/C

prin care se selectează elementele C care sunt copii elementelor B, care la rândul lor sunt copii elementelor A, care este cel mai cuprinzător element al documentului XML. Sintaxa XPath s-a făcut pentru a simula sintaxa URI (Uniform Resource Identifier) și sintaxa căilor spre fișiere.

Expresii mai complicate pot fi construite prin specificarea unei axe diferite de axa 'copil' implicită, un nod test diferit de un simplu nume, sau predicate, care sunt scrise între paranteze pătrate pentru fiecare pas. De exemplu, expresia

  • A//B/*[1]

selectează primul element ('[1]'), oricare ar fi numele lui ('*'), care este copilul ('/') unui nod B, care la rândul său este copilul unui descendent mai cuprinzător ('//') al unui element A, care este copilul nodului contextual curent (expresia nu începe cu '/'). Merită notat că dacă există mai multe elemente B corespunzătoare în document, se va returna un set întreg de primi copii.

Sintaxa extinsă[modificare | modificare sursă]

Folsind sintaxa extinsă, cele două exemple s-ar fi scris

  • /child::A/child::B/child::C
  • child::A/descendant-or-self::node()/child::B/child::*[position()=1]

În acest exemplu, la fiecare pas al XPath-ului, axa (e.g. child sau descendant-or-self) este specificată în mod explicit, fiind urmată de :: și mai apoi de node test, precum A sau node() din exemplul de mai sus.

Specificatorii axiali[modificare | modificare sursă]

Specificatorii axiali indică direcția de navigare din interiorul arborelui care reiese din reprezentarea documentului XML. Axele disponibile, în sintaxa completă sau abreviată, sunt:

child
implicit, nu trebuie specificat în sintaxa abreviată
attribute
@
descendant
/
descendant-or-self
//
parent
.. exemplu punct-punct
ancestor
indisponibil în sintaxa abreviată
ancestor-or-self
indisponibil în sintaxa abreviată
following
indisponibil în sintaxa abreviată
preceding
indisponibil în sintaxa abreviată
following-sibling
indisponibil în sintaxa abreviată
preceding-sibling
indisponibil în sintaxa abreviată
self
.exemplu punct
namespace
indisponibil în sintaxa abreviată

Ca exemplu de folosire a axei attribute din sintaxa abreviată, //a/@href selectează un atribut numit href dintr-un element a element oriunde în arborele documentului. Axa self este cel mai des folosită în interiorul unui predicat pentru a face referire la nodul curent selectat. Ca exemplu, h3[.='Vezi și'] selectează un element numit h3 din contextul curent, al cărui conținut este Vezi și.

Testarea nodurilor[modificare | modificare sursă]

Verificarea nodurilor se poate face fie prin specificarea numelui nodurilor sau prin intermediu unor expresii mai generale. În cazul documentelor XML în care prefixul domeniilor de nume gs a fost definit, //gs:enquiry va găsi toate elementele enquiry din domeniul de nume, iar //gs:* va găsi toate elementele, indiferent de numele local, din domeniu de nume.

Alte formate de testări ale numelor de noduri sunt:

comment()
găsește un nod comentariu, ex. <!-- Comment -->
text()
găsește toate nodurile de tip text, ex. the hello în <k>hello</k>
processing-instruction()
găsește toate instrucțiunile de preprocesare XML, precum <?php echo $a; ?>. În acest caz, processing-instruction('php') va fi o protrivire.
node()
găsește toate nodurile de orice tip.

Predicate[modificare | modificare sursă]

Expresii cu diferite nivele de complexitate pot fi definite prin intermediul parantezelor pătrate, care trebuie îndeplinite înainte ca nodul să fie identificat printr-un XPath. Spre exemplu //a[@href='help.php'], care va identifica un element a cu un atribut href a cărui valoare este help.php.

Nu există o limită pentru numărul de predicate de la un pas, și nu sunt mărginite la ultimul pas al unui XPath. Pot fi de asemenea imbricate pe câte nivele este necesar. Căile specificate în predicate încep de la contextul pasului curent și care nu alterează acel context. Toate predicatele trebuie satisfăcute pentru a exista o potrivire.

Când //a[/html/@lang='en'][@href='help.php'][1]/@target este aplicat unui documenti XHTML, va selecta valoare atributului target a primului element a care are atributul href definit ca având valoarea help.php, pentru un document cu un element html de cel mai înalt nivel care are și atributul lang setat ca fiind en. Referința către un atribut al unui element de cel mai înalt nivel din primul predicat nu afectează nici contextul altor predicate și nici localizarea pasului respectiv.

Ordinea predicatelor este totuși importantă. Fiecare predicat 'filtrează' pasul unei locații node-set pentru nodul selectat în ordine. //a[1][/html/@lang='en'][@href='help.php']/@target va găsi o potrivire dacă primul element a într-un document @lang='en' care satisface și @href='help.php'

Funcții și operatori[modificare | modificare sursă]

XPath 1.0 definește patru tipuri de date: node-sets (grupuri de noduri lipsite de o ordine intrinsecă), șiruri, numere și booleene.

Operatorii disponibili sunt:

  • Operatorii "/", "//" și "[...]" utilizați pentru căile expresiilor, după cum este descris mai sus.
  • Operatorul de unificare, "|", utilizat pentru unificarea a două grupuri de noduri.
  • Operatorii booleeni "and" și "or", precum și funcția "not()"
  • Operatorii aritmetici "+", "-", "*", "div" (împărțire) și "mod" (restul împărțirii)
  • Operatori de comparație "=", "!=", "<", ">", "<=", ">="

Biblioteca de funcții include și:

  • Funcții pentru manipularea șirurilor de caractere: concat(), substring(), contains(), substring-before(), substring-after(), translate(), normalize-space(), string-length()
  • Funcții pentru manipularea numerelor: sum(), round(), floor(), ceiling()
  • Funcții pentru obținerea proprietăților nodurilor: name(), local-name(), namespace-uri()
  • Funcții pentru obținerea informațiilor despre contextul de procesare: position(), last()
  • Funcții de conversie a tipului: string(), number(), boolean()

Cele mai folosite în mod curent sunt prezentate mai jos. Pentru mai multe detalii, vezi - documentul cu recomandări al consoräiului W3C

Funcțiile de setare a nodurilor[modificare | modificare sursă]

position()
întoarce un număr care reprezintă poziția acestui nod în secvența de noduri care sunt procesate în mod curent (spre exemplu, nodurile selectate printr-un xsl: instrucțiunea for-each din XSLT).
count(node-set)
întoarce numărul de nodurilor din comanda node-set care a este furnizată ca argument al său.

Funcțiile șiruri de caractere[modificare | modificare sursă]

string(object?)
convertește oricare dintre cele patru tipuri de date XPath la un șir de caractere, conform regulilor predefinite. Dacă argumentul este node-set, funcția returnează primul nod din document, în format șir de caractere, ignorând restul nodurilor.
concat(string, string, string*)
concatenează șiruri de caractere
contains(s1, s2)
întoarce true dacă s1 conține s2
normalize-space(string?)
toate spațiile de la începutul sau sfârșitul unei secvențe sunt eliminate, iar spațiile multiple sunt înlocuite cu un singur spațiu. Această funcție este foarte utilă când documentul original XML este formatat pentru a fi lizibil, ceea ce ar putea duce la un caracter nesigur al procesării șirurilor de caractere.

Funcțiile booleene[modificare | modificare sursă]

not(boolean)
neagă orice expresie booleeană
true()
evaluează cu adevărat.
false()
evaluează cu fals.

Funcțiile numerice[modificare | modificare sursă]

sum(node-set)
prin convertirea valorilor șirurilor de caractere ale nodurile găsite de XPath în numere, întoarce suma acestor numere.

Expresiile pot fi create în interiorul predicatelor folosindu-se operatorii : =, !=, <=, <, >= și >. Expresiile buleene pot fi combinate între paranteze () sau între and și or ca și între funcția not() descrisă mai sus. Calculele numerice pot folosi *, +, -, div și mod. Șirurile de caractere pot consta în orice caractere de tip Unicode.

În interiorul și în exteriorul predicatelor, node-set-uri întregi pot fi combinate, prin folosirea caracterului pipe |.

v[x or y] | w[z] va întoarce un singur node-set care conține toate elementele v care au elementele copii x sau y, precum și toate elementele w care au elementele copii z, găsite în contextul curent.

//item[@price > 2*@discount] selectează item-urile al căror atribut de preț este de cel puțin două ori valoarea numerică a atributului discount.

XPath 2.0[modificare | modificare sursă]

XPath 1.0 a fost publicat ca recomandare W3C pe 16 noiembrie 1999; XPath 2.0 a fost publicat ca recomandare W3C pe 23 ianuarie 2007. XPath 2.0 reprezintă o creștere semnificativă atât cantitativă cât și a capabilității limbajului XPath.

Cea mai semnificativă schimbare este aceea că XPath 2.0 are un multe tipuri; XPath 2.0 suportă tipuri atomice, definite ca tipuri native definite sub forma XML Schema, și poate să folosească și tipuri definite de utilizator dintr-un schema. Fiecare valoare este acum o secvență (o singură valoare atomică sau un nod este văzut drept o secvență de lungime unu). Node-set-urile din XPath 1.0 sunt înlocuite de secvențe de noduri, care pot fi în orice ordine.

Pentru a putea suporta mai multe tipuri, XPath 2.0 oferă un număr sporit de funcții și operații.

XPath 2.0 este un subset al XQuery 1.0. Oferă suport pentru expresii for, care este o versiune simplificată a expresiilor "FLWOR" din XQuery. Este posibil să descrii limbajul prin părțile de XQuery pe care nu le include: principalele exemple sunt interogările prolog, constuctorii de elemente și atribute, restul de sintaxă "FLWOR", și de expresii typeswitch.

Exemplu[modificare | modificare sursă]

Dat fiind exemplul de document XML

<?xml version="1.0" encoding="utf-8"?>
<wikimedia>
  <projects>
    <project name="Wikipedia" launch="2001-01-05">
      <editions>
        <edition language="English">en.wikipedia.org</edition>
        <edition language="German">de.wikipedia.org</edition>
        <edition language="French">fr.wikipedia.org</edition>
        <edition language="Polish">pl.wikipedia.org</edition>
      </editions>
    </project>
    <project name="Wiktionary" launch="2002-12-12">
      <editions>
        <edition language="English">en.wiktionary.org</edition>
        <edition language="French">fr.wiktionary.org</edition>
        <edition language="Vietnamese">vi.wiktionary.org</edition>
        <edition language="Turkish">tr.wiktionary.org</edition>
      </editions>
    </project>
  </projects>
</wikimedia>

Expresia XPath

/wikimedia/projects/project/@name

selectează atributele numelor pentru toate proiectele și

/wikimedia/projects/project/editions/edition[@language="English"]/text()

selectează adresele tuturor proiectelor în engleză ale Wikimedia (textul pentru toate elementele edition în care atributul language este egal cu English), iar următorul

/wikimedia/projects/project[@name="Wikipedia"]/editions/edition/text()

selectează toate adresele tuturor Wikipediilor (textul tutuor elementelor edition care există sub elementul project cu un nume de atribut Wikipedia)

Implementări[modificare | modificare sursă]

ActionScript
C/C++
Implementări pentru motoare de baze de date
Java

The Java package Format:Javadoc:SE has been part of Java standard edition since Java 5. Technically this is an XPath API rather than an XPath implementation, and it allows the programmer the ability to select a specific implementation that conforms to the interface.

JavaScript
.NET Framework
Perl
PHP
Python
Ruby
Scheme

Utilizare XPath în limbajele Schema[modificare | modificare sursă]

XPath is increasingly used to express constraints in schema languages for XML.

  • The (now ISO standard) schema language Schematron pioneered the approach.
  • A streaming subset of XPath is used in W3C XML Schema for expressing uniqueness and key constraints.
  • XForms uses XPath to bind types to values.
  • The approach has even found use in non-XML applications, such as the constraint language for Java called PMD: the Java is converted to a DOM-like parse tree, then XPaths rules are defined over the tree.

Vezi și[modificare | modificare sursă]

Format:XSL

Legături externe[modificare | modificare sursă]