Utiliser XML avec MySQL 5.1 (part 3/5)

août 10, 2009
Tags: ,

(<- précédent)

Interroger un flux XML avec Xpath

L’emploi de XML ne présenterait pas beaucoup d’intérêt sans la possibilité de pouvoir interroger sa structure pour accéder à une information particulière : le langage XPath répond à cette attente et est (en partie du moins) aujourd’hui intégré à MySQL. Mais avant de voir comment utiliser XPath à travers MySQL, il est nécessaire de se pencher sur la syntaxe de ses expressions, dont la construction la plus importante est sans conteste le chemin de localisation (location path).

Le chemin de localisation

De manière similaire à la navigation au sein d’un système de fichiers, un chemin de localisation se compose d’une succession d’étapes, séparées les unes des autres par un /. La description d’un chemin peut se faire de façon absolue ou relative, auquel cas un nœud contexte est utilisé afin de déterminer à partir de quel endroit doit s’effectuer la recherche.

Chaque étape d’un chemin de localisation peut se diviser en trois parties (axe de recherche, test du nœud et ensemble de prédicats), réunies sous la forme suivante :

Axis::Node-Test[Predicate1][Predicate2]…

L’axe de recherche (Axis)

L’axe de recherche permet de spécifier dans quel sens orienter la sélection des nœuds que l’on veut récupérer par rapport au nœud courant. Ainsi, il est possible de choisir de chercher dans l’ensemble des nœuds des descendants, plutôt que de se limiter (par défaut) aux nœuds directement enfants.

Il existe une dizaine d’axes de recherche, dont les plus usités sont :

  • child, qui limite à l’exploration des nœuds éléments directement enfants du nœud contexte,
  • descendant, qui englobe, en plus des nœuds enfants, tous les éléments descendants,
  • descendant-or-self, identique à descendant avec en plus le nœud contexte inclus,
  • ancestor, qui contient tous les nœuds ancêtres,
  • ancestor-or-self, identique à ancestor avec en plus le nœud contexte,
  • following-sibling, qui fait référence aux éléments frères suivants,
  • preceding-sibling, qui fait référence aux éléments frères précédents,
  • attribute, qui se cantonne à la recherche dans les nœuds attributs.

Le test du nœud (Node-Test)

Généralement, le test repose sur le nom du nœud que l’on veut retrouver. Cependant, XPath ne se limite pas à la recherche de simples éléments, mais à tous types de nœuds. Il est donc ainsi possible de préciser le type de nœud que l’on veut atteindre grâce aux fonctions suivantes :

  • node(), qui valide tous types de nœuds,
  • text(), pour les nœuds texte,
  • comment(), pour les commentaires,
  • processing-instruction(), pour les instructions de traitements.

Les prédicats (Predicates)

Les prédicats, délimités par un « [«  et un « ]« , permettent de filtrer plus finement l’ensemble des nœuds retrouvés par le chemin de localisation, en évaluant l’expression qu’ils contiennent et en ne retenant que les nœuds qui la valident. Plusieurs prédicats peuvent se suivre, filtrant ainsi un peu plus précisément l’ensemble des nœuds à garder.

Les expressions mises en place dans les prédicats peuvent, en plus des quelques fonctions existantes et des opérateurs habituels, exploiter des ensembles de nœuds (node-sets) récupérés grâce à… des chemins de localisation !

Ainsi, il est possible d’adapter la validité d’un chemin de localisation en fonction même de tout élément de l’arborescence du flux XML.

Par exemple, si l’on considère l’expression XPath suivante :

//article[@rubrique = /site/menu/rubrique[2]]

On récupère tous les articles qui possèdent un attribut rubrique ayant la même valeur que la deuxième rubrique du menu du site.

Cet autre exemple :

//article[not( @rubrique = preceding-sibling::article/@rubrique)]

permet de ne sélectionner que les articles qui n’ont pas leur attribut rubrique égal à l’attribut rubrique d’un article précédent. En d’autres termes, on ne récupère ici que le premier article de chaque rubrique.

Quelques raccourcis

Afin de faciliter la lecture et l’écriture de requêtes XPath, il existe bien heureusement un ensemble de raccourcis pratiques:

Raccourcis Xpath

self::node() .
parent::node() ..
attribute::name @name
//descendant-or-self::node()/ //
element[position() = X] element[X]

(à suivre… utiliser XML avec MySQL 5.1 : Les fonctionnalités Xpath de MySQL 5)

Leave a Reply