Un document XML peut être vu comme un arbre:
Foundations of Databases
Abiteboul
Hull
Vianu
Addison Wesley
1995
The Lord of the Rings
J. R. R. Tolkien
Houghton Mifflin
2001
]]>
Étant donné un arbre, comment peut ont produire le document XML correspondant ?
//pseudo-code
void print(Node n)
{
if (n is text or comment) { output_text(n) }
else {
output_text ("<" + tag(n) + ">");
for k in children(n)
print(k);
output_text ("</" + tag(n) + ">");
}
On appelle ordre du document un ordre total sur les nœuds d'un document qui correspond à leur ordre dans un fichier sérialisé. Il correspond aussi à la numérotation lors du parcours préfixe
Pour simplifier on suppose un fichier sans texte, uniquement avec des balises ouvrantes/fermantes
type Node = { label : string; children : List<Node> }
Stack<Node> stack;
stack.push (new Node("#document"), []));
while (true) {
tag = read ();
if end_of_file () break;
if tag is opening {
parent = stack.peek();
node = new Node(tag, []);
parent.addChild(node);
stack.push(node);
}
if tag is closing {
stack.pop();
}
}
En pratique, on utilise des bibliothèques toutes faites pour lire/écrire des fichiers!
Les documents représentant des données (semi-) structurées, on souhaite en extraire de l'information
On va pouvoir écrire des requêtes sur des critères scalaires ( « renvoyer tous les livres publiés après 2000 »), mais aussi sur des critères de structure (« renvoyer tous les éléments qui ont un fils author »)
XPath est un langage de selection de nœud dans un document XML. Il ne permet que de sélectionner des nœuds, pas d'en construire de nouveaux. C'est un langage restreint qui ne contient pas de fonctions, variables, … On peut le voir comme un équivalent du SELECT de SQL
Sélectionner tous les titres du document (de manière compliquée)
/descendant::author/parent::book/child::title
La syntaxe d'une requête XPath est:
/axe1::test1[ pred1 ]/ … /axen::testn[ predn ]
exemple:
/descendant::book[ child::year > 2000] / child::title
Étant donné la requête:
/axe1::test1[ pred1 ]/ … /axen::testn[ predn ]
/descendant::author/parent::book/child::title
Le standard XPath définit un grand nombre d'axes
On peut sélectionner des nœuds selon les critères suivants
p ::= p or p
| p and p
| not (p)
| count(…), contains(…), position(), …
| chemin XPath
| e1 op e2
e1 et e2 sont des expressions arithmétiques, op peut être <, >, =, !=, +, -, *, /, mod, …
On évalue le prédicat et on converti son résultat en valeur de vérité. Si la valeur vaut vrai, on garde le nœud courant, si elle vaut faux, on ne le garde pas
XPath connait 4 types de données pour les prédicats :
/descendant::book [ count(child::author) > 2
or contains(child::author, "Tolk")
]/child::title