Document structuré et métadonnées

Introduction au langage XML

XPath

Retour sur la notion d’arborescence

Le texte peut être vu comme une hiérarchie ordonnée d’objets contenus (OHCO – ordered hierarchy of content objects)1 :

les objets contenus sont, par exemple, des chapitres, des sections, des sous-sections, des paragraphes, des citations, etc., ces objets sont « imbriqués » les uns dans les autres – une section contient plusieurs paragraphes – c’est pourquoi on parle de structure hiérarchique, ces mêmes objets apparaissent les uns à l’intérieur des autres, mais également les uns à la suite des autres :

  • le texte est donc ordonné ;
  • Le modèle de données de XML, arborescent, est précisément conforme à OHCO ;

Cette structure hiérarchique (arbre XML) est facilement compréhensible par l’homme, mais également par la machine. Il est donc très aisé de manipuler ce type de données.

1Steve DeRose, David Durand, Elli Mylonas, and Allen Renear’s 1990 “What is text, really?”

Retour sur la notion d’arborescence

              
<?xml version="1.0" encoding="UTF-8"?>

 
   
     Victor
     Hugo
   
   
   avenue Victor-Hugo à Paris
   
     26 février 1802
     22 mai 1885
   
 


              
            

Représenter l’arbre de ce document XML. Faire attention à l’élément racine, au texte, ainsi qu’aux attributs.

Arbre XML

XML Path Language : langage de chemin XML

XPath est principalement utilisé par les langages de programmation XSLT et XQuery. C’est un langage de requête pour identifier des parties d’un documents XML. Une requête ou expression XPath permet de rechercher des nœuds. Le résultat de cette requête est une séquence de nœuds ou de valeurs atomiques.

Nœuds – notions

« Un document XML est une arborescence de nœuds. Certains nœuds contiennent d’autres nœuds. Un seul nœuds racine contient enfin tous les autres nœuds. XPath est un langage pour sélectionner des nœuds et ensembles de nœuds de cette arborescence.»1

Il existe 7 types de nœuds :

  • le nœud racine (≠ de l’élément racine, on parle aussi de nœud document)
  • les nœuds éléments
  • les nœuds attributs
  • les nœuds texte
  • les nœuds commentaires
  • les nœuds instructions de traitement
  • les nœuds d’espace de noms
1Harold, Elliotte Rusty et Means, W. Scott. « XML en concentré : manuel de référence »

Types de données

Toute expression XPath retourne un de ces 4 types de données

  • nœuds : une séquence de 0 ou plusieurs nœuds
  • chaîne de caractères : une séquence de 0 ou plusieurs caractères unicode
  • nombres : les nombres XPath sont des nombres à virgule flottante, et incluent les valeurs « Inf », « -Inf » et « NaN »
  • booléens : une valeur binaire (true ou false)

Chemin Xpath

Une Expression XPath indique un chemin depuis un nœud de départ vers un nœud ou un ensemble de nœuds cibles.

Un chemin est dit absolu lorsqu’il commence à la racine, et relatif lors qu’il part d’un nœud courant ou contextuel.

Un chemin est composé d’étapes de parcours, séparées par « / ». Placé en début d’expression, le signe « / » représentant le nœud racine.

Étape Xpath

Dans une étape on trouve 3 concepts : un axe, un filtre, un ou des prédicats

axe::filtre[prédicat_1][prédicat_N]

L’axe est le sens du parcours, le filtre correspond aux nœuds à atteindre et les prédicats, optionnels, sont les conditions qui doivent être remplies par les nœuds recherchés.

Axes Xpath

  • self:: : nœud courant ;
  • attribute:: : nœud attribut – c’est un axe particulier ;
  • child:: : nœud enfant – seuls les nœuds racine et éléments ont des enfants ;
  • parent:: : le nœud parent
  • descendant:: tous les nœuds contenus par le nœud courant
  • ancestor:: tous les nœuds qui contiennent le nœud courant
  • ancestor-or-self:: tous les nœuds qui contiennent le nœud courant, y compris ce dernier
  • descendant-or-self:: tous les nœuds contenus par le nœud courant, y compris ce dernier
  • following:: tous les nœuds qui suivent le nœud courant
  • preceding:: tous les nœuds qui précèdent le nœud courant
  • following-sibling:: tous les nœuds qui partagent un parent et suivent le nœud courant
  • preceding-sibling:: tous les nœuds qui partagent un parent et précèdent le nœud courant
Axes

les filtres

  • nomElement : sélectionne les nœuds qui portent le même nom
  • text() : sélectionne les nœuds de type texte
  • comment() : sélectionne les nœuds de type commentaire
  • processing-instruction() : sélectionne les nœuds de type instruction de traitement

Les Jokers permettent de trouver plusieurs éléments et types de nœuds en même temps, sans connaître leur nom.

  • * : tout nœud élément quelque soit son nom
  • node() : tous les nœuds (racine, éléments, attributs, commentaires, etc.)
  • @* : tout nœud attribut quelque soit son nom

Exemple XPath

              
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xslt.xsl"?>

  
    
      Victor
      Hugo
    
    
    avenue Victor-Hugo à Paris
    
      26 février 1802
      Besançon
      22 mai 1885
      Paris
    
  


              
            
  • / : nœud racine ou document, retourne tout le document
  • /child::node() : tous les nœuds enfants du nœud racine
  • /child::personnes : l’élément personnes, enfant du nœud racine
  • /child::personnes/child::personne : l’élément personne, fils de personnes
  • /child::personnes/child::personne/child::existence/child::date/attribute::type : les attributs @type des
  • éléments date

Syntaxe abrégée

  • child:: est l’axe par défaut, il peut être omis : /child::personnes = /personnes
  • /descendant-or-self::node()/ (tous les descendants) peut être remplacé par « // » : /child::personnes/child::personne/child::existence/child::date = //date
  • attribute:: (nœud attribut) peut être remplacé par « @ » : //attribute::type = //@type
  • self::node() (nœud courant) peut être remplacé par « . »
  • parent::node() (nœud parent) peut être remplacé par « .. » : ../nœudParent
  • / : nœud racine ou document, retourne tout le document
  • /node() : tous les nœuds enfants du nœud racine
  • /personnes : l’élément personnes, enfant du nœud racine
  • /personnes/personne : l’élément personne, fils de personnes
  • /personnes/personne//date/@type : les attributs @type des éléments date

Les prédicats ou conditions

Chaque étape d’un chemin XPath peut contenir 0 ou plusieurs prédicats

Un prédicat est une expression XPath entre crochets « [] » qui suit le test d’un filtre (ou nœud)

Un prédicat correspond à une condition que doit remplir le nœud pour être retenu

Exemples Prédicat

              
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xslt.xsl"?>

  
    
      Victor
      Hugo
    
    
    avenue Victor-Hugo à Paris
    
      26 février 1802
      Besançon
      22 mai 1885
      Paris
    
  


              
            
  • //identité[prénom] : tous les éléments identité, s’ils possèdent un sous-élément prénom
  • //prénom[parent::identité] : tous les éléments prénom, s’ils possèdent un parent identité
  • //date[@type] : tous les éléments date s’ils possèdent un attribut type
  • //lieu[@type='décès'] : tous les éléments lieu, s’ils possèdent un attribut type qui a pour valeur 'décès'

Les Opérateurs

Opérateurs arithmétiques

/data/num[1] - /data/num[2]
  • addition « + »
  • soustraction « - »
  • multiplication « * »
  • division « div »
  • modulo « mod »

Opérateurs de comparaison

              
//p[position() > 1]
//chapitre[head != 'Introduction']
//chapitre/[@type = 'Introduction' or @type = 'conclusion']
              
            
  • inférieur* « < » inférieur ou égal* « <= » supérieur* « > »
  • supérieur ou égal* « >= »
  • égal « = »
  • différent « != »
  • et « and »
  • or « or »

*Dans un document XSLT on utilisera &lt; et &gt;

Fonctions XPath 1.0

Fonctions sur les nombres

              

number(node) => NaN

/node/number() => 2.0

ceiling(node) => 4.0

round(node) => 3.0

              
            
  • number number(object?) : convertit son argument en nombre
  • number sum(node-set nodes) : somme de tous les nœuds en argument
  • number floor(number x) : retourne le plus grand entier inférieur ou égal à x
  • number ceiling(number x) : retourne le plus petit entier supérieur ou égal à x
  • number round(number x) : retourne l’entier le plus proche de x

Fonctions sur les booléens

              

boolean(node) => true

boolean(node/sub)=> false

not(boolean(node/sub))=> true

              
            
  • true() => true
  • boolean boolean(object o) : convertit l’argument en booléen
  • boolean not(boolean) : inverse la valeur de l’argument (vrai devient faux et faux devient vrai)
  • boolean true() : retourne toujours vrai
  • boolean false() : retourne toujours faux

Fonctions sur les nœuds

              

//node/position() => (1, 2)

count(//node) => 2

name(/ns:root) => ns:root (préfixe + nom)
local-name(/ns:root) => root

              
            
  • number position() : position du nœud courant dans l’ensemble contextuel
  • number count(nodeset?) : compte le nombre de nœuds en argument
  • string local-name(node-set?) : retourne le nom local du nœud
  • string name(node-set?) : retourne le nom qualifié du nœud (préfixe + nom local)
  • string namespace-uri(node-set?) : retourne l’espace de nom du nœud

Fonctions sur les chaînes de caractères

              

/root/node/string() => '10'

/root/node/string-length() => 2
concat('Hello', ' World') => 'Hello World'

/node/concat(@att, .) => 'HelloWorld'

              
            
  • string string(string?) : convertit un objet en chaîne de caractères
  • string normalize-space(string?) : retire les blancs en début ou fin de chaîne, et remplace les groupes
  • d’espaces ou les retour à la ligne par un espace unique
  • string concat(string, string, string*) : concatène les arguments
  • number string-length(string?) : retourne la longueur de la chaîne de caractères en argument
  • boolean starts-with(string s1, string s2) : vérifie si la chaîne s1 commence par la chaîne s2

Fonctions sur les chaînes de caractères

              

/root/node/contains(., 'Hello') => true

substring-before(/root, ' World') => 'Hello'

substring(/root, 7, 5) => World
substring(/root, 7) => World

              
            
  • boolean contains(string s1, string s2) : vérifie sur la chaîne s1 contient la chaîne s2
  • string substring-before(string s1, string s2) : retourne la sous-chaîne de s1 placée avant s2
  • string substring-after(string s1, string s2) : retourne la sous-chaîne de s1 placée après s2
  • string substring(string s, number index, number length?) : retourne la sous-chaîne de s commençant à l’index et de longueur lenght
  • string translate(string s1, string s2, string s3) : remplace dans s1 chaque occurrence de s2 par une occurrence de s3