Manuel INF 6540 - Téluq

Transcription

Manuel INF 6540 - Téluq
Manuel INF 6540
Daniel Lemire, professeur responsable
Kamel Aouiche, auxiliaire de recherche
Lucie Moulet, auxiliaire de recherche
Jean-François Savard, concepteur associé
Renée Dumas, spécialiste en communication écrite
Montréal, 4 avril 2009
Sommaire
Sommaire
iii
Guide d’étude
Introduction . . . . . . . . . . . . . . . . . . . . . . .
Objectifs . . . . . . . . . . . . . . . . . . . . . . . . .
Contenu . . . . . . . . . . . . . . . . . . . . . . . . .
Problématique . . . . . . . . . . . . . . . . . . . . .
Découplement des informations . . . . . . . .
XML et interopérabilité . . . . . . . . . . . .
Flexibilité et évolution des schémas de données
Les modules du cours . . . . . . . . . . . . . . . . . .
Caractéristiques médiatiques . . . . . . . . . . . . . .
Encadrement . . . . . . . . . . . . . . . . . . . . . .
L’évaluation . . . . . . . . . . . . . . . . . . . . . . .
Les travaux notés . . . . . . . . . . . . . . .
Examen en salle . . . . . . . . . . . . . . . .
Gestion du temps et pondération . . . . . . . . . . . .
Version PDF du cours . . . . . . . . . . . . . . . . . .
Remerciements . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
1
2
2
3
3
4
5
6
6
7
7
8
8
10
11
Module 1 : Introduction à XML
1.1 Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Objectifs . . . . . . . . . . . . . . . . . . . . .
1.1.2 Qu’est-ce que le XML? . . . . . . . . . . . . . .
1.1.3 Démarche . . . . . . . . . . . . . . . . . . . . .
1.2 Installation de Mozilla Firefox . . . . . . . . . . . . . .
1.2.1 Objectif . . . . . . . . . . . . . . . . . . . . . .
1.2.2 Activité . . . . . . . . . . . . . . . . . . . . . .
1.2.3 Installation de polices de caractères optionnelles
1.2.4 Avertissement . . . . . . . . . . . . . . . . . . .
1.2.5 Autres navigateurs . . . . . . . . . . . . . . . .
1.2.6 Retour . . . . . . . . . . . . . . . . . . . . . . .
1.3 Création de documents XML . . . . . . . . . . . . . . .
1.3.1 Objectif . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
13
13
13
14
15
15
15
16
16
16
16
16
16
iii
iv
1.3.2
1.4
1.5
1.6
Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Autres éditeurs pour le XML . . . . . . . . . . . . . . . . . .
1.3.3 Retour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Introduction à XML . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4.2 Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4.3 Quelques notions du XML . . . . . . . . . . . . . . . . . . .
1.4.4 La philosophie du XML . . . . . . . . . . . . . . . . . . . .
1.4.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . .
Principes de XML . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.2 Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.3 Quelques principes et notions importantes du XML . . . . . .
1.5.4 Points importants dans la syntaxe de base . . . . . . . . . . .
1.5.5 Dans l’ordre ou dans le désordre . . . . . . . . . . . . . . . .
1.5.6 Appels d’entités . . . . . . . . . . . . . . . . . . . . . . . .
1.5.7 Les commentaires . . . . . . . . . . . . . . . . . . . . . . .
1.5.8 Les instructions de traitement . . . . . . . . . . . . . . . . .
1.5.9 Jeux de caractères . . . . . . . . . . . . . . . . . . . . . . .
1.5.10 La déclaration XML . . . . . . . . . . . . . . . . . . . . . .
1.5.11 Les espaces . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.12 Les fins de ligne . . . . . . . . . . . . . . . . . . . . . . . .
1.5.13 Les hyperliens . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.14 Documents bien formés . . . . . . . . . . . . . . . . . . . .
Définition de type de document . . . . . . . . . . . . . . . . . . . . .
1.6.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.6.2 Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.6.3 Document XML valable . . . . . . . . . . . . . . . . . . . .
1.6.4 Normes de définition de type de document . . . . . . . . . . .
1.6.5 Documents valables utilisant la norme DTD . . . . . . . . . .
1.6.6 La syntaxe des documents DTD . . . . . . . . . . . . . . . .
1.6.7 Exemple supplémentaire . . . . . . . . . . . . . . . . . . . .
1.6.8 Les attributs . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.6.9 Les entités . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.6.10 DTD interne et externe . . . . . . . . . . . . . . . . . . . . .
1.6.11 Les entités paramètres . . . . . . . . . . . . . . . . . . . . .
1.6.12 Commentaires dans les fichiers DTD . . . . . . . . . . . . .
1.6.13 Une comparaison entre Relax NG et DTD . . . . . . . . . . .
1.6.14 Une approche plus modulaire . . . . . . . . . . . . . . . . .
1.6.15 Définir l’élément-racine . . . . . . . . . . . . . . . . . . . .
1.6.16 Définir le type de contenu en Relax NG . . . . . . . . . . . .
1.6.17 Est-ce qu’il existe un outil pour passer d’un format à l’autre
(DTD, Relax NG, XML Schema)? . . . . . . . . . . . . . . .
1.6.18 Est-ce qu’un document DTD est un document XML? . . . . .
1.6.19 Pourquoi est-ce qu’il n’est pas suffisant d’utiliser des documents bien formés? À quoi sert la validation? . . . . . . . . .
16
18
18
19
19
19
19
21
22
22
22
23
23
25
25
25
26
27
27
28
29
30
30
30
31
31
31
31
32
34
35
37
37
39
40
40
41
41
45
46
47
47
48
48
CC BY-NC-SA
v
1.7
1.8
1.9
1.6.20 Est-ce vraiment nécessaire d’avoir des documents valables?
Est-ce que je dois vraiment toujours travailler avec des fichiers
DTD, XML Schema ou Relax NG? . . . . . . . . . . . . . . .
1.6.21 Livres de référence . . . . . . . . . . . . . . . . . . . . . . .
La validation des documents XML . . . . . . . . . . . . . . . . . . .
1.7.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.7.2 Activité de validation . . . . . . . . . . . . . . . . . . . . . .
Procédure pour valider des documents XML . . . . . . . . .
Vérification de la procédure . . . . . . . . . . . . . . . . . .
1.7.3 Retour . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Espaces de noms . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.8.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.8.2 Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.8.3 Les vocabulaires XML . . . . . . . . . . . . . . . . . . . . .
1.8.4 Les identificateurs de ressources uniformes (URI) . . . . . . .
1.8.5 Les espaces de noms . . . . . . . . . . . . . . . . . . . . . .
1.8.6 Les DTD et les espaces de noms . . . . . . . . . . . . . . . .
1.8.7 Déclaration de l’espace de noms . . . . . . . . . . . . . . . .
1.8.8 Les déclarations croisées . . . . . . . . . . . . . . . . . . . .
1.8.9 Le préfixe par défaut . . . . . . . . . . . . . . . . . . . . . .
1.8.10 Rappel des notions formelles . . . . . . . . . . . . . . . . . .
1.8.11 Les espaces de noms et Relax NG . . . . . . . . . . . . . . .
1.8.12 Le préfixe « xml » . . . . . . . . . . . . . . . . . . . . . . .
1.8.13 Rappel : des espaces de noms pour les attributs? . . . . . . .
1.8.14 En résumé, qu’est-ce que les espaces de noms? . . . . . . . .
Travail noté 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.9.1 Objectifs et pondération . . . . . . . . . . . . . . . . . . . .
1.9.2 Consignes . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 1 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 2 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 3 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 4 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 5 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 6 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 7 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 8 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 9 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 10 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Question 11 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Module 2 : XML en tant que syntaxe pour les documents
2.1 Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Objectifs . . . . . . . . . . . . . . . . . . . .
2.1.2 Démarche . . . . . . . . . . . . . . . . . . . .
2.2 Introduction au XHTML . . . . . . . . . . . . . . . .
2.2.1 Objectif . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
48
48
49
49
49
49
53
54
54
54
54
54
55
55
55
56
59
59
60
61
61
62
62
62
62
62
63
63
64
65
66
66
67
67
68
68
69
71
71
71
71
72
72
CC BY-NC-SA
vi
2.3
2.4
2.5
2.6
2.2.2 Activité . . . . . . . . . . . . . . . . . . . . . . . .
2.2.3 Qu’est-ce que le XHTML? . . . . . . . . . . . . . .
2.2.4 La structure du document XHTML : head et body . .
2.2.5 Les paragraphes en HTML . . . . . . . . . . . . . .
2.2.6 Les listes en HTML . . . . . . . . . . . . . . . . .
2.2.7 Les tableaux en HTML . . . . . . . . . . . . . . . .
2.2.8 Les caractères italiques et gras . . . . . . . . . . . .
2.2.9 Les listes de définitions . . . . . . . . . . . . . . . .
2.2.10 Les lignes horizontales . . . . . . . . . . . . . . . .
2.2.11 Les images . . . . . . . . . . . . . . . . . . . . . .
2.2.12 Les hyperliens . . . . . . . . . . . . . . . . . . . .
2.2.13 Les abbréviations . . . . . . . . . . . . . . . . . . .
2.2.14 Les adresses . . . . . . . . . . . . . . . . . . . . .
2.2.15 Les indices et exposants . . . . . . . . . . . . . . .
2.2.16 Le code et les exemples . . . . . . . . . . . . . . .
2.2.17 Les citations . . . . . . . . . . . . . . . . . . . . .
2.2.18 Les révisions . . . . . . . . . . . . . . . . . . . . .
2.2.19 La langue . . . . . . . . . . . . . . . . . . . . . . .
2.2.20 Les commentaires . . . . . . . . . . . . . . . . . .
2.2.21 Séparation du contenu et de la présentation . . . . .
2.2.22 SVG . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.23 MathML . . . . . . . . . . . . . . . . . . . . . . .
2.2.24 Convertir du HTML mal formé . . . . . . . . . . . .
2.2.25 Spécification Relax NG . . . . . . . . . . . . . . . .
2.2.26 HTML 5 . . . . . . . . . . . . . . . . . . . . . . .
2.2.27 Conclusion . . . . . . . . . . . . . . . . . . . . . .
2.2.28 Livres de référence . . . . . . . . . . . . . . . . . .
2.2.29 Activité d’autoévaluation . . . . . . . . . . . . . . .
XML comme format de documents . . . . . . . . . . . . . .
2.3.1 Objectif . . . . . . . . . . . . . . . . . . . . . . .
2.3.2 Activité . . . . . . . . . . . . . . . . . . . . . . . .
2.3.3 Le SGML (Standardized General Markup Language)
2.3.4 Le XML comme format de documents . . . . . . . .
2.3.5 Le format DocBook . . . . . . . . . . . . . . . . .
2.3.6 L’ODF (Open Document Format) . . . . . . . . . .
XML sur le web . . . . . . . . . . . . . . . . . . . . . . . .
2.4.1 Objectif . . . . . . . . . . . . . . . . . . . . . . .
2.4.2 Activité . . . . . . . . . . . . . . . . . . . . . . . .
2.4.3 Le XHTML et le web . . . . . . . . . . . . . . . .
Travail noté 2 . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.1 Objectifs et pondération . . . . . . . . . . . . . . .
2.5.2 Consignes . . . . . . . . . . . . . . . . . . . . . . .
En cas de panne . . . . . . . . . . . . . . . . . . . .
Pistes de discussion . . . . . . . . . . . . . . . . . .
2.5.3 Critères de correction et de notation . . . . . . . . .
Travail noté 3 . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
72
72
74
74
76
77
79
79
80
80
81
81
81
82
82
82
82
82
83
83
83
85
85
85
92
93
93
94
94
94
94
94
95
96
101
102
102
102
102
104
104
105
105
106
106
107
CC BY-NC-SA
vii
2.6.1
2.6.2
2.6.3
Objectifs, pondération et critères de correction
Description du travail . . . . . . . . . . . . . .
Consignes . . . . . . . . . . . . . . . . . . .
Annexe 1. Document XSLT . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 107
. 107
. 108
. 110
Module 3 : Technologies XML
3.1 Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Démarche . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2 Activité . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.3 Un regard critique . . . . . . . . . . . . . . . . . . . . . . .
3.2.4 Les machines de Turing et la technologie XML . . . . . . . .
3.2.5 Qu’est-ce que le XSLT . . . . . . . . . . . . . . . . . . . . .
3.2.6 Les langages déclaratifs . . . . . . . . . . . . . . . . . . . .
3.2.7 Les fichiers XSLT . . . . . . . . . . . . . . . . . . . . . . .
3.2.8 « Éléments xsl:template » . . . . . . . . . . . . . . . . . . .
3.2.9 « Éléments xsl:value-of » . . . . . . . . . . . . . . . . . . . .
3.2.10 Arithmétique en XPath . . . . . . . . . . . . . . . . . . . . .
3.2.11 Manipulations des chaînes de caractères en XPath . . . . . . .
3.2.12 Chemins XPath plus sophistiqués . . . . . . . . . . . . . . .
3.2.13 Modularité avec les éléments « xsl:apply-templates » . . . . .
3.2.14 Chemins XPath pour la sélection des attributs . . . . . . . . .
3.2.15 Expression XPath « . » . . . . . . . . . . . . . . . . . . . . .
3.2.16 Spécifier les valeurs d’attributs . . . . . . . . . . . . . . . . .
3.2.17 Expression XPath « .. » . . . . . . . . . . . . . . . . . . . . .
3.2.18 Expression XPath « // » . . . . . . . . . . . . . . . . . . . .
3.2.19 Expression XPath « * » . . . . . . . . . . . . . . . . . . . .
3.2.20 Expression XPath avec « | » . . . . . . . . . . . . . . . . . .
3.2.21 Expression XPath pour le nom d’un élément . . . . . . . . .
3.2.22 Notion de nœuds XSLT . . . . . . . . . . . . . . . . . . . . .
3.2.23 Expressions XPath pour compter et additionner les éléments .
3.2.24 Utilisation de l’attribut « mode » . . . . . . . . . . . . . . . .
3.2.25 Fonction « generate-id » . . . . . . . . . . . . . . . . . . . .
3.2.26 Utilisation des tests . . . . . . . . . . . . . . . . . . . . . . .
3.2.27 Tester le contenu des chaînes de caractères . . . . . . . . . .
3.2.28 Accès aux éléments d’un ensemble d’éléments . . . . . . . .
3.2.29 Utiliser XSLT comme base de données et éléments « for-each »
3.2.30 Obtenir l’aggrégation avec la fonction « generate-id » . . . . .
3.2.31 Un peu plus de performance avec la function XSLT « key » .
3.2.32 Les variables . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.33 Les paramètres . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.34 Générer un commentaire . . . . . . . . . . . . . . . . . . . .
3.2.35 Créer des éléments dynamiquement avec « xsl:element » . . .
3.2.36 Copier des nœuds avec « xsl:copy » et « xsl:copy-of » . . . .
113
113
113
113
114
114
114
114
114
115
116
116
118
119
120
121
122
124
127
129
130
130
131
131
131
132
132
134
135
137
138
139
140
141
144
148
149
150
152
152
153
CC BY-NC-SA
viii
3.3
3.2.37
3.2.38
3.2.39
3.2.40
3.2.41
3.2.42
3.2.43
3.2.44
3.2.45
3.2.46
3.2.47
3.2.48
3.2.49
3.2.50
3.2.51
CSS .
3.3.1
3.3.2
3.3.3
3.3.4
3.3.5
3.3.6
3.3.7
3.3.8
3.3.9
3.3.10
3.3.11
3.3.12
3.3.13
3.3.14
3.3.15
3.3.16
3.3.17
3.3.18
3.3.19
3.3.20
3.3.21
3.3.22
3.3.23
3.3.24
3.3.25
3.3.26
3.3.27
3.3.28
3.3.29
3.3.30
Union, intersection et différence en XSLT . . . . . . .
Espaces de noms . . . . . . . . . . . . . . . . . . . .
Les axes . . . . . . . . . . . . . . . . . . . . . . . . .
L’étude d’un exemple: docbook.xslt . . . . . . . . . .
Activité suggérée . . . . . . . . . . . . . . . . . . . .
Autres moteurs XSLT . . . . . . . . . . . . . . . . .
Pour voir le résultat de la transformation XSLT . . . .
SVG et XSLT . . . . . . . . . . . . . . . . . . . . . .
XPath, XPointer et XLink . . . . . . . . . . . . . . .
XPath 2.0 . . . . . . . . . . . . . . . . . . . . . . . .
XLT 2.0 . . . . . . . . . . . . . . . . . . . . . . . . .
XQuery . . . . . . . . . . . . . . . . . . . . . . . . .
XPath versus XSLT . . . . . . . . . . . . . . . . . . .
En terminant . . . . . . . . . . . . . . . . . . . . . .
Livres de référence . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Objectif . . . . . . . . . . . . . . . . . . . . . . . . .
Activité . . . . . . . . . . . . . . . . . . . . . . . . .
Qu’est-ce que les CSS . . . . . . . . . . . . . . . . .
Point de vue critique . . . . . . . . . . . . . . . . . .
Notions de base . . . . . . . . . . . . . . . . . . . . .
Contenu en ligne ou en bloc ? . . . . . . . . . . . . .
Centrer un élément . . . . . . . . . . . . . . . . . . .
Les commentaires . . . . . . . . . . . . . . . . . . .
Sélectionner le premier caractère ou la première ligne .
Ajouter du contenu avant et après un élément . . . . .
Qu’est-ce qu’un pseudo-élément? . . . . . . . . . . .
Sélecteurs d’intéraction . . . . . . . . . . . . . . . . .
Règles par défaut . . . . . . . . . . . . . . . . . . . .
L’astérisque . . . . . . . . . . . . . . . . . . . . . . .
Sélection sur la base des attributs . . . . . . . . . . .
Les espaces de noms . . . . . . . . . . . . . . . . . .
Sélection de la langue . . . . . . . . . . . . . . . . .
Sélection de plusieurs éléments . . . . . . . . . . . .
Sélection sur la base de la relation entre les éléments .
Sélection d’élément par valeur ID . . . . . . . . . . .
Mais que se passe-t-il en cas de conflit? . . . . . . . .
Le modèle de boîte CSS . . . . . . . . . . . . . . . .
Quand le contenu excède le contenant . . . . . . . . .
Encodage des caractères . . . . . . . . . . . . . . . .
Différentes règles pour différents média . . . . . . . .
Inclure d’autres fichiers CSS . . . . . . . . . . . . . .
Indentation de la première ligne d’un paragraphe . . .
Modifier la casse du texte . . . . . . . . . . . . . . .
Autres variantes des polices . . . . . . . . . . . . . .
Ajouter des compteurs . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
154
155
156
157
160
160
160
161
161
162
163
163
167
167
167
168
168
168
168
168
169
171
172
172
172
172
173
173
173
175
175
176
176
176
177
178
179
181
183
183
183
184
184
184
184
185
CC BY-NC-SA
ix
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
185
186
187
188
188
188
188
188
189
189
191
191
192
Module 4 : Traitement du XML en Java
4.1 Aperçu . . . . . . . . . . . . . . . . . . . . .
4.1.1 Objectifs . . . . . . . . . . . . . . .
4.1.2 Démarche . . . . . . . . . . . . . . .
4.2 Modèles de programmation . . . . . . . . . .
4.2.1 Objectif . . . . . . . . . . . . . . . .
4.2.2 Activité . . . . . . . . . . . . . . . .
4.2.3 Traitement du XML comme du texte .
4.2.4 Traitement événementiel . . . . . . .
4.2.5 Traitement avec itérateurs . . . . . .
4.2.6 Traitement avec modèle en arbre . . .
4.2.7 Transformations . . . . . . . . . . .
4.2.8 XPath . . . . . . . . . . . . . . . . .
4.2.9 XML comme extension d’un langage
4.2.10 Traitement par abstraction . . . . . .
4.2.11 Sérialisation XML . . . . . . . . . .
4.2.12 Services web . . . . . . . . . . . . .
4.3 Rappel sur la programmation Java . . . . . .
4.3.1 Objectif . . . . . . . . . . . . . . . .
4.3.2 Activité . . . . . . . . . . . . . . . .
4.3.3 Définitions . . . . . . . . . . . . . .
Notion d’objet . . . . . . . . . . . .
Notion de classe . . . . . . . . . . .
Notion de méthode . . . . . . . . . .
Notion d’interface . . . . . . . . . .
Notion d’héritage . . . . . . . . . . .
Notion d’encapsulation . . . . . . . .
4.3.4 Exemples . . . . . . . . . . . . . . .
4.3.5 Exemples avancés . . . . . . . . . .
4.3.6 Lecture de fichiers . . . . . . . . . .
4.3.7 Astuces . . . . . . . . . . . . . . . .
4.3.8 Retour sur l’activité . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
193
193
193
194
194
194
194
195
196
199
200
201
202
202
203
203
205
209
209
210
210
210
210
210
210
211
211
211
212
212
213
213
3.4
3.3.31 Traitement des retours de chariot
3.3.32 Des nouveautés en CSS 3 . . .
3.3.33 Optimisation des fichiers CSS .
3.3.34 En terminant . . . . . . . . . .
3.3.35 Livres de référence . . . . . . .
Travail noté 4 . . . . . . . . . . . . . .
3.4.1 Objectifs et pondération . . . .
3.4.2 Consignes . . . . . . . . . . . .
3.4.3 Exercice 1 . . . . . . . . . . .
3.4.4 Exercice 2 . . . . . . . . . . . .
3.4.5 Exercice 3 . . . . . . . . . . . .
3.4.6 Exercice 4 . . . . . . . . . . . .
3.4.7 Exercice 5 . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CC BY-NC-SA
x
4.4
Tutoriel sur DOM . . . . . . . . . . . . . . . . . . .
4.4.1 Objectifs . . . . . . . . . . . . . . . . . . .
4.4.2 Activité . . . . . . . . . . . . . . . . . . . .
4.4.3 Le tutoriel pour se familiariser avec le DOM
Introduction . . . . . . . . . . . . . . . . .
4.4.4 Notions de base . . . . . . . . . . . . . . . .
4.4.5 Point de vue critique . . . . . . . . . . . . .
4.4.6 Un document XML . . . . . . . . . . . . . .
4.4.7 Charger un document XML en Java . . . . .
4.4.8 Accès à l’élément-racine . . . . . . . . . . .
4.4.9 L’interface « Node » . . . . . . . . . . . . .
4.4.10 Création de documents . . . . . . . . . . . .
4.4.11 Modifier un « Document » . . . . . . . . . .
4.4.12 Les espaces de noms . . . . . . . . . . . . .
4.4.13 Deux problèmes avec solution . . . . . . . .
Problème 1 . . . . . . . . . . . . . . . . . .
Solution du problème 1 . . . . . . . . . . . .
Problème 2 . . . . . . . . . . . . . . . . . .
Solution du problème 2 . . . . . . . . . . . .
4.4.14 DOM et ECMAScript . . . . . . . . . . . .
4.4.15 Asynchronous JavaScript And XML (AJAX)
4.4.16 DOM et autres langages . . . . . . . . . . .
4.4.17 Conclusion . . . . . . . . . . . . . . . . . .
4.4.18 Livres de référence . . . . . . . . . . . . . .
DOM . . . . . . . . . . . . . . . . . . . . . . . . .
4.5.1 Objectif . . . . . . . . . . . . . . . . . . . .
4.5.2 Activité . . . . . . . . . . . . . . . . . . . .
Travail noté 5 . . . . . . . . . . . . . . . . . . . . .
4.6.1 Objectifs et pondération . . . . . . . . . . .
4.6.2 Consignes générales . . . . . . . . . . . . .
4.6.3 Exercice 1 . . . . . . . . . . . . . . . . . . .
4.6.4 Exercice 2 . . . . . . . . . . . . . . . . . . .
4.6.5 Exercice 3 . . . . . . . . . . . . . . . . . . .
4.6.6 Exercice 4 . . . . . . . . . . . . . . . . . . .
4.6.7 Exercice 5 . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
213
213
213
213
213
214
214
214
215
215
216
221
225
226
228
228
228
229
229
231
232
237
237
237
238
238
238
238
238
239
240
241
242
243
244
Module 5 : Resource Description Framework (RDF)
5.1 Aperçu . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1 Objectifs . . . . . . . . . . . . . . . . . . .
5.1.2 Représentation des connaissances et graphes
5.1.3 Démarche . . . . . . . . . . . . . . . . . .
5.1.4 Préparation à l’examen . . . . . . . . . . .
5.1.5 Évaluation du cours . . . . . . . . . . . . .
5.2 Introduction au RDF . . . . . . . . . . . . . . . . .
5.2.1 Introduction . . . . . . . . . . . . . . . . . .
5.2.2 Point de vue critique . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
245
245
245
245
246
247
247
247
247
247
4.5
4.6
CC BY-NC-SA
xi
5.3
5.4
5.2.3 Notions de base . . . . . . . . . . . . . . . . .
5.2.4 Le RDF en XML . . . . . . . . . . . . . . . .
5.2.5 Les classes en RDF . . . . . . . . . . . . . . .
5.2.6 Et s’il n’y a pas de symbole « # » dans l’URI? .
5.2.7 Des objets qui sont eux-mêmes des sujets . . .
5.2.8 Les contenants en RDF . . . . . . . . . . . . .
5.2.9 RDFa . . . . . . . . . . . . . . . . . . . . . .
5.2.10 Conclusion . . . . . . . . . . . . . . . . . . .
Le RDF par l’exemple . . . . . . . . . . . . . . . . .
5.3.1 Introduction . . . . . . . . . . . . . . . . . . .
5.3.2 Un exemple : Dublin Core . . . . . . . . . . .
5.3.3 Un exemple : Creative Commons . . . . . . .
5.3.4 Un exemple : FOAF . . . . . . . . . . . . . .
5.3.5 Un exemple : RSS/RDF . . . . . . . . . . . . .
5.3.6 Conclusion . . . . . . . . . . . . . . . . . . .
Travail noté 6 . . . . . . . . . . . . . . . . . . . . . .
5.4.1 Objectifs et pondération . . . . . . . . . . . .
5.4.2 Consignes . . . . . . . . . . . . . . . . . . . .
5.4.3 Exercice 1 . . . . . . . . . . . . . . . . . . . .
5.4.4 Exercice 2 . . . . . . . . . . . . . . . . . . . .
5.4.5 Exercice 3 . . . . . . . . . . . . . . . . . . . .
5.4.6 Exercice 4 . . . . . . . . . . . . . . . . . . . .
5.4.7 Exercice 5 . . . . . . . . . . . . . . . . . . . .
5.4.8 Exercice 6 . . . . . . . . . . . . . . . . . . . .
Avant de réaliser l’exercice... . . . . . . . . .
Exercice à réaliser... . . . . . . . . . . . . . .
5.4.9 Exercice 7 . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Annexe A : Glossaire
Annexe B : Webographie XML
1
Blogues . . . . . . . . . . . . . . . . . . . . . . .
2
Cours en ligne, en français . . . . . . . . . . . . .
3
Cours en ligne, en anglais . . . . . . . . . . . . . .
4
Liens généraux, en français . . . . . . . . . . . . .
5
Articles, en français . . . . . . . . . . . . . . . . .
6
Articles, en anglais . . . . . . . . . . . . . . . . .
7
Références tirées du site Wikipedia (anglais) . . . .
7.1
Spécification XML . . . . . . . . . . . . .
7.2
Software . . . . . . . . . . . . . . . . . .
7.3
Ressources pour les développeurs . . . . .
8
Liens vers des livres portant sur le XML, en anglais
248
252
256
257
258
261
263
263
263
263
264
268
272
274
276
277
277
277
278
278
278
279
279
279
279
281
282
283
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
287
287
287
287
287
288
288
288
288
288
288
289
Annexe C : Pense-bête DTD
291
Annexe D : Pense-bête HTML
293
CC BY-NC-SA
xii
Annexe E : Pense-bête XSLT
Bibliographie
295
299
CC BY-NC-SA
Guide d’étude
Introduction
Bienvenue dans le cours INF 6450 Gestion de l’information avec XML. Mon nom est
Daniel Lemire et je suis le professeur de ce cours. J’anime un blogue sur le XML à
l’adresse http://www.daniel-lemire.com/ blogue/category/xml/.
Avertissement: le site web du cours utilise une technique HTML qui rend l’utilisation
du bouton « Reculer d’une page » hasardeuse.
Ce document contient toutes les informations utiles à votre démarche dans le cours.
Je vous suggère, avant de commencer l’étude du premier module, de prendre connaissance des objectifs du cours, de son contenu, de sa problématique, de son organisation
en modules, des caractéristiques médiatiques de son environnement, ainsi que des propositions de répartition de votre temps d’étude pendant les quinze semaines du cours.
Normalement, vous étudierez les modules de façon séquentielle; des indications plus
précises sont fournies dans chaque module quant aux liens entre les différentes activités.
L’installation du navigateur Firefox est obligatoire pour suivre ce cours; c’est d’ailleurs
la première activité du module 1.
Objectifs
Le but de ce cours est de vous donner tous les outils nécessaires pour utiliser le XML
dans un projet en technologie de l’information, que ce soit un projet de développement
logiciel, un projet scientifique, ou dans le cadre d’un système d’informations. Il est
aussi une préparation utile pour des travaux en gestion des connaissances, recherche
d’informations, bibliothéconomie, e-Learning, génie logiciel, web sémantique, etc.
Les objectifs du cours sont :
– Utiliser un « vocabulaire » ou une application XML pour présenter des informations
en format XML.
1
Guide d’étude
2
– Déterminer si un document XML est bien formé ou valable.
– Apprécier les coûts de développement de solutions XML au sein d’une organisation.
– Appliquer la méthodologie orientée objet pour l’utilisation, la fusion et le filtrage
des fichiers XML.
– Produire et interpréter des fichiers XML : des fichiers les plus simples aux fichiers
RDF.
– Utiliser des transformations XSLT et des instructions CSS.
– Traduire, au sein de son organisation, sa compréhension du XML dans la gestion des
informations.
– Interpréter un fichier RDF comme un tableau sujet/verbe/objet.
Contenu
Dans ce cours, nous traiterons des points suivants :
– Historique, raisons qui ont entraîné la création du XML, comparaison avec HTML
et SGML
– Le document XML : syntaxe, éléments, attributs et entités
– Documents bien formés
– Documents valables : Document Type Definitions (DTD), XML Schema, Relax NG,
Schematron et Examplotron
– Vocabulaires et espaces de noms
– Le XML comme format de document: XHTML, SVG, MathML, Open Document
Format et DocBook.
– Modélisation de l’information en XML
– XML, XSLT, XPath, XLink, XPointer, XQuery, CSS
– Utilisation du XML à partir de langages orientés objets (Java, JavaScript, C++)
– Modèle objet XML (DOM)
– Asynchronous JavaScript And XML (AJAX)
– Filtrage, fusion et extraction du XML en Java
– Métadonnées en XML : Resource Description Framework (RDF), Dublin Core,
Creative Commons, FOAF, RSS 1.0, web sémantique.
Le cours ne traite pas en profondeur des technologies propriétaires telles que celles
d’Oracle ou de Microsoft. Le cours n’en demeure pas moins axée sur la pratique : tous
les concepts introduits dans le cours sont mis en application. Parce que le cours se veut
une préparation à l’utilisation du XML dans des projets concrets, les avantages et les
inconvénients des diverses techniques sont présentés.
Problématique
La gestion des connaissances se fait de plus en plus en utilisant la technologie du web,
qui se tourne elle-même vers les données semi-structurées et la syntaxe XML, en
CC BY-NC-SA
Problématique
3
particulier. Le XML (Extensible Markup Language) est la norme dans l’échange des
données sur le web et au sein des organisations, tout en étant un des piliers du web
sémantique. Les applications et outils supportant le XML, que ce soit pour l’analyse
syntaxique, le filtrage ou autres activités, sont maintenant très sophistiqués, nombreux
et s’appliquent à des domaines variés. Pour s’en convaincre, il suffit de voir la liste des
acronymes et les sujets auxquels ils correspondent : OWL (ontologies), RDF (description des ressources), XSL (transformations et présentation), RuleML (logique), etc.
Dans une organisation, le XML joue un rôle sur au moins trois plans :
1. Découplement des informations;
2. Interopérabilité;
3. Flexibilité et évolution des schémas de données.
Découplement des informations
Dans la gestion des connaissances, le XML joue souvent un rôle dans le découplement
des informations : métadonnées versus données, présentation versus contenu, implémentation versus logique, etc. L’ubiquité du XML et des outils le supportant permet,
par exemple, de découpler de façon pratique le système d’exploitation et le logiciel
de traitement de texte utilisé : les fichiers Open Office et les nouveaux fichiers Microsoft Office sont en format XML, permettant ainsi, en principe, à n’importe quelle
plateforme logicielle d’aller chercher le contenu, le texte. Cette interopérabilité n’était
pas possible avec le format binaire « traditionnel » que Microsoft utilisait dans les
années 90. Le nouveau format utilisé par Microsoft Word distingue nettement la présentation du contenu. De la même manière, le format XHTML permet de laisser le
contenu textuel semi-structuré dans le fichier lui-même et de placer la présentation
dans un fichier CSS. D’autre part, tout fichier XHTML peut être facilement traité par
un analyseur de syntaxe XML générique, peu importe la plateforme avec laquelle il a
été produit. Au contraire, le HTML « traditionnel » exige des analyseurs de syntaxe
spécifiques au HTML et de conception très robuste.
XML et interopérabilité
Pour une organisation, le fait de stocker, ou du moins de pouvoir transformer, les informations et les connaissances en XML rend beaucoup plus facile qu’auparavant le
partage de ces mêmes informations et connaissances. En principe, n’importe qui peut
traiter les fichiers XML provenant de n’importe quelle organisation en utilisant un logiciel générique. Dans une certaine mesure, on se met à l’abri du blocage de la part
d’un fournisseur (vendor locking), ce qui a tant nui à plusieurs organisations dans le
passé. Par exemple, c’était le cas d’une entreprise qui utilisait, pour une fonction stratégique, un logiciel conçu par une société qui devait fermer ou qui refusait de fournir
une fonction particulière pourtant nécessaire. Si les informations sont en format XML,
il est possible, du moins en théorie, pour une organisation d’extraire avec précision
CC BY-NC-SA
Guide d’étude
4
l’information et de la traiter; il lui suffit d’utiliser n’importe quel analyseur de syntaxe
XML et de comprendre l’application XML utilisée.
Pensons à une entreprise distribuée qui, pour collaborer, doit non seulement s’entendre
sur une ontologie commune entre ses différentes constituantes, mais aussi définir un
protocole d’échange des informations et connaissances. Comme le XML s’est imposé
en tant que norme, le problème est simplifié : il suffit maintenant de « seulement »
s’entendre sur un vocabulaire. Le XML fournit non seulement la syntaxe, mais aussi
les outils nécessaires pour vérifier qui respecte ou ne respecte pas la syntaxe. Les outils
pour modifier, traiter, fusionner le XML ne sont plus spécifiques aux besoins d’une
entreprise ou d’un type d’entreprise : tous partagent les mêmes outils de base, car tous
utilisent la même syntaxe. Les problèmes d’intégration sont donc plus faciles à résoudre
et on passe moins de temps à faire de la rétro-ingénierie (reverse-engineering). Il faut
évidemment toujours bien documenter et comprendre les vocabulaires, mais un lot de
problèmes purement techniques sont balayés.
Pensons également aux projets récents portant sur les objets d’apprentissage sur lesquels travaille la Télé-université. La plupart de ces projets sont constitués en réseaux :
on désire échanger des objets d’apprentissage entre des individus qui ne se rencontrent
jamais. Ainsi, en utilisant, par exemple, l’application XML IEEE LOM pour décrire
aux clients potentiels nos objets, nous savons que le récipiendaire, peu importe sa plateforme logicielle, pourra au minimum traiter la syntaxe. Le XML n’est donc pas un
progrès ou une nouveauté technologique : la théorie de la syntaxe des fichiers textes est
un sujet bien développé. Le XML s’impose davantage comme progrès social : le web
a amené les gens à s’entendre une fois pour toute sur une syntaxe suffisamment simple
et universelle pour les documents semi-structurés.
Le cours INF 6450 Gestion de l’information avec XML ne porte donc pas uniquement
sur la technologie elle-même; il envisage plutôt le XML comme une norme, mais aussi
comme un ensemble de normes, incluant RDF, qui ont toutes en commun d’avoir un
lien fort avec le web et la gestion de l’information et des connaissances.
Flexibilité et évolution des schémas de données
Un autre rôle du XML dans l’organisation : se substituer aux modèles relationnels
dans lesquels on impose des champs de données fixes. Par exemple, on décrit chaque
étudiant par un numéro de matricule, un nom et une date de naissance; on peut aussi
associer l’étudiant à une liste de cours suivis. Bien que le modèle relationnel puisse
sembler très flexible, il n’est pas toujours idéal : le web n’est pas une base de données
relationnelles et, en fait, ce n’est pas du tout une base de données. S’il fallait convertir
les pages web HTML en un schéma de base de données relationnelles, on constaterait
rapidement qu’il s’agit d’un travail fastidieux, voire impossible.
D’un autre côté, les pages web, les documents Microsoft Word et d’autres formes de
données non structurées possèdent aussi leurs inconvénients. Supposons que j’accède
au bottin de la Téluq par le web. En principe, je peux écrire un programme qui va
automatiquement chercher le numéro de téléphone de « Richard Hotte ». En pratique
CC BY-NC-SA
Les modules du cours
5
cependant, comme le HTML est avant tout un format de présentation de l’information,
cette approche est fragile et peu pratique : les machines ont tout simplement beaucoup
de mal à extraire de l’information précise à partir de documents non structurés, contrairement aux êtres humains qui peuvent très bien reconnaître que telle page web présente
bel et bien le numéro de téléphone de « Richard Hotte ».
Ainsi, le XML se situe un peu entre les bases de données et les formats sans sémantique : on parle d’information semi-structurée. On garde une grande partie de la flexibilité qui a permis au web de devenir l’outil unique de gestion de l’information que l’on
connaît. En même temps, on permet aux systèmes informatiques d’interagir avec toute
cette information de façon automatique. De plus, avec le XML, il n’est pas du tout problématique de concevoir des schémas d’information ou de les réutiliser. En somme, le
XML représente un compromis à la fois sémantique et flexible.
Les modules du cours
Le cours comporte 5 modules. Le premier module introduit au XML proprement dit :
sa syntaxe et ses capacités de modélisation. Le module 2 porte sur le XML en tant que
format pour les documents; on y présente la notion de séparation du contenu et de la
présentation. Les modules 3, 4 et 5 portent respectivement sur l’ensemble de ce que l’on
nomme parfois les « technologies XML » incluant XSLT, CSS, etc., sur le traitement
du XML en utilisant un langage de programmation comme Java et, finalement, sur le
RDF en tant que langage pour la description des ressources.
Pour chaque module, nous avons rédigé des textes d’appoint et préparé des questionnaires d’autoévaluation qui vous permettront de vérifier votre maîtrise du contenu, au
fur et à mesure de votre apprentissage. En outre, pour nous permettre de vous évaluer,
vous réaliserez un travail noté par module.
Il est préférable de procéder à l’étude des modules de façon séquentielle : en effet,
il faut d’abord savoir interpréter la syntaxe XML avant de pouvoir aborder le XML
comme format pour les documents. En outre, il faut une connaissance du XML comme
format de document pour comprendre l’utilité des « technologies XML » et faire du
traitement en Java. Finalement, le RDF exige une maîtrise suffisante de l’ensemble du
XML, parce que la syntaxe peut sembler rébarbative à quelqu’un peu expérimenté. Il
est cependant possible d’aborder les modules 3 et 4 de front.
En résumé, le cours comporte les cinq modules suivants :
– Module 1 : Introduction à XML (extensibilité, DTD, Relax NG, XML Schema, espaces de noms)
– Module 2 : XML en tant que syntaxe pour les documents (XHTML, SVG, MathML,
DocBook, ODF)
– Module 3 : Technologies XML (XSLT, CSS, XPath, XQuery, XLink)
– Module 4 : Traitement du XML en Java (DOM, SAX, Itérateurs, Sérialisation,
AJAX, Services web)
CC BY-NC-SA
Guide d’étude
6
– Module 5 : Resource Description Framework (RDF) (Dublin Core, Creative Commons, FOAF, RSS 1.0, Atom)
Caractéristiques médiatiques
L’environnement du cours est un site web réalisé entièrement en XML. Les figures
sont en SVG (un format XML couvert dans le cours). Vous pouvez faire vos lectures
(textes, consignes, etc.) sur le site, mais aussi en utilisant un document imprimé, (Manuel INF 6450) généré à partir du site web par une transformation XSLT (sujet couvert
dans le cadre du cours). Le cours contient de nombreux exemples de code en XML et
Java : vous devriez être capable, à la fin du cours, de lire sans mal du XML en ligne,
sans coloration syntaxique. Tous les modules comprennent des activités d’autoévaluation sous la forme de questionnaires (rédigés eux-même en XML) visant à vérifier
la compréhension de vos lectures; vous répondrez à ces questionnaires sur le site, en
ligne, car leur efficacité est optimisée par les possibilités du web. Un va-et-vient entre
lectures et questionnaires d’autoévaluation s’imposera, mais à votre rythme.
En outre, sur le site web, se trouvent la documentation touchant l’installation et l’utilisation du logiciel Firefox nécessaire au cours, diverses activités de création et de validation de documents XML, les consignes pour les travaux notés, les pense-bêtes qui,
comme leur nom l’indique, vous seront utiles à différents moments. Vous y avez accès par des hyperliens dans la colonne de gauche de la page-écran, et ce pour chaque
module.
Les étudiants qui désirent un livre de référence pour ce cours peuvent acheter « XML en
concentré : Manuel de référence » d’Elliotte Rusty Harold, W-Scott Means, Philippe
Ensarguet (traducteur), Frédéric Laurent (traducteur) chez O’Reilly paru le 21 avril
2005 (ISBN : 2841773531). En outre, un des auteurs de ce livre de référence, Elliotte
Rusty Harold a une page d’actualité sur le XML: Cafe con Leche XML News and
Resources.
Par ailleurs, nous avons préparé une feuille de route qui donne un aperçu de la démarche, un glossaire définissant quelques termes importants du cours et une webographie contenant plusieurs liens en français et en anglais. Ils sont accessibles en tout
temps à partir des modules, par des boutons placés dans la partie supérieure de la pageécran.
Encadrement
L’encadrement, assuré par une personne tutrice que vous assigne l’Université, se fait
par courriel. Ainsi, toutes vos interrogations sur le cours ou sur l’environnement d’apprentissage doivent lui être adressées par courriel; celle-ci y répondra dans les plus
CC BY-NC-SA
L’évaluation
7
brefs délais. Par ailleurs, nous vous demandons d’inscrire « [INF6450] » dans l’objet de tous vos messages. En ce qui concerne les travaux notés que vous transmettrez également par courriel à votre personne tutrice pour qu’elle les corrige, vous
devrez en plus indiquer, dans l’objet du message, le numéro du travail, par exemple
« [INF6450][TRAVAIL5] »; dans le message de transmission, vous indiquerez également votre nom, votre numéro d’étudiant (8 chiffres), la date de remise de votre travail
et le nom de votre personne tutrice. Des consignes précises sont fournies dans chaque
travail noté.
L’évaluation
Pour évaluer vos apprentissages dans ce cours, nous avons préparé 6 travaux notés et
un examen en salle. Le tableau qui suit les présente sommairement.
Activités notées
Modules
Pondération
Travail noté 1 (question- Module 1
10 %
naire)
Travail noté 2 (discussion Modules 2-5
5%
et compte rendu)
Travail noté 3 (rédaction) Module 2
10 %
Travail noté 4 (program- Module 3
10 %
mation)
Travail noté 5 (program- Module 4
15 %
mation)
Travail noté 6 (program- Module 5
10 %
mation)
Examen en salle
Modules 1-5
40 %
Total
100 %
Les travaux notés
Les travaux notés 1, 3, 4, 5 et 6 sont associés à un module et vérifient l’atteinte des
objectifs de ce module. Le travail noté 1 prend la forme d’un questionnaire, le travail
noté 3 consiste à rédiger un document en XML; les travaux notés 4, 5 et 6 comportent
des exercices qui exigent de la programmation. Je vous recommande de réaliser ces
travaux notés après avoir effectué les lectures et les activités d’autoévaluation du module en question. Il n’est pas nécessaire de faire les travaux dans l’ordre qu’ils apparaissent dans le cours; en effet, le travail noté 3 peut être fait après les autres travaux,
par exemple. Cependant, le travail noté 1 doit être fait avant les autres et le travail
noté 6, après les travaux notés 4 et 5.
Quant au travail noté 2, la discussion dans le forum du cours, il peut commencer dès
le début du module 2 et vous avez toute la durée du cours pour le réaliser. Avant de
commencer cette activité, nous vous suggérons fortement d’avoir terminé l’étude du
CC BY-NC-SA
Guide d’étude
8
module 1, car il faut bien comprendre les définitions et concepts de base du XML.
Notez que l’évaluation du travail 2 porte sur le compte rendu que vous rédigerez à la
suite de votre participation dans le forum. Tous les travaux doivent être transmis à la
personne tutrice par courriel.
Examen en salle
L’examen en salle compte pour 40 % de la note du cours. Il s’agit d’un examen de
3 heures comportant 5 questions, lesquels portent sur le contenu couvert par les travaux 1, 3, 4, 5 et 6. Un examen factice est disponible dans le dernier module pour vous
permettre de vérifier si vous êtes prêt. La correction de l’examen est rigoureuse : vous
devez décrire le comportement exact des programmes et pouvoir répondre aux questions de façon aussi précise que durant les travaux. Il est important d’avoir lu tous les
textes et d’avoir fait toutes les activités d’autoévaluation du cours pour réussir l’examen. Aucune documentation n’est permise durant l’examen.
Vers la douzième semaine du cours, l’Université vous informera de la date, de l’heure
et de l’endroit de passation de l’examen.
Gestion du temps et pondération
Dans le tableau qui suit, nous indiquons le temps à prévoir pour chaque activité, ainsi
que la pondération associée à chacune. Le temps consacré à la lecture inclut la lecture
des textes conçus pour le cours. L’ordre dans lequel les activités sont présentées est
l’ordre suggéré.
Activités
Temps suggéré
Pondération
Introduction au cours
2 heures
Aucune
Lectures et question- 15 heures
Aucune
naires du module 1
(incluant
l’installation
logicielle)
Travail noté 1 (question- 5 heures
10 %
naire)
Lectures et question- 10 heures
Aucune
naires du module 2
Travail noté 2 (discussion 5 heures
5%
dans le forum et compte
rendu)
Travail noté 3 (rédaction) 15 heures
10 %
Lectures et question- 10 heures
Aucune
naires du module 3
(incluant la programmation XSLT et CSS)
CC BY-NC-SA
Gestion du temps et pondération
Activités
Travail noté 4 (programmation)
Lectures et questionnaires du module 4
(incluant la programmation Java)
Travail noté 5 (programmation)
Lectures et questionnaires du module 5
Travail noté 6 (programmation)
Examen
Total
9
Temps suggéré
20 heures
Pondération
10 %
10 heures
Aucune
20 heures
15 %
5 heures
Aucune
15 heures
10 %
3 heures
135 heures
40 %
100 %
Un deuxième tableau répartit les activités selon les semaines, en comptant une moyenne
de 9 heures de travail par semaine, pendant 15 semaines. La participation au forum
s’étale sur plusieurs semaines (environ les deux tiers du cours).
Semaine
Activités
1
Présentation du cours, lectures et questionnaires (module 1)
2
Lectures et questionnaires (module 1)
3
Travail noté 1, lectures et questionnaires (module 2)
4
Lectures et questionnaires (module 2),
travail noté 2: forum
5
Travail noté 3
6
Forum, travail noté 3, lectures et questionnaires (module 3)
7
Forum, lectures et questionnaires (module 3)
8
Forum, travail noté 4
9
Forum, travail noté 4
10
Forum, travail noté 4, lectures et questionnaires (module 4)
11
Forum, lectures et questionnaires (module 4), travail noté 5
12
Forum, travail noté 5
13
Forum, travail noté 5, lectures et questionnaires (module 5)
14
Forum, lectures et questionnaires (module 5), travail noté 6
15
Forum, travail noté 6
CC BY-NC-SA
Guide d’étude
Semaine
10
Activités
Examen en salle
À partir du tableau précédent, nous vous proposons un tableau semaine/module. Un
« X » indique que des activités du module en question sont prévues pour une semaine
donnée. L’astérisque signifie que vous devriez terminer le travail noté prévu pour ce
module durant la semaine marquée.
Semaine
Module 1
Module 2
Module 3
Module 4
Module 5
1
X
2
X
3
X*
X
4
X
5
X
6
X*
X
7
X
8
X
9
X
10
X*
X
11
X
12
X
13
X*
X
14
X
15
* Forum
X*
Version PDF du cours
Le cours est non seulement disponible en XML sur le web, mais aussi en format PDF.
En effet, un des avantages de la séparation du contenu et de sa présentation, tel qu’on
l’enseigne dans le cours, c’est qu’on peut ensuite présenter l’information selon plusieurs formats. Dans ce cours, nous avons utilisé XSLT pour transformer le XML en
PDF. La version papier que vous avez reçue, intitulée Manuel INF 6450 (version pdf),
est une version pdf écourtée du cours; elle comprend le guide d’étude qui présente le
cours, le contenu de chaque module et le travail noté qui lui est associé, ainsi que le
glossaire, la webographie et les trois pense-bêtes, mais pas les questionnaires d’autoévaluation; ce manuel compte plus de 200 pages.
Vous pouvez y accéder par le lien qui suit :
– Manuel INF 6450 (1,2 Mo).
Vous pouvez aussi accéder au manuel complet du cours par ce lien :
– Manuel INF 6450 complet (1,6 Mo).
CC BY-NC-SA
Remerciements
11
Remerciements
Le cours INF 6450 Gestion de l’information avec XML a été conçu par le professeur
Daniel Lemire avec la collaboration de Kamel Aouiche, assistant de recherche, de Lucie Moulet, assistante de recherche, et du concepteur associé Jean-François Savard.
Le professeur Lemire les remercie vivement; il remercie également les professeurs
Koné Mamadou Tadiou (Université Laval), Richard Hotte (UQAM) et Marc Couture
(UQAM), ainsi que le spécialiste en sciences de l’éducation Robert Ippersiel, qui ont
effectué une lecture critique de la documentation du cours. Un des étudiants du cours,
monsieur Dosseh Abiassi, a signalé plusieurs pages de coquilles.
En outre, le professeur remercie chaleureusement Renée Dumas, spécialiste en communication écrite, pour son apport à la qualité linguistique du cours, pour son sens
pédagogique de la communication et pour sa complicité dans cette aventure. Il remercie également l’équipe de production multimédia, dirigée par Jean-Charles Dormeux,
pour leur sollicitude et leur professionnalisme.
CC BY-NC-SA
Module 1 : Introduction à XML
1.1
1.1.1
Aperçu
Objectifs
À la fin de ce module, vous devriez avoir une bonne idée de ce qu’est le XML et pouvoir
facilement lire et écrire du XML simple. Les objectifs spécifiques du module sont :
– Utiliser un vocabulaire ou une application XML pour présenter des informations en
format XML;
– Déterminer si un document XML est bien formé ou valable;
– Interpréter des fichiers XML utilisant des espaces de noms.
Avant d’entreprendre votre démarche dans ce module, nous vous invitons à lire le texte
qui suit pour avoir un aperçu de ce qu’est le XML.
1.1.2
Qu’est-ce que le XML?
Le XML ou Extensible Markup Language est une syntaxe générique utilisée pour formater des données avec des balises simples et lisibles. Par exemple, pour décrire un
étudiant, une syntaxe XML possible serait :
<étudiant>
<nom>Tremblay</nom>
<prénom>Jean</prénom>
<matricule>849490234</matricule>
</étudiant>
Par la suite, si nous désirions décrire l’ensemble des étudiants inscrits à un cours, nous
pourrions utiliser la syntaxe suivante :
<cours>
<nom>Introduction au traitement de texte</nom>
13
Module 1 : Introduction à XML
14
<université>Téluq</université>
<inscriptions>
<étudiant>
<nom>Tremblay</nom>
<prénom>Jean</prénom>
<matricule>849490234</matricule>
</étudiant>
<étudiant>
<nom>Hotte</nom>
<prénom>Richard</prénom>
<matricule>8443444</matricule>
</étudiant>
</inscriptions>
</cours>
Dans ces exemples, observez la présence de texte entre les signes < et > : il s’agit de
balises. Une balise marque le début ou la fin d’un élément. La balise <cours> marque
le début de l’élément « cours », alors que la balise </cours> en marque la fin. Notez
qu’un élément peut contenir d’autres éléments, et ainsi de suite.
Cette nouvelle syntaxe a émergé dans les années 90, avec le développement du web.
Depuis, le XML est devenu très courant dans l’industrie informatique et fait partie des
notions de base que les informaticiens doivent maîtriser, au même titre que les bases
de données ou la programmation orientée objet. Elle est caractérisée par la simplicité
d’abord : le HTML et le XML ont un parent commun, le SGML qui était complexe
et difficile à maîtriser; on a donc voulu « réparer » le SGML, en proposant des solutions plus simples. Entre autres choses, le web a permis d’observer que les technologies
simples pouvaient être très puissantes; c’est ce qui en a fait toute la force : une technologie accessible, ouverte et avec un minimum de complexité.
D’ailleurs, l’inventeur du web, Tim Berners-Lee a rapidement adopté le XML et en
propose, depuis, une nouvelle vision qui repose entièrement sur le XML : le web sémantique. La prémisse étant que, si l’on sépare le contenu de la présentation, le web
n’en sera que plus riche. En effet, on observe que les formats qui confondent la présentation et le contenu, tels que Microsoft Word ou le HTML, limitent la capacité de nos
logiciels. Par exemple, il peut être difficile pour un logiciel de trouver automatiquement
la deuxième section d’un texte placé sur le web et de la reformater automatiquement,
pour qu’on puisse l’inclure dans un rapport annuel.
1.1.3
Démarche
Vous devez étudier et maîtriser le contenu de ce module avant de passer aux autres, car
il est de base : il définit ce qu’est le XML et vous permet d’apprendre sa terminologie
propre. Selon les sections de ce module, lisez les textes proposés, faites les activités
suggérées, répondez aux questionnaires d’autoévaluation. Lorsque vous maîtrisez le
CC BY-NC-SA
Installation de Mozilla Firefox
15
contenu du module, réalisez la première activité d’application, le travail noté 1, avant
de passer au module suivant.
Nous vous suggérons d’étudier le module dans l’ordre suivant :
–
–
–
–
–
–
–
Installation de Mozilla Firefox
Création de documents XML, avec un éditeur de texte
Introduction à XML
Principes de XML
Définition de type de document (DTD), Relax NG et XML Schema
Validation des documents XML
Espaces de noms
Le pense-bête présente quelques symboles importants sur les DTD et leur signification;
dans la version imprimée du cours, il se trouve en annexe.
1.2
1.2.1
Installation de Mozilla Firefox
Objectif
Installer le logiciel Firefox; l’utiliser pour naviguer dans le web ou ouvrir des documents sur votre ordinateur.
1.2.2
Activité
Si le système d’exploitation de votre ordinateur est Windows, vous utilisez sans doute
Internet Explorer (IE), le navigateur internet fourni d’office avec ce système. Malheureusement, ce navigateur ne supporte pas pleinement le XML et XHTML et, pour ce
cours, étant donné qu’une partie du contenu est en XML et XHTML, il est nécessaire
d’utiliser un navigateur qui le supporte parfaitement. Nous vous demandons de télécharger un autre navigateur, soit Mozilla Firefox, dont le téléchargement est gratuit.
Pour la version française de Mozilla Firefox, rendez-vous à l’adresse http://frenchmozilla.sourceforge.net/firefox/; lisez les informations, sélectionnez le fichier correspondant à votre système d’exploitation et téléchargez-le; lancez ensuite la procédure d’installation et suivez bien les directives données. Sous Windows, il est possible que vous
deviez faire redémarrer votre ordinateur après l’installation. Il est nécessaire d’avoir
Firefox 2.0 ou mieux pour suivre ce cours: vous pouvez vérifier la version que vous
avez en tapant « about: » dans la boîte de saisie des URL.
Quand l’installation sera terminée, vérifiez que vous pouvez utiliser Firefox pour naviguer dans le web avant de poursuivre le cours.
CC BY-NC-SA
Module 1 : Introduction à XML
1.2.3
16
Installation de polices de caractères optionnelles
Il se peut que votre navigateur vous avertisse de l’absence de certaines polices optionnelles la première fois que vous chargez une page contenant du MathML. Vous pouvez
ignorer ces avertissements. Si vous le désirez, afin d’éviter ces avertissements, vous
pouvez installer des polices de caractères supplémentaires qui sont sur le site du projet
MathML de la fondation Mozilla. Ce n’est pas nécessaire dans le cadre de ce cours.
1.2.4
Avertissement
Firefox est constamment mis à jour par son équipe de développement. Il est possible
que vous constatiez parfois des différences entre ce qui est annoncé dans le cours et le
comportement de votre version de Firefox.
1.2.5
Autres navigateurs
Outre Firefox, les navigateurs Opera et Camino sont aussi compatibles avec les normes
XML utilisées dans ce cours. Cependant, pour les fins des activités notées utilisant le
navigateur et certaines fonctions du site web, il est nécessaire d’utiliser Firefox.
1.2.6
Retour
Avez-vous pu installer Firefox et naviguer dans le web? Si oui, passez aux prochaines
activités, sinon contactez votre personne tutrice ou cherchez encore un peu.
1.3
1.3.1
Création de documents XML
Objectif
Créer des documents XML et les ouvrir avec le navigateur Firefox.
1.3.2
Activité
Il est facile de créer des documents XML sous Windows; il faut d’abord ouvrir un
éditeur de texte. Tout éditeur de texte ferait l’affaire, mais avec Windows, Microsoft
fournit par défaut Bloc-notes (NotePad). Pour ouvrir le Bloc-notes, il suffit d’aller dans
le menu « Démarrer », sous « Accessoires », et de cliquer sur l’icône du Bloc-notes. Si
vous utilisez un autre système d’exploitation que Windows, une petite recherche vous
permettra de trouver rapidement un éditeur de texte déjà installé sur votre machine.
Vous n’avez plus qu’à taper du code XML. Comme exercice, tapez le texte suivant :
CC BY-NC-SA
Création de documents XML
17
<premier>
Ceci est mon premier document XML.
</premier>
Enregistrez-le ensuite sous le nom « premier.xml ». Malheureusement, le Bloc-notes
a la fâcheuse habitude de toujours ajouter l’extension « .txt » à la fin des noms de
fichiers. Donc, à chaque enregistrement, vous devrez sélectionner « Tous » dans la liste
déroulante de « Type » de fichier, comme le montre la figure qui suit.
Bloc-note
opte par défaut pour le jeu de caractères (ou codage) ANSI ce qui, pour les fins de
ce cours, correspond au jeu de caractères ISO-8859-1. Sous Windows XP ou mieux, on
peut aussi sélectionner le jeu de caractères UTF-8.
Ouvrez maintenant le fichier « premier.xml » dans Firefox, un navigateur qui sait reconnaître le XML; vous verrez alors apparaître votre document XML tel que vous l’avez
tapé. Si vous avez fait une faute de syntaxe XML, Firefox vous l’indiquera.
Le XML ressemble beaucoup au code HTML avec lequel sont créées les pages web.
Nous reviendrons plus tard sur le HTML, après avoir étudié plus à fond le XML. Le
module 2 comporte une activité d’introduction au HTML. Pour l’instant, retenez seulement qu’il est possible d’écrire le HTML comme du XML bien formé. L’exemple qui
suit est un document HTML qui est aussi du XML bien formé.
<html>
<body>
Bonjour
</body>
</html>
CC BY-NC-SA
Module 1 : Introduction à XML
18
Comme exercice facultatif, recopiez le texte précédent commençant par <html> et se
terminant par </html> dans un fichier, en utilisant un éditeur de texte comme le Blocnotes, que l’on trouve dans les accessoires de Windows. Enregistrez le fichier sous le
nom « test.html »; n’oubliez pas de sélectionner « Tous » dans la liste déroulante de
« Type » de fichier, dans la boîte de dialogue d’enregistrement. Ensuite, ouvrez votre
fichier avec le navigateur Firefox; vous devriez voir le texte « Bonjour » s’afficher.
Ces quelques exemples montrent comment il est simple d’utiliser et de créer des fichiers XML. Le XML permet toutefois de faire beaucoup plus, comme d’échanger des
messages entre des applications ou de décrire à un ordinateur le contenu d’un document.
De la même façon, en utilisant le Bloc-notes, on peut créer des documents DTD (chapitre 3 du module 1). Nous verrons que les documents DTD sont aussi des fichiers au
format texte servant à spécifier, dans une certaine mesure, ce qui est permis et ce qui
ne l’est pas dans un document XML.
Autres éditeurs pour le XML
Un produit commercial très recherché pour l’édition du XML est XMLSpy, en anglais
seulement. C’est probablement l’éditeur XML le plus puissant sur le marché; il en
existe une version d’essai gratuite.
Un autre excellent éditeur pour le XML, gratuit et en anglais seulement, est jEdit.
Comme cet éditeur est un programme Java, il faut installer une machine virtuelle Java
au préalable, tel le SDK J2SE. En outre, on peut ajouter à jEdit le plugiciel XML
qui permet de naviguer dans les documents XML et d’en assurer la validité. Le plugiciel XSLT permet aussi de tester des documents XSLT et des expressions XPath
(module 3 du cours).
Finalement, pour Windows seulement, Cooktop est un éditeur XML gratuit créé par
Victor Pavlov. Il permet d’éditer des fichiers XML, DTD, et XSLT, en plus de manipuler des expressions XPath.
Sous MacOS, l’éditeur gratuit Smultron est recommandé.
1.3.3
Retour
Avez-vous pu créer un document XML avec l’extension XML? Est-ce qu’il s’est ouvert dans Firefox sans erreur? Si oui, passez aux autres activités, sinon contactez votre
personne tutrice ou cherchez encore un peu.
CC BY-NC-SA
Introduction à XML
19
F IG . .1 – Tim Bray en mai 2007 (photographie par Lou Springer).
1.4
1.4.1
Introduction à XML
Objectif
Connaître les notions de base du XML.
1.4.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte place
la technologie XML dans son contexte.
1.4.3
Quelques notions du XML
Le XML est un « métalangage » permettant d’échanger de l’information, principalement sur le web. Il a été conçu par Tim Bray, Jon Bosak et de nombreux autres collaborateurs, entre 1996 et 1999. On dit que c’est un « métalangage » parce qu’il est une
façon pratique de créer de nouveaux langages pour échanger des informations, mais
qu’il ne constitue pas un langage en soi. Le XML n’essaie pas, par lui-même, de résoudre tous les problèmes : il fournit par contre les outils nécessaires pour que, dans
tous les domaines, des individus puissent résoudre leurs problèmes. Ainsi, on dit que
le XML est « extensible » (peut être étendu) et que c’est un métalangage : les deux
affirmations vont dans le même sens et notent la capacité du XML à s’adapter à des
besoins différents.
I looked at it and I saw that the markup said what the information is,
not what it looks like. Why isn’t everything this way ? I still basically am
asking that question. (Tim Bray)
Un document XML est essentiellement du texte contenant des balises. Une balise est
un segment de texte commençant par < et se terminant par >, comme <personne>. Voici
un exemple simple de document XML :
CC BY-NC-SA
Module 1 : Introduction à XML
20
<personne>
<nom>Jean</nom>
<age>42</age>
</personne>
Le XML est très présent sur le web et les documents XML peuvent être affichés par
certains navigateurs récents, comme Internet Explorer et Firefox. On échange aussi le
XML entre des logiciels et des serveurs sur le web, et le XML est de plus en plus utilisé
en bureautique, comme format pour les traitements de texte par exemple. Comme un
document XML est avant tout du texte, il n’est pas avantageux d’utiliser le XML pour
stocker des informations de type multimédia (vidéo, musique); le champ d’application
du XML demeure toutefois très vaste.
Le XML définit une grammaire stricte et relativement simple de manière que les outils
XML génériques puissent traiter tous les documents XML, peu importe leur domaine
d’application. On dit d’un document qui respecte cette grammaire qu’il est bien formé.
Ainsi, il n’est pas nécessaire d’utiliser des outils coûteux et propriétaires pour faire du
XML.
L’application la plus commune du XML correspond au scénario suivant. Un groupe de
personnes travaillant dans un domaine particulier, disons l’industrie de la construction,
ont besoin d’échanger des informations, par exemple le prix et la description des matériaux. Elles doivent s’entendre sur un format informatique commun de manière que
tous les logiciels, écrits ou utilisés par les différents participants, puissent communiquer
entre eux, sans problème. L’information pourra ainsi être transmise sans intervention
humaine.
Concrètement, on utilise le XML dans le contexte d’une application XML. Une application XML est un jeu de balises et son utilisation dans un domaine particulier, par
exemple la musique ou la cuisine. On peut définir un jeu de balises et, dans une certaine mesure, son utilisation en se servant d’un document DTD, Relax NG ou XML
Schema (sujets que nous étudierons plus tard dans le cours). Dans un sens, une application XML forme un langage. On dit d’un document XML qui respecte les normes
d’une application XML donnée qu’il est valable : un document valable est bien formé.
En théorie, on pourrait penser que l’importance du XML est mineure. En effet, n’est-il
pas facile de s’entendre sur des formats communs? L’expérience montre que ce n’est
pas si facile. D’abord, définir avec rigueur un format de données est complexe. D’autre
part, le développement de logiciels particuliers à chaque format est coûteux : avec un
métalangage comme XML, on peut réutiliser souvent les mêmes librairies logicielles.
Finalement, l’individu qui acquiert une expérience avec XML dans le contexte de l’industrie de la construction pourra facilement réutiliser cette expertise dans le domaine
de la mode, par exemple. Il est plus facile de trouver des experts en XML que des
experts dans un format de données, format particulier à un domaine pointu.
Le XML n’est pas un langage de programmation bien qu’on puisse l’utiliser avec des
langages comme Java (module 4). On se sert par contre de plus en plus du XML pour
CC BY-NC-SA
Introduction à XML
21
les fichiers de configuration des logiciels. Par exemple, il est probable que, si vous utilisez un serveur web dans votre entreprise, ce serveur ait des fichiers de configuration
en XML. Un document XML ne fait rien : ce n’est qu’une source passive d’informations, comme n’importe quel document, comme des pages web.
1.4.4
La philosophie du XML
Le XML met à profit un principe essentiel à l’architecture du web : be conservative
in what you do, be liberal in what you accept from others (soyez strict dans ce que
vous produisez, mais généreux dans ce que vous acceptez). En d’autres mots, le XML
fonctionne parce que les gens tentent le plus possible de produire du XML de qualité
(bien formé et valable), mais ils acceptent que les autres fassent des entorses aux règles.
C’est, en partie, ce qu’on entend lorsqu’on dit que le XML est « extensible ». Cette
règle est parfois appelée la loi de Postel parce qu’elle fut rédigée par Jon Postel dans la
spécification RFC 793.
Par exemple, supposons que vous écriviez un logiciel qui s’attend à recevoir des commandes ayant la forme suivante.
<commande>
<produit>papier</produit>
<quantite>2</quantite>
</commande>
Supposons maintenant que le logiciel qui émet les commandes est mis à jour et qu’il
vous transmet dorénavant les commandes sous le format suivant.
<commande>
<produit>papier</produit>
<quantite>2</quantite>
<emballage>oui</emballage>
</commande>
Selon les principes du XML, votre logiciel doit continuer à fonctionner, il doit ignorer le nouvel élément qu’il ne connaît pas. En d’autres mots, votre logiciel doit être
généreux et ne pas exiger une conformité parfaite. Tant qu’il dispose des informations
dont il a besoin, votre logiciel doit continuer à fonctionner. C’est ce principe fondateur
qui permet à des millions de personnes d’utiliser le XML pour s’échanger des données
sans le moindre arbitrage. Plus généralement, les technologies XML tentent de fonctionner le plus correctement possible même si les données ne correspondent pas à ce
qu’on attendait.
Plus généralement, le XML respecte plusieurs principes fondamentaux qui lui accorde
plusieurs bénéfices.
– Il est facile d’entretenir et modifier au fil du temps une application basée sur XML.
CC BY-NC-SA
Module 1 : Introduction à XML
22
– Le XML est modulaire : on peut décomposer les applications en plusieurs fichiers,
on peut traiter séparément différents morceaux d’un même document XML.
– Les spécifications XML minimisent la redondance sans la réduire à néant : il y a
plusieurs façons de faire une même chose en XML, mais ce nombre est généralement limité. On a souvent le choix entre plusieurs stratégies, mais pas un trop grand
nombre.
– Les technologies XML tiennent compte des personnes ayant des handicaps, notamment parce que plusieurs modes de présentation sont possibles.
– Le XML ne dépend pas d’une plate-forme particulière : que vous utilisiez Linux,
Mac OS ou Windows, vous pouvez travailler avec le XML.
– Le XML est international : le XML supporte toutes les langues, pas seulement l’anglais.
– Le XML est extensible : on peut facilement faire évoluer les formats sans avoir à
réécrire tous nos logiciels.
– Il est facile d’apprendre le XML.
– Il est facile pour un humain de lire du XML.
– Le XML est efficace : un ordinateur peu puissant peut traiter du XML rapidement.
– Le XML est un format textuel.
– Le XML est simple.
– Le XML assure la pérennité des informations.
– Le XML permet l’interopérabilité des systèmes.
– Un document XML peut être réutilisé facilement à plusieurs fins.
– Le XML est stable : les spécifications ne changent pas trop souvent.
– Le XML est universel : c’est un métalangage qui s’applique à un grand nombre de
problèmes.
1.4.5
Conclusion
Le XML n’est pas une nouveauté scientifique. Le XML représente, par contre, un pas
en avant parce que c’est un des rares méta-langages universel. Le XML est aussi fondé
sur des principes importants comme la pérennité, la simplicité, etc. qui ne sont pas
toujours présents en technologie de l’information.
1.5
1.5.1
Principes de XML
Objectif
Découvrir les grands principes du XML
CC BY-NC-SA
Principes de XML
1.5.2
23
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte porte
sur la syntaxe de base du XML. Les notions importantes sont la balise, l’élément,
l’élément-racine et l’attribut.
1.5.3
Quelques principes et notions importantes du XML
Rappelons qu’une balise est un segment de texte commençant par < et se terminant
par >. Par exemple, <lavie> est une balise qui marque le début de l’élément vie. Une
balise commençant par </, comme </lavie>, est une balise de fin; dans cet exemple,
elle termine l’élément lavie.
Le nom XML de la balise est le texte suivant le symbole < (ou </ pour une balise de
fin) et pouvant contenir n’importe quelle lettre ou chiffre (a, b,... 0, 1, 2,...) ou les trois
symboles de ponctuation, soit la marque de soulignement ( _ ), le trait d’union ( - ) ou
le point (. ); un nom XML ne peut contenir d’autres symboles de ponctuation, ni un
espace. En outre, il ne peut pas commencer par un chiffre, un trait d’union ou un point.
Par exemple, le nom XML de la balise <lavie> est « lavie », alors que la balise <7lavie>
ne serait pas autorisée. On réserve les noms débutant par xml, Xml, xMl, xmL, XMl,
xML,Xml et XML pour les spécifications XML. Ainsi, la balise <xmldanslavie> est à
éviter.
Pour les balises de début, aussi dites d’ouverture, on peut ajouter un attribut au
nom XML de la balise. Un attribut porte un nom XML qui doit respecter les mêmes
règles que les noms XML des balises; il est suivi du symbole « = » et d’une valeur
placée entre guillemets ou apostrophes. Par exemple, la balise <lavie age="5"> indique que l’élément la vie a un attribut (age="5") qui a comme nom XML « age » et
comme valeur « 5 ». Une balise peut avoir plusieurs attributs, comme <lavie age="5"
sexe="M">, mais ils doivent tous porter des noms XML différents : <lavie age="5"
age="7"> n’est pas autorisée.
Par convention, on réserve l’attribut « xml:lang » à la spécification de la langue dans
laquelle le texte est écrit. Cette spécification est optionnelle et assez rarement utilisée.
Si on veut indiquer que le contenu d’un élément est en français, on fera comme dans cet
exemple : « <explication xml:lang="fr">J’avais besoin d’une voiture.</explication> ».
On peut ajouter au code de la langue, un code de région comme dans « fr-CA » ou
« en-US ». Le code de la langue et le code de la région doivent être séparés par un tiret.
Les codes de langue ou de région qui peuvent être utilisées sont disponibles à l’URL
http://www.iana.org/assignments/language-subtag-registry.
Un élément est l’ensemble du texte borné par deux balises ayant le même nom XML,
comme <lavie> et </lavie>. On dit que l’élément <lavie></lavie> a pour nom XML
« lavie ». L’élément hérite des attributs de sa balise de départ : l’élément <lavie
age="5"></lavie> a l’attribut « age="5" ». Il est à noter que la casse est significative
en XML : les balises <A> et <a> n’ont pas le même nom XML. Dans le cas particulier où l’élément est vide (sans contenu), on peut remplacer <lavie></lavie> par
CC BY-NC-SA
Module 1 : Introduction à XML
24
<lavie/> pour abréger. Un élément peut contenir d’autres éléments, comme dans <lavie><a></a></lavie>, ou du texte, ou du texte et des éléments comme
<lavie>fd<a>fsd</a>fd</lavie>.
Si un élément contient d’autres éléments, il doit aussi contenir, entre ses balises de
début et de fin, les balises de début et de fin de chaque élément. Notez, de plus, que
deux éléments ne peuvent se chevaucher, comme <b><a></b></a>; avant de passer à
un autre élément, il faut terminer le premier avec sa balise de fin. L’exemple précédent
est du XML mal formé!
Pour bien comprendre, illustrons notre propos par un exemple. Un document XML
prend la forme suivante :
<racine>
<element1>http://www.google.com</element1>
<element2>Un moteur de recherche</element2>
</racine>
Dans ce document, il y a trois éléments. Tout d’abord, il y a l’élément-racine qui comprend tout ce qui est entre les balises <racine> et </racine>. La première balise marque
le début de l’élément-racine. Tout document XML bien formé doit avoir un élémentracine et un seul élément-racine. Tous les autres éléments doivent être contenus dans
cet élément-racine. Dans notre exemple, cet élément a deux sous-éléments :
<element1>http://www.google.com</element1>
et
<element2>Un moteur de recherche</element2>
On peut ajouter un attribut à un des éléments de la façon suivante :
<racine date="aujourd’hui"> et </racine>
Le texte date="aujourd’hui" est un attribut de l’élément-racine avec pour nom « date »
et comme valeur d’attribut « aujourd’hui ».
Tout le texte qui ne se trouve pas dans une balise, mais qui se trouve dans l’élémentracine se décompose en nœuds de texte. Par exemple, le document suivant contient un
élément contenant un nœud de texte.
<racine>mon texte</racine>
CC BY-NC-SA
Principes de XML
1.5.4
25
Points importants dans la syntaxe de base
Un document XML ne doit avoir qu’un et un seul élément appelé « élément-racine »,
qui doit contenir tous les autres éléments.
Il faut correctement ouvrir et fermer les éléments en séquence, ainsi <a><b></a></b>
n’a aucun sens en XML, il faut plutôt écrire <a><b></b></a> ou alors
<a></a><b></b>.
Les éléments peuvent eux aussi avoir des attributs, par exemple <a att="test"></a>,
mais il faut obligatoirement mettre la valeur de l’attribut entre guillemets (") ou apostrophes (’).
1.5.5
Dans l’ordre ou dans le désordre
Dans un document XML, l’ordre dans lequel les éléments sont présentés importe. Par
exemple, les deux documents XML suivants ne sont pas équivalents.
<racine>
<element1>http://www.google.com</element1>
<element2>Un moteur de recherche</element2>
</racine>
<racine>
<element2>Un moteur de recherche</element2>
<element1>http://www.google.com</element1>
</racine>
Par contre, l’ordre dans lequel les attributs sont présentés est sans importance. Les deux
documents XML suivants sont donc équivalents.
<racine attr1="test" attr2="retest"></racine>
<racine attr2="retest" attr1="test" ></racine>
1.5.6
Appels d’entités
Un élément peut contenir du texte, mais ne peut contenir le symbole <, comme dans
l’exemple <a><</a>, parce que cela mène à de la confusion. On ne peut non plus y
trouver le symbole & ou la séquence « ]]> ». Que faire alors s’il faut utiliser le caractère
< dans un texte mathématique, par exemple? Il faut utiliser un appel d’entité. Un appel
d’entité est un bout de texte qui commence par une esperluette ( & ) et se termine par un
CC BY-NC-SA
Module 1 : Introduction à XML
26
point-virgule ( ; ). Nous verrons plus tard que nous pouvons définir nos propres appels
d’entités; les appels d’entités suivants font partie de la définition du XML :
appel d’entité
résultat
&lt;
<
&amp;
&
&gt;
>
&quot;
"
&apos;
’
Ainsi, si le nom de votre compagnie est John&Smith, vous ne devrez pas utiliser un
élément comme ceci <nom>John&Smith</nom>; il vous faudra plutôt utiliser
<nom>John&amp;Smith</nom>.
Le texte « ]]> » s’écrit « ]]&gt; ».
On utilise aussi les appels d’entités pour noter les valeurs des attributs. Supposons que
la valeur d’un attribut est un guillemet suivi d’une apostrophe ("’). Les deux choix
possibles <nom att="’""> et <nom att=”"’> ne sont pas valables. Dans ce cas, il faudra écrire <nom att="’&quot;">, <nom att=’&apos;"’>, <nom att="&apos;&quot;">
ou <nom att=’&apos;&quot;’>.
Prenez le temps de mémoriser ces appels d’entités et retenez bien dans quel cas on peut
être obligé de les utiliser.
Il arrive parfois qu’il soit trop lourd d’utiliser des appels d’entités, et on peut alors
utiliser un segment « CDATA ». Un tel segment débute par « <![CDATA[ » et se termine par « ]]> ». Tout le texte au sein du segment est rendu verbatim. Ainsi, le texte
« <![CDATA[<monelement />]]> » est équivalent à « <monelement /> ».
1.5.7
Les commentaires
Dans un document XML, on peut ajouter un commentaire qui est normalement destiné
à être lu par un humain. Par exemple, dans un fichier de configuration XML, les commentaires pourraient être utilisés pour expliquer la signification des différents éléments
pour qu’un humain puisse faire des modifications au besoin.
Un commentaire commence par <!-- et se termine par --> et ne doit pas contenir deux
tirets de suite (--) entre ces deux bornes, il ne doit pas se terminer par un tiret, mais
peut contenir n’importe quel autre texte. Un commentaire peut apparaître avant ou
après l’élément-racine, dans un élément, entre deux éléments, etc. Cependant, un commentaire ne peut pas apparaître au sein d’une balise, comme <a <!--ceci est la balise
a-->>. C’est du XML mal formé!
CC BY-NC-SA
Principes de XML
1.5.8
27
Les instructions de traitement
En pratique, il serait parfois utile d’appeler des fonctions externes (ou programmes) à
partir du XML. Par exemple, vous pourriez avoir un programme « cout » qui donne
le prix d’un produit à partir de son numéro de série : pourquoi ne pas appeler ce programme directement du XML? Le XML ne permet pas de le faire : le XML n’est
qu’un métalangage pour produire des documents.
Par contre, en XML, on peut utiliser des instructions de traitement. L’instruction de
traitement ne fait rien en soi, mais peut indiquer à vos programmes comment trouver un
certain résultat. L’exemple suivant décrit un produit portant le numéro de série 423890
et dont le prix pourrait être déterminé par une application appelée « cout ».
<produit>
<serie>423890</serie>
<valeur><?cout 423890?></valeur>
</produit>
La syntaxe d’une telle instruction de traitement est simple. L’instruction débute par <?
et se termine par ?>; immédiatement après <?, un nom XML valable doit apparaître
(tous les noms XML valables sont autorisés à l’exception de xml, Xml, XMl, XML,
XmL, xMl, xML et xmL). Rappelons que, comme pour n’importe quel contenu textuel XML, il faut faire des appels d’entités pour < et &. Une instruction de traitement
n’est pas une balise ou un élément.
Notez que le langage informatique PHP utilise les instructions de traitement avec
comme nom « php ». Voyons l’exemple suivant :
<produit>
<serie>423890</serie>
<?php echo "test" ?>
</produit>
Tout comme les commentaires, on peut mettre les instructions de traitement partout
dans un document XML, sauf à l’intérieur d’une balise.
1.5.9
Jeux de caractères
Historiquement, on a longtemps représenté les caractères en utilisant des octets (8 bits).
Aux États-Unis, on utilisait la norme ASCII qui utilisait les sept premiers bits de chaque
octet. Avec le temps, les normes ISO se sont imposées. En français, on utilise souvent
le jeu de caractères « ISO-8859-1 ». L’outil Bloc-note de Microsoft utilise par défaut
un jeu de caractères qui est très similaire à ISO-8859-1 (qu’ils nomment parfois ANSI).
Malheureusement, n’utiliser que 8 bits pour représenter les caractères signifie qu’il est
CC BY-NC-SA
Module 1 : Introduction à XML
28
impossible de tenir compte des langues asiatiques, par exemple, et qu’on ne peut mélanger un texte français avec de l’arabe. Pour cette raison, en 1991, la norme Unicode
fut proposée.
La norme Unicode est de plus en plus utilisée et elle est popularisée en partie par son
utilisation dans le XML. En effet, par défaut, un document XML utilise Unicode (spécifiquement UTF-8 ou UTF-16) et ce sont les seuls jeux de caractères qu’un processeur
XML est requis de connaître. L’avantage principal d’Unicode est sa richesse : la version 5.0 du format Unicode permet de représenter 99 000 caractères différents incluant
les caractères Klingon de Star Trek. En comparaison, le jeu de caractères ISO-8859-1
permet de représenter moins de 255 caractères (8 bits).
La plupart des logiciels récents supportent la norme Unicode. D’ailleurs, depuis le tout
début, une chaîne de caractères en Java est représentée en utilisant la norme Unicode.
Par contre, il restera toujours des logiciels utilisant les jeux de caractères ISO.
1.5.10
La déclaration XML
La déclaration XML ressemble à s’y méprendre à une instruction de traitement et prend
la forme <?xml ... ?>. Une déclaration XML n’est pas une balise ou un élément. Le
contenu d’une déclaration XML comporte généralement au maximum trois attributs :
version="...", encoding="..." et standalone="...". La version 1.0 du XML est la plus utilisée; bien que la version 1.1 existe, elle est fort peu utilisée. Selon l’un des inventeurs
du XML, Tim Bray, il est peu probable qu’il y ait une version 2.0 du XML .
Je ne pense pas qu’il y aura de XML 2.0. Les obstacles politiques seraient effrayants - tout le monde voudra sa part du gâteau -, et la base
installée de logiciels qui reconnaissent XML comprend aujourd’hui à peu
près tous les ordinateurs liés à Internet, donc une transition me semblerait trop onéreuse. (Interview de Tim Bray, JDN Développeurs, 29 janvier
2007)
On utilise souvent une déclaration XML avec « encoding="ISO-8859-1" » pour
pouvoir utiliser les accents dans le document : les jeux de caractères Unicode ne
sont pas toujours supporté par plusieurs outils logiciels n’ayant pas été mis à jour
au vingt-et-unième siècle; l’utilisation des accents en français sans la déclaration
« encoding="ISO-8859-1" » peut alors entraîner des problèmes. L’attribut « standalone » prend la valeur yes ou no, selon que l’on veut que la DTD externe soit lue ou
non. Nous traiterons des DTD, plus tard.
Dans ce cours, nous supposons que vous utilisez un éditeur de texte qui ne supporte
pas les normes UTF-8 et UTF-16. En conséquence, le document XML suivant ne serait
pas bien formé, car il utilise des accents :
<étudiant>
Jean
</étudiant>
CC BY-NC-SA
Principes de XML
29
Par contre, le document XML qui suit est bien formé :
<?xml version="1.0" encoding="ISO-8859-1"?>
<étudiant>
Jean
</étudiant>
La déclaration XML doit obligatoirement être au tout début du document ou être
carrément absente : même un espace n’est pas permis.
1.5.11
Les espaces
En XML, les espaces entre les éléments comptent, qu’il s’agisse d’un retour de charriot,
d’une tabulation ou d’un simple espace. Ainsi, le document suivant se décompose en
7 parties ou nœuds : un élément-racine nommé html qui contient d’abord un nœud de
texte (le retour de charriot) suivi d’un élément produit contenant le nœud de texte « 1 »,
suivi d’un autre nœud de texte (le retour de charriot), suivi d’un élément serie (vide),
suivi d’un troisième nœud de texte (le retour de charriot).
<html>
<produit>1</produit>
<serie />
</html>
Par contre ce document ne contient que 4 nœuds (3 éléments et 1 nœud de texte) :
<html><produit>1</produit><serie /></html>
En effet, comme il n’y a pas d’espace ou de retour de charriot entre les balises, il n’y a
qu’un seul nœud de texte. Si on omet les attributs, les nœuds débutent et se terminent
généralement avec les balises.
On peut indiquer que les espaces entre les éléments sont significatifs avec l’attribut
xml:space qui peut prendre la valeur default ou la valeur preserve. Dans cet exemple,
on souhaite indiquer que les espaces sont significatifs :
<html xml:space="preserve">
<produit>1</produit>
<serie />
</html>
CC BY-NC-SA
Module 1 : Introduction à XML
1.5.12
30
Les fins de ligne
Les fichiers de texte sont souvent organisés en lignes. Selon le système d’exploitation,
il y a plusieurs façon de représenter une fin de ligne. Les systèmes d’exploitation Microsoft utilisent deux caractères (« retour de charriot » et « nouvelle ligne ») à la fin de
chaque ligne. Les autres système utilisent généralement un seul caractère (« nouvelle
ligne »). Les processeurs XML sont requis de normaliser la situation et de remplacer
les deux caractères utilisés par les systèmes Microsoft par un seul caractère lors de la
lecture du fichier. Ainsi, peu importe comment l’on note les fins de ligne, un processeur
XML ne vera qu’un caractère « nouvelle ligne ».
1.5.13
Les hyperliens
Il arrive fréquemment qu’on utilise des hyperliens dans les documents XML. On distingue deux types d’hyperliens : les hyperliens contenant une adresse absolue (telle
que http://domaine.ca/pong.png) et les hyperliens contenant des adresses relatives
(pong.png). On reconnaît les adresses relatives parce qu’elles ne débutent pas par un
protocole tel que http ou ftp. Pour compléter les adresses relatives et les transformer
en adresses absolues, on utilise fréquemment l’adresse du document. Ainsi, si le document suivant se trouve à l’adresse http://domaine.ca/fichier.xml, alors un logiciel pourra
charger une image située à l’adresse http://domaine.ca/pong.png :
<racine>
adresse relative:
<image lien="pong.png" />
</racine>
Le XML permet de spécifier un attribut xml:base qui sert à interpréter les adresses relatives remplaçeant l’adresse du document. Le document suivant pointe vers une image
à l’adresse http://domaine.ca/image/pong.png :
<racine xml:base="http://domaine.ca/" >
<p xml:base="image/">
<image lien="pong.png" />
</p>
</racine>
1.5.14
Documents bien formés
Un document XML qui respecte ces règles de base est dit « bien formé ». Pour éviter
la confusion, il ne faut pas utiliser des synonymes comme « correct ».
La terminologie utilisée peut sembler très aride. Cependant, la rigueur qu’exige le XML
est aussi garante de la cohérence. Comme tous les termes sont bien définis, il est plus
CC BY-NC-SA
Définition de type de document
31
facile de s’entendre entre experts. Comme le XML est surtout utilisé pour la communication entre les logiciels, la rigueur évitera plus tard les bogues et les incompréhensions.
Pouvoir reconnaître un document XML bien formé ou comprendre pourquoi un document n’est pas bien formé, permet de s’assurer qu’un logiciel pourra traiter les informations, et qu’on saura quoi faire en cas de problème.
1.6
1.6.1
Définition de type de document
Objectif
Comprendre la notion de type de document et son rôle dans la définition de document
valable.
1.6.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte traite
des définitions de type de document (DTD) qui servent à définir les documents XML
valables.
1.6.3
Document XML valable
Nous avons vu ce qu’était un document XML bien formé : un seul élément-racine, les
éléments ne se chevauchent pas, les noms XML ne commencent pas par un chiffre, et
ainsi de suite. De plus, un document XML bien formé peut contenir n’importe quel élément et dans n’importe quel ordre, et tous les éléments peuvent contenir des attributs,
et peu importe ceux-ci.
En pratique, il est souvent suffisant pour les documents XML d’être bien formés, mais
il arrive qu’on veuille imposer des contraintes supplémentaires aux éléments et attributs pouvant être utilisés. Par exemple, un élément « étudiant » pourrait posséder un
numéro d’étudiant, mais pas l’inverse : un élément « numéro d’étudiant » ne pouvant
contenir qu’un numéro et pas d’autres éléments. On peut aussi vouloir contraindre le
contenu d’un document XML pour des raisons d’interopérabilité. Par exemple, si un
groupe d’experts s’entendent sur un format XML pour un type de données, il est utile
de pouvoir vérifier si un fichier XML donné correspond bien à ce sur quoi on s’est entendu. Un document XML qui est bien formé et qui respecte les contraintes définissant
son type de document est dit valable (ou valide).
En d’autres mots, un document XML qui est bien formé et qui, en plus, satisfait aux
contraintes dictant quels éléments et attributs peuvent être utilisés, et dans quel ordre
et avec quel contenu, est dit valable.
CC BY-NC-SA
Module 1 : Introduction à XML
1.6.4
32
Normes de définition de type de document
Il y a plusieurs façons de définir des types de documents XML. L’approche la plus
répandue, la plus ancienne et la plus simple, est la norme de définition de type de
document (DTD). C’est la seule approche présentée dans ce cours. Les deux autres
possibilités émergentes les plus répandues sont XML Schema et Relax NG.
On fait généralement deux reproches à l’approche DTD : un document DTD n’est pas
du XML et la norme n’est pas assez riche pour spécifier le contenu des documents
XML avec finesse. En effet, L’approche DTD ne permet pas de déclarer qu’un contenu
textuel doit être une date ou un nombre, et il n’y a pas de support pour les espaces de
noms, sujet que nous traiterons plus loin dans ce module.
D’un autre côté, la norme DTD est très répandue et tous les logiciels qui supportent
XML supportent maintenant cette norme, incluant Java et Firefox. Les nouveaux formats comme XHTML 2.0 sont toujours publiés avec une spécification DTD. Les autres
possibilités, comme XML Schema, Relax NG, Schematron et Examplotron, sont moins
bien supportées.
La norme XML Schema permet de définir avec une grande finesse des types de données
comme une date ou un code de langue (« fr », « en »). Cette norme est très utile si on
veut spécifier avec beaucoup de détail le format de nos documents XML. Comme vous
pouvez le constater dans l’exemple suivant, la norme XML Schema permet non seulement de spécifier le nom des éléments et des attributs (« shipTo », « billTo », « comment », « items », « orderDate »), mais aussi leur type (« xsd:string », « xsd:decimal »,
« xsd:date »).
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress" >
<xsd:sequence>
<xsd:element name="name"
type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city"
type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip"
type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
CC BY-NC-SA
Définition de type de document
33
La norme XML Schema est supportée en Java depuis la version 1.5. Il n’est pas nécessaire d’utiliser une librairie spécialisée.Elle est cependant sujette à des critiques très
sévères de la part des experts en XML tels que Tim Bray (co-inventeur du XML) qui
écrivait en novembre 2006 sur son blogue :
Everybody who actually touches the technology has known the truth
for years, and it’s time to stop sweeping it under the rug. W3C XML Schemas (XSD) suck. They are hard to read, hard to write, hard to understand,
have interoperability problems, and are unable to describe lots of things
you want to do all the time in XML. Schemas based on Relax NG, also
known as ISO Standard 19757, are easy to write, easy to read, are backed
by a rigorous formalism for interoperability, and can describe immensely
more different XML constructs.
En somme, XML Schema est trop difficile à utiliser et à comprendre. Tim Bray, ainsi
que de nombreux autres experts, préconisent plutôt l’utilisation de Relax NG. Cette
norme, comme XML Schema, possède plusieurs avantages sur la norme DTD : elle
permet de spécifier des types de données (comme une date ou un nombre), supporte
les espaces de noms, etc. De plus, la norme Relax NG est plus élégante techniquement
et parfois plus simple que la norme XML Schema. Des formats importants comme
l’Open Document Format, DocBook (format XML), TEI, XHTML 2.0 et Atom sont
définis par RelaxNG plutôt que par XML Schema. (Une définition XML Schema sera
sans doute produite pour le format XHTML 2.0.) Relax NG dispose aussi d’une syntaxe
« compacte », qui n’est pas en XML contrairement au format par défaut de Relax NG,
et que nous allons utiliser dans nos exemples. Voici un exemple de Relax NG :
element addressBook {
element card {
element name { text },
element email { text }
}*
}
Cet exemple spécifie que le document XML doit avoir comme élément racine un élément « addressBook », contenant zéro ou plus éléments « card ». Un élément « card »
doit obligatoirement contenir un élément « name » suivi d’un élément « email ». On
trouve facilement des tutoriels de qualité sur Relax NG. L’un meilleur tutoriel est en
anglais à l’adresse http://relaxng.org/compact-tutorial-20030326.html.
Tout en étant plus élégante que la norme DTD, le format Relax NG est plus limitée que
XML Schema puisqu’il ne permet que quatre types de contraintes sur le nombre d’occurences d’un élément (zeroOrMore comme dans notre exemple, optional, un nombre
précis (comme une seule fois) et oneOrMore) alors que le XML Schema permet des
contraintes beaucoup plus spécifiques. Cependant, la richesse de la norme XML Schema
a un coût : il s’agit d’une norme beaucoup plus difficile à utiliser et à apprendre en pratique.
CC BY-NC-SA
Module 1 : Introduction à XML
34
On peut valider un document XML par rapport à une définition RelaxNG avec la librairie Jing (http://www.thaiopensource.com/relaxng/jing.html).
On peut passer automatiquement d’un document DTD à un document XML Schema ou
Relax NG avec un outil comme NekoDTD (http://people.apache.org/ andyc/neko/doc/
dtd/conversions.html).
En somme, la norme DTD n’est sans doute pas ce qui se fait de mieux, mais c’est
de loin la norme la plus utilisée historiquement, et c’est celle que nous allons étudier
en détail. Pour certaines applications, la norme DTD demeure supérieure aux alternatives mentionnées précédemment: la définition d’entités n’est pas possible en XML
Schema ou Relax NG, par exemple. Si vous maîtrisez la norme DTD, vous n’aurez
aucun mal à utiliser une autre norme comme Relax NG puisque les principes essentiels sont les mêmes. Notez que la webographie contient quelques liens vers les normes
XML Schema et Relax NG.
1.6.5
Documents valables utilisant la norme DTD
Un document valable commence par une déclaration XML, comme celle qui suit :
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
Elle est suivie d’une déclaration de type de document sous la forme <!DOCTYPE ... SYSTEM ... > , où l’on remplace les premiers trois points par le
nom XML de l’élément-racine que le document doit avoir, et les deuxièmes
trois points par une URL vers le document DTD. L’URL peut être absolue,
comme « http://www.google.com/mydtd.dtd », ou locale, comme « madtd.dtd »
ou « ../dtd/madtd.dtd ». Dans le second cas, il faut que le fichier DTD soit sur
le disque, à l’endroit indiqué par rapport au fichier XML. Ainsi, dans l’exemple
« ../dtd/madtd.dtd », il faudrait que le fichier « madtd.dtd » soit dans le répertoire
« dtd », voisin du répertoire où se trouve le fichier XML. Ainsi, immédiatement après
la déclaration XML, on pourrait avoir le texte suivant :
<!DOCTYPE baliseracine SYSTEM "http://www.mondomain.com/madtd.dtd">
où « baliseracine » est le nom de l’élément-racine du document, alors que le chemin
« http://www.mondomain.com/madtd.dtd » nous dit où trouver le document DTD.
Rappelons que l’attribut « encoding » nous donne le jeu des caractères. On choisit
souvent « ISO-8859-1 », mais par défaut, XML utilise un jeu de caractères Unicode
(UTF-8). Si le contenu est en français (avec les accents), il est essentiel que le fichier
soit enregistré avec le jeu de caractères déclaré sinon on pourra constater des messages
d’erreurs ou des accents manquants. L’attribut « standalone » permet au logiciel de
décider, s’il est nécessaire, d’aller chercher la DTD externe avant de lire le fichier XML,
même si, très souvent, un logiciel tel Mozilla Firefox ignore la consigne et ne va pas
CC BY-NC-SA
Définition de type de document
35
chercher la DTD externe. En gros, s’il y a une DTD externe, on utilisera l’attribut
« standalone="no" », autrement on utilise « standalone="yes" ».
1.6.6
La syntaxe des documents DTD
Les documents DTD contiennent des instructions de la forme <!ELEMENT ... >. Bien
que celle-ci ait l’apparence d’une balise XML, ce n’est pas du XML. Dans une instruction, on met d’abord un nom XML qui correspond à un nom d’élément : par exemple,
l’instruction « <!ELEMENT montant ... > » définira ce qui peut être contenu dans
un élément de nom « montant ». Tout ce qui suit le nom de l’élément dicte ce que
l’élément peut contenir. Le plus souvent, on place la description du contenu entre parenthèses (« <!ELEMENT montant (quelque chose) > »), sauf pour les cas particuliers
(« ANY » et « EMPTY ») définis plus loin. De façon courante, on définit le contenu
d’un élément par une liste de noms XML, correspondant à des noms d’élément et séparés par des virgules. Par exemple, l’instruction « <!ELEMENT montant (devise,valeur)
> » nous informe qu’un élément « montant » doit contenir un élément « devise » suivi
d’un élément « valeur ». Notons que l’ordre des éléments importe et que les instructions
« <!ELEMENT montant (devise,valeur) > » et « <!ELEMENT montant (valeur,devise)
> » ne sont pas équivalentes.
Bien qu’on ne puisse exprimer toutes les possibilités, la syntaxe DTD permet tout de
même de spécifier un grand nombre de règles. Par exemple, le symbole « ? » permet de
spécifier qu’un élément peut être présent ou non (élément optionnel). Ainsi, l’instruction « <!ELEMENT montant (devise?,valeur) > » signifie que l’élément « montant »
peut contenir un élément « devise » (ou non) et doit contenir un élément « valeur ».
Si jamais l’élément « devise » apparaît, il doit apparaître avant l’élément « valeur ».
Si jamais on veut qu’un élément soit optionnel et que, s’il apparaît, il puisse apparaître
plus d’une fois, on utilise le symbole « * ». Ainsi, l’instruction « <!ELEMENT montant
(devise*,valeur) > » signifie qu’on peut avoir zéro, un ou plusieurs éléments « devise »,
puis un élément « valeur ». De la même façon, le symbole « + » est utilisé pour spécifier
qu’un élément doit être présent, mais peut apparaître plus d’une fois.
Au lieu d’utiliser la virgule, on peut utiliser le symbole « | » pour spécifier qu’un élément ou un autre peut apparaître. Ainsi, l’instruction « <!ELEMENT montant (devise|valeur) > » signifie que l’élément « montant » peut contenir soit l’élément « devise », soit l’élément « valeur » (l’un ou l’autre, mais pas les deux ou aucun des deux).
Finalement, on peut combiner le tout; par exemple, l’instruction « <!ELEMENT montant (devise+|valeur*) > » signifie que l’élément « montant » peut contenir au moins un
élément « devise » (et rien d’autre) ou alors, aucun, 1 ou plusieurs éléments « valeur ».
Si jamais on veut qu’un élément puisse contenir du texte, on utilise le terme technique « #PCDATA » dans l’instruction DTD. Par exemple, l’instruction « <!ELEMENT
montant (#PCDATA) > » signifie que l’élément « montant » contient du texte et seulement du texte (pas d’éléments). Supposons maintenant qu’on veut permettre du contenu
mixte, comme dans l’exemple qui suit :
<mixte>
CC BY-NC-SA
Module 1 : Introduction à XML
36
Ceci est du contenu <important>mixte</important>
parce qu’il s’agit de mélange de texte et de
<important>balises</important>.
</mixte>
On pourrait penser que l’instruction « <!ELEMENT mixte (#PCDATA|important) > »
permettra du texte ou des éléments « important », et c’est vrai; mais elle permet l’un
(juste du texte) ou l’autre (juste un élément « important »), mais pas un mélange des
deux. Pour pouvoir obtenir le résultat désiré, soit un mélange d’éléments « important »
et de texte, il faut permettre la répétition du choix, comme dans l’instruction « <!ELEMENT mixte (#PCDATA|important)* > ». Il s’agit de la seule façon de spécifier qu’on
permet un mélange de texte et d’éléments (contenu mixte).
Voyons un autre exemple de contenu mixte. Considérons l’instruction « <!ELEMENT
montant (#PCDATA|devise)* > ». Ce qu’elle signifie exactement, c’est que les éléments
« montant » peuvent contenir un mélange de texte et des éléments « devise », comme
l’exemple qui suit :
<montant>
Le montant est spécifié en <devise>dollars</devise>.
</montant>
On peut aussi utiliser « ANY » pour spécifier qu’un élément peut contenir n’importe
quoi (n’importe quelle séquence d’éléments déclarés dans la DTD et du texte) ou
« EMPTY » pour spécifier qu’un élément doit être vide (sans même un seul espace).
C’est le seul cas où l’on n’utilise pas de parenthèses lors de la définition du contenu,
comme dans ces exemples : <!ELEMENT question ANY> et <!ELEMENT question
EMPTY>.
Un document DTD prendra donc la forme d’un fichier en format texte contenant une
suite d’instructions comme :
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
problemset (title?,recall?,item*)*>
recall (#PCDATA | section | codexml )*>
item (question, choice+)>
choice (response, feedback)>
question (#PCDATA)>
response (#PCDATA)>
feedback (#PCDATA)>
codexml (#PCDATA)>
title (#PCDATA)>
section (#PCDATA)>
Notez qu’on écrit rarement de nouvelles DTD : dans un domaine particulier, il existera
souvent des DTD déjà utilisées; sinon, on fera l’effort de les créer, mais qu’une seule
fois. L’important demeure toutefois de pouvoir lire et comprendre les DTD.
CC BY-NC-SA
Définition de type de document
1.6.7
37
Exemple supplémentaire
Pour s’assurer de bien comprendre, voyons un autre exemple :
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
lettre (#PCDATA | personne)*>
personne (age, nom)>
age (#PCDATA)>
nom (#PCDATA) >
Cette DTD nous spécifie que l’élément « lettre » contient du mélange de texte et d’éléments « personne » (contenu mixte), alors que l’élément « personne » doit contenir un
élément « age », suivi d’un élément « nom ».
Par exemple, ce document XML serait valable :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE lettre [
<!ELEMENT lettre (#PCDATA | personne)*>
<!ELEMENT personne (age, nom)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT nom (#PCDATA) >
]>
<lettre>
Ceci est une lettre pour
<personne><age>51</age><nom>Jean</nom></personne>.
</lettre>
Assurez-vous de bien comprendre pourquoi ce document est valable avant de continuer.
1.6.8
Les attributs
Par défaut, aucun élément n’est autorisé à avoir un attribut. Pour permettre d’ajouter un
attribut à un élément, il faut une instruction de la forme <!ATTLIST recipiendaire age
...> qui spécifie que l’élément recipiendaire peut avoir un attribut « age ». On permet généralement aux valeurs d’attribut de contenir n’importe quel texte, ce qu’on représente
par « CDATA ». Hormis le contenu, il existe deux types d’attributs : les attributs obligatoires (« #REQUIRED ») et les attributs optionnels (« #IMPLIED »). Par exemple,
l’instruction « <!ATTLIST recipiendaire age CDATA #IMPLIED> » signifie qu’on
peut (ou pas) accorder à un élément « recipiendaire » un attribut nommé « age » pouvant contenir n’importe quel texte. Si l’on désire que l’attribut soit obligatoire, on utilise une instruction comme « <!ATTLIST recipiendaire age CDATA #REQUIRED> ».
Si l’on veut permettre à un élément d’avoir plusieurs attributs, on peut le faire en utilisant plusieurs instructions comme dans « <!ATTLIST recipiendaire age CDATA #REQUIRED> <!ATTLIST recipiendaire nom CDATA #REQUIRED> »; on peut aussi
combiner les instructions dans une seule : « <!ATTLIST recipiendaire age CDATA
CC BY-NC-SA
Module 1 : Introduction à XML
38
#REQUIRED nom CDATA #REQUIRED> ». Cependant, il n’est pas possible de spécifier l’ordre dans lequel les attributs doivent apparaître, les instructions « <!ATTLIST
recipiendaire age CDATA #REQUIRED nom CDATA #REQUIRED> » et « <!ATTLIST nom CDATA #REQUIRED recipiendaire age CDATA #REQUIRED> » sont
équivalentes.
L’attribut « xml:lang » utilisé pour définir la langue d’un texte, peut être déclaré comme
ceci : « <!ATTLIST monelement xml:lang CDATA #IMPLIED> ». L’attribut xml:space
peut être déclaré comme ceci : « <!ATTLIST monelement xml:space (default|preserve)
#IMPLIED> ».
On peut également spécifier qu’un élément donné a toujours un attribut donné (indiqué
ou non dans le XML) comme ceci : « <!ATTLIST recipiendaire age CDATA #FIXED
"40 ans"> ». Dans ce dernier exemple, tous les éléments « recipiendaire » ont l’attribut
« age="40 ans" », même si on omet de l’indiquer dans la balise de départ de l’élément
« recipiendaire ».
Plus simplement, on peut spécifier une valeur par défaut qui ne prendra effet que si
l’on n’a pas explicitement indiqué l’attribut. Par exemple, l’instruction « <!ATTLIST
recipiendaire age CDATA "40 ans"> » signifie que l’élément « recipiendaire » aura
l’attribut « age="40 ans" », à moins qu’on ne spécifie autre chose dans le XML.
Il peut être utile de donner une liste de valeurs que pourra prendre un attribut. Par
exemple, une pièce de monnaie est soit sur « face », soit sur « pile » : il n’y a que
deux choix. Si la liste de choix est composée de textes sans espace ou ponctuation,
sauf la barre du soulignement ( _ ), le trait d’union ( - ) et le point ( . ), alors on peut
faire une énumération comme dans l’exemple suivant : « <!ATTLIST piece position
(face|pile) #REQUIRED> ». On peut aussi spécifier une valeur par défaut, si l’on suppose, jusqu’à preuve du contraire, que la pièce est dans la position « face », comme
ceci « <!ATTLIST piece position (face|pile) "face"> »
On peut également spécifier qu’un attribut servira à identifier un élément de façon
unique. Pour ce faire, on utilise une instruction comme « <!ATTLIST recipiendaire
code ID> ». Il n’est pas possible, pour deux attributs de type ID, d’avoir la même valeur
dans un même document XML. En somme, si l’on donne une valeur « ID », elle devrait
correspondre de façon unique à un élément et un seul. Un attribut de type « ID » doit
avoir comme valeur un « nom XML », c’est-à-dire un texte sans espace ou ponctuation,
sauf la barre du soulignement ( _ ), le trait d’union ( - ) et le point ( . ), et qui ne
commence pas par un chiffre, un trait d’union ou un point.
On peut faire référence aux attributs de type « ID » avec des attributs de
type « IDREF ». La valeur d’un attribut « IDREF » doit non seulement être un
nom XML, mais doit aussi avoir un attribut de type « ID » qui possède cette même
valeur quelque part dans le document XML. Par exemple, si on a l’instruction « <!ATTLIST recipiendaire code ID> », on pourra ensuite faire référence à l’élément ayant
une valeur d’attribut « code » particulière, avec une instruction comme « <!ATTLIST
mauvaispayeur code IDREF> ».
Dans ce contexte, le document XML qui suit n’est pas valable :
CC BY-NC-SA
Définition de type de document
39
<mondocument>
<recipiendaire code="s765" />
<recipiendaire code="s766" />
<mauvaispayeur code="s894" />
</mondocument>
Par contre, l’exemple qui suit est valable :
<mondocument>
<recipiendaire code="s765" />
<recipiendaire code="s766" />
<mauvaispayeur code="s765" />
</mondocument>
Il existe d’autres types d’attributs, mais ils sont peu utilisés.
1.6.9
Les entités
Vous vous rappelez sans doute que le XML définit quelques entités par défaut, « &lt; »,
par exemple. On peut toutefois définir ses propres entités avec une instruction DTD
comme celle-ci :
<!ENTITY monentite "Introduction à XML">
La signification de ce dernier exemple, c’est que partout où « &monentite; » apparaît
dans un document, il sera remplacé par le texte « Introduction à XML ». Ce remplacement s’applique aussi aux valeurs par défaut des attributs de la DTD.
On peut mettre des éléments et des attributs dans une entité comme dans cet exemple :
<!ENTITY monentite "<p titre=’x’>mon paragraphe</p>">
Il n’est cependant pas permis de ne mettre qu’une partie d’un élément comme ceci :
<!ENTITY monentite "<p>mon paragraphe">
Une entité peut faire appel à une autre entité :
<!ENTITY montexte "La vie.">
<!ENTITY monentite "<p>&montexte;</p>">
Une entité ne peut cependant pas faire appel à elle même de manière récursive, directement ou indirectement. Cet exemple n’est donc pas valable :
CC BY-NC-SA
Module 1 : Introduction à XML
40
<!ENTITY montexte "La vie. &monentite;">
<!ENTITY monentite "<p>&montexte;</p>">
1.6.10
DTD interne et externe
Normalement, on fait référence à un document DTD à l’aide d’une URL, c’est ce qu’on
appelle la DTD externe. Mais il est possible d’ajouter ses propres instructions DTD
directement dans le document XML, en ajoutant une DTD interne qui est lue avant la
DTD externe.
Prenons l’exemple suivant, soit un document XML qui débute par :
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE problemset SYSTEM "../dtd/quiz.dtd"[
<!ELEMENT question #PCDATA>
]>
Dans ce cas, tout ce passe comme si on ajoutait la ligne « <!ELEMENT question #PCDATA> » à la DTD externe. Normalement, il ne devrait jamais y avoir de conflit entre
les deux DTD (interne et externe); on ne peut pas redéfinir un élément, mais on peut
y définir des éléments!
Par contre, les entités peuvent être redéfinies et la définition trouvée dans le DTD interne l’emporte.
On peut même omettre complètement la DTD externe comme dans l’exemple suivant :
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
<!DOCTYPE jeu [
<!ELEMENT jeu (nom,(age|niveau))>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT niveau (#PCDATA)> ]>
1.6.11
Les entités paramètres
On peut aussi définir des entités particulières qui ne s’appliquent que dans le contexte
de la DTD, et non pas dans le document XML. Pour ces entités, au lieu d’utiliser
l’esperluette ( & ), on utilise plutôt le symbole du pourcentage ( % ). Ainsi, l’instruction
suivante :
<!ENTITY % monentite "#PCDATA|age*">
CC BY-NC-SA
Définition de type de document
41
signifie que partout, dans la DTD externe, où se trouve le texte « %monentite; », il sera
remplacé par « #PCDATA|age* »; on appelle ces entités des « entités paramètres ». On
peut définir une entité paramètre dans la DTD interne, mais on ne peut pas l’y utiliser;
elle doit être utilisée dans la DTD externe. Si l’entité paramètre « %monentite; » est
définie, à la fois dans la DTD interne et dans la DTD externe, la DTD interne a préséance. En somme, les entités paramètres ne s’appliquent que dans la DTD externe;
elles ne s’appliquent ni dans le document XML, ni dans le DTD interne, soit la partie
de la DTD définie dans le document XML.
1.6.12
Commentaires dans les fichiers DTD
Pour rendre un fichier DTD plus compréhensible, on peut ajouter des commentaires.
La syntaxe est la même que pour les fichiers XML comme le montre l’exemple suivant.
<!-- Un élément lettre contient des éléments
personne et du texte -->
<!ELEMENT lettre (#PCDATA | personne)*>
<!-- Un élément personne contient un élément age
et un élément nom -->
<!ELEMENT personne (age, nom)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT nom (#PCDATA) >
Les commentaires dans les fichiers Relax NG non-textuel sont obtenus en débutant une
ligne par le symbole « # » comme dans cet exemple.
element addressBook {
# les éléments addressBook contiennent 0, 1, ou plusieurs
# éléments card
element card {
# les éléments card contiennent un élément
# name et un élément email
element name { text },
element email { text }
}*
}
1.6.13
Une comparaison entre Relax NG et DTD
Une fois qu’on connaît bien le format DTD, il est facile d’apprendre Relax NG. Prenons
d’abord un de nos exemples de fichier DTD.
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
lettre (#PCDATA | personne)*>
personne (age, nom)>
age (#PCDATA)>
nom (#PCDATA) >
CC BY-NC-SA
Module 1 : Introduction à XML
42
Une étude attentive vous permettra de constater que ce fichier est très similaire au
fichier Relax NG suivant, qui lui est essentiellement équivalent.
element lettre {
# un élément lettre contient
# du texte et des éléments
# personne
(text
| element personne {
# un élément personne
# contient un élément age
# suivi d’un élément nom
element age {text},
element nom {text},
}
)*
}
Pour bien comprendre, prenons un autre exemple, plus complexe cette fois-ci. Voici un
autre fichier DTD discuté précédemment.
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
problemset (title?,recall?,item*)*>
recall (#PCDATA | section | codexml )*>
item (question, choice+)>
choice (response, feedback)>
question (#PCDATA)>
response (#PCDATA)>
feedback (#PCDATA)>
codexml (#PCDATA)>
title (#PCDATA)>
section (#PCDATA)>
Voici l’équivalent en Relax NG. Si vous l’étudiez avec soin, vous verrez qu’encore une
fois, le format Relax NG est très similaire au format DTD.
element problemset {
(
element title { text } ?,
element recall {
( text
| element section {text}
| element codexml {text}) *
} ?,
element item {
element question {text},
CC BY-NC-SA
Définition de type de document
43
element choice {
element response { text},
element feedback {text}
}+
} *
)*
}
Prenons maintenant un exemple de fichier DTD contenant un attribut.
<!ELEMENT lettre (#PCDATA|personne)*>
<!ELEMENT personne (age,nom,estunhomme?)>
<!ATTLIST personne
nas CDATA #IMPLIED>
<!ELEMENT age (#PCDATA)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT estunhomme EMPTY>
L’équivalent Relax NG est, encore une fois, assez compréhensible comme vous pourrez
le constater, l’instruction ATTLIST étant remplacée par l’instruction « attribute ».
element lettre {
# un élément lettre contient
# du texte et des éléments
# personne
(text
| element personne {
# une élément personne
# contient un élément age
# suivi d’un élément nom
# et, optionnellement, d’un
# élément estunhomme qui est
# obligatoirement vide,
# l’élément personne peut aussi
# avoir un attribut nas
attribute nas {text}?,
element age {text},
element nom {text},
element estunhomme {empty}?
}
)*
}
Lorsqu’on utilise l’instruction attribute, la présence de l’attribut est requise à moins
d’ajouter le point d’interrogation (« ? ») à la suite de l’instruction.
CC BY-NC-SA
Module 1 : Introduction à XML
44
Le format Relax NG permet aussi de définir des motifs qui peuvent être réutilisés.
Prenons ce fichier DTD simple.
<!ELEMENT carte (page)>
<!ELEMENT page (carte)>
L’équivalent en Relax NG donne ceci.
carte = element carte { page }
page = element page { carte }
Le format Relax NG a cependant plusieurs avantages. Par exemple, l’esperluette (&)
permet de spécifier que des éléments puissent être inclus dans n’importe quel ordre. Il
n’y a pas d’équivalent en DTD. Considérons l’exemple suivant.
element addressBook {
element card {
element name { text }
& element email { text }
}*
}
On peut alors permettre le XML suivant. Il n’est pas possible de spécifier le contenu de
l’élément card avec une instruction DTD similaire.
<addressBook>
<card><name>Jean</name><email>l@c</email></card>
<card><email>l@c</email><name>Jean</name></card>
</addressBook>
Supposons maintenant qu’un élément puisse avoir soit l’attribut nas, soit à la fois les
attributs nas1 et nas2. Alors qu’il n’est pas possible de représenter cette condition en
DTD, c’est une chose facile en Relax NG.
element homme {
( attribute nas {text} |
(
attribute nas1 {text},
attribute nas2 {text}
)
)
}
Vous êtes invité à poursuivre vos lectures sur le format Relax NG en faisant des recherches sur le web.
CC BY-NC-SA
Définition de type de document
1.6.14
45
Une approche plus modulaire
En pratique, les fichiers DTD et Relax NG peuvent devenir complexes. On souhaite
donc souvent les diviser en plusieurs fichiers plus petits. Par exemple, pour une spécification portant des ventes et achats de biens, on pourra avoir un fichier portant sur
la description des biens, un fichier portant sur la description des acheteurs, et ainsi de
suite. Une approche modulaire, avec de petits fichiers, a aussi l’avantage qu’on peut
réutiliser les fichiers dans plus d’une spécification.
À titre d’exemple, reprenons le fichier DTD portant sur la définition de l’élément « problemset ». Au lieu de définir tout d’un seul coup, on peut commencer par un fichier
DTD qui ne définit que l’élément « choice » :
<!ELEMENT choice (response, feedback)>
<!ELEMENT feedback (#PCDATA)>
<!ELEMENT response (#PCDATA)>
Pour les fins de notre exemple, supposons que ce dernier fichier porte le nom de
« choice.dtd » et se trouve à l’adresse « http://www.mondomaine.com/choice.dtd ».
On pourra alors en importer le contenu dans un autre fichier externe avec une « entité
paramètre externe ». À la différence d’une entité paramètre usuelle, une entité paramètre externe pointe vers un autre document que le logiciel devra traiter. On définit
l’entité paramètre externe avec l’instruction « SYSTEM » suivie d’une adresse web
comme dans cet exemple :
<!ENTITY % monentite SYSTEM "http://www.mondomaine.com/choice.dtd">
Pour inclure le contenu du fichier externe (« choice.dtd » dans notre exemple), il suffit
tout simplement de faire appel à l’entité comme ceci :
<!ENTITY % monentite SYSTEM "http://www.mondomaine.com/choice.dtd">
%monentite;
Dans ce cas, tout se déroule comme si le contenu du fichier « choice.dtd » était inséré à
l’endroit où se trouve l’appel (« %monentite; »). On peut définir l’élément « problemset » à l’aide du fichier DTD suivant :
<!ENTITY % monentite SYSTEM "http://www.mondomaine.com/choice.dtd">
%monentite;
<!ELEMENT problemset (title?,recall?,item*)*>
<!ELEMENT recall (#PCDATA | section | codexml )*>
<!ELEMENT item (question, choice+)>
<!ELEMENT question (#PCDATA)>
<!ELEMENT codexml (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT section (#PCDATA)>
CC BY-NC-SA
Module 1 : Introduction à XML
46
On peut obtenir le même résultat avec Relax NG, un peu plus simplement avec l’utilisation de l’instruction « include ». Créons d’abord un fichier « choice.rnc » avec le
contenu suivant :
choiceele = element choice {
element response { text},
element feedback {text}
}
On peut alors réutiliser le motif « choiceele » dans n’importe quel autre fichier Relax NG comme le montre cet exemple :
include "choice.rnc"
element problemset {
(
element title { text } ?,
element recall {
( text
| element section {text}
| element codexml {text}) *
} ?,
element item {
element question {text},
choiceele+
} *
)*
}
En bref, il est facile de diviser des spécifications Relax NG ou DTD en plusieurs fichiers
plus petits, plus faciles à éditer, et qui peuvent être plus facilement réutilisés.
1.6.15
Définir l’élément-racine
Avec une DTD, il n’est pas possible de définir l’élément-racine. Celui-ci est déclaré
par l’instruction DOCTYPE qui se trouve dans le document XML. Avec Relax NG,
on peut non seulement spécifier l’élément-racine avec le mot-clef start, mais on peut
aussi permettre une certaine flexibilité. Par exemple, l’instruction « start = problemset
| choice » placée dans un fichier Relax NG, nous indique qu’on peut utilisé l’élément
problemset ou l’élément choice comme élément-racine.
CC BY-NC-SA
Définition de type de document
1.6.16
47
Définir le type de contenu en Relax NG
Dans tous nos exemples de Relax NG, nous n’avons prévu que du contenu textuel (text)
ou des éléments vides (empty). Relax NG permet de spécifier le contenu d’un élément
ou d’un attribut d’une manière très fine. Il emprunte ici la spécification mise au point
par XML Schema. En particulier, on peut spécifier un contenu textuel à l’aide d’une
expression régulière. Voici quelques exemples.
Type
Explication
Exemple
xsd:date
Une date formattée avec 2001-01-01 ou 1999-12la convention YYYY- 30
MM-DD
xsd:dateTime
Un moment spécifique à 2000-12-31T03:32:00
la seconde près
xsd:string pattern = Une chaîne de caractères maison
"[ˆ:]+"
contenant au moins un
caractère, à l’exclusion
du symbole :
xsd:string
pattern = Deux chaînes de carac- 01/01
".+/.+"
tères séparée par un caractère /
xsd:string
pattern = Deux chaînes de carac- [email protected]
".+@.+"
tères séparée par un caractère @
"text" | "html"
text ou html
text
xsd:string
min- Une chaîne caractères fai- monmotdepasse
Length="7"
max- sant entre 7 et 25 caracLength="25"
tères
xsd:decimal minExclu- Un nombre entre 0 et 10
5
sive="0.0"
maxInclusive="10.0"
xsd:decimal fractionDi- Un nombre n’ayant pas 5.001
gits="3"
plus de 3 chiffres après la
virgule (le point)
On déclare ensuite le contenu d’un élément ou d’un attribut comme ceci : element
madate xsd:date.
1.6.17
Est-ce qu’il existe un outil pour passer d’un format à l’autre
(DTD, Relax NG, XML Schema)?
Oui, le programme Java Trang (http://www.thaiopensource.com/relaxng/trang.html)
permet de passer facilement d’un format à l’autre.
CC BY-NC-SA
Module 1 : Introduction à XML
1.6.18
48
Est-ce qu’un document DTD est un document XML?
Absolument pas. Par contre, une DTD est un document textuel. Les fichiers
XML Schema sont par contre toujours en XML, alors que les fichiers Relax NG sont
parfois en XML, parfois en simple format textuel comme dans nos exemples.
1.6.19
Pourquoi est-ce qu’il n’est pas suffisant d’utiliser des documents bien formés? À quoi sert la validation?
Les documents XML sont faits pour être échangés et assurer la pérennité des informations. Si plusieurs individus ou plusieurs institutions s’entendent sur une DTD commune, il sera beaucoup plus facile d’échanger de l’information.
1.6.20
Est-ce vraiment nécessaire d’avoir des documents valables?
Est-ce que je dois vraiment toujours travailler avec des fichiers DTD, XML Schema ou Relax NG?
En pratique, la validation n’est pas essentielle et une application logicielle ne devrait
pas exiger des documents valables. Si vous concevez une application, la règle implicite
est que toute balise ou attribut non prévue devrait être ignorée. Un navigateur qui sait
lire et afficher du XML devrait pouvoir lire tout XML bien formé, même s’il n’est pas
valable. Si vous inventez une nouvelle balise XHTML, le navigateur devrait tout simplement ne pas en tenir compte. Les concepteurs du XML n’ont pas inscrit la nécessité
d’être valable à même la définition du XML et c’est un choix qui n’a jamais été remis
en question par l’organisme de normalisation W3C.
Il arrive, par exemple, qu’il soit inutilement complexe d’exiger que les documents
soient bien formés. Si on se contraint à des documents bien formés, on peut même
en arriver à des solutions qui sont techniquement inférieures. Pour quelques exemples,
voir l’article (en anglais) « Must Ignore vs. Microformats » d’Elliotte Rusty Harold à
l’adresse http://cafe.elharo.com/xml/must-ignore-vs-microformats/.
Consultez le pense-bête DTD pour avoir une vue d’ensemble et pour réviser.
1.6.21
Livres de référence
– Eric van der Vlist, Relax NG, O’Reilly Media, 2003, 486 pages.
– Priscilla Walmsley, Definitive XML Schema, Prentice Hall Trade, 2001.
CC BY-NC-SA
La validation des documents XML
1.7
1.7.1
49
La validation des documents XML
Objectif
Valider des documents XML.
1.7.2
Activité de validation
On peut facilement vérifier si un document XML est « bien formé ». Il suffit de lui
donner l’extension « .xml » (ou « .xhtml ») et de l’ouvrir dans Mozilla Firefox, par
exemple. Pour effectuer une telle vérification, il existe aussi des services en ligne, dont
celui de la Brown University.
Cependant, il arrive qu’on veuille vérifier que le document est non seulement bien
formé, mais aussi valable par rapport à des documents DTD locaux. Apprenons donc à
valider des documents XML, en exécutant les directives qui suivent, car cela vous sera
très utile dans vos travaux en XML.
La procédure que nous proposons suppose que vous connaissez bien les éléments de
base d’un système d’exploitation, comme l’utilisation de la ligne de commande et
l’exécution de programmes. Nous ne donnons la procédure que pour Windows, mais
elle est très similaire sous MacOS ou Linux.
Procédure pour valider des documents XML
Avant de procéder à la validation, préparons notre environnement. Allez dans un répertoire, par exemple « C:\XML », et créez le fichier « monfichier.dtd » avec le contenu
suivant, en utilisant le bloc-notes :
<!ELEMENT etudiant (numero,age)>
<!ELEMENT numero (#PCDATA)>
<!ELEMENT age (#PCDATA) >
Puis, créez un document appelé « mauvais.xml » avec le contenu suivant, toujours à
l’aide du bloc-notes :
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE etudiant SYSTEM "monfichier.dtd">
<etudiant><age>12</age></etudiant>
Il est important que les deux fichiers soient dans le même répertoire. En effet, la ligne
<!DOCTYPE etudiant SYSTEM "monfichier.dtd"> dans le fichier « mauvais.xml »
indique qu’il devrait y avoir un fichier « monfichier.dtd » dans le même répertoire.
Vérifions maintenant si le fichier « mauvais.xml » est valable.
CC BY-NC-SA
Module 1 : Introduction à XML
50
1. D’abord, vous devez disposer d’une machine virtuelle Java récente (Java 1.4 ou
mieux) sur votre ordinateur, incluant le compilateur Java : « javac ». Si vous
n’en avez pas, il faut effectuer un téléchargement et une installation d’une telle
machine. En outre, vous devez avoir sur votre ordinateur le SDK, pas uniquement le JRE. Sur la page qui se trouve à l’adresse http://java.sun.com/j2se/1.4.2/
download.html, cliquez sur « Download J2SE SDK ». Le téléchargement peut
prendre plusieurs minutes. Il suffit ensuite de lancer le fichier exécutable que
vous venez d’enregistrer sur votre ordinateur pour installer le SDK. Une fois le
SDK installé, vous pouvez poursuivre l’activité de vérification.
2. Placez le fichier Validateur.java dans le répertoire où se trouvent déjà vos fichiers
« mauvais.xml » et « monfichier.dtd », soit dans « C:\XML ». Votre fichier « Validateur.java » devrait avoir le contenu suivant :
//fichier Validateur.java
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.*;
/**
* Ce programme est inspiré de Xerces-J. Il a été modifié
* par Daniel Lemire pour le cours "Gestion de l’information
* avec XML".
*
* Date de la première modification: 5 novembre 2004.
*
* Il suffit de compiler le programme avec
* "javac Validateur.java".
* On peut ensuite valider un document en faisant
* "java Validateur monfichier.xml".
*
*/
public class Validateur extends DefaultHandler {
public Validateur() {
}
public void warning(SAXParseException ex)
throws SAXException {
printError("Avertissement", ex);
}
public void error(SAXParseException ex)
throws SAXException {
printError("Erreur", ex);
}
CC BY-NC-SA
La validation des documents XML
51
public void fatalError(SAXParseException ex)
throws SAXException {
printError("Erreur fatale", ex);
}
protected void printError(String type, SAXParseException ex) {
System.err.print("[");
System.err.print(type);
System.err.print("] ");
if (ex== null) {
System.out.println("!!!");
}
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf(’/’);
if (index != -1)
systemId = systemId.substring(index + 1);
System.err.print(systemId);
}
System.err.print(" ligne: ");
System.err.println(ex.getLineNumber());
System.err.println(", colonne: ");
System.err.print(ex.getColumnNumber());
System.err.print(", description: ");
System.err.print(ex.getMessage());
System.err.println();
System.err.flush();
}
public static void main(String argv[])
throws org.xml.sax.SAXException,
javax.xml.parsers.ParserConfigurationException {
Validateur counter = new Validateur();
PrintWriter out = new PrintWriter(System.out);
XMLReader parser = null;
parser = SAXParserFactory.newInstance().newSAXParser().
getXMLReader();
parser.setContentHandler(counter);
parser.setErrorHandler(counter);
parser.setFeature("http://xml.org/sax/features/validation",
true);
parser.setFeature("http://xml.org/sax/features/namespaces",
true);
try {
parser.parse(argv[0]);
CC BY-NC-SA
Module 1 : Introduction à XML
52
} catch (SAXParseException e) {
} catch (Exception e) {
System.err.println("erreur: Erreur de traitement -"
+e.getMessage());
}
}
}
3. Ensuite, lancez la machine virtuelle Java avec une ligne de commande. Pour
cela, il faut ouvrir une fenêtre de commande. Sous Windows XP, dans le menu
« Démarrer », cliquez sur « Exécuter »; une fenêtre s’ouvre, tapez le nom de
programme « cmd » pour ouvrir une fenêtre de commande. Notez qu’avec les
versions plus anciennes de Windows, comme Windows 98, il faut taper « command.com ». Une fenêtre s’ouvre alors avec un fond noir, c’est la fenêtre de
commande. Vous allez pouvoir y taper des lignes de commande pour vérifier si
votre document XML est valable. Les commandes de base sont : « dir » (affiche
le contenu d’un répertoire), « cd » (change de répertoire), « cd .. » (répertoire parent), « mkdir » (création d’un nouveau répertoire), « copy » (copie d’un fichier),
« move » (déplacement d’un fichier), et « del » (supprime un fichier).
4. Testez l’installation de votre machine virtuelle en tapant « java » suivi du retour
de chariot. Vous devriez recevoir un message qui commence par :
Usage: java [-options] class [args...]
(to execute a class)
or java -jar [-options] jarfile [args...]
(to execute a jar file)
ou quelque chose de similaire. Testez aussi l’installation du compilateur en tapant « javac »; vous devriez voir un message qui commence par quelque chose
comme :
Usage: javac <options> <source files>
Si ce n’est pas le cas, nous vous conseillons de vérifier l’installation de votre
machine virtuelle et de procéder à sa réinstallation au besoin. Si tout est bien
installé et que ça ne fonctionne toujours pas, vous devrez indiquer le chemin
pour trouver le compilateur en tapant la ligne de commande
PATH=adresse_du_fichier_javac.exe
Le fichier « javac.exe » se trouve dans le dossier « bin » du dossier où vous
avez installé le SDK. Par défaut, ce fichier se trouve dans le « C: ». L’adresse
du répertoire contenant le fichier « javac.exe » est donc « C:\j2sdk1.4.2_06\bin »
ou « C:\Program Files\Java\jdk1.5.0\bin ». Si vous ne savez plus où est installé
le SDK, vous pouvez faire une recherche, à partir du menu « Démarrer » de
Windows. Une fois le chemin indiqué, retapez la commande « javac » et cette
fois, tout devrait fonctionner. Comme il peut être lourd de modifier la variable
d’environnement PATH chaque fois, il est possible de la modifier une fois pour
toute : allez dans « Démarrer », choisissez « Paramètres », puis « Panneau de
configuration », et ouvrez « Système », cliquez sur l’onglet « Avancé »; cliquez
CC BY-NC-SA
La validation des documents XML
53
ensuite sur le bouton « Variables d’environnement », sélectionnez « PATH »
dans la liste des variables, cliquez sur le bouton « Modifier » et ajoutez, à la
fin du contenu de la variable, « ;adresse_du_fichier_javac.exe », par exemple
« ;C:\Program Files\Java\jdk1.5.0\bin ».
5. Ensuite, placez-vous dans le dossier où se trouvent votre fichier XML et sa DTD.
Vous savez toujours où vous vous trouvez dans l’arborescence de votre ordinateur, puisque chaque ligne de commande commence par l’adresse où vous êtes.
La commande pour se déplacer est « cd adresse ». Par exemple, si la ligne commence par « C:\Documents and Settings\lucie> », vous êtes dans le dossier de
lucie. Pour aller au dossier XML qui se trouve sur le disque C, il faut taper :
« cd C:\XML », puis faire le retour de chariot. Une nouvelle ligne apparaît et
commence par : « C:\XML> ». Maintenant que vous êtes dans le dossier où se
trouve votre fichier XML, vous pouvez vérifier s’il est valable.
6. Faites « javac Validateur.java » pour compiler le petit programme qui pourra vous
servir à vérifier la validité des documents XML. Vous ne devriez pas avoir de mal
avec la compilation. Par exemple, vous pourriez voir à l’écran :
C:\XML>javac Validateur.java
Note: Validateur.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.
Vous pouvez ignorer les avertissements vous incitant à utiliser l’option « deprecation ».
7. Tapez la ligne de commande « java Validateur mauvais.xml », puis faites un
retour de chariot. Il est important de respecter la casse dans les lignes de commande. Si rien de significatif ne s’affiche, votre fichier est valable, sinon, une description des erreurs s’affichera (en anglais). Si la machine virtuelle quitte avec
l’erreur « java.lang.NoClassDefFoundError » alors que vous êtes bien dans le
bon répertoire, faites alors « java -cp . Validateur mauvais.xml ».
8. Pour quitter, vous n’avez qu’à fermer la fenêtre de commande.
Vérification de la procédure
Après avoir tapé la commande « java Validateur mauvais.xml » pour vérifier si le fichier
« mauvais.xml » est valable, vous devriez obtenir le message d’erreur suivant indiquant
qu’il manque un élément « numero » (le message exact peut varier et il pourrait être en
français) :
> java Validateur mauvais.xml
[Error] mauvais.xml:3:-1: Element "etudiant" does not allow "age" here.
[Error] mauvais.xml:3:-1: Element "etudiant" requires additional elements.
Pour vous assurer de bien comprendre, reprenez la procédure; créez un autre document
appelé « bon.xml » avec le contenu suivant :
CC BY-NC-SA
Module 1 : Introduction à XML
54
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE etudiant SYSTEM "monfichier.dtd">
<etudiant><numero>1</numero><age>12</age></etudiant>
Cette fois-ci, vous devriez, en vérifiant que le document est valable, obtenir le message
suivant :
> java Validateur bon.xml
1.7.3
Retour
Est-ce que vous avez pu vérifier si les fichiers « mauvais.xml » et « bon.xml » étaient
valables? Si oui, passez aux autres activités, sinon contactez la personne tutrice ou
cherchez encore un peu.
1.8
1.8.1
Espaces de noms
Objectif
Utiliser les espaces de noms
1.8.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte traite
des espaces de noms auxquels il faut faire appel quand on utilise plusieurs « vocabulaires » XML, en même temps.
1.8.3
Les vocabulaires XML
Un « vocabulaire XML » est un ensemble de noms de balises et d’attributs ayant une
signification donnée. Par exemple, les gens de la comptabilité au sein d’une entreprise
pourraient avoir un vocabulaire XML pour décrire certaines transactions, alors que
les ingénieurs pourraient avoir leur propre vocabulaire pour décrire certains processus
techniques. Les deux équipes pourraient utiliser les mêmes noms d’élément, comme
« échéance », mais avec des significations différentes. On dira alors que nous avons
deux vocabulaires XML.
Voyons un autre exemple. Imaginez que votre institution ait un vocabulaire XML pour
les expéditions de marchandise et un vocabulaire XML pour la rédaction des factures.
Un document XML combinant à la fois de l’information concernant une expédition et
une facture devra utiliser deux vocabulaires.
CC BY-NC-SA
Espaces de noms
55
Un vocabulaire XML peut être associé à un document DTD; il peut aussi être associé
à un espace de noms.
1.8.4
Les identificateurs de ressources uniformes (URI)
Un identificateur de ressources uniformes (Uniform Resource Identifier ou URI) est
une adresse Internet composée d’un nom de protocole ou « schéma », comme file, http,
ftp, news, mailto, gopher, urn, suivi d’un deux-points « : », lui-même suivi d’un chemin,
comme « www.mondomain.com/fichier ». Un URI ne pointe pas nécessairement vers
un fichier, mais peut très bien être une adresse purement fictive ou une adresse pointant
vers une application logicielle sur un serveur.
Par
exemple,
«
http://www.mondomain.com/fichier
»
et
« mailto:[email protected] » sont des URI. Les URI ne doivent pas contenir
d’accents, et la casse est significative sauf pour ce qui est du nom du protocole
(HTTP versus http) et du nom de domaine (xerox.com versus XEROX.COM). Nous
reviendrons sur les URI dans le module 5.
1.8.5
Les espaces de noms
Un espace de noms est identifié par un URI; il y a correspondance unique entre
les espaces de noms et les URI. Deux espaces de noms ayant le même URI
sont identiques. Tous les utilisateurs d’un même vocabulaire XML devraient s’entendre sur un même URI. Par exemple, l’URI de l’espace de noms du XHTML est
« http://www.w3.org/1999/xhtml ». L’URI agit un peu comme le numéro d’assurance sociale des vocabulaires XML. Il s’agit d’une analogie un peu étrange, voire
originale, mais c’est ainsi.
Évidemment, la notion d’espace de noms n’a de sens que si l’on considère plusieurs
espaces de noms et, par conséquent, plusieurs vocabulaires.
1.8.6
Les DTD et les espaces de noms
Avant de préciser le lien entre les DTD et les espaces de noms, il importe de comprendre que les espaces de noms furent proposés après l’adoption des DTD. Il y a donc
une certaine incompatibilité entre les DTD et les espaces de noms. C’est d’ailleurs
l’une des raisons pour laquelle plusieurs organismes, dont OASIS et le W3C, tentent
de proposer des solutions de remplacement pour les DTD.
Rappelons que l’on donne une DTD à un document, en ajoutant une déclaration de type
de document, immédiatement après la déclaration XML, et dont la forme est :
<!DOCTYPE balise SYSTEM "http://www.mondomain.com/madtd.dtd">
CC BY-NC-SA
Module 1 : Introduction à XML
56
C’est la même chose avec les espaces de noms. Si vous avez, par exemple, un vocabulaire pour les expéditions et un vocabulaire pour les factures, définis respectivement
par des DTD situées à :
http://www.mondomain.com/expedition.dtd
et
http://www.mondomain.com/facture.dtd,
vous ne pourriez pas combiner les deux vocabulaires ainsi :
<!DOCTYPE balise SYSTEM "http://www.mondomain.com/expedition.dtd"
"http://www.mondomain.com/facture.dtd">
Même si l’on pouvait combiner deux DTD de la sorte, cela aurait plusieurs inconvénients : quoi faire si les deux DTD définissent un élément « client », mais de façon
différente? La solution est de créer un nouveau vocabulaire XML qui combine les deux
et traite chaque vocabulaire comme un « espace de noms ».
Dans l’exemple qui suit, nous considérons deux vocabulaires, « facture » et « expedition » qui ont les DTD suivantes :
<!ELEMENT facture (montant, nom)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT montant (#PCDATA)>
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
<!ELEMENT
1.8.7
expedition (nom)>
nom (prenom, nomfamille, adresse)>
prenom (#PCDATA)>
nomfamille (#PCDATA)>
adresse (#PCDATA)>
Déclaration de l’espace de noms
On peut utiliser le symbole « : » dans les noms XML, mais on ne l’utilise généralement
qu’une seule fois dans un nom donné. Tout ce qui précède le deux-points est appelé le
« préfixe ».
On a vu qu’un espace de noms est identifié par un URI. À leur tour, les URI peuvent
être associés à un « préfixe ». Tout attribut ou élément qui utilise un préfixe donné fait
automatiquement partie de l’espace de noms identifié par l’URI. Seul l’URI identifie
un espace de noms : le choix du préfixe est sans importance. Un document peut avoir
un seul espace de noms, mais douze préfixes différents.
CC BY-NC-SA
Espaces de noms
57
On définit un « préfixe » à l’aide d’un attribut ayant comme préfixe « xmlns ». La
définition du préfixe est alors valable pour l’ensemble de l’élément, y compris la balise
où se situe l’attribut « xmlns: ». Ainsi, dans le document XML suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
<fact:montant>10$</fact:montant>
<fact:nom>Jean</fact:nom>
</fact:facture>
on reconnaît que l’élément « fact:facture » et tout son contenu utilisent l’espace de
noms « http://www.domaine.com/facture » que nous avons décrit par une DTD plus
haut. Le préfixe « fact » est ici associé à l’URI « http://www.domaine.com/facture »
et tous les éléments et attributs ayant le préfixe « fact » sont considérés faire partie de
l’espace de noms « http://www.domaine.com/facture ».
Il est « illégal » d’utiliser un préfixe qui n’a pas été défini... Ainsi, le document suivant
est bien formé, mais il ne respecte pas les conventions des espaces de noms :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<fact:facture>
<fact:montant>10$</fact:montant>
<fact:nom>Jean</fact:nom>
</fact:facture>
Avez-vous remarqué que ces derniers documents n’ont pas de déclaration de type de
document et ne peuvent donc pas être des documents XML valables? La plupart des
documents XML utilisant les espaces de noms sont dans ce cas. Si jamais nous avions
une déclaration de type de document, il faudrait une DTD qui contiennent les éléments
« fact:facture », « fact:montant » et « fact:nom ». En d’autres mots, ce nouveau document XML ne peut utiliser la DTD facture décrite plus haut. Nous ne traiterons pas de
cette approche ici, car on combine rarement les DTD de la sorte.
Le choix du préfixe « fact: » est arbitraire. On peut changer le nom du préfixe, car
seul l’URI identifie de façon unique l’espace de noms. Par exemple, le document XML
suivant est équivalent à celui que nous venons de décrire.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<facture:facture xmlns:facture="http://www.domaine.com/facture">
<facture:montant>10$</facture:montant>
<facture:nom>Jean</facture:nom>
</facture:facture>
On peut aussi redéfinir un préfixe comme dans l’exemple qui suit :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<facture:facture xmlns:facture="http://www.domaine.com/facture">
CC BY-NC-SA
Module 1 : Introduction à XML
58
<facture:montant xmlns:facture="http://www.domaine.com/facture2">
10$</facture:montant>
<facture:nom>Jean</facture:nom>
</facture:facture>
Dans ce dernier cas, on dira que l’élément « montant » est dans l’espace de
noms « http://www.domaine.com/facture2 » et non pas dans l’espace de noms
« http://www.domaine.com/facture ». Tout élément et attribut, utilisant le préfixe
« facture » dans l’élément « montant », seraient eux aussi dans l’espace de noms
« http://www.domaine.com/facture2 ».
L’endroit où apparaît la déclaration d’espace de noms est aussi sans conséquence. Par
exemple, les deux documents suivants sont équivalents :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<enveloppe xmlns:facture="http://www.domaine.com/facture">
<facture:facture >
<facture:montant>10$</facture:montant>
<facture:nom>Jean</facture:nom>
</facture:facture>
</enveloppe>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<enveloppe>
<facture:facture xmlns:facture="http://www.domaine.com/facture">
<facture:montant>10$</facture:montant>
<facture:nom>Jean</facture:nom>
</facture:facture>
</enveloppe>
On dit que deux documents sont équivalents, au sens des espaces de noms, s’ils ne
diffèrent que par les préfixes d’espaces de noms et par les endroits où apparaissent les
déclarations d’espaces de noms.
Évidemment, avec les espaces de noms, on peut combiner plusieurs vocabulaires. Par
exemple, si nous voulons décrire une commande en utilisant les vocabulaires « facture »
et « expedition », on peut très bien le faire comme le montre l’exemple suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<facture xmlns:fact="http://www.domaine.com/facture">
<fact:montant>10$</fact:montant>
<fact:nom>Jean</fact:nom>
<exp:expedition xmlns:exp="http://www.domaine.com/expedition">
<exp:nom>
<exp:prenom>Jean</exp:prenom>
<exp:nomfamille>Bertrand</exp:nomfamille>
CC BY-NC-SA
Espaces de noms
59
<exp:adresse>1040, rue Jean</exp:adresse>
</exp:nom>
</exp:expedition>
</facture>
En outre, on pourrait même combiner les espaces de noms de façon arbitraire comme
le montre le prochain exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
<fact:montant>10$</fact:montant>
<exp:nom xmlns:exp="http://www.domaine.com/expedition">
<exp:prenom>Jean</exp:prenom>
<exp:nomfamille>Bertrand</exp:nomfamille>
<exp:adresse>1040, rue Jean</exp:adresse>
</exp:nom>
</fact:facture>
1.8.8
Les déclarations croisées
La déclaration d’espace de noms n’est valable qu’au sein de l’élément. Pour déterminer l’espace de nom auquel appartient un élément, il ne suffit donc pas de remonter
et de s’arrêter à la première déclaration que l’on trouve. Voyez si vous pouvez voir
pourquoi l’espace de nom de l’élément « fact:montant » dans l’exemple suivant est
« http://www.domaine.com/facture » et non « http://www.domaine.com/facture2 ».
<?xml version="1.0" encoding="ISO-8859-1" ?>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
<fact:facture xmlns:fact="http://www.domaine.com/facture2">
</fact:facture>
<fact:montant />
</fact:facture>
1.8.9
Le préfixe par défaut
On peut utiliser le préfixe par défaut, c’est-à-dire ne pas mettre de préfixe du tout.
L’utilisation du préfixe par défaut est optionnelle dans un document XML. Comme
tout autre préfixe, le préfixe par défaut peut être réutilisé, redéfini plusieurs fois dans
un même document. Voici un exemple de préfixe par défaut :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
<fact:montant>10$</fact:montant>
CC BY-NC-SA
Module 1 : Introduction à XML
60
<nom xmlns="http://www.domaine.com/expedition">
<prenom>Jean</prenom>
<nomfamille>Bertrand</nomfamille>
<adresse>1040, rue Jean</adresse>
</nom>
</fact:facture>
Notons cependant que le préfixe par défaut ne s’utilise que pour les éléments : les
attributs sans préfixe ne sont dans aucun espace de noms, et cela sans exception.
1.8.10
Rappel des notions formelles
La définition d’un préfixe d’espace de noms inclut l’élément où le préfixe est défini et
tout son contenu, et rien d’autre. Le document qui suit fait une utilisation incorrecte
des espaces de noms :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<expedition>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
</fact:facture>
<fact:nom></fact:nom>
</expedition>
parce que le préfixe « fact » n’est défini qu’au sein de l’élément « facture ».
Bien que cela ne soit pas recommandable, il est possible de redéfinir les préfixes d’espace de noms. C’est simple si l’on se rappelle que la définition d’un préfixe inclut
l’élément où la définition est faite. Ainsi, dans l’exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<expedition>
<fact:facture xmlns:fact="http://www.domaine.com/facture">
<fact:nom xmlns:fact="http://www.domaine.com/nom"></fact:nom>
</fact:facture>
</expedition>
l’élément « nom » appartient à l’espace de noms « http://www.domaine.com/nom » et
non à l’espace de noms « http://www.domaine.com/facture ».
Par convention, on doit toujours accorder à un préfixe d’espace de noms un
URI et il serait incorrect d’écrire <fact:facture /> au lieu de <fact:facture
xmlns:fact="http://www.domaine.com/facture"> dans l’exemple précédent.
CC BY-NC-SA
Espaces de noms
1.8.11
61
Les espaces de noms et Relax NG
Alors que les DTD ne permettent pas de traiter les espaces de noms, les spécifications
Relax NG et XML Schema le permettent. L’utilisation des espaces de noms en Relax
NG est particulièrement simple comme le montre cet exemple.
namespace fact = "http://www.domaine.com/facture"
namespace fact2 = "http://www.domaine.com/facture2"
element fact:facture {
element fact:nom {text},
element fact:montant {text},
element fact2:id {text}
}*
}
Le document XML suivant sera alors valable.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<f:facture xmlns:f="http://www.domaine.com/facture">
<f:nom>Daniel</f:nom>
<f:montant>10,80$</f:montant>
<f2:id xmlns:f2="http://www.domaine.com/facture2">10,80$</f2:id>
</f:facture>
Par défaut, il n’y a pas d’espace de noms lorsqu’un préfixe n’est pas utilisé, mais on
peut définir l’espace de noms par défaut comme ceci :
namespace fact = "http://www.domaine.com/facture"
default namespace = "http://www.domaine.com/facture2"
element fact:facture {
element fact:nom {text},
element fact:montant {text},
element id {text}
}*
}
Les deux exemples précédents de Relax NG sont d’ailleurs équivalents.
1.8.12
Le préfixe « xml »
Par convention, le préfixe « xml » est réservé à des applications telles que la
déclaration de la langue utilisée (« xml:lang ») ou le traitement des espaces
CC BY-NC-SA
Module 1 : Introduction à XML
62
(« xml:space »). Il n’est pas nécessaire d’y associer explicitement un URI : l’URI
« http://www.w3.org/XML/1998/namespace » y est automatiquement associé.
1.8.13
Rappel : des espaces de noms pour les attributs?
Les choses se corsent un peu quand on considère les attributs. Alors qu’un élément sans
préfixe tombe dans l’espace de noms par défaut si celui-ci a été défini par un attribut
« xmlns="..." », ce n’est pas le cas pour les attributs. Un attribut sans préfixe n’est dans
aucun espace de noms; pour y être, un attribut doit être muni d’un préfixe.
1.8.14
En résumé, qu’est-ce que les espaces de noms?
Une DTD définit un ensemble fixe d’éléments, ensemble qui ne peut être recombiné avec d’autres DTD; c’est un instrument rigide. Par contre, les espaces de noms
permettent de recombiner des éléments provenant de différentes applications; ils permettent donc une grande flexibilité.
Alors que la DTD définit des éléments et comment les utiliser ensemble, les espaces de
noms ne permettent d’établir qu’un lien entre un élément et un URI, mais sans indiquer
les contraintes d’utilisation.
1.9
1.9.1
Travail noté 1
Objectifs et pondération
Ce travail compte pour 10 % de la note globale du cours.
Ce travail contribue à l’évaluation des objectifs suivants :
– Utiliser un « vocabulaire » ou une application XML avec vocabulaire XML pour
présenter des informations dans le format XML.
– Déterminer si un document XML est bien formé ou valable.
– Interpréter des fichiers XML utilisant des espaces de noms.
Les sept premières questions du travail valent 2,5 points chacune, la huitième vaut 3,5
points; la neuvième question vaut 9 points, la dixième et la onzième valent 5 points
chacune. Ce premier travail noté permet d’obtenir 40 points et compte pour 10 % de la
note globale.
1.9.2
Consignes
Il est recommandé d’avoir terminé les activités d’autoévaluation du premier module
avant de faire le travail noté.
CC BY-NC-SA
Travail noté 1
63
Vous devez remettre à la personne tutrice, par courriel et en fichier attaché, un document
(Word 97/2000/XP, ODF, PDF, RTF ou en format texte) clairement identifié à votre
nom. Indiquez également votre numéro d’étudiant (8 chiffres), la date du travail, le
nom de la personne tutrice, avec les mentions « Travail noté 1 » et « INF 6450 ».
Ne transmettez pas vos solutions en plusieurs fichiers. Ne transmettez pas une
archive compressée (zip ou autre). Il s’agit d’un travail personnel et vous ne devez
pas partager vos réponses.
L’objet de votre courriel doit commencer par « [INF6450][TRAVAIL1] »; dans
le message, indiquez votre nom, votre numéro d’étudiant (8 chiffres), la date de
remise de votre travail et le nom de votre personne tutrice, ainsi que les mentions
« Travail noté 1 » et « INF 6450 ».
Lorsque le contenu d’un document XML fait partie d’une question, vous devez
supposer que le document débute avec le premier caractère et se termine avec le
dernier : il n’y a pas d’espace ou de retour de chariot, ni au début ni à la fin des
fichiers XML, mais tous les autres espaces ou retours de chariot comptent. Vous
devez également supposer que les documents ne sont pas enregistrés avec la norme
UTF-8 ou UTF-16, mais plutôt avec un outil banal comme le Bloc-notes qui sélectionne
par défaut un jeu de caractères similaire à ISO-8859-1.
Bon travail!
Question 1
Soit le document XML suivant :
<conf xml:space="preserve">
<unite groupe="universite" temps="1086585433" maison="Jean" >
Davantage l’an prochain.
</unite>
<maison/>
</conf>
1. Quel est le nom de l’élément-racine ?
2. Combien d’éléments compte ce document ?
3. Combien y a-t-il de balises dans ce document ?
4. Combien y a-t-il de nœuds de texte dans ce document ?
5. Combien d’attributs trouve-t-on dans ce document ?
Question 2
Soit le document XML suivant :
CC BY-NC-SA
Module 1 : Introduction à XML
64
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!DOCTYPE _ [
<!ENTITY % administration "Jeanne Perron" >
<!ENTITY administration "Jean Boudin">
<!ELEMENT _ (president,comptable,adjoint)*>
<!ELEMENT president (#PCDATA)>
<!ELEMENT comptable (#PCDATA)>
<!ELEMENT adjoint (#PCDATA)>
]>
<_>
<president>&administration;</president>
<comptable>&administration;</comptable>
<adjoint>Marion Lepage</adjoint>
</_>
1.
2.
3.
4.
5.
Quel est le nom de l’élément-racine ?
Quel est le contenu de l’élément « president » ?
Quel est le contenu de l’élément « comptable » ?
Est-ce qu’on pourrait omettre l’élément « adjoint » ?
Combien d’éléments « president » peut contenir l’élément-racine ?
Question 3
Soit le document XML suivant :
<?xml version="1.0"?>
<recherche
xmlns="http://www.google.com/" xmlns:yahoo="http://www.yahoo.com/">
<mots-clefs
xmlns="http://www.yahoo.com/">fraise, orange</mots-clefs>
<yahoo:mot
xmlns:yahoo2="http://www.yahoo.com/"><nombre>3</nombre>
</yahoo:mot>
</recherche>
1. À quel espace de noms, identifié par son URI, est-ce que l’élément « mots-clefs »
appartient?
2. À quel espace de noms, identifié par son URI, est-ce que l’élément « recherche »
appartient?
3. À quel espace de noms, identifié par son URI, est-ce que l’élément « yahoo:mot »
appartient?
4. À quel espace de noms, identifié par son URI, est-ce que l’élément « nombre »
appartient?
5. Combien y a-t-il d’espaces de noms dans ce document?
CC BY-NC-SA
Travail noté 1
65
Question 4
En utilisant un navigateur comme Mozilla Firefox, il est possible de déterminer
si un document XML est bien formé. Dans cette question, nous vous demandons
d’expliquer pourquoi les cinq documents présentés ci-dessous ne sont pas bien formés. Notez qu’on ne vous demande pas seulement d’indiquer où se trouve le problème
ou de rapporter le message d’erreur qu’un outil vous donnerait.
Expliquez clairement pourquoi les documents XML suivants ne sont pas bien formés.
1. (Indice. Si Mozilla donne l’erreur suivante « XML Parsing Error: illegal parameter entity reference », expliquez ce que cela signifie!)
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!DOCTYPE compagnie [
<!ENTITY % administration "(president,comptable,adjoint)" >
<!ELEMENT compagnie ( %administration;*)>
<!ENTITY administration "Jean Boudin">
<!ELEMENT president (#PCDATA)>
<!ELEMENT comptable (#PCDATA)>
<!ELEMENT adjoint (#PCDATA)>
]>
<compagnie>
<president>&administration;</president>
<comptable>&administration;</comptable>
<adjoint>Marion Lepage</adjoint>
</compagnie>
2. <?xml version="1.0" ?>
<cours>
<professeur>Éric Beaudin</professeur>
<trimestre>automne</trimestre>
<titre>Introduction aux affaires</titre>
</cours>
3. <client>
<nom>AWS Inc.</nom>
<type>SMS5SB11</type>
<province>QC</province>
<site>http://domaine.com/cgi-bin/script.pl?box=sms5sb11&option=B</site>
</client>
4. <?xml version="1.0" encoding="ISO-8859-1"
<maison cout$="125000">
<adresse>124, rue Rochond</adresse>
</maison>
?>
5. <?xml version="1.0" encoding="ISO-8859-1"
?>
CC BY-NC-SA
Module 1 : Introduction à XML
66
<personne>
<prenom>Jean</prenom>
</personne>
<personne>
<prenom>Jeanne</prenom>
</personne>
Question 5
Trouvez les 5 erreurs de validation du document suivant :
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE université [
<!ELEMENT université (faculté*,description*)*>
<!ELEMENT faculté (département*)>
<!ELEMENT département EMPTY>
<!ATTLIST département nom CDATA #REQUIRED
xmlnote (vide|plein) "plein">
<!ATTLIST université téléphone ID #REQUIRED>
]>
<université téléphone="514-4321" xml:lang="fr">
<description>La plus grande.</description>
<faculté nom="sciences">
<département nom="mathématiques">
</département>
<département nom="sociologie" xmlnote="vide"/>
</faculté>
</université>
Question 6
Soit le document DTD suivant :
<!ELEMENT cours (module*) >
<!ELEMENT module (#PCDATA) >
<!ATTLIST module nom CDATA #REQUIRED
optionnel (vrai|faux) "faux">
Il est situé à l’adresse « cours.dtd ». Écrivez un document XML pour décrire un cours
de 3 modules qui s’intitulent respectivement : « 1. La vie sous-marine », « 2. La vie
extraterrestre » et « 3. La vie supraterrestre ». Seul le troisième module est optionnel.
Votre document XML doit être valable.
CC BY-NC-SA
Travail noté 1
67
Question 7
Un document XML « normalisé » est tel que seul l’élément-racine contient des déclarations d’espace de noms. Écrivez un document XML qui soit équivalent à celui qui
suit, au sens des espaces de noms : seul l’élément-racine contiendra des déclarations
d’espace de noms.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<lettre xmlns="http://macompagnie.com/expedition">
<recipiendaire>
Jeanne Rigault
</recipiendaire>
<facture xmlns="http://macompagnie.com/comptabilite">
<recipiendaire>
Jean Perron
</recipiendaire>
<expediteur>
MaCompagnie.com
</expediteur>
<montant xml:space="preserve">
850$
</montant>
</facture>
<expediteur>
Daniel Legault
</expediteur>
</lettre>
Question 8
Même question.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<a xmlns="http://www.a.b/a" x="a">
<b xmlns="http://www.a.b/b" x="a">
<c xmlns="http://www.a.b/c" x="a">
<d x="a"/>
</c>
</b>
</a>
CC BY-NC-SA
Module 1 : Introduction à XML
68
Question 9
Produisez un document XML contenant une DTD interne codifiant les spécifications
suivantes; dans le cas où les DTD ne permettent pas de codifier une spécification, vous
devez l’ignorer.
Nous voulons représenter un annuaire (élément nommé « annuaire ») contenant aucun, une seule ou plusieurs personnes (élément nommé « personne »). L’élément « annuaire » peut avoir un attribut nommé « titre ». Les éléments « personne » sont constitués, dans l’ordre, d’un élément « nom » contenant du texte, d’un élément « prenom »
contenant du texte, d’un ou plusieurs éléments « courriel » contenant du texte, d’un
élément optionnel « commentaire » contenant du texte, et de un ou plusieurs éléments
« ami » devant être vide, soit sans aucun contenu.
Les éléments « personne » ont deux attributs, un attribut « type » qui peut prendre les
valeurs « étudiant », « professeur », « tuteur » et « cadre » avec « étudiant » comme
valeur par défaut, et un attribut obligatoire « nas » qui doit servir d’identifiant unique.
Les éléments « ami » ont un attribut « nas » qui doit correspondre à la valeur d’attribut
« nas » d’un des éléments « personne ».
Question 10
Un document DTD a été proposé par John Shipman pour présenter des recettes de
cuisine (« recipe » est « recette » en anglais, alors qu’on pourrait traduire librement
« subrecipe » par « sous-recette » et « narrative » par « description textuelle », puis
« time » par « durée », comme dans « temps de cuisson ») :
<!ENTITY % narrative "(ingredients | para)+">
<!ELEMENT recipe (title, author?,
(subrecipe+ | section+ | %narrative;))>
<!ELEMENT subrecipe (title?, (section+ | %narrative;))>
<!ELEMENT title (#PCDATA)>
<!ATTLIST title
original
CDATA
#IMPLIED
>
<!ELEMENT section %narrative;>
<!ATTLIST section
title
CDATA
#IMPLIED
>
<!ELEMENT author (#PCDATA)>
<!ATTLIST author
source
CDATA
#IMPLIED
>
<!ELEMENT para (#PCDATA|time)* >
<!ATTLIST para
title
CDATA
#IMPLIED
>
CC BY-NC-SA
Travail noté 1
69
<!ELEMENT time (#PCDATA)>
<!ELEMENT ingredients (item+)>
<!ELEMENT item (#PCDATA)>
Supposons que cette DTD est disponible à l’URL
http://infohost.nmt.edu/tcc/help/xml/recipes/recipe.dtd
Sur la base de cette DTD, produisez un document XML valable pour présenter une recette de votre choix. Il n’est essentiel qu’il s’agisse d’une vraie recette. Votre document
XML doit utiliser tous les éléments et attributs définis par le document DTD. Vous devrez peut-être imaginer une recette un peu compliquée! Votre document doit avoir une
déclaration XML et utiliser au moins un accent.
Question 11
Quel est l’équivalent en DTD du fichier Relax NG suivant ?
carte = element carte { attribute courriel { text }, text }
page = element page { text }
livre = element livre { (carte | page?) }
CC BY-NC-SA
Module 2 : XML en tant que
syntaxe pour les documents
2.1
2.1.1
Aperçu
Objectifs
À la fin de ce module, vous devriez avoir approfondi votre compréhension du XML
à l’aide d’exemples et mieux voir le rôle qu’il peut jouer dans votre organisation. En
effet, il n’est pas suffisant de savoir ce qu’est le XML en tant que métalangage, il faut
également comprendre d’où il vient et quel rôle il joue dans son domaine de prédilection : le web. L’objectif spécifique du module est :
– Traduire, au sein de son organisation, sa compréhension du XML dans la gestion des
informations.
Pour atteindre cet objectif, nous vous proposons deux activités notées, soit une discussion de groupe sur le marquage sémantique et la rédaction d’un texte en utilisant le
XML. Les lectures et les activités d’autoévaluation de ce module servent à alimenter et
à préparer les activités notées.
2.1.2
Démarche
Vous devez effectuer les lectures de ce module avant de passer aux modules suivants.
Nous vous invitons à procéder à l’étude de ce module dans l’ordre suivant :
– Introduction au XHTML, MathML et SVG
– XML comme format de documents (SGML, DocBook, ODF)
– XML sur le web
S’il y a lieu, vérifiez vos connaissances en répondant au questionnaire d’autoévaluation.
71
Module 2 : XML en tant que syntaxe pour les documents
72
Par ailleurs, à partir du moment où vous commencez l’étude du module 2, vous pouvez
entreprendre le travail noté 2, soit l’activité de discussion en groupe dans le forum, laquelle peut s’étendre sur tout le cours (participation au forum). Vous pouvez toutefois
commencer cette discussion (travail noté 2) plus tard dans le cours. Par contre, le
module se termine par le travail noté 3, soit la rédaction d’un texte avec XML, que vous
devez réaliser avant de passer au module suivant.
Le pense-bête offre un rappel du HTML; dans la version imprimée du cours, il se trouve
en annexe.
2.2
2.2.1
Introduction au XHTML
Objectif
Connaître les notions de base du XHTML.
2.2.2
Activité
Lisez le texte qui suit, avant de lire les deux autres suggérés dans ce module. C’est un
impératif pour bien progresser dans votre apprentissage du XML.
2.2.3
Qu’est-ce que le XHTML?
Le HTML a été inventé par Tim Berners-Lee, alors qu’il travaillait pour le centre de
recherche CERN en Suisse. L’intention de Berners-Lee était de proposer un système révolutionnaire de gestion de l’information qu’il appela World Wide Web. Comme pièce
maîtresse de son architecture, il avait besoin d’un format de documents qu’il appela
HTML (HyperText Markup Language). La première page web, dont l’adresse était
http://nxoc01.cern.ch/hypertext/WWW/TheProject.html, vit le jour en 1990.
Le HTML est un langage à base de balises, un peu comme une application XML. En
fait, il existe une application XML appelée XHTML, qui est à la fois du HTML et
du XML. Le document que vous lisez en ce moment en est un exemple. En effet, le
document que vous lisez est à la fois du XML bien formé et valable, mais aussi
du HTML.
Rappelons qu’une « application XML » est un ensemble de balises et d’attributs, c’està-dire un vocabulaire XML, avec des conventions d’usage dont certaines peuvent être
représentées par un document DTD.
La très grande majorité des documents sur le web sont écrits en HTML et, de plus en
plus, en XHTML. Une des raisons principales de l’utilisation du XHTML, c’est que
les outils qui traitent le XML peuvent aussi traiter du XHTML puisque ce dernier est
aussi du XML. Il est donc possible, dans une organisation, de combiner le contenu
CC BY-NC-SA
Introduction au XHTML
73
web (HTML) avec le stockage des informations en XML. Comme nous le verrons plus
tard dans le cours (module 3, section portant sur le XSLT), on peut même transformer
automatiquement le XML en XHTML.
Si on dit « HTML » tout court, ce n’est pas nécessairement du XML et il se peut que
les outils conçus pour le XML ne puissent être utilisés pour le traiter. Cependant, si
on dit « XHTML », alors il s’agit à la fois de HTML et de XML et on peut utiliser
les outils destinés au XML pour en traiter le contenu. Voici quelques différences entre
le HTML et le XHTML :
Les serveurs web distinguent le contenu en fournissant aux navigateurs différents
codes MIME (Multipurpose Internet Mail Extensions), alors que le HTML a le code
MIME « text/html », on utilise le code MIME « application/xml » ou « application/xhtml+xml » pour le XHTML. Avec le serveur web Apache, on obtient le résultat
désiré en ajoutant un fichier « .htaccess », dans le même répertoire que nos fichiers
XHTML, contenant la ligne « AddType application/xml .xhtml ».
– En HTML traditionnel, on n’a pas à fermer les éléments. Ainsi, le code suivant
« <p><i>texte</p> » est acceptable en HTML, mais en XHTML, il faut écrire
« <p><i>texte</i></p> ».
– Les valeurs d’attributs en HTML n’ont pas à être entre des guillemets ou apostrophes. Ainsi, le code « <table border=0> » est acceptable en HTML, mais en
XHTML, il faut écrire « <table border="0"> ».
– En HTML, la casse des noms est sans importance. Ainsi, on peut remplacer « <p> »
par « <P> », alors que ce n’est pas permis en XHTML.
Dans ce cours, nous nous intéresserons surtout au XHTML. Un document XHTML
prend la forme suivante :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
Voici mon document.
</body>
</html>
On reconnaît d’abord la déclaration XML qui n’a rien de particulier : <?xml version="1.0" encoding="ISO-8859-1" ?>. Comme pour tout document XML, on peut
omettre la déclaration XML d’un document XHTML, mais si nous voulons écrire en
français avec des lettres accentuées, il est nettement préférable d’avoir la déclaration
XML de notre exemple.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
74
On reconnaît ensuite la déclaration de type de document : <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd">. Observez qu’elle apparaît sur deux lignes, que c’est souvent le cas, mais
que c’est un choix purement esthétique. La déclaration de type de document est un peu
particulière : il s’agit d’une déclaration utilisant un identifiant public. On doit utiliser
un tel identifiant quand on veut signifier qu’il s’agit d’une application XML commune;
on évite ainsi que des milliers de personnes aillent chercher des documents DTD à
l’adresse « http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ». On s’attend qu’un
logiciel qui dépend d’une application XML commune n’ait pas besoin d’aller chercher
les documents DTD, chaque fois que le document XML est lu. Un navigateur comme
Firefox ne tient pas compte de la DTD externe, on peut donc omettre la déclaration
DOCTYPE sans problème.
Le reste du document est simplement un élément-racine « html » contenant deux
éléments : un élément head et un élément body. L’élément head doit contenir un
élément title, alors que l’élément body peut être vide, mais peut aussi posséder du
contenu XML mixte (texte et diverses balises XHTML). L’espace de nom ayant l’URI
« http://www.w3.org/1999/xhtml » est utilisé.
Si vous copiez le texte qui précède dans un éditeur de texte comme Bloc-notes et que
vous enregistrez le fichier sous un nom comme « test.xhtml », vous devriez être capable
d’ouvrir le fichier dans votre navigateur et de voir le texte « Voici mon document. »
s’afficher à l’écran. Les documents HTML sont tous des documents en format texte et
l’extension du fichier est arbitraire : on utilise tout aussi bien « .htm » que « .html »,
« .xhtml » ou même « .xml ». L’avantage de l’extension « .xhtml » est d’informer
le navigateur qu’il s’agit d’un document XHTML, donc un document HTML et un
document XML.
2.2.4
La structure du document XHTML : head et body
Comme nous le disions, l’élément-racine d’un document XHTML est nommé « html ».
Cet élément contient deux et exactement deux sous-éléments : head et body. L’élément head n’est pas affiché directement dans le navigateur et contient des métadonnées,
c’est-à-dire une description du contenu. Un élément head doit au minimum contenir
un élément title qui donne le titre du document XHTML. Par la suite, l’élément body
contient un ensemble de balises et du texte (contenu mixte) qui sera affiché directement
dans le navigateur.
2.2.5
Les paragraphes en HTML
L’élément body contient des balises et du texte. Les retours de ligne sont traités comme
des espaces normaux. Ainsi, les deux documents suivants seront affichés de la même
manière par un navigateur.
<?xml version="1.0" encoding="ISO-8859-1" ?>
CC BY-NC-SA
Introduction au XHTML
75
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
Voici mon document.
Voici ma vie.
Voici mon chat.
</body>
</html>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
Voici mon document.
Voici ma vie.
Voici mon chat.
</body>
</html>
La question qui se pose alors est : Comment faire des paragraphes? En effet, dans
les deux documents plus haut, le texte s’affichera sur une seule ligne (vous pouvez
le tester!). La solution consiste à utiliser l’élément « p » pour « paragraphe ». Pour
avoir trois paragraphes, on remplace le document HTML précédent par celui qui suit.
Observez que chaque balise « p » ouverte doit être fermée.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
<p>Voici mon document.</p>
<p>Voici ma vie.</p>
<p>Voici mon chat.</p>
</body>
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
76
</html>
2.2.6
Les listes en HTML
Supposons que l’on veuille faire une liste, comme ceci :
– Premier point : le chat est noir.
– Second point : le chat est blanc.
– Dernier point : le chat est marron.
On peut obtenir ce résultat avec un élément « ul » pour unordered list (liste sans ordre),
contenant des éléments « li ». Observez que chaque balise « li » ouverte doit être
fermée.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
<ul>
<li>Premier point: le chat est noir.</li>
<li>Second point: le chat est blanc.</li>
<li>Dernier point: le chat est marron.</li>
</ul>
</body>
</html>
Supposons maintenant que nous voulions une liste avec un compteur :
1. Le chat est noir.
2. Le chat est blanc.
3. Le chat est marron.
Il suffit alors de remplacer l’élément « ul » par l’élément « ol » pour ordered list (liste
ordonnée) :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
CC BY-NC-SA
Introduction au XHTML
77
<ol>
<li>Le chat est noir.</li>
<li>Le chat est blanc.</li>
<li>Le chat est marron.</li>
</ol>
</body>
</html>
2.2.7
Les tableaux en HTML
Supposons maintenant que nous voulions produire un tableau. On peut l’obtenir à l’aide
d’un élément « table ». Cet élément contiendra plusieurs éléments « tr » (éléments
correspondant à une ligne) qui eux-mêmes contiennent des éléments « td » (éléments
correspondant à une cellule). Ainsi, pour obtenir un tableau comme celui-ci :
Nom
Valeur
Mustang
50 $
Ferrari
500 $
On utilise le code suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
<table>
<tr>
<td>Nom</td>
<td>Valeur</td>
</tr>
<tr>
<td>Mustang</td>
<td>50 $</td>
</tr>
<tr>
<td>Ferrari</td>
<td>500 $</td>
</tr>
</table>
</body>
</html>
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
78
Supposons maintenant que l’on veuille un tableau avec des lignes pour marquer et
diviser les cellules. Il suffit alors d’utiliser l’attribut « border ». Sa valeur numérique
représente l’épaisseur en pixels de la bordure. Ainsi, pour obtenir ce résultat :
Nom
Valeur
Mustang
50 $
Ferrari
500 $
On utilisera le code XHTML suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
<table border="1">
<tr>
<td>Nom</td>
<td>Valeur</td>
</tr>
<tr>
<td>Mustang</td>
<td>50 $</td>
</tr>
<tr>
<td>Ferrari</td>
<td>500 $</td>
</tr>
</table>
</body>
</html>
Tous les tableaux ne sont pas si simples. On peut faire en sorte qu’une même cellule
occupe deux colonnes (<td colspan="2">) ou deux rangées (<td rowspan="2">). Aussi,
souvent, on utilise l’élément « th » au lieu de l’élément « td » pour désigner la première
rangée d’un tableau lorsque celle-ci forme l’entête descriptive du tableau. Il est aussi
possible d’utiliser un élément « caption » au sein d’un tableau pour noter le titre du
tableau :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
CC BY-NC-SA
Introduction au XHTML
79
</head>
<body>
<table border="1">
<caption>Valeur de différents véhicule</caption>
<tr>
<th>Nom</th>
<th>Valeur</th>
</tr>
<tr>
<td>Mustang</td>
<td>50 $</td>
</tr>
<tr>
<td>Ferrari</td>
<td>500 $</td>
</tr>
</table>
</body>
</html>
2.2.8
Les caractères italiques et gras
On peut très facilement utiliser des effets de polices de caractères en HTML. Pour
obtenir des caractères en italique, par exemple maman, il suffit d’utiliser un élément
« i » comme ceci : <i>maman</i>. Pour des caractères en gras, comme maman,
il suffit d’utiliser un élément « b » comme ceci : <b>maman</b>. On peut également combiner les deux, comme maman, en écrivant <i><b>maman</b></i> ou bien
<b><i>maman</i></b>. Il est cependant préférable d’utiliser « em » (emphase) au lieu
de « i » et « strong » (fort) au lieu de « b » : le navigateur choisira alors de rendre le
texte dans un élément « em » avec un italique ou une autre technique appropriée, et de
rendre le texte dans un élément « strong » en caractères gras ou une autre technique
appropriée. On évite ainsi de confondre la présentation (italique ou gras) et la sémantique (emphase ou point fort). Dans le cas où un terme est défini, vous devriez utiliser
un élément « dfn » (définition) comme dans cet exemple: « La <dfn>mort</dfn> est la
fin de la vie ». La plupart des navigateurs afficheront alors le mot « mort » en caratères
italiques.
2.2.9
Les listes de définitions
Supposons que nous voulions une liste de définitions comme celle qui suit :
Voiture Véhicule sur roues.
Chat Bête sauvage qui se nourrit de lait.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
80
Éléphant Bête sauvage de couleur rose.
On obtient ce résultat en XHTML avec un élément « dl » pour definition list contenant
une série d’éléments « dt » et « dd » en paire, où l’élément « dt » fournit le terme à
définir et l’élément « dd » sa définition.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Titre de mon document</title>
</head>
<body>
<dl>
<dt>Voiture</dt>
<dd>Véhicule sur roues. </dd>
<dt>Chat</dt>
<dd>Bête sauvage qui se nourrit de lait. </dd>
<dt>Éléphant</dt>
<dd>Bête sauvage de couleur rose. </dd>
</dl>
</body>
</html>
2.2.10
Les lignes horizontales
Pour obtenir une ligne horizontale, on utilise l’élément « hr » qui doit être vide. On
doit donc écrire <hr></hr> ou plus simplement <hr />. Voici une ligne horizontale :
2.2.11
Les images
Au moment d’écrire ces lignes, on trouve un logo de l’UQÀM à l’URL
http://www.uqam.ca/img/logo/logo.jpg.
Pour insérer une image dans un document HTML, il suffit d’utiliser une balise « img »
avec comme attribut « src » pour source, soit l’URL. Par exemple, le code
<img src="http://www.uqam.ca/img/logo/logo.jpg"></img>
ou
<img src="http://www.uqam.ca/img/logo/logo.jpg" />
CC BY-NC-SA
Introduction au XHTML
81
permettra d’insérer le logo de l’UQÀM dans un document. Il est préférable de prévoir
que l’image pourrait ne pas être trouvée ou affichée en ajoutant un attribut « alt » qui
contient du texte décrivant le contenu de l’image; si l’image n’est pas disponible, le
texte contenu dans l’attribut « alt » s’affichera. Le résultat final prend la forme <img
src="http://www.uqam.ca/img/logo/logo.jpg" alt="logo de l’UQÀM" /> ce qui donne :
2.2.12
Les hyperliens
Pour inclure un hyperlien, comme dans l’exemple de la page de l’UQÀM
[lien vers http://www.uqam.ca/], il suffit d’utiliser la syntaxe « <a
href="http://www.uqam.ca/">page de l’UQÀM</a> ».
On peut également ajouter des marqueurs dans une page web en utilisant la syntaxe
« <a name="point1">Premier point de mon document</a> ». Contrairement à la syntaxe « <a href="..."> », l’attribut « name » n’ajoute pas un hyperlien, mais un marqueur
généralement invisible dans la page. Par exemple, si la page contient plusieurs sections,
on peut ajouter un marqueur au début de chaque section. On pourra alors faire des liens
non seulement vers le document, mais aussi vers la section marquée dans le document.
Ainsi, l’hyperlien « <a href="pageweb.html#point1">aller vers le premier point du document pageweb.html</a> » mènera l’utilisateur dans le document « pageweb.html »,
précisément au marqueur du « point 1 », s’il existe, évidemment.
2.2.13
Les abbréviations
On utilise parfois des abbréviations dans une page web tel que « etc. » ou « no ».
On peut indiquer au navigateur qu’il s’agit d’une abbréviation avec un élément
abbr comme ceci : « <abbr>no</abbr> ». Il est parfois utile d’utiliser l’attribut « title » pour décrire l’abbréviation en question comme dans ceci : « <abbr
title="numéro">no</abbr> ». De la même façon, on peut noter les acronymes avec
un élément « acronym » comme ceci : « <acronym title="Organisation du traité de
l’Atlantique Nord">OTAN</acronym> ».
2.2.14
Les adresses
Il est fréquent qu’une page web contienne un adresse. Le XHTML nous permet d’indiquer au navigateur qu’il s’agit bien d’une adresse avec l’élément « address », comme
ceci : « <address> Daniel Lemire<br /> 100, rue Sherbrooke </address> ». Ici, l’élément « br » sert à noter un retour de charriot.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
2.2.15
82
Les indices et exposants
Dans un texte, il arrive qu’on veuille utiliser des exposants et des indices. Les éléments
« sup » et « sub » servent à cette fonction. Par exemple, « premier » peut s’écrit « 1er
». Il n’est malheureusement pas possible de noter automatiquement des notes en bas de
page en HTML ou XHTML.
2.2.16
Le code et les exemples
Il y a plusieurs éléments permettant de traiter de la programmation informatique ou des
mathématiques. Le code informatique peut s’écrire dans un élément « code ». Le texte
saisi à l’écran par un utilisateur peut s’écrire dans un élément « kbd ». Les exemples de
sortie à l’écran peuvent s’écrire dans un élément « samp » (pour sample) et les variables
peuvent s’écrire dans un élément « var ». Voici un exemple : « <p>La valeur de la variable <var>i</var> est obtenue avec ce code:</p><code>int i = 1; i+=1</code><p>On
s’attend à ce que l’utilisateur tape <kbd>Yes</kbd> pour oui. Voici un exemple de résultat: <samp>Error!</samp>.</p> ».
2.2.17
Les citations
Pour citer quelqu’un, on peut utiliser un élément « q » lorsqu’il s’agit d’un courte
citation au sein d’un paragraphe ou élément « blockquote » lorsque la citation doit
former un court paragraphe. Plusieurs navigateur mettent automatiquement le contenu
de l’élément « q » entre guillemets et le contenu de l’élément « blockquote » en retrait.
Voici un exemple : « <p> Jean a dit: <q>mon cher!</q>. Par la suite, je lui ai lu ce
texte fatidique.</p><blockquote><p>Oh! Comme la mer a merée! Oh! Comme j’ai
jéjé!</p></blockquote> ».
2.2.18
Les révisions
Les éléments del et ins permettent de noter un retrait et un ajout, respectivement,
comme dans cet exemple: « J’ai <del>marié</del><ins>épousé</ins> ta mère ». Le
navigateur se chargera d’afficher les retraits et les ajouts de manière compréhensible.
2.2.19
La langue
Le XHTML respecte la spécification XML voulant qu’on indique la langue dans laquelle est écrite un texte avec l’attribute « xml:lang ». Cet attribut est optionnel,
mais peut s’avérer pratique. Dans le cas où un texte en langue étrangère est présent dans un paragraphe, on peut utiliser l’élément « span » pour en indiquer la
CC BY-NC-SA
Introduction au XHTML
83
langue. Voici un exemple : « <p xml:lang="fr-CA">Jean aime les <span xml:lang="enUS">computers</span></p> ». L’élément « span » ne sert qu’à nous permettre de sélectionner un texte au sein d’un autre élément.
2.2.20
Les commentaires
Ajouter des commentaires en XHTML est facile. Les commentaires du XML s’appliquent: il suffit de débuter le commentaire par <!-- et de le terminer par -->. Il n’est
pas permis d’inclure au sein d’un commentaire deux tirets (--) ni de terminer un commentaire par un tiret.
2.2.21
Séparation du contenu et de la présentation
Avec le XHTML, on peut contrôler en partie l’apparence du texte, en utilisant des italiques ou en plaçant des bordures dans nos tableaux. Ce contrôle est cependant limité :
on ne peut pas ajuster l’indentation des paragraphes et on ne peut que difficilement
ajuster les marges de la page. Nous verrons au module 3, dans la section sur le CSS,
qu’il existe une façon élégante d’y arriver.
2.2.22
SVG
On utilise de plus en plus la norme Scalar Vector Graphics (SVG) pour dessiner des
figures en utilisant le XML. Le fichier suivant représente un rond jaune avec le texte
« INF 6450 » au centre et deux lignes par dessus formant un X (notez les éléments
« rect », « circle », « text » et « line »). Vous pouvez l’enregistrer sur votre disque et
l’ouvrir avec Firefox (version 2.0 ou mieux). Vous pouvez déjà utiliser le format SVG
avec plusieurs logiciels de bureautique ou tout simplement insérer un élément « svg »
dans un document XHTML.
Voici le code d’une image SVG.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="300" height="300" stroke="black" fill="red"/>
<circle cx="150" cy="150" r="150" stroke="black" fill="yellow"/>
<text x="150" y="150" style="text-anchor: middle">INF 6450</text>
<line x1="0" y1="0" x2="300" y2="300"
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
84
style="stroke:rgb(99,99,99);"/>
<line x1="300" y1="0" x2="0" y2="300"
style="stroke:rgb(99,99,99);"/>
</svg>
Voici le rendu de l’image par votre navigateur.
La signification des divers éléments devraient être claire. L’élément « svg » définit la
planche à dessin avec sa largeur et sa hauteur. L’élément « rect » trace un rectangle à
partir de deux coins opposés (0,0 et 300,300 dans notre exemple) . L’élément « circle »
trace un cercle avec un centre et un rayon donnés. L’élément line trace une ligne
d’un point à un autre. L’élément text inclut du texte à la position donnée. Il est aussi
possible de tracer des ellipses et des formes arbitraires. Il est même possible d’animer
du SVG.
Il est facile d’apprendre le SVG par l’exemple si vous avez des notions de graphisme.
Le site suivant comprend plusieurs exemples instructifs : http://www.w3schools.com/
svg/svg_examples.asp. Vous pouvez aussi utiliser un logiciel de graphisme gratuit
comme Inkscape (disponible sur les plate-formes Apple, Windows et Linux, voir http:/
CC BY-NC-SA
Introduction au XHTML
85
/www.inkscape.org/). Le site mozilla.org comprend une description complète du SVG
(http://developer.mozilla.org/en/docs/SVG) tel qu’il est utilisé dans Firefox.
2.2.23
MathML
De la même façon qu’on peut représenter des graphiques en XML, on peut aussi représenter des formules mathématiques (supporté par Firefox 1.0 ou mieux). La syntaxe
MathML est complexe et nécessite une bonne maîtrise de la typographique mathématique. Les éléments de bases d’une équation MathML sont « mi » (pour les variables
ou fonctions), « mn » (pour les nombres) et « mo » (pour les opérateurs). D’autres
éléments viennent s’ajouter comme « msup » (mise en exposant). On peut insérer un
élément « math » directement dans un fichier XHTML. Il arrive malheureusement que
des polices de caractères manquantes empêchent l’affichage correcte de la formule.
Voici la formule « x2 +x+2 » en MathML.
<math xmlns="http://www.w3.org/1998/Math/MathML">
<msup><mi>x</mi><mn>2</mn></msup>
<mo>+</mo>
<mi>x</mi>
<mo>+</mo><mn>2</mn></math>
x2 + x + 2
Vous pouvez utiliser des outils en ligne tel que itex2MML pour écrire vos équations.
2.2.24
Convertir du HTML mal formé
Dans une organisation, il est fréquent d’avoir à composer avec des sites web qui ne
respectent pas les normes les plus élémentaires. Réécrire le HTML en XHTML peut
sembler une tâche très ardue. Heureusement, il existe des outils gratuits pour corriger du HTML mal formé et générer automatiquement un XHTML valable, comme
par exemple HTMLTidy (http://tidy.sourceforge.net/). Le W3C rend aussi disponible
un outil de vérification en ligne des sites web pour s’assurer de leur conformité avec
les normes (http://validator.w3.org/). Vous pourrez facilement constater que plusieurs
pages à l’UQÀM ne sont pas du HTML valable, y compris certaines pages web de ce
cours !
2.2.25
Spécification Relax NG
Il existe des définitions de type de document officielle pour le XHML, mais elles sont
longues et peu lisible. Sean B. Palmer a écrit une spécification Relax NG pour un sousensemble du XHTML que je reproduis ici avec permission. Je vous invite à vérifier que
vous pouvez en comprendre l’essentiel.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
86
default namespace html = "http://www.w3.org/1999/xhtml"
# Common Attributes
Core.attrs =
attribute
attribute
attribute
attribute
id { xsd:ID }?,
class { text }?,
style { text }?,
title { text }?
I18n.attrs =
attribute xml:lang { text }?,
attribute dir { "ltr" | "rtl" }?
Main.attrs =
Core.attrs, I18n.attrs,
attribute onclick { text }?
# Content Models
BlockMinusForm =
(address | blockquote | del | div.elem | dl | h1 | h2 |
h3 | hr | ins | ol | p | pre | script | table | ul)*
Block = (BlockMinusForm | form)*
InlineMinusMedia =
(a | abbr | br | cite | code | del | em | input | ins |
label | script | span | strong | sub | sup | textarea | text)*
Inline = (InlineMinusMedia | img | object)*
Flow = (Block | Inline)*
# Elements
start = html
html = element html {
I18n.attrs,
head, body
}
head = element head {
I18n.attrs,
attribute profile { text }?,
title, base?, (script* & style* & meta* & link*)
}
CC BY-NC-SA
Introduction au XHTML
87
title = element title {
I18n.attrs,
text
}
base = element base {
attribute href { text },
empty
}
meta = element meta {
I18n.attrs,
attribute content { text }?,
attribute name { text }?,
empty
}
link = element link {
Main.attrs,
attribute href { text }?,
attribute rel { text }?,
attribute type { text }?,
empty
}
style = element style {
I18n.attrs,
attribute type { text },
attribute title { text }?,
text
}
script = element script {
attribute type { text },
attribute src { text }?,
text
}
body = element body {
Main.attrs,
attribute onload { text }?,
Block
}
div.elem = element div {
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
88
Main.attrs,
Flow
}
p = element p {
Main.attrs,
Inline
}
h1 = element h1 {
Main.attrs,
Inline
}
h2 = element h2 {
Main.attrs,
Inline
}
h3 = element h3 {
Main.attrs,
Inline
}
ul = element ul {
Main.attrs,
li+
}
ol = element ol {
Main.attrs,
li+
}
li = element li {
Main.attrs,
Flow
}
dl = element dl {
Main.attrs,
(dt, dd+)+
}
dt = element dt {
Main.attrs,
CC BY-NC-SA
Introduction au XHTML
89
Inline
}
dd = element dd {
Main.attrs,
Flow
}
address = element address {
Main.attrs,
Inline
}
hr = element hr {
Main.attrs,
empty
}
pre = element pre {
Main.attrs,
InlineMinusMedia
}
blockquote = element blockquote {
Main.attrs,
attribute cite { text }?,
Block
}
ins = element ins {
Main.attrs,
attribute cite { text }?,
Flow
}
del = element del {
Main.attrs,
attribute cite { text }?,
Flow
}
a = element a {
Main.attrs,
attribute href { text }?,
attribute rel { text }?,
(text & img* & span*)
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
90
}
span = element span {
Main.attrs,
Inline
}
br = element br {
Core.attrs,
empty
}
em = element em {
Main.attrs,
Inline
}
strong = element strong {
Main.attrs,
Inline
}
code = element code {
Main.attrs,
Inline
}
cite = element cite {
Main.attrs,
Inline
}
abbr = element abbr {
Main.attrs,
Inline
}
sub = element sub {
Main.attrs,
Inline
}
sup = element sup {
Main.attrs,
Inline
}
CC BY-NC-SA
Introduction au XHTML
91
object = element object {
Main.attrs,
attribute data { text }?,
attribute type { text }?,
Flow
}
img = element img {
Main.attrs,
attribute alt { text },
attribute src { text },
attribute height { text }?,
attribute width { text }?,
empty
}
form = element form {
Main.attrs,
attribute action { text },
attribute method { text }?,
BlockMinusForm
}
label = element label {
Main.attrs
}
input = element input {
Main.attrs,
attribute type { "text" | "submit" | "hidden" },
attribute name { text }?,
attribute size { text }?,
attribute value { text }?,
empty
}
textarea = element textarea {
Main.attrs,
attribute cols { text },
attribute rows { text },
attribute name { text }?,
text
}
table = element table {
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
92
Main.attrs,
caption?, tr+
}
caption = element caption {
Main.attrs,
Inline
}
tr = element tr {
Main.attrs,
(th | td)+
}
th = element th {
Main.attrs,
Flow
}
td = element td {
Main.attrs,
Flow
}
2.2.26
HTML 5
Une nouvelle spécification du XHTML et du HTML appelée HTML 5 est en préparation. Elle est compatible avec les syntaxes HTML 4 et XHTML qu’elle vise à remplacer. Un document HTML 5 peut prendre la forme d’un document XML ou d’un
document HTML. La déclaration doctype n’est utilisée que dans le cas où le document
n’est pas un document XML et a été grandement simplifiée : il suffit d’inclure la ligne
<!DOCTYPE html> au début du fichier. Voici un exemple de document HTML 5 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Ceci est un exemple</title>
</head>
<body>
<p>Voici un paragraphe.</p>
</body>
</html>
Un document HTML 5 en XML ne nécessite pas de déclaration doctype :
CC BY-NC-SA
Introduction au XHTML
93
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ceci est un exemple</title>
</head>
<body>
<p>Voici un paragraphe.</p>
</body>
</html>
En HTML 5, on n’utilise plus les éléments acronym et plusieurs autres éléments moins
utiles (basefont, big, center, s, strike, tt, u, frame, frameset, noframe, applet, isindex,
dir). Plusieurs nouveaux éléments ont été ajoutés notamment les éléments section et
article. On peut aussi ajouter une figure à un document avec une légende:
<figure>
<img src="image.png" />
<legend>Exemple d’image</legend>
</figure>
Les éléments canvas, video et audio sont aussi ajoutés : le HTML devient pleinement
multimédia.
2.2.27
Conclusion
Le XHTML est un vocabulaire XML. Vous pouvez en consulter la DTD en ligne, à
l’adresse http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd; il ne s’agit pas d’une
DTD facile à lire, mais elle est néanmoins disponible. Notez qu’il existe de très bons
livres de référence pour approfondir le XHTML, mais pour ce cours, il suffit de
connaître les quelques balises présentées dans ce document.
Un des avantages importants du XHTML sur des pages web traditionnelles (souvent
mal formées) est qu’on peut facilement traiter des pages XHTML avec des outils destinés au XML. Par exemple, à partir des pages XHTML et XML de ce cours, j’ai pu
créer automatiquement une version PDF du cours. En somme, on peut plus facilement
extraire et traiter l’information d’une page XHTML que l’on peut le faire d’une page
HTML mal formée.
Pour avoir une vue d’ensemble des notions étudiées, consultez le pense-bête sur
le HTML.
2.2.28
Livres de référence
– Jennifer Robbins, HTML and XHTML Pocket Reference, O’Reilly Media, 2006, 97
pages.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
94
– Jean Engels, XHTML et css : cours et exercices, Eyrolles, 2006.
2.2.29
Activité d’autoévaluation
Afin de vous assurez d’avoir bien compris les notions présentées dans cette leçon,
vous devez créer un document XHTML valable, utilisant les différents éléments que
nous avons étudiés. Afin que votre navigateur reconnaisse le document comme étant
du XHTML, vous devriez utiliser l’extension « xthml ». Si vous déposez le fichier sur
un serveur web Apache, il peut être nécessaire de créer aussi un fichier « .htaccess »
et de le déposer dans le même répertoire que votre fichier XHTML afin que le serveur
puisse reconnaître les fichiers XHTML. Votre fichier « .htaccess » pourrait avoir le
contenu suivant :
DirectoryIndex index.xhtml index.html index.php index.pl index.cgi
AddType application/xml .xhtml
2.3
2.3.1
XML comme format de documents
Objectif
Comprendre le XML comme format de documents.
2.3.2
Activité
Après avoir lu Introduction au XHTML, lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation.
Ce texte porte sur plusieurs formats de documents avec balises. D’abord, il y a le
HTML que nous avons présenté, qui est un format de documents pour le web; et comme
nous l’avons vu, il existe une version XML du HTML, appelée XHTML, qui est à la
fois du XML et du HTML.
2.3.3
Le SGML (Standardized General Markup Language)
En 1969, Charles Goldfarb, Edward Mosher et Raymond Lorie ont inventé le
GML (Generalized Markup Language). Chercheurs chez IBM, ils voulaient faciliter
l’échange d’informations entre les outils d’édition, de formatage et de recherche de
documents. Le GML possédait déjà un concept de « type de documents » similaire
aux documents DTD modernes. Chez IBM, le GML a été utilisé pour la production
d’environ 90 % des documents électroniques.
CC BY-NC-SA
XML comme format de documents
95
En 1978, l’American National Standards Institute (ANSI) a travaillé sur un projet de
langage de description de textes, basé sur le GML; le projet s’est terminé en 1985 par
la normalisation du SGML. Le centre de recherche CERN a été l’une des premières
institutions, outre IBM, à mettre au point des outils pour le SGML.
On dit souvent que le SGML est l’ancêtre du XML, dans la mesure où les créateurs
du XML connaissaient le SGML et voulaient faire mieux. Le HTML est aussi fortement inspiré du SGML et existait au moment où le XML a été proposé. Il n’est donc pas
surprenant que le XML et le HTML se ressemblent et puissent même se retrouver dans
un seul format, le XHTML. La principale difficulté avec le SGML est sa complexité.
On considère généralement que partout où le SGML était utilisé, il est maintenant préférable d’utiliser le XML. Comme les deux normes sont similaires, on migre souvent
du SGML au XML. Quoiqu’il y ait de petits ennuis de conversion, le passage au XML
permet de traiter les nouveaux documents avec les nombreux outils XML et de suivre
la tendance.
Le SGML n’est pas très différent du XHTML. Par exemple, les paragraphes sont spécifiés avec des éléments « para » de la même façon qu’ils sont spécifiés avec des éléments
« p » en XHTML.
2.3.4
Le XML comme format de documents
Notons que le SGML, le HTML et le XML sont avant tout des formats de documents.
On utilise maintenant le XML comme outil de programmation pour stocker et pour
échanger des informations entre les logiciels; toutefois, l’objectif des créateurs du XML
n’était que de créer un format de documents simple et pratique.
Pour les documents, un des avantages des nombreux formats basés sur le XML ou
le SGML est qu’ils « décrivent l’information » au lieu de la présenter. Par la suite, il
est facile de publier ou transformer un document XML en document PDF, HTML ou
autre, selon les besoins. La séparation du contenu et de sa présentation est un facteur
de productivité important parce qu’on simplifie la tâche de l’écriture, la ramenant au
contenu seulement.
La séparation du contenu et de sa présentation existe, en partie, dans le XHTML. Par
exemple, quand on ajoute un élément de paragraphe « p », on fait un choix qui s’appuie
sur la logique du texte, non sur son apparence. Quant aux choix des polices, de l’espace
entre les lignes, de l’espace entre les paragraphes ou des couleurs, ils ne sont généralement pas pris en compte par le XHTML. Mais tout n’est pas parfait; l’utilisation de
balises pour appeler de l’italique, soit « i » en XHTML, ne nous assure pas une séparation complète entre la présentation et le contenu. Par exemple, il serait plus « logique »
d’indiquer qu’un mot appartient à une langue étrangère et qu’il apparaisse dès lors en
italique. Ainsi, au lieu d’écrire « La vie est <i>cool</i>. », on aimerait écrire « La vie
est <anglais>cool</anglais>. » ou quelque chose de similaire. Le XHTML constitue
donc un compromis entre une séparation complète du contenu et de sa présentation, et
l’absence de séparation.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
96
Comme nous le verrons dans le troisième module, la façon la plus naturelle de dicter la présentation d’un document XHTML est d’utiliser un ou plusieurs fichiers CSS.
En plaçant les instructions de formatage dans des fichiers CSS, distincts des fichiers
XHTML, on obtient une bonne séparation du contenu et de sa présentation. Cette approche a un grand avantage : si on doit changer l’apparence d’un site web, on peut se
contenter d’éditer quelques fichiers CSS au lieu de modifier le contenu lui-même qui
se trouve dans plusieurs fichiers XHTML. Par exemple, si on veut que le texte contenu
dans les tableaux soit en caractères gras et que le texte des listes apparaisse en rouge,
on utilisera les instructions CSS suivantes :
td {font-weight:bold;}
li {color:red;}
Le XML est aussi très utile pour aider à l’autodescription des informations. Par
exemple, si dans un texte vous mettez tous les termes techniques en italique, il est
possible que vous puissiez plus tard faire une recherche dans votre document pour
tous les termes techniques. Toutefois, quelqu’un qui ne connaîtrait pas votre convention pourrait avoir beaucoup de mal à faire la même recherche. Par contre, si vous
utilisez un élément particulier pour les termes techniques comme les balises <technique></technique>, il devient beaucoup plus facile à quelqu’un d’autre de s’y retrouver dans votre document. On pourrait objecter que l’ajout de nombreuses balises alourdira le texte qui occupera alors trop de place sur le disque; l’expérience montre que la
pérennité des documents doit presque toujours être privilégiée par rapport à l’utilisation
de l’espace disque.
En outre, le XML est un format ouvert : on peut utiliser une multitude d’outils différents pour manipuler les documents XML; nous ne sommes pas limités à des produits
spécifiques à une compagnie ou institution donnée. Le XML a donc l’avantage sur
plusieurs autres formats quant à sa pérennité.
2.3.5
Le format DocBook
Développé à partir de 1991, le format DocBook est un format de documents souvent utilisé pour la documentation technique. Le format DocBook est une application
SGML qui devient une application XML. Il existe de nombreux outils permettant de
transformer un document DocBook en document HTML ou PDF.
Le format DocBook possède de nombreux avantages pour la rédaction de documents
techniques parce qu’il assure une grande séparation entre le contenu et sa présentation :
il ne permet que des balises ayant trait à la logique du texte; par exemple, il n’est pas
possible de spécifier une police de caractères en DocBook. L’auteur peut alors concentrer son attention sur le contenu du document, sans perdre de temps avec le formatage,
qui est une étape ultérieure. La séparation du contenu et de sa présentation permet aussi
que plusieurs personnes puissent travailler sur un même projet de documentation tout
en assurant une présentation uniforme, parce que DocBook ne comprend pas d’instructions de formatage.
CC BY-NC-SA
XML comme format de documents
97
Malheureusement, comme les autres formats hérités du SGML, plusieurs documents en
format DocBook sont du SGML et non du XML; on ne peut donc pas utiliser les outils
XML pour tous les documents DocBook. Par contre, la situation est en train de changer;
il devient plus facile de déterminer si un document est bel et bien un document XML :
la déclaration XML placée au début d’un document DocBook nous l’indique.
Le format DocBook est fréquemment utilisé dans les projets de logiciels libres et « open
source », ainsi que par certaines grandes sociétés, comme IBM. En général, les avantages du format DocBook sont plus visibles dans un contexte de travail d’équipe.
La création d’un document DocBook simple n’est pas très difficile. Tout d’abord, bien
qu’elle puisse varier selon les versions, la déclaration de type de document d’un document DocBook ressemble à ceci :
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
Dans ce cas, on voit que le document DTD se trouve à l’adresse :
http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd
Il faut cependant noter qu’il s’agit d’un document DTD qui dépend d’autres documents
DTD et que la lecture d’un tel type de document DTD n’est pas très facile.
L’élément-racine d’un document DocBook peut varier, mais les deux principales structures sont « book » (livre) et « article »; notez que l’on peut commencer par l’une ou
l’autre :
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<book>
(...)
</book>
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<article>
(...)
</article>
Ensuite, on doit ajouter un élément « bookinfo » ou « articleinfo », selon que le document est un livre ou un article. Le plus souvent, les éléments en question contiennent
un élément « title » contenant le titre, ainsi qu’un élément « author » qui contiendra les
éléments « firstname » (prénom) et « surname » (nom de famille). On peut aussi ajouter
un élément « copyright » (droit d’auteur) qui contiendra un élément « year » (année)
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
98
et un élément « holder » (titulaire). Voici quelques structures courantes de documents
DocBook :
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<book>
<bookinfo>
<title>Notre documentation</title>
<author>
<firstname>Alexis</firstname>
<surname>Letrotteur</surname>
</author>
<copyright><year>2004</year><holder>Bell Canada</holder></copyright>
</bookinfo>
(...)
</book>
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<article>
<articleinfo>
<title>Le sens de la vie</title>
<author>
<firstname>Gilles</firstname>
<surname>Proulx</surname>
</author>
<copyright><year>2004</year>
<holder>Gouvernement du Canada</holder>
</copyright>
</articleinfo>
(...)
</article>
L’élément de base d’un document DocBook est l’élément « para » qui note la présence
d’un paragraphe. Dans le cas d’un livre, on va le plus souvent faire suivre l’élément
« bookinfo » d’éléments « chapter » (chapitre), qui eux-mêmes peuvent contenir des
éléments « section », comme dans l’exemple qui suit :
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<book>
<bookinfo>
<title>Notre documentation</title>
CC BY-NC-SA
XML comme format de documents
99
<author>
<firstname>Alexis</firstname>
<surname>Letrotteur</surname>
</author>
<copyright><year>2004</year><holder>Bell Canada</holder></copyright>
</bookinfo>
<chapter>
<title>Premier chapitre</title>
<section>
<title>Première section du premier chapitre</title>
<para>Mettre ici le premier paragraphe de la première section.</para>
</section>
</chapter>
</book>
Observez que tous les éléments « chapter », ainsi que tous les éléments « section »
débutent par un élément « title » : c’est souvent suffisant. Il n’est pas permis de commencer un élément « section » ou « chapter » directement par un élément « para ».
Par contre, on pourrait omettre d’avoir des sections dans nos chapitres, comme dans
l’exemple qui suit :
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
<book>
<bookinfo>
<title>Notre documentation</title>
<author>
<firstname>Alexis</firstname>
<surname>Letrotteur</surname>
</author>
<copyright><year>2004</year><holder>Bell Canada</holder></copyright>
</bookinfo>
<chapter>
<title>Premier chapitre</title>
<para>Mettre ici le premier paragraphe du premier chapitre.</para>
</chapter>
</book>
Dans le cas d’un simple article, nous n’utiliserons pas les éléments « chapitre » et il
suffit, le plus souvent, d’utiliser des éléments « section », comme dans l’exemple qui
suit :
<?xml version="1.0" encoding=’ISO-8859-1’ standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
100
<article>
<articleinfo>
<title>Notre documentation</title>
<author>
<firstname>Alexis</firstname>
<surname>Letrotteur</surname>
</author>
<copyright><year>2004</year><holder>Bell Canada</holder></copyright>
</articleinfo>
<section>
<title>Première section de l’article</title>
<para>Mettre ici le premier paragraphe de la première section.</para>
</section>
<section>
<title>Deuxième section de l’article</title>
<para>Mettre ici le premier paragraphe de la seconde section.</para>
</section>
</article>
On pourrait aussi utiliser les éléments « sect1 », « sect2 », « setc3 » et ainsi de suite,
pour obtenir les notions de section, sous-section, sous-sous-section et ainsi de suite.
Comme le format DocBook est destiné à la documentation technique, il existe plusieurs balises pour décrire le code informatique. L’élément le plus simple est l’élément
« programlisting ». Ainsi, pour ajouter un petit programme Java dans un document
DocBook, on utilisera l’élément suivant :
<programlisting>
public static void main(String[] arg) {
System.out.println("Allo!");
}
</programlisting>
On peut également placer un élément « programlisting » dans les éléments « section »,
« chapter », « para », etc.
Tout comme en HTML, on peut créer des listes avec les éléments « itemizedlist »
(liste non ordonnée, équivalent de « ul » en HTML) et « orderedlist » (liste ordonnée,
équivalent de « ol » en HTML). Une liste est constituée d’éléments « listitem » qui ne
peuvent contenir directement du texte : on met généralement des éléments « para » dans
les éléments « listitem ». Par contre, les éléments « listitem » ne peuvent apparaître hors
des éléments « itemizedlist » et « orderedlist ». En outre, on place les listes dans les
éléments « chapter », « section », etc. Voici quelques exemples :
<itemizedlist>
<listitem>
<para>un triangle</para>
CC BY-NC-SA
XML sur le web
101
</listitem>
<listitem>
<para>un losange</para>
</listitem>
</itemizedlist>
<orderedlist>
<listitem>
<para>Premier élément (numéro 1)</para>
</listitem>
<listitem>
<para>Second élément (numéro 2)</para>
</listitem>
</orderedlist>
Le format DocBook est supporté par certains traitement de textes comme OpenOffice
qui est disponible gratuitement.
2.3.6
L’ODF (Open Document Format)
Historiquement, les formats de bureautiques ont été propriétaires, que ce soit le format
WordPerfect ou le format Microsoft Word. Pour une institution, cela pose le problème
de la pérennité des documents : qu’est-ce qui se produit si la compagnie qui propose
un format décide de ne plus supporter un ancien format, parce qu’elle fait faillite ou
change sa stratégie commerciale ? Qu’est-ce qui se produit si elle décide d’augmenter
le coût de ses produits ? L’Open Document Format (ODF) est une norme XML adoptée
en mai 2005 par OASIS et est devenu une norme ISO (ISO 26300.2006) le 30 novembre
2006. Le format ODF est un format XML que tout le monde peut utiliser librement.
Nous allons voir différentes techniques dans ce cours qui permettent de manipuler des
documents XML et elles s’appliquent au format ODF.
Le format ODF n’est pas très différent des nouveaux formats Open XML utilisés par
Microsoft Office, mais au lieu de n’être soutenu que par une seule compagnie, ODF
provient d’une entente entre plusieurs grandes sociétés : Adobe Systems, IBM, Intel,
Novell et Sun Microsystems. Dans les deux cas (ODF et Open XML), les fichiers XML
sont mis dans une archive compressée et nous avons accès à la sémantique des balises
XML. Le logiciel OpenOffice utilise le format ODF et a les avantages d’être gratuit
et disponible pour une variété de systèmes (Apple, Linux, Microsoft, etc.). Il est aussi
possible de créer des documents ODF à partir de Microsoft Office 2007 à l’aide d’une
composante logicielle supplémentaire (Open XML Translator). Dans le cadre de ce
cours, vous pouvez remettre vos travaux dans le format ODF.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
2.4
2.4.1
102
XML sur le web
Objectif
Comprendre le XHTML pour publier des documents sur le web.
2.4.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation.
2.4.3
Le XHTML et le web
Rappelons d’abord que le XHTML est un format hybride : il tient à la fois du HTML
et du XML. Nous allons étudier ce format, examiner son importance et son rôle pour
la publication de documents sur le web.
Produire du XHTML est une des principales façons de publier du XML sur le web. Le
XHTML en question peut être produit à la main avec un éditeur de texte : dans ce cas,
il faudra s’assurer qu’il est bien formé. Avec un navigateur comme Mozilla Firefox, on
peut s’en assurer en l’enregistrant avec un nom portant l’extension « .xhtml », comme
« mon_fichier.xhtml », et en l’ouvrant avec le navigateur. On peut aussi produire du
XHTML en « transformant un fichier XML », ce que nous verrons dans le prochain
module. Finalement, on utilise aussi beaucoup de XML sur le web sans passer par le
XHTML, soit en utilisant la technologie CSS, que nous étudierons dans le prochain
module, soit en destinant le XML aux machines.
L’avantage du XHTML est de pouvoir bénéficier de toute la puissance du XML,
de toutes les astuces et outils que l’on connaît en XML, tout en conservant le format HTML qui s’est montré utile au fil des ans.
On peut se demander alors pourquoi le HTML ne suffit pas. Après tout, le web s’est
fait avec le HTML et ça fonctionne bien. L’embarras avec le HTML, c’est qu’il permet
de faire des choses que les machines ne savent pas bien traiter. Par exemple, prenons le
document HTML typique suivant :
<html>
<body>
<p>Voici mon <i>document.
<p><b>Il est beau, non?
</body>
</html>
Cet exemple n’est pas un document XML valable! On voit bien qu’il s’agit d’un document avec deux paragraphes (balises « p »), dont une partie est en caractères gras
CC BY-NC-SA
XML sur le web
103
(balise « b ») et une autre en italique (« i »). On peut toutefois se demander, à juste
titre, si la phrase « Il est beau, non? » est en italique ou pas.
Il y a deux façons de rendre ce document HTML en XHTML :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>le titre est obligatoire en XHTML</title>
</head>
<body>
<p>Voici mon <i>document</i>.</p>
<p><b>Il est beau, non?</b></p>
</body>
</html>
ou encore
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>le titre est obligatoire en XHTML</title>
</head>
<body>
<p>Voici mon <i>document.</i></p>
<p><i><b>Il est beau, non?</b></i></p>
</body>
</html>
On constate aisément que le XHTML ne tolère pas les ambiguïtés qui rendent le HTML
difficile à traiter par les machines. C’est un avantage de taille, car il existe plusieurs
outils gratuits pour traiter le XML et qui peuvent être utilisés avec le XHTML, alors
que les outils pour traiter le HTML sont plus difficiles à développer et, en général, plus
capricieux parce qu’ils doivent traiter des ambiguïtés.
Le XHTML permet aussi de faire des choses qui n’existent pas en HTML. Par exemple,
on peut utiliser des appels d’entités. Supposons que le nom d’un auteur ou le titre
de son livre apparaissent à plusieurs reprises dans un document. La redondance de
l’information peut être une source d’erreur : si on change le titre du livre à un endroit,
il faut le changer partout. Avec le XHTML, on peut déclarer les entités suivantes :
<!ENTITY titre
"Le père de tous les documents">
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
<!ENTITY monnom
104
"Daniel Lemire">
Ensuite, on pourra avoir le document suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [
<!ENTITY titre "Le père de tous les documents">
<!ENTITY monnom "Daniel Lemire">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&titre;</title>
</head>
<body>
<p>Le titre de ce livre est: &titre;. L’auteur est &monnom;.</p>
<p>Copyright 2010, par &monnom;.</p>
</body>
</html>
Le résultat à l’écran, dans un navigateur qui comprend le XHTML, sera :
Le titre de ce livre est: Le père de tous les documents.
L’auteur est Daniel Lemire.
Copyright 2010, par Daniel Lemire.
2.5
2.5.1
Travail noté 2
Objectifs et pondération
Ce travail compte pour 5 % de la note globale du cours.
Il contribue à l’évaluation de l’objectif suivant :
– Traduire, au sein de son organisation, sa compréhension du XML dans la gestion des
informations.
Ce travail consiste à discuter d’un sujet avec les autres étudiants du cours et à réunir
vos textes dans un compte rendu.
CC BY-NC-SA
Travail noté 2
2.5.2
105
Consignes
Avant d’entreprendre ce travail noté, il est recommandé d’avoir terminé les activités
d’autoévaluation du module 1 et d’avoir commencé l’étude du module 2. Vous avez
jusqu’à la fin du cours pour réaliser ce travail.
Vous devez contribuer au forum de façon originale et substantielle.
1. Choisissez un sujet qui vous intéresse; quelques pistes de discussion vous sont
suggérées plus loin.
2. Effectuez des recherches sur le web, prenez des notes.
3. Inscrivez-vous sur Facebook si ce n’est pas déjà fait (http://fr-fr.facebook.com/).
Facebook est un site de réseautage social. L’inscription sur Facebook est gratuite
et elle ne prend que quelques minutes. Par contre, n’allez pas demander de l’aide
aux services de l’Université pour vous brancher à Facebook : demandez plutôt à
votre tuteur de vous aider.
4. Accédez au groupe du cours « INF 6450 » à l’adresse http://www.facebook.com/
group.php?gid=57220667716. Vous trouverez au sein de la page du groupe un
forum de discussion.
5. Rédigez votre intervention de façon claire et précise afin d’inciter les lecteurs à
vous lire et à commenter; prenez soin de préciser vos références.
6. Lisez les messages de vos collègues et échangez. Répondez à vos interlocuteurs
et réagissez à leur contribution.
7. Quand vous jugerez votre participation suffisante, que aurez terminé votre discussion, réunissez les textes que vous avez produits.
8. Rédigez un compte rendu de votre participation (Word 97/2000/XP, ODF, PDF,
RTF ou au format texte) qui doit contenir une copie des textes que vous avez
produits dans le forum ou blogue.
9. Transmettez à votre personne tutrice, par courriel, votre compte rendu clairement identifié à votre nom, en le joignant au message en fichier attaché. L’objet
de votre courriel doit commencer par « [INF6450][TRAVAIL2] »; dans le
message, indiquez votre nom, votre numéro d’étudiant (8 chiffres), la date
de remise de votre travail et le nom de votre personne tutrice, ainsi que les
mentions « Travail noté 2 » et « INF 6450 ». Ne transmettez pas plusieurs
fichiers. Ne transmettez pas une archive compressée (zip ou autre).
En cas de panne
Il peut arriver que vous ne puissiez vous brancher au groupe Facebook du cours. En
effet, Facebook peut tomber en panne, vous refuser l’accès ou même cessez d’exister.
Comme alternative, vous pouvez aussi commenter sur le blogue du cours.
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
106
Pistes de discussion
Bien que votre contribution doive être originale et que nous vous invitions fortement
à faire une recherche préalable sur le web pour nourrir vos discussions, vous pouvez
utiliser les pistes suivantes :
– Le blogue du cours à http://www.daniel-lemire.com/blogue/category/xml/ est régulièrement mis à jour.
– Le Security Assertion Markup Language (SAML) doit permettre d’identifier et d’autoriser les utilisateurs sur plusieurs sites en ne leur demandant qu’une seule fois leur
mot de passe.
– La langage RuleML permet d’écrire des règles formelles en XML et de les échanger
entre divers sites.
– Les versions récentes de Microsoft Office utilisent de façon agressive le XML
comme format de documents. On trouve sur le web plusieurs articles traitant de cette
question, dont un article sur les conséquences de l’utilisation de XML par Microsoft
pour les logiciels antivirus et un article sur les conséquences légales des choix faits
par Microsoft.
– Le clone gratuit de Microsoft Office, OpenOffice (voir openoffice.org) utilise lui
aussi un format XML pour ses documents. De plus, il est possible de trouver sur
le web plusieurs articles portant sur l’utilisation du XML faite par OpenOffice.
– Le jeu vidéo très populaire World of Warcraft offre un outil à base de XML permettant de modifier l’interface du jeu.
– Le W3C a récemment publié les spécifications de VoiceXML 2.0 avec une annonce
en français; de plus, le magazine Silicon a publié un article sur le sujet. En principe, VoiceXML devrait permettre de créer des systèmes contrôlés par la parole : par
exemple, un outil de gestion de l’inventaire par téléphone qui permettrait de demander un rapport des stocks à partir d’un numéro de série.
– On a appris récemment que le gouvernement américain rend disponibles les données
météorologiques au format XML.
2.5.3
Critères de correction et de notation
L’évaluation porte sur l’originalité de votre propos, sur l’ampleur de la recherche sousjacente à votre discussion et sur la qualité des textes que vous proposez.
– Originalité : Est-ce que votre contribution diffère de ce qu’on trouve déjà dans le
forum ou sur le blogue? (30 %)
– Contenu et recherche : Est-ce que votre contribution démontre une recherche substantielle sur le sujet? Est-ce que vous avez donné 3 ou 4 références (comme des
URL) pertinentes et originales? (60 %)
– Présentation : Est-ce que votre contribution est faite de textes lisibles, clairs, cohérents, écrits dans un français correct? (10 %)
CC BY-NC-SA
Travail noté 3
2.6
2.6.1
107
Travail noté 3
Objectifs, pondération et critères de correction
Ce travail compte pour 10 % de la note globale du cours.
Il contribue à l’évaluation des objectifs suivants :
– Utiliser un « vocabulaire » ou une application XML pour présenter des informations
en format XML.
– Déterminer si un document XML est bien formé ou valable.
– Traduire, au sein de son organisation, sa compréhension du XML dans la gestion des
informations.
Votre travail sera noté en utilisant les critères suivants :
–
–
–
–
–
votre capacité à créer un document DocBook valable et bien formé (30 %),
votre utilisation des balises requises (15 %),
l’utilisation d’une instruction spéciale (XSLT) (5 %)
production d’un document XHTML valable selon les consignes (20 %).
le contenu de votre texte (clarté, cohérence, qualité du français) (30 %).
Il est recommandé d’avoir terminé les activités d’autoévaluation des modules 1 et 2
avant d’entreprendre ce travail noté. Pour réaliser ce travail, vous devez utiliser la technologie XSLT (sans nécessairement la maîtriser); vous pouvez également commencer
les autres modules avant de le terminer si vous jugez que votre connaissance du XML
n’est pas encore suffisante. Vous avez jusqu’à la fin du cours pour réaliser ce travail.
2.6.2
Description du travail
En respectant les consignes spécifiques qui suivent, vous rédigerez un texte qui répondra à la question suivante : « Pourquoi est-ce que je devrais utiliser XML dans mon
projet? ». Vous fournirez au minimum 6 bonnes raisons justifiant l’utilisation de XML
au sein d’un projet stratégique.
Votre texte, que vous nommerez « INF6450travail3_votrenom.xml », sera un document DocBook d’au moins 2000 mots (environ 130 lignes), comptant au moins deux
« chapitres » (éléments « chapter »), chacun comptant au minimum 2 sections.
En outre, vous devez produire un document XHTML valable qui résume brièvement vos 6 arguments. Le document XHTML doit être nommé
« INF6450travail3_votrenom.xhtml » et doit être du XHTML valable. Votre document doit utiliser au moins un élément « acronym », un élément « samp », et un
élément « blockquote ».
Transmettez les deux documents à votre tuteur par courriel en tant que fichiers attachés.
L’objet de votre courriel doit commencer par « [INF6450][TRAVAIL3] »; dans
le message, indiquez votre nom, votre numéro d’étudiant (8 chiffres), la date de
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
108
remise de votre travail et le nom de votre personne tutrice, ainsi que les mentions
« Travail noté 3 » et « INF 6450 ». Ne transmettez pas une archive compressée (zip
ou autre).
Ce travail de rédaction est personnel et votre texte doit être original.
Rappelons que lorsqu’on vous donne le contenu d’un document XML, vous devez
supposer que le document débute avec le premier caractère et se termine avec le dernier.
2.6.3
Consignes
1. Un document DocBook débute normalement par la définition de type de document (DTD) :
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4CR2//EN"
"http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd">
Cependant, il suffit de visiter l’URL
http://www.oasis-open.org/docbook/xml/4.4CR2/docbookx.dtd
pour se rendre compte que le document DTD de DocBook n’est pas trivial : il
comporte un grand nombre d’éléments dont nous n’avons pas besoin. En particulier, DocBook a plusieurs balises pour la description du code source informatique.
Utilisez donc un document DTD nommé « simpledocbook.dtd », une version
grandement simplifiée de DocBook et ayant le contenu suivant :
<!ELEMENT book (bookinfo,chapter*)>
<!ELEMENT chapter (title,section*)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT bookinfo (title,author,copyright)>
<!ELEMENT author (firstname,surname)>
<!ELEMENT copyright (year,holder)>
<!ENTITY % divers "para|programlisting|itemizedlist|orderedlist">
<!ELEMENT section (title,(%divers;)+)>
<!ELEMENT para (#PCDATA)>
<!ELEMENT programlisting (#PCDATA)>
<!ELEMENT holder (#PCDATA)>
<!ELEMENT surname (#PCDATA)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT itemizedlist (listitem+)>
<!ELEMENT orderedlist (listitem+)>
<!ELEMENT listitem (%divers;)+>
2. Placez ce document DTD dans le même répertoire que votre document
XML.
CC BY-NC-SA
Travail noté 3
109
3. Rédigez le texte de votre document DocBook en utilisant au moins une fois
tous les éléments de cette DTD, y compris « programlisting » et « listitem ».
Votre déclaration de type de document doit être :
<!DOCTYPE book SYSTEM "simpledocbook.dtd">
Même si, à strictement parler, un élément « programlisting » doit contenir le
texte d’un programme, aux fins de ce travail noté, vous pouvez utiliser du XML
dans cet élément.
Note. Votre document ne sera pas un véritable document DocBook, car il n’aura
pas une déclaration normale de type de document. Cependant, il vous serait possible de remplacer la déclaration de type de document par une déclaration normale et vous auriez alors un véritable document DocBook.
4. Un document DocBook ne contient pas les informations de formatage et, en
général, n’est pas très lisible. Pour permettre une lecture plus aisée du document,
utilisez le document XSLT qui se trouve à l’annexe 1, plus loin. Copiez le
document en question et enregistrez-le sous le nom « docbook.xml », dans le
même répertoire que votre document XML. Le XSLT permet de transformer
le document DocBook en HTML. On ne vous demande pas de comprendre le
XSLT, car le sujet sera étudié dans le prochain module.
5. Pour l’instant, ajoutez simplement l’instruction suivante dans votre document XML, immédiatement après la déclaration XML
<?xml-stylesheet href="docbook.xml" type="application/xml"?>
6. Ensuite, une fois votre document XML terminé, ouvrez-le dans Firefox; vous
devriez voir votre document nouvellement formaté. Assurez-vous que le document « docbook.xml » de l’annexe 1 est bien dans le même répertoire que votre
document DocBook.
Constatez alors comment votre document XML est présenté de façon totalement
différente de son allure originale. C’est un résultat de la division entre le contenu
et sa présentation : le fichier XSLT s’occupe ici de la présentation, alors que
votre texte XML ne comporte que le contenu. Par exemple, la version formatée
dispose d’une table des matières qui se génère automatiquement, alors que le
document XML n’a aucune notion de table des matières.
7. La production du document XHTML se fait de manière similaire, mais sans
l’utilisation d’un document XSLT. Pour tester la validité de votre document,
vous pouvez utiliser l’outil de validation du W3C disponible à l’adresse
« http://validator.w3.org/ » (voir « Validate by File Upload »).
8. Transmettez à votre personne tutrice, par courriel, vos documents XML clairement identifiés à votre nom, en les joignant au message. Vous devez transmettre
deux documents XML : un document DocBook et son résumé en XHTML. Dans
la zone « Objet », inscrivez le sigle du cours et le numéro du travail (INF 6450 Travail noté 3) dans le message, indiquez votre nom, votre numéro d’étudiant (8
chiffres), la date de remise de votre travail et le nom de votre personne tutrice,
ainsi que les mentions « INF 6450 » et « Travail noté 3 ».
CC BY-NC-SA
Module 2 : XML en tant que syntaxe pour les documents
110
Annexe 1. Document XSLT
Le document XSLT suivant servira à convertir votre document DocBook en HTML.
C’est là un avantage du format DocBook : on peut facilement le convertir en d’autres
formats. Nous étudierons le XSLT dans le troisième module.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="ISO-8859-1" />
<xsl:template match="book"> <html>
<head><xsl:apply-templates select="bookinfo"/></head>
<body><h1><xsl:value-of select="bookinfo/title" /></h1>
<p style="text-indent:1em;">
<xsl:value-of select="bookinfo/author/firstname" />
<xsl:text> </xsl:text>
<xsl:value-of select="bookinfo/author/surname" />
&#169;
<xsl:value-of select="bookinfo/copyright/year" />
</p><h2>Table des matières</h2>
<ul><xsl:apply-templates select="chapter" mode="tdm"/></ul>
<xsl:apply-templates select="chapter"/>
</body></html>
</xsl:template>
<xsl:template match="bookinfo">
<title><xsl:value-of select="title" />
par <xsl:value-of select="author/firstname" /><xsl:text>
</xsl:text><xsl:value-of select="author/surname" />
</title>
</xsl:template>
<xsl:template match="chapter" mode="tdm">
<li><a href="#{generate-id(.)}">
<xsl:number format="digit" lang="fr" count="chapter"/>.
<xsl:value-of select="title" /></a></li>
<ul><xsl:apply-templates select="section" mode="tdm"/></ul>
</xsl:template>
<xsl:template match="section" mode="tdm">
<li><a href="#{generate-id(.)}">
<xsl:number format="digit" lang="fr"
count="chapter"/>.<xsl:number format="digit" lang="fr" count="section"/>
<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></li>
</xsl:template>
<xsl:template match="chapter">
<h2><a name="{generate-id(.)}" >Chapitre
CC BY-NC-SA
Travail noté 3
111
<xsl:number format="digit" lang="fr"
count="chapter"/>.<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></h2>
<div style="margin-left:1em">
<xsl:apply-templates select="section"/> </div>
</xsl:template>
<xsl:template match="section">
<h3><a name="{generate-id(.)}">
<xsl:number format="digit" lang="fr"
count="chapter"/>.<xsl:number format="digit" lang="fr"
count="section"/>
<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></h3>
<div style="margin-left:1em">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="itemizedlist">
<ul style="margin-left:1em"><xsl:apply-templates /></ul>
</xsl:template>
<xsl:template match="orderedlist">
<ol style="margin-left:1em"><xsl:apply-templates /></ol>
</xsl:template>
<xsl:template match="listitem">
<li style="text-indent:0.5em"><xsl:apply-templates /></li>
</xsl:template>
<xsl:template match="programlisting">
<pre style="color:blue;background-color:rgb(200,200,200); margin-left:1em">
<code>
<xsl:apply-templates />
</code></pre>
</xsl:template>
<xsl:template match="para">
<xsl:choose>
<xsl:when test="name(..) = ’listitem’">
<xsl:apply-templates /></xsl:when>
<xsl:otherwise><p><xsl:apply-templates /></p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="title" />
</xsl:stylesheet>
CC BY-NC-SA
Module 3 : Technologies XML
3.1
3.1.1
Aperçu
Objectifs
Nous avons vu que le XML permet de stocker et d’échanger des informations et que
certaines formes de XML, comme le XHTML, s’affichent de façon lisible dans un navigateur. Cependant, dans une organisation, il faut souvent pouvoir afficher de façon
lisible du XML qui n’est pas nécessairement compris par un navigateur. Dans ce module, nous présentons deux technologies importantes qui solutionnent cette situation :
XSLT et CSS. Nous verrons aussi que le XSLT permet de transformer automatiquement le XML en d’autres formats, ce qui peut être très utile.
L’objectif spécifique du module est :
– Interpréter des fichiers XML utilisant des espaces de noms, des transformations
XSLT ou des instructions CSS.
Une activité, le travail noté 4, nous permettra d’évaluer votre atteinte de cet objectif.
3.1.2
Démarche
Il n’est pas nécessaire de terminer l’étude de ce module avant de passer aux autres
modules du cours.
Nous vous invitons à procéder à l’étude de ce module dans l’ordre suivant :
– XSLT, XPath, XQuery, XPointer et XLink
– CSS
Lisez les textes et vérifiez vos connaissances en répondant aux deux questionnaires
d’autoévaluation; réalisez ensuite le travail noté 4 qui prend la forme d’un questionnaire
portant sur XSLT et CSS.
113
Module 3 : Technologies XML
114
Le pense-bête pour le XSLT, en annexe dans la version imprimée du cours, rassemble
les principaux éléments du XSLT et précise leur fonction.
3.2
3.2.1
XSLT
Objectif
Comprendre le XSLT comme application XML pour transformer les documents, grâce
aux feuilles de style.
3.2.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte porte
sur le langage XSL (Extensible Stylesheet Language), mais en particulier sur les XSL
Transformations (XSLT). On traitera également des chemins XPath et de XQuery.
3.2.3
Un regard critique
Le XML n’est pas un langage de programmation. Néanmoins, on peut utiliser le XML
pour définir un langage comme le XSL. Est-ce que c’est une bonne idée ? Plusieurs
auteurs, dont Alan Holub, croient que le XML est une syntaxe trop lourde pour la
programmation.
XML is perhaps the worst programming language ever conceived. I’m
not talking about XML as a data-description language, which was its original design. I’m talking about perverting XML for programming applications. It’s inappropriate to use XML as a scripting language (...). These
sorts of XML "programs" are unreadable, unmaintainable, an order of magnitude larger than necessary, and audaciously inefficient at runtime. (Alan
Holub, Software Development Times, September 2006)
Personnellement, je trouve que le XSLT est amusant et utile. Il est utilisé par des millions de sites web et on ne peut prétendre être un expert en XML sans une bonne
maîtrise du XSLT.
3.2.4
Les machines de Turing et la technologie XML
Une machine de Turing est un modèle abstrait qui sert à représenter les ordinateurs.
La thèse de Church-Turing affirme que tout traitement d’information peut être accompli par une machine de Turing. On accepte généralement cette hypothèse comme étant
CC BY-NC-SA
XSLT
115
vraie en informatique. Un langage de programmation est Turing-complet s’il peut effectuer tous les calculs qu’une machine de Turing peut faire. Le Java, le XSLT et
XQuery sont des langages qui sont Turing-complet. Tous les langages informatiques
ne sont pas Turing-complet : CSS ne l’est pas.
3.2.5
Qu’est-ce que le XSLT
La première version du langage XSLT (Extensible Stylesheet Language Transformation) a été publiée en 1997 et elle est devenue une recommandation W3C en 1999. Elle
fait partie du XSL (Extensible Stylesheet Language) qui comprend une seconde composante, les XSL-FO (Extensible Stylesheet Language Formatting Objects). La technologie XSL tire son origine du besoin d’un langage simple, mais suffisamment puissant
pour pouvoir contrôler finement l’affichage du XML. On utilise beaucoup le XSLT sur
le web et au sein des systèmes d’information, alors que le XSL-FO est davantage utile
pour les applications de mise en page spécialisées. Dans ce cours, nous nous soucierons
seulement du XSLT, dont l’utilité dépasse de loin les problèmes de présentation.
L’objectif poursuivi par le XSLT est de transformer les documents XML en d’autres
documents. Par exemple, supposons que vous ayez le document suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<facture>
<montant>10.10</montant>
<personne>Jean Rochond</personne>
<raison>Achat d’ordinateur</raison>
</facture>
et que vous vouliez transformer ce type de document XML en document HTML qui
aurait la forme suivante :
<html>
<head>
<title>Facture de Jean Rochond</title>
</head>
<body><p>Ceci est une facture pour Jean Rochond de 10.10$
pour: Achat d’ordinateur.</p></body>
</html>
Si votre entreprise utilise du XML et que vous désirez envoyer des factures par courriel, vous pourriez envoyer le document HTML au lieu du document XML. De cette
manière, le client pourrait consulter sa facture sans avoir à comprendre le XML.
On pourrait bien sûr écrire un programme en Java qui effectuerait cette opération, mais
la conception d’un programme Java prend du temps et on cherche parfois une solution
plus économique, plus rapide. Avec l’exemple que nous venons de voir, on pourrait
CC BY-NC-SA
Module 3 : Technologies XML
116
automatiser la transformation de XML en HTML en moins d’une quinzaine de minutes.
Pour obtenir le résultat désiré, il faut utiliser un petit fichier XSLT.
3.2.6
Les langages déclaratifs
Un langage comme Java est orienté objet et procédural. Ce n’est pas, par contre, un
langage déclaratif et on dit donc qu’il est impératif. Les langages déclaratifs sont des
langages qui définissent le problème au lieu d’en définir la solution. On les reconnaît
souvent parce qu’ils énoncent des règles au lieu d’énoncer des procédures.
Le langage Prolog est un exemple de langage déclaratif parce que le programmeur
ne fait que saisir des relations sans définir comment l’ordinateur doit combiner ses
relations:
pere(X,Y) :- parent(X,Y),homme(X).
freresoeur(X,Y) :- parent(Z,X), parent(Z,Y).
Le SQL est aussi déclaratif parce qu’on spécifie à l’ordinateur quelles informations on
veut sans pour autant spécifier comment l’information doit être trouvée:
SELECT age FROM table WHERE age > 25;
Le XSLT et XQuery sont des exemples plus récents de langages déclaratifs. On affirme souvent que les langages déclaratifs sont plus lents que les langages impératifs
parce que le logiciel doit lui-même trouver la meilleure stratégie pour évaluer le programme sans recevoir beaucoup d’indices de la part de l’humain. Le contraire peut
aussi être vrai: comme le logiciel peut optimiser à sa guise l’exécution du programme
étant donné l’absence de structure imposée par l’humain, il est possible pour un langage déclaratif de surpasser en vitesse un langage impératif. En pratique, personne ne
se plaint vraiment de la lenteur relative du XSLT, de SQL ou de Prolog. Cependant,
pour le programmeur habitué à la programmation impérative, la programmation déclarative peut être source de confusion. Avec l’expérience, on se rend compte que, pour
bien des problèmes, la programmation déclarative est préférable surtout lorsqu’on ne
veut pas se soucier des détails techniques comme la façon dont le fichier XML est lu et
comment il est stocké en mémoire.
Le XSLT (et XQuery) peut aussi être considéré comme un langage fonctionnel (voir
FXSL ou The Functional Programming Language XSLT - A proof through examples
par Dimitre Navatchev) au même titre que APL, Lisp, Haskell, Maple, Mathematica,
Ocaml ou Scheme.
3.2.7
Les fichiers XSLT
Le fichier XSLT contient des règles qu’un « processeur XSLT » applique aux fichiers
XML pour les transformer. Heureusement, si vous utilisez Firefox, vous avez déjà un
CC BY-NC-SA
XSLT
117
processeur XSLT moderne à même votre navigateur. Lors de l’ouverture d’un document XML, Firefox tente automatiquement de trouver et d’exécuter un document XSLT
pour transformer le document XML.
Un processeur XSLT va parcourir tous les éléments de votre document en commençant
par l’élément-racine et, à chaque fois, il va tenter d’appliquer une règle.
Commençons par créer le fichier XSLT suivant qu’on enregistrera sur le disque comme
étant « xslt.xml » :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>
Ce fichier ne contient aucune « règle » et constitue le document XSLT de base. Nous
vous suggérons de faire l’exercice de création de ce document avec Bloc-notes, par
exemple.
Un fichier XSLT est un document XML bien formé, utilisant l’espace de noms
« http://www.w3.org/1999/XSL/Transform » et ayant pour élément-racine stylesheet
(ou transform), lequel a lui-même un attribut « version ». On ne discute ici que de
la première version de XSLT (1.0); on utilise donc 1.0 comme valeur d’attribut pour
version.
Prenons maintenant le fichier XML que nous avions auparavant; modifions-le un peu
en le faisant pointer vers le fichier XSLT nouvellement créé :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml"
type="application/xml"?>
<facture>
<montant>10.10</montant>
<personne>Jean Rochond</personne>
<raison>Achat d’ordinateur</raison>
</facture>
On
ajoute
donc
la
ligne
:
«
<?xml-stylesheet
href="xslt.xml"
type="application/xml"?> ». Cette ligne indique au navigateur, ou à un autre logiciel, que le document XML peut être transformé par le fichier XSLT nommé
« xslt.xml ». Le chemin peut être relatif ou absolu : on pourrait donc aussi avoir une
ligne comme :
«<?xml-stylesheet href="http://www.mondomaine.com/xslt.xml"
type="application/xml"?>»
si l’URL « http://www.mondomaine.com/xslt.xml » pointe vers un fichier XSLT.
CC BY-NC-SA
Module 3 : Technologies XML
118
Il suffit d’enregistrer ce nouveau document XML dans le même répertoire que le fichier
« xslt.xml », disons avec le nom « test.xml », puis d’ouvrir le fichier « test.xml » dans
Firefox. Normalement, on ne devrait rien voir à l’écran (une page vide), car le document XSLT utilisé est vide de toute instruction et le résultat ne sera pas du HTML.
Le résultat peut cependant varier selon le navigateur utilisé, car votre navigateur pourrait afficher le texte, même s’il ne s’agit pas de HTML : dans ce cas, vous ne verriez
que le texte contenu dans le document XML, les balises en moins. Vous pouvez tester
vos scripts XSLT en ligne directement sur la page web http://www.daniel-lemire.com/
blogue/xsltprocessor.html. Avec ce dernier outil, écrit en ECMAScript, il n’est pas nécessaire d’avoir une instruction xml-stylesheet : on peut traiter n’importe quel fichier
XML avec n’importe quelle transformation XSLT. En ce sens, on peut programmer en
XSLT sans jamais utiliser l’instruction xml-stylesheet.
3.2.8
« Éléments xsl:template »
Modifions maintenant le fichier « xslt.xml » de façon à rendre l’expérience plus intéressante. Tout d’abord, traitons tous les éléments « facture » du document XML. Pour
obtenir le résultat, il faut placer un élément « <xsl:template match="facture"> » dans
l’élément-racine du document XSLT comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
On doit mettre quelque chose ici!!!
</xsl:template>
</xsl:stylesheet>
Il faut voir l’élément « xsl:template » comme une règle qui dit : à chaque fois qu’on
rencontre un élément qui s’appelle « facture », faisons ceci. Le modèle est inclus dans
l’élément « xsl:template ». Dans l’exemple de document XSLT que nous venons de
voir, le processeur XSLT remplacerait tous les éléments « facture » qu’il rencontre par
le texte « On doit mettre quelque chose ici!!! », ce qui donnerait comme résultat le
fichier suivant (le résultat exact peut varier un peu selon le processeur XSLT) :
<?xml version="1.0" encoding="ISO-8859-1" ?>
On doit mettre quelque chose ici!!!
Malheureusement, ce n’est pas du HTML valable et Firefox devrait n’afficher qu’un
écran vide si vous tentez d’ouvrir le fichier « test.xml » avec un lien vers un tel fichier XSLT. Nous allons donc modifier le fichier XSLT, en ajoutant des balises, comme
ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
CC BY-NC-SA
XSLT
119
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html><body>On doit mettre quelque chose ici!!!</body></html>
</xsl:template>
</xsl:stylesheet>
Cette fois, si vous ouvrez le document « test.xml », vous devriez voir le texte « On doit
mettre quelque chose ici!!! » s’afficher dans votre navigateur. Faites l’expérience.
Dans les exemples que nous allons proposer, nous omettons les éléments « html » et
« body » par souci de simplicité. La présence de ces éléments n’est pas nécessaire et
n’est utile que pour afficher le résultat dans un navigateur. À vous de les ajouter si vous
désirez afficher le résultat.
Pour résumer, chaque fois que le processeur XSLT rencontre un élément « facture », il applique le modèle qui se trouve dans l’élément « <xsl:template
match="facture"> ». Notez que si l’élément « facture » contient lui-même des éléments, ils ne sont pas automatiquement visités par le processeur XSLT. Ce dernier
considère que dès qu’un modèle est appliqué à un élément, il peut alors parcourir le
reste du document sans se soucier du contenu de cet élément qui est maintenant « couvert ».
3.2.9
« Éléments xsl:value-of »
Jusqu’à présent, le résultat n’est pas très fascinant parce que les éléments
« xsl:template » ont été utilisés comme des outils pour faire du « Rechercher/Remplacer ». Le contenu de l’élément « facture » n’est pas traité, on le remplace
bêtement par autre chose.
Nous pouvons traiter le contenu d’un élément à l’aide d’un élément « xsl:value-of »
avec la syntaxe <xsl:value-of select="..." />. La valeur de l’élément « select » est un
chemin (appelé expression XPath) : les chemins les plus simples sont constitués du
nom d’un sous-élément. Par exemple, si le processeur traite un élément « facture »
qui contient un élément « montant », alors l’élément <xsl:value-of select="montant"
/> nous donne le contenu de l’élément « montant ». C’est ainsi que nous pouvons
trouver le nom de la personne devant recevoir une facture, en utilisant <xsl:value-of
select="personne" />.
Voyons maintenant un exemple plus complexe de fichier XSLT :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
CC BY-NC-SA
Module 3 : Technologies XML
120
</head>
<body>
<p>Ceci est une facture pour <xsl:value-of select="personne" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Si vous modifiez le fichier « xslt.xml » et que vous ouvrez le fichier « test.xml » dans un
navigateur supportant le XSLT (comme Firefox), vous devriez voir s’afficher à l’écran
la ligne « Ceci est une facture pour Jean Rochond de 10.10$ pour: Achat d’ordinateur. ». Il faut avouer que c’est déjà beaucoup plus intéressant comme application!
Ce qui se passe, c’est que le nouveau document XSLT transforme notre document XML
en un document HTML :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Facture de Jean Rochond</title>
</head>
<body><p>Ceci est une facture pour Jean Rochond
de 10.10$ pour: Achat d’ordinateur.</p></body>
</html>
Pour résumer, nous pouvons aller chercher le contenu textuel d’une expression
XPath avec une instruction comme « <xsl:value-of select="..." /> » où « ... » est
une expression XPath comme le nom de l’élément.
3.2.10
Arithmétique en XPath
Nous pouvons aussi nous servir des expressions XPath pour faire du calcul simple. Par
exemple, les trois expressions suivantes donneront 2, 2 et 2.5 respectivement :
<xsl:value-of select="1+1" />
<xsl:value-of select="2*1" />
<xsl:value-of select="5 div 2" />
Il arrive qu’on doive calculer une somme de nombres. Par exemple, supposons qu’un
facture comporte une liste de montants.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml"
CC BY-NC-SA
XSLT
121
type="application/xml"?>
<facture>
<montant>10.10</montant>
<montant>20.10</montant>
<montant>40.10</montant>
</facture>
La fonction XPath « sum » nous permet de calculer la somme des montants sans effort
comme dans cet exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<body>
<xsl:value-of select="sum(montant)" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Comme en Java, on a aussi les fonctions « floor », « ceiling », « mod » et « round ».
On peut aussi utiliser les paranthèses dans toutes expressions XPath : « (5 + 2) div 2 ».
3.2.11
Manipulations des chaînes de caractères en XPath
Outre les fonctions arithmétiques, on peut aussi manipuler les chaînes de caractères en
XPath. La fonction la plus simple est « string-length ». Elle calcule la longueur d’une
chaîne. Une autre fonction simple est « normalize-space » qui élimine tous les espaces
au début et à la fin d’une chaîne en plus de remplacer les espaces répétés par un espace
simple. La fonction « translate » permet de remplacer des caractères. Par exemple, pour
remplacer les é par des e et les à par des a, on pourrait utiliser l’instruction suivante
« translate("à la vérité","éà","ea") » qui renvoie « a la verite ».
On peut extraire des sous-chaînes de caractères de diverses manières : la fonction « substring » permet d’extraire une sous-chaîne lorsqu’on en connaît sa position et sa longueur, la fonction « substring-after » permet d’aller chercher un suffixe, la fonction
« substring-before » permet d’aller chercher un préfixe. Par exemple, « substring("la
vie est belle",3,7) » renvoie « vie est », « substring-after("la vie est belle","est") » renvoie « belle » alors que « substring-before("la vie est belle","est") » renvoie « la vie »
On peut aussi additionner deux chaînes de caractères pour en faire une seule avec la
fonction « concat ». L’expression « concat("a","b") » a comme valeur "ab".
CC BY-NC-SA
Module 3 : Technologies XML
122
On peut tester une chaîne pour la présence d’une sous-chaîne avec la fonction XPath
« contains ». L’expression « contains("abc","bc") » est vraie parce que "bc" est une
sous-chaîne de "abc", alors que l’expression « contains("abc","bz") » est fausse.
3.2.12
Chemins XPath plus sophistiqués
Supposons maintenant que nous devions traiter un document XML un peu plus complexe, comme celui qui suit :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml" type="application/xml"?>
<facture>
<montant>10.10</montant>
<personne>
<sexe>M</sexe>
<nom>Rochond</nom>
<prenom>Jean</prenom>
</personne>
<raison>Achat d’ordinateur</raison>
</facture>
Observez que l’élément « personne » contient maintenant trois sous-éléments : sexe,
nom et prenom. Quand on demande au XSLT d’inclure le contenu d’un élément, à
l’aide d’une instruction « xsl:value-of », il retire d’abord toutes les balises. Il garde
les espaces entre les éléments, le texte, et les retours de chariot; seules les balises sont
retirées. En somme, le résultat de l’instruction « xsl:value-of » appliqué à un élément
est son contenu textuel. Précisons que dans le cas où on sélectionne non pas un élément,
mais plusieurs, l’instruction value-of ne s’applique qu’au premier élément rencontré.
Ainsi, si nous utilisions le fichier XSLT précédent destiné à des éléments « personne »
ne contenant que du texte, nous obtiendrions à l’écran, dans Firefox, le texte « Ceci est
une facture pour M Rochond Jean de 10.10$ pour: Achat d’ordinateur. ». Pourquoi ce
résultat? Parce qu’à l’endroit où se trouve <xsl:value-of select="personne" /> s’insère
le contenu de l’élément, sans le balisage, ce qui fait que seul le contenu des souséléments, dans l’ordre, est affiché.
De façon concrète, le fichier XML est transformé en contenu HTML :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Facture de
M
Rochond
Jean
</title>
CC BY-NC-SA
XSLT
123
</head>
<body><p>Ceci est une facture pour
M
Rochond
Jean
de 10.10$ pour: Achat d’ordinateur.</p>
</body>
Par ailleurs, nous pouvons modifier le fichier XSLT pour aller chercher le contenu
respectif des sous-éléments « prenom » et « nom ». Pour ce faire, il suffit de remplacer
« select="personne" » par « select="personne/prenom" » et « select="personne/nom" »,
car la valeur de l’attribut « select » se comporte un peu comme dans les adresses web :
le symbole « / » entre deux noms d’élément signifie « sous-élément ». Nous pourrons
alors utiliser le fichier XSLT suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p>Ceci est une facture pour <xsl:value-of select="personne/prenom" />
<xsl:value-of select="personne/nom" /> de <xsl:value-of select="montant" />$
pour: <xsl:value-of select="raison" />.</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Si nous testons ce nouveau fichier XSLT dans Firefox, nous constaterons que le résultat
est presque correct : cette fois-ci, le fichier « test.xml » s’affiche comme « Ceci est une
facture pour JeanRochond de 10.10$ pour: Achat d’ordinateur. ».
Notez qu’il manque un espace entre Jean et Rochond. Cela se produit parce que dans
un document XSLT, on ignore les espaces entre les éléments (dans le cas où il n’y a
que des espaces entre les deux éléments) : pour obtenir un espace, il faut en marquer la
présence en insérant un élément « xsl:text » comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
CC BY-NC-SA
Module 3 : Technologies XML
124
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p>Ceci est une facture pour <xsl:value-of select="personne/prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="personne/nom" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
En effet, alors que les espaces entre les éléments sont ignorés, l’espace dans un élément
« xsl:text » sera pris en compte. Attention à la confusion : les espaces entre les éléments
sont ignorés dans le fichier XSLT, mais pas dans le fichier XML qui est traité!
Nous constatons que les chemins XPath peuvent contenir non seulement le nom d’un
élément, mais aussi le nom d’un sous-élément, comme « personne/prenom ». Cela peut
nous permettre de construire des modèles complexes qui peuvent aller extraire des
valeurs contenues dans des sous-éléments.
3.2.13
Modularité avec les éléments « xsl:apply-templates »
Notre fichier « xslt.xml » se complexifie et devient plus difficile à comprendre. Tout est
dans un seul modèle, le modèle facture. Pour simuler un problème probable, imaginons
que notre XML est plus complexe et prend la forme :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml" type="application/xml"?>
<facture>
<montant>10.10</montant>
<recipiendaire>
<personne>
<sexe>M</sexe>
<nom>Rochond</nom>
<prenom>Jean</prenom>
</personne>
</recipiendaire>
<commercant>
<personne>
<sexe>F</sexe>
<nom>Ladouce</nom>
<prenom>Jeanne</prenom>
CC BY-NC-SA
XSLT
125
</personne>
</commercant>
<raison>Achat d’ordinateur</raison>
</facture>
Dans ce nouveau document XML, se trouvent deux éléments « personne ». Il serait
bête, dans le document XSLT, de répéter le travail chaque fois qu’on veut afficher un
élément « personne ». Regardons ce que cela pourrait donner en pratique :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p>Ceci est une facture pour
<xsl:value-of select="recipiendaire/personne/prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="recipiendaire/personne/nom" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
<p>Votre commerçant:
<xsl:value-of select="commercant/personne/prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="commercant/personne/nom" /> </p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Observez comment on répète le texte suivant à deux reprises :
<xsl:value-of select="recipiendaire/personne/prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="recipiendaire/personne/nom" />
Voici une autre solution, plus élégante, qui donne le même résultat :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- d’abord un modèle pour les éléments facture -->
CC BY-NC-SA
Module 3 : Technologies XML
126
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="recipiendaire/personne" /></title>
</head>
<body>
<p>Ceci est une facture pour
<xsl:apply-templates select="recipiendaire" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
<p>Votre commerçant: <xsl:apply-templates select="commercant" /> </p>
</body>
</html>
</xsl:template>
<!-- le modèle pour les éléments facture
utilise un modèle pour les éléments personne -->
<xsl:template match="personne">
<xsl:value-of select="prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="nom" />
</xsl:template>
</xsl:stylesheet>
Quelques éléments « xsl:value-of » ont été remplacés par des éléments « xsl:applytemplates ». Un élément « xsl:apply-templates » prend le contenu et, au lieu d’insérer
le contenu textuel comme le fait « xsl:value-of » à l’endroit prévu, il insère plutôt le
résultat obtenu par l’application de modèles (éléments « xsl:template »). Ainsi, dans
l’exemple que nous venons de voir, chaque fois que le processeur XSLT rencontre
l’instruction « <xsl:apply-templates select="recipiendaire" /> », il prend l’élément « recipiendaire » et essaie d’appliquer ses modèles. Comme il n’a pas de modèle pour les
éléments « recipiendaire », il explore le contenu de l’élément et y trouve immédiatement un élément « personne ». Puisqu’il dispose d’un modèle pour ce type d’élément, il
va l’appliquer. Par ailleurs, comme les éléments « recipiendaire » et « commercant » ne
contiennent qu’un élément « personne », c’est donc le modèle défini pour les éléments
« personne » qui s’appliquera dans les deux cas.
Normalement, les éléments « xsl:apply-templates » sont utilisés au sein des éléments
« xsl:template ». On peut aussi les utiliser au sein d’autres éléments que nous discuterons prochainement, « xsl:param » et « xsl:variable ».
Notre fichier « xslt.xml » est maintenant plus modulaire, parce qu’il contient deux
modèles (éléments « xsl:template »).
En résumé, il est souvent préférable d’utiliser un élément « xsl:apply-templates »
qu’un élément « xsl:value-of » quand la complexité du modèle augmente; ceci
permet d’assurer la modularité et de garder la simplicité du document XSLT.
CC BY-NC-SA
XSLT
127
Par défaut, l’instruction apply-templates traite les documents dans l’ordre où ils se présentent dans le document original. On peut forcer le XSLT à trier les éléments avant
de le traiter avec l’instruction xsl:sort. Dans notre exemple, on peut remplacer l’élément <xsl:apply-templates select="recipiendaire" /> par cet élément si on veut que les
individus soient triés par leur nom de famille.
<xsl:apply-templates match="étudiant" >
<xsl:sort select="personne/nom" order="ascending" data-type="text" />
</xsl:apply-templates>
Si on souhaite un tri sur la valeur numérique d’une expression, on remplacera datatype="text" par data-type="number".
On peut aussi importer un autre fichier XSLT avec l’instruction xsl:import. Celle-ci doit
apparaître au tout début du fichier XSLT comme premier sous-élément de l’élément
xsl:stylesheet comme dans cet exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="mesregles.xsl"/>
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
</xsl:template>
</xsl:stylesheet>
En cas de conflit entre les règles de fichier XSLT principal et celles du fichier importé,
les règles du fichier XSLT principal l’emporte.
3.2.14
Chemins XPath pour la sélection des attributs
Maintenant que nous avons un document XSLT modulaire, il est plus facile de l’enrichir. Supposons que le document XML contienne des attributs... Le numéro d’assurance sociale des individus peut être indiqué par des attributs « nas », en utilisant le
symbole « @ » dans l’expression XPath, comme dans l’exemple qui suit :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml" type="application/xml"?>
<facture>
<montant>10.10</montant>
<recipiendaire>
<personne nas="423432432">
<sexe>M</sexe>
CC BY-NC-SA
Module 3 : Technologies XML
128
<nom>Rochond</nom>
<prenom>Jean</prenom>
</personne>
</recipiendaire>
<commercant>
<personne nas="432444333">
<sexe>F</sexe>
<nom>Ladouce</nom>
<prenom>Jeanne</prenom>
</personne>
</commercant>
<raison>Achat d’ordinateur</raison>
</facture>
En outre, si nous voulons afficher le numéro d’assurance sociale de l’individu entre
parenthèses, nous pourrons utiliser le fichier « xslt.xml » suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p>Ceci est une facture pour
<xsl:apply-templates select="recipiendaire" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
<p>Votre commerçant: <xsl:apply-templates select="commercant" /> </p>
</body>
</html>
</xsl:template>
<xsl:template match="personne">
<xsl:value-of select="prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="nom" />
( <xsl:value-of select="@nas" /> )
</xsl:template>
</xsl:stylesheet>
CC BY-NC-SA
XSLT
129
Notez que le chemin XPath « <xsl:value-of select="@nas" /> » ne donne pas le contenu
de l’élément « nas », mais plutôt la valeur de l’attribut ayant pour nom « nas ».
3.2.15
Expression XPath « . »
Supposons que, dans un modèle, nous voulions obtenir non pas la valeur d’un attribut
ou d’un sous-élément, mais la valeur de l’élément lui-même. On obtient ce résultat
avec l’expression XPath « . » (un point). Par exemple, nous pourrions définir le modèle
suivant :
<xsl:template match="prenom">
<xsl:value-of select="." />
</xsl:template>
Dans l’expression « select="." », le point représente l’élément courant, c’est-à-dire
l’élément « prenom ». Donc, l’élément « <xsl:value-of select="." /> » donne le contenu
de l’élément « courant ». Nous pourrions remplacer le fichier XSLT précédent par celui
qui suit et obtenir les mêmes résultats :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p>Ceci est une facture pour
<xsl:apply-templates select="recipiendaire" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
<p>Votre commerçant: <xsl:apply-templates select="commercant" /> </p>
</body>
</html>
</xsl:template>
<xsl:template match="personne">
<xsl:apply-templates select="prenom" />
<xsl:text> </xsl:text>
<xsl:value-of select="nom" />
( <xsl:value-of select="@nas" /> )
</xsl:template>
<xsl:template match="prenom">
CC BY-NC-SA
Module 3 : Technologies XML
130
<xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet>
Nous pourrions objecter que les instructions « <xsl:apply-templates select="recipiendaire" /> » et « <xsl:apply-templates select="commercant" /> »
sont étranges puisqu’il n’y a pas de modèle « recipiendaire » ou « commercant ».
Cependant, la règle par défaut qui s’applique aux éléments est d’appliquer les modèles
à leurs sous-éléments et ainsi de suite.
3.2.16
Spécifier les valeurs d’attributs
Nous savons maintenant comment aller chercher la valeur d’un attribut en utilisant une
expression XPath contenant le symbole « @ ». Cependant, qu’en est-il de la spécification des valeurs d’attributs? Supposons le document suivant :
<facture>
<montant>10.10</montant>
</facture>
Nous voulons le simplifier pour n’avoir que :
<facture montant="10.10" />
Nous pouvons obtenir ce résultat en utilisant les accolades, pour indiquer une valeur
XPath comme valeur d’attribut, de la façon suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<facture montant="{montant}" />
</xsl:template>
</xsl:stylesheet>
<section>Expression XPath «.»</section>
3.2.17
Expression XPath « .. »
L’expression « select=".." » (deux points successifs) peut être utilisée pour représenter
l’élément dans lequel se trouve l’élément courant. Ainsi, dans le modèle suivant
CC BY-NC-SA
XSLT
131
<xsl:template match="prenom">
<xsl:value-of select=".." />
</xsl:template>
l’instruction « <xsl:value-of select=".." /> » donne la valeur (texte contenu dans
l’élément sans les balises) de l’élément « personne » dans lequel est contenu l’élément « prenom ». Nous pouvons aller chercher le parent du parent avec l’instruction
<xsl:value-of select="../.." />.
Lorsque l’élément courant est l’élément-racine, l’expression « .. » (deux points successifs) ne devrait pas être utilisée.
3.2.18
Expression XPath « // »
Parfois, il est avantageux de sélectionner par nom tous les éléments qui sont dans l’élément courant ou dans un sous-élément; nous pouvons obtenir ce résultat avec l’expression XPath « // » (deux barres obliques). L’expression XPath « //prenom » sélectionne
tous les éléments prenom incluant ceux qui seraient contenus dans un élément nom, par
exemple. L’instruction <xsl:value-of select="//personne" /> donnera donc le contenu
textuel du premier élément personne recontré dans le document.
3.2.19
Expression XPath « * »
Parfois, il est avantageux de sélectionner tous les éléments qui sont dans l’élément
courant; nous pouvons obtenir ce résultat avec l’expression XPath « * » (astérisque).
Par exemple, le modèle qui suit s’applique à tous les éléments :
<xsl:template match="*">
Ceci est un élément.
</xsl:template>
Une expression avec « @* » sélectionne tous les attributs contenus dans un élément.
Dans certains cas, plus d’un modèle s’applique à un élément donné : en cas de doute, le
processeur applique le modèle le plus « spécifique »; le modèle pour « * » ne s’applique
que s’il n’existe aucun autre modèle.
De la même façon, nous pouvons indiquer au processeur XSLT d’appliquer les règles
à tous les éléments, en utilisant la syntaxe <xsl:apply-templates select="*" />.
3.2.20
Expression XPath avec « | »
Parfois, nous voulons sélectionner plusieurs noms d’éléments; nous pouvons obtenir
ce résultat avec le symbole « | » (barre verticale) qui signifie « union ». Par exemple, le
CC BY-NC-SA
Module 3 : Technologies XML
132
modèle qui suit s’applique à tous les éléments « facture » et « montant », et seulement
à ces éléments :
<xsl:template match="facture|montant">
Ceci est un élément facture ou montant.
</xsl:template>
3.2.21
Expression XPath pour le nom d’un élément
Supposons que nous voulions afficher uniquement les noms des éléments (sans leur
contenu). Nous pouvons obtenir ce résultat avec la fonction XPath « name » qui donne
le nom de l’élément. La fonction name inclut le préfixe de l’espace de noms. Si on
souhaite le nom de l’élément sans le préfixe, on peut utiliser la fonction « local-name ».
La fonction « namespace-uri » donne l’URI de l’espace de noms de l’élément.
Ainsi, le document XSLT suivant permet d’afficher tous les noms des éléments XML,
sans le contenu textuel de ces éléments.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:value-of select="name(.)" />
<xsl:apply-templates select="*" />
</xsl:template>
</xsl:stylesheet>
Nous pourrions aussi vouloir afficher non seulement le nom de l’élément courant, mais
aussi le nom de l’élément-parent, ce qu’on peut faire avec le document XSLT suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:value-of select="name(..)" /> / <xsl:value-of select="name(.)" />
<xsl:apply-templates select="*" />
</xsl:template>
</xsl:stylesheet>
3.2.22
Notion de nœuds XSLT
Un processeur XSLT traite un fichier XML en partant du début et en appliquant ses
règles au fur et à mesure qu’il rencontre des éléments. Rappelons que si le processeur
CC BY-NC-SA
XSLT
133
XSLT rencontre un élément pour lequel il n’a aucune règle (modèle), il visite tous les
sous-éléments et applique le modèle par défaut, soit reproduire le texte quand il en
rencontre, en omettant les balises.
Une autre façon de décrire ce comportement est de dire que le XSLT utilise un modèle
de fichiers XML « en arbre de nœuds ». Imaginons un arbre où, à la racine, se trouve
un nœud spécial représentant le document dans son ensemble. Avec XPath, nous pouvons pointer directement sur le nœud-racine (le document lui-même) en utilisant la
barre oblique « / » que nous plaçons au début de l’expression XPath, comme dans
« <xsl:value-of select="/" /> ». Dans ce cas, « <xsl:value-of select="/jean" /> » donne
la valeur de l’élément-racine, si celui-ci se nomme « jean ».
Le nœud-racine contient lui-même l’élément-racine. Chaque élément et chaque élément de texte sont aussi des nœuds dans ce modèle d’arbre XSLT. Alors que les nœuds
de texte ne peuvent pas contenir d’autres nœuds, les nœuds d’élément peuvent contenir
plusieurs autres nœuds dont d’autres nœuds d’élément et de texte.
Ainsi, par défaut, le processeur XSLT qui atteint un élément visite tous les éléments et
les nœuds de texte qu’il contient. Un nœud de texte rencontré est simplement recopié,
par défaut, alors que pour les éléments, on visite également leur contenu. C’est ce qui
explique que, par défaut, s’il n’y a aucune règle dans le document XSLT, un document
XML est recopié sans les balises.
D’autres nœuds existent comme les nœuds de commentaire, les nœuds d’instructions
de traitement et les nœuds d’espaces de noms, mais ils sont moins importants que
le nœud du document (nœud-racine), les nœuds d’attribut, les nœuds de texte ou les
nœuds d’élément. Dans le modèle d’arbre, les nœuds d’espaces de noms et les nœuds
d’attribut sont attachés à l’élément, mais ne sont pas un enfant (« child »).
Nous avons déjà vu que « * » et « @* » permettaient de sélectionner les sous-éléments
et attributs d’un élément. On peut sélectionner les nœuds de texte avec la fonction
XPath « text() ». Notons aussi que l’élément « <xsl:apply-templates/> » signifie que
les modèles s’appliquent à tous les nœuds contenus dans le nœud courant. Les règles
par défaut qui s’appliquent en XSLT sont :
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
<xslt:template match="processing-instruction()|comment()"
/>
En résumé, un processeur XSLT représente un document XML comme un arbre et
tente de le visiter de la racine vers les feuilles. Lorsqu’il rencontre un modèle pour un
CC BY-NC-SA
Module 3 : Technologies XML
134
nœud, il l’applique et ne poursuit pas automatiquement la visite des nœuds qui y sont
contenus, à moins de rencontrer un élément « xsl:apply-templates ».
3.2.23
Expressions XPath pour compter et additionner les éléments
Avec XSLT et XPath, on peut faire un certain nombre d’opérations, comme compter
les éléments. La fonction XPath « count » compte le nombre de nœuds (éléments)
sélectionnés. Soit le document XML suivant :
<facture>
<montant>10.10</montant>
<montant>20.10</montant>
</facture>
Supposons qu’on veuille calculer automatiquement le nombre d’éléments « montant »
pour obtenir quelque chose comme ceci :
<facture nombre="2" />
Il suffit simplement d’utiliser la fonction « count », comme dans l’exemple de document XSLT qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<facture nombre="{count(montant)}" />
</xsl:template>
</xsl:stylesheet>
Supposons maintenant qu’on veuille numéroter les montants pour bien indiquer quel
montant apparaît en premier, quel montant apparaît en deuxième, et ainsi de suite.
Pour ce faire, il n’y a pas d’expression XPath appropriée, mais nous pouvons obtenir
le résultat désiré à l’aide de l’élément XSLT « xsl:number » et son attribut « count ».
En effet, le document XSLT qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<xsl:apply-templates select="montant" />
</xsl:template>
<xsl:template match="montant">
CC BY-NC-SA
XSLT
135
Montant numero <xsl:number count="montant" />
est <xsl:value-of select="." />.
</xsl:template>
</xsl:stylesheet>
permet d’obtenir le résultat suivant :
Montant numero 1 est 10.10.
Montant numero 2 est 20.10.
L’élément « xsl:number » avec l’attribut « count » permet de numéroter des éléments
sur la base de leur nom, que l’on utilise comme valeur de l’attribut « count ».
On peut aussi additionner des nombres avec la fonction XPath « sum ». L’exemple
suivant fera la somme des valeurs numériques contenues dans les éléments « montant »
(10.10 et 20.10).
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="facture">
<xsl:value-of select="sum(montant)" />
</xsl:template>
</xsl:stylesheet>
3.2.24
Utilisation de l’attribut « mode »
Il arrive que nous voulions définir plus d’un modèle pour un élément donné. Nous pouvons ajouter des modèles en utilisant l’attribut « mode » qui s’applique aux éléments
« xsl:apply-templates » et « xsl:template ». La règle est très simple : si votre élément
« xsl:apply-templates » a une valeur d’attribut pour « mode », alors seuls les éléments
« xsl:template » ayant la même valeur d’attribut pour « mode » s’appliquent. On utilise
souvent l’attribut « mode » pour faire des tables des matières.
Prenons, par exemple, la liste de cours suivants :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<universite>
<cours><nom>INF 102 Introduction avancée</nom>
<description>Un cours d’introduction à l’informatique pour futurs
ingénieurs.</description></cours>
<cours><nom>INF 101 Introduction</nom>
<description>Un cours d’introduction à l’informatique pour les
étudiants en éducation.</description></cours>
<cours><nom>INF 103 Java</nom>
CC BY-NC-SA
Module 3 : Technologies XML
136
<description>Un cours d’introduction au Java</description></cours>
</universite>
Nous pourrions vouloir que s’affiche d’abord seulement la liste des noms de cours et
que cette dernière soit suivie d’une liste détaillée comprenant le nom et la description
du cours :
La liste des cours en bref:
– INF 102 Introduction avancée
– INF 101 Introduction
– INF 103 Java
La liste détaillée des cours:
– INF 102 Introduction avancée: Un cours d’introduction à l’informatique pour futurs
ingénieurs.
– INF 101 Introduction: Un cours d’introduction à l’informatique pour les étudiants
en éducation.
– INF 103 Java: Un cours d’introduction au Java
Nous pouvons obtenir ce résultat avec le document XSLT suivant qui utilise l’attribut
« mode » :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="universite">
<html><body>
<p>La liste des cours en bref:</p>
<ul>
<xsl:apply-templates select="cours" mode="initial" />
</ul>
<p>La liste détaillée des cours:</p>
<ul>
<xsl:apply-templates select="cours" mode="complet" />
</ul>
</body></html>
</xsl:template>
<xsl:template match="cours" mode="initial">
<li><xsl:value-of select="nom" /></li>
</xsl:template>
<xsl:template match="cours" mode="complet">
<li><xsl:value-of select="nom" /> :
<xsl:value-of select="description" /></li>
</xsl:template>
CC BY-NC-SA
XSLT
137
</xsl:stylesheet>
3.2.25
Fonction « generate-id »
La fonction XSLT « generate-id » génère un « nom » unique pour chaque élément d’un
document XML. Ce nom sera toujours le même pour un même élément, même si nous
le rencontrons à plusieurs reprises. Si nous reprenons la liste des cours de l’exemple
précédent sur l’utilisation de l’attribut « mode », nous pourrions générer un identifiant
unique pour chaque cours et l’afficher comme dans l’exemple de document XSLT qui
suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="universite">
<html><body>
<p>La liste des cours en bref :</p>
<ul>
<xsl:apply-templates select="cours" mode="initial" />
</ul>
<p>La liste détaillée des cours :</p>
<ul>
<xsl:apply-templates select="cours" mode="complet" />
</ul>
</body></html>
</xsl:template>
<xsl:template match="cours" mode="initial">
<li><xsl:value-of select="nom" />
(identifiant: <xsl:value-of select="generate-id(.)" />)</li>
</xsl:template>
<xsl:template match="cours" mode="complet">
<li><xsl:value-of select="nom" /> :
<xsl:value-of select="description" />
(identifiant: <xsl:value-of select="generate-id(.)" />)</li>
</xsl:template>
</xsl:stylesheet>
Nous pourrions alors obtenir un résultat comme celui-ci :
La liste des cours en bref:
– INF 102 Introduction avancée (identifiant: id2243749)
– INF 101 Introduction (identifiant: id2243760)
– INF 103 Java (identifiant: id2243686)
CC BY-NC-SA
Module 3 : Technologies XML
138
La liste détaillée des cours:
– INF 102 Introduction avancée: Un cours d’introduction à l’informatique pour futurs
ingénieurs. (identifiant: id2243749)
– INF 101 Introduction: Un cours d’introduction à l’informatique pour les étudiants
en éducation. (identifiant: id2243760)
– INF 103 Java: Un cours d’introduction au Java (identifiant: id2243686)
Les valeurs exactes que prennent les identifiants sont sans importance, mais il importe
que ce soit toujours la même valeur pour un même élément. Par exemple, le cours sur
Java obtient toujours l’identifiant « id2243686 » dans notre exemple.
3.2.26
Utilisation des tests
Nous pouvons tester des conditions à l’aide d’expressions XPath contenant les symboles « < », « = », « != », « or », « and », « > », « >= », « <= ». Nous utilisons les
tests en XSLT avec les éléments « xsl:choose » et « xsl:if ». Par exemple, faire quelque
chose de particulier, si le nom de l’élément courant est « montant ».
<xsl:template match="*">
<xsl:if test="name(.) = ’montant’">
Il s’agit d’un élément nommé «montant».
</xsl:if>
</xsl:template>
La syntaxe de l’élément « xsl:if » est très simple; si la valeur de l’expression XPath
contenue dans l’attribut « test » est vraie, le contenu de l’élément « xsl:if » s’applique,
sinon, on l’omet. Notez qu’il n’y a pas d’élément « xsl:else »
Nous pouvons aussi traiter plusieurs tests dans un seul élément « xsl:choose » comme
ceci :
<xsl:template match="*">
<xsl:choose>
<xsl:when test="name(.)=’montant’">
Il y a une balise "montant"
</xsl:when>
<xsl:when test="name(.)=’facture’">
J’ai trouvé une "facture"
</xsl:when>
<xsl:otherwise>
Je ne connais pas cet élément
</xsl:otherwise>
</xsl:choose>
</xsl:template>
CC BY-NC-SA
XSLT
139
On peut aussi combiner plusieurs tests avec les opérateurs logiques and, or et not
comme le montre le prochain exemple.
<xsl:template match="*">
<xsl:choose>
<xsl:when test="name(.)=’montant’ or name(.)=’facture’">
Il y a une balise "montant" ou une
balise "facture"
</xsl:when>
<xsl:when test="not(name(.)=’argent’)">
Ce n’est ni montant, ni facture, ni argent.
</xsl:when>
<xsl:otherwise>
Je ne connais pas cet élément.
</xsl:otherwise>
</xsl:choose>
</xsl:template>
On peut aussi tester la langue d’un élément avec la fonction XPath « lang ». L’expression « count(//p[lang(’en’)]) » compte le nombre d’élément « p » ayant été déclaré
comme contenant du texte en langue anglaise.
Observez qu’un élément « xsl:choose » contient plusieurs éléments « xsl:when »
qui sont testés tour à tour, jusqu’à ce qu’une condition soit vraie; l’élément
« xsl:otherwise » est présent pour l’éventualité où tous les tests échouent. Tous les
tests sont réalisés en séquence et dès qu’une condition est vraie, les tests s’arrêtent et
le contenu de l’élément « xsl:when » est évalué.
En XSLT, il ne faut pas abuser des tests; il est préférable d’utiliser des éléments
« xsl:template » qui sont plus modulaires.
3.2.27
Tester le contenu des chaînes de caractères
Nous avons vu comment comparer le nom ou le contenu d’un élément avec une chaîne
de caractères donnée, mais il arrive qu’on veuille faire des comparaisons plus fine.
Heureusement, il existe des fonctions XPath permettant d’analyser le contenu des
chaînes. Par exemple, « starts-with("a",@toto) » renvoie la valeur vraie si et seulement si la valeur de l’attribut « toto » débute avec la lettre « a ». L’expression « endswith("a",@toto) » est vraie si et seulement si la valeur de l’attribut « toto » se termine
avec la lettre « a ». De la même façon, « contains("abc",@toto) » renvoie la valeur vraie
si et seulement si la valeur de l’attribut « toto » contient la chaîne « abc » (comme dans
« j’ai un abc »).
CC BY-NC-SA
Module 3 : Technologies XML
3.2.28
140
Accès aux éléments d’un ensemble d’éléments
Avec XSLT, nous pouvons traiter du XML un peu comme nous traitons un tableau en
Java ou en C/C++. Par exemple, supposons que nous ayons une liste de clients avec
leur numéro de téléphone, comme ceci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<listedeclients>
<client telephone="543-5454"><nom>Jacques</nom></client>
<client telephone="545-5455"><nom>Sylvain</nom></client>
<client telephone="443-4456"><nom>Claude</nom></client>
<client telephone="533-3445"><nom>Yvon</nom></client>
</listedeclients>
Notez que l’expression XPath « /listedeclients/client » est en fait une séquence (ensemble ordonné) d’éléments. Ainsi, « /listedeclients/client[2] » représente le deuxième
(et non le troisième!) élément « client », celui dont le nom est « Sylvain ».
Maintenant, si nous voulons obtenir le numéro de téléphone du deuxième client de
la liste, il faut d’abord ajouter le symbole « / » (barre oblique) pour indiquer qu’on
cherche un sous-nœud de l’élément en question, suivi de « @telephone » pour désigner l’attribut « telephone ». Le document XSLT suivant nous donnerait le numéro de
téléphone désiré :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="listedeclients">
<xsl:value-of select="/listedeclients/client[2]/@telephone" />
</xsl:template>
</xsl:stylesheet>
Ou, plus simplement :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="listedeclients">
<xsl:value-of select="client[2]/@telephone" />
</xsl:template>
</xsl:stylesheet>
Notez que l’expression « /listedeclients/client[0] » n’est pas valable, car la numérotation des éléments d’une séquence débute à 1 en XSLT, contrairement à Java et à C/C++.
CC BY-NC-SA
XSLT
141
Notez aussi qu’on aurait pu obtenir le même résultat avec l’expression XPath « (/listedeclients/client/@telephone)[2] », car « /listedeclients/client/@telephone » est aussi
une séquence (mais une séquence d’attributs). Nous devons toutefois ajouter une parenthèse pour marquer la priorité des opérations. En effet, la syntaxe « a/b[2] » signifie :
deuxième nœud de type « b » dans les nœuds de type « b ». Comme il ne peut y avoir
qu’un seul attribut d’un type donné dans un élément, la syntaxe « a/@b[2] » donnera
toujours un ensemble vide. D’un autre côté, la syntaxe « (a/b)[2] » signifie : deuxième
nœud de type « b » dans la séquence des nœuds de type « b » contenus dans les nœuds
de type « a ». De la même manière, « //b[2] » donne la liste de tous les éléments b « b »
dans le document apparaissant deuxième dans la liste des éléments contenus dans un
autre élément, alors que « (//b)[2] » est le deuxième élément « b » rencontré dans tout
le document.
Vous croyez avoir bien compris ? Quelle est la différence entre « (b)[2] » et « b[2] » ?
Quelle est la différence entre « (b[2])/a » et « b[2]/a » ?
3.2.29
Utiliser XSLT comme base de données et éléments « foreach »
L’exemple de la liste des clients avec leur numéro de téléphone nous permet de
faire plus. Nous pouvons y utiliser XSLT comme « moteur (primitif) de base
de données », en cherchant les éléments selon leur contenu. L’expression XPath
« /listedeclients/client[nom=’Sylvain’] » nous donnera les éléments pour lesquels
le contenu du sous-élément « nom » est « Sylvain ». L’expression plus complète
« /listedeclients/client[nom=’Sylvain’]/@telephone » pointera directement sur l’attribut « telephone » dont la valeur est « 545-5455 ». D’un autre côté, l’expression
XPath « /listedeclients/client[@telephone=’533-3445’]/nom », nous donnera l’élément
« nom » contenant le nom du client ayant le numéro de téléphone indiqué.
L’absence du symbole « = » dans le crochets indique qu’il s’agit d’un test d’existence.
Ainsi, « /listedeclients/client[nom] » donne les éléments « client » qui ont un sousélément « nom ». De la même façon, « /listedeclients/client[@telephone] » donne les
éléments « client » qui ont un attribut « telephone ».
Supposons maintenant que nous soyons devant un fichier XML comme celui-ci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<listes>
<vendeur nom="Jean">
<client telephone="543-5454"><nom>Jacques</nom></client>
<client telephone="545-5455"><nom>Sylvain</nom></client>
<client telephone="443-4456"><nom>Claude</nom></client>
<client telephone="533-3445"><nom>Yvon</nom></client>
</vendeur>
<vendeur nom="Raymond">
<client telephone="432-2145"><nom>Arthur</nom></client>
CC BY-NC-SA
Module 3 : Technologies XML
142
<client telephone="545-5456"><nom>Sylvain</nom></client>
<client telephone="443-4556"><nom>Claudette</nom></client>
<client telephone="533-3445"><nom>Yvon</nom></client>
</vendeur>
</listes>
Il est maintenant plus fastidieux de trouver le numéro de téléphone d’un certain client,
car il faut visiter tous les vendeurs. De plus, chaque vendeur peut avoir un numéro de
téléphone (possiblement différent) pour chaque client. Comme nous allons le voir, le
XSLT permet de gérer assez facilement ces situations.
Tout d’abord, l’expression « //client » donne une séquence de tous les éléments
« client » dans le nœud courant. Avec l’expression XPath « //client[nom=’Sylvain’] »,
nous pouvons obtenir la séquence de tous les éléments « client » ayant pour nom « Sylvain ». Dans ce cas précis, il y a plus d’un élément dans la réponse. Pour visiter l’ensemble des éléments dans la séquence, il suffit d’utiliser l’élément « xsl:for-each »
comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>Numéros de téléphone pour Sylvain:
<ul>
<xsl:for-each select="//client[nom=’Sylvain’]/@telephone" >
<li><xsl:value-of select="." /></li>
</xsl:for-each>
</ul>
</body></html>
</xsl:template>
</xsl:stylesheet>
Le résultat de l’application de ce fichier XSLT au fichier XML contenant les numéros
de téléphone sera :
<html><body>Numéros de téléphone pour Sylvain:
<ul>
<li>545-5455</li>
<li>545-5456</li>
</ul>
</body></html>
CC BY-NC-SA
XSLT
143
Dans une telle boucle, il peut être utile de savoir quel est le numéro du nœud courant.
On obtient ce numéro avec la fonction XSLT « position() » qui a la valeur 1 quand il
s’agit du premier nœud et la valeur « last() » quand il s’agit du dernier nœud. On peut
aussi utiliser une instruction xsl:sort au sein d’un élément for-each.
Supposons maintenant que nous voulions compter le nombre de fois qu’un client est
dans la base de données. Un modèle XSLT comme celui qui suit semble une bonne
piste :
<xsl:template match="client">
<li><xsl:value-of select="count(//client[nom=./nom])" /></li>
</xsl:template>
Malheureusement, entre les crochets (partie conditionnelle de l’expression XPath), le
symbole « . » ne représente plus l’élément « client » XSLT courant, mais bien chacun
des éléments « client » du document tour à tour : la condition « nom=./nom » est ici
toujours satisfaite. Heureusement, il existe une fonction XSLT, appelée « current() »,
qui représente toujours l’élément XSLT courant. Donc, si nous voulons parcourir tout
le document et trouver combien de fois chaque client est dans la liste, nous pourrions
utiliser le document XSLT suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="listes">
<html><body><ul>
<xsl:apply-templates match="*" />
</ul></body></html>
</xsl:template>
<xsl:template match="vendeur">
<li><p>Nom du vendeur: <xsl:value-of select="@nom" /></p>
<ul><xsl:apply-templates match="*" /></ul></li>
</xsl:template>
<xsl:template match="client">
<li><xsl:value-of select="nom" />:
<xsl:value-of select="count(//client[nom=current()/nom])" /></li>
</xsl:template>
</xsl:stylesheet>
Le résultat de la transformation sera alors :
CC BY-NC-SA
Module 3 : Technologies XML
144
<html><body><ul>
<li>
<p>Nom du vendeur: Jean</p>
<ul>
<li>Jacques:
1</li>
<li>Sylvain:
2</li>
<li>Claude:
1</li>
<li>Yvon:
2</li>
</ul>
</li>
<li>
<p>Nom du vendeur: Raymond</p>
<ul>
<li>Arthur:
1</li>
<li>Sylvain:
2</li>
<li>Claudette:
1</li>
<li>Yvon:
2</li>
</ul>
</li>
</ul></body></html>
Nous verrons dans la section suivante comment faire pour ne présenter chaque client
qu’une seule fois.
3.2.30
Obtenir l’aggrégation avec la fonction « generate-id »
Supposons qu’on veuille calculer le total des éléments « quantite », mais en faisant
l’aggrégation pour chaque valeur de l’attribut « type » dans l’exemple suivant.
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="produits.xsl" type="text/xsl" ?>
<produits>
<france>
<quantite type="bain">53</quantite>
<quantite type="chambre">12</quantite>
</france>
CC BY-NC-SA
XSLT
145
<canada>
<quantite type="bain">14</quantite>
<quantite type="chambre">12</quantite>
</canada>
</produits>
On pourrait tenter de résoudre ce problème avec une expression XPath de la forme
« sum(//quantite[@type=current()/@type]) ». Malheureusement, on risque alors de calculer plusieurs fois la même somme. Par exemple, tentez d’appliquer la transformation
suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="produits">
<html>
<body>
<xsl:apply-templates select="*" />
</body>
</html>
</xsl:template>
<xsl:template match="quantite">
<p>
<xsl:value-of select="@type" />
- <xsl:value-of select="sum(//quantite[@type=current()/@type])" />
</p>
</xsl:template>
</xsl:stylesheet>
Vous obtiendrez alors le résultat suivant :
<html><body>
<p>bain
- 67</p>
<p>chambre
- 24</p>
<p>bain
- 67</p>
<p>chambre
- 24</p>
</body></html>
Pour calculer la somme qu’une seule fois pour chaque valeur de l’attribut type, on
pourrait ne faire le calcul que la première fois qu’on rencontre une valeur d’attribut
CC BY-NC-SA
Module 3 : Technologies XML
146
donnée. L’expression XPath « //quantite[@type=x] » représente l’ensemble des éléments quantite ayant un attribut de valeur x. L’expression « //quantite[@type=x][1] »
nous donne le premier élément de ce type rencontré. On pourrait penser que l’expression XPath « //quantite[@type=x][1]=current() » permet de déterminer si le nœud
courant est le premier. Malheureusement, cette expression XPath vérifie plutôt si
les deux éléments ont le même contenu. Comme nous avons deux éléments quantite ayant le même contenu dans notre exemple, cette solution ne suffit pas. La
fonction generate-id quant à elle associe un identifiant unique à chaque nœud d’un
document XML et permet donc de distinguer les éléments entre eux même lorsqu’ils ont le même contenu. L’expression « //quantite[@type=current()/@type]) »
donne la séquence de tous les éléments quantite ayant un attribut type de même
valeur que l’élément courant, alors que « (//quantite[@type=current()/@type])[1] »
sélectionne le premier de cette liste. On peut vérifier si l’élément « quantite »
est le premier du document ayant un certain type avec la fonction « generateid » et l’expression « generate-id((//quantite[@type=current()/@type])[1]) = generateid(.) ». On peut aussi vérifier que c’est le dernier avec l’expression « generateid((//quantite[@type=current()/@type])[last()]) = generate-id(.) ». En utilisant cette astuce, on peut obtenir l’aggrégation souhaitée avec le programme XSLT suivant où l’on
fait la somme seulement pour le premier élément rencontré ayant un certain type :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="produits">
<html>
<body>
<xsl:apply-templates select="*" />
</body>
</html>
</xsl:template>
<xsl:template match="quantite">
<xsl:if
test="generate-id((//quantite[@type=current()/@type])[1])
= generate-id(.)" >
<p>
<xsl:value-of select="@type" />
- <xsl:value-of select="sum(//quantite[@type=current()/@type])" />
</p>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
On peut appliquer cette technique à notre exemple de la section précédente avec les
vendeurs et les clients. La transformation suivante permet de ne calculer la fréquence
de chaque client qu’une seule fois.
CC BY-NC-SA
XSLT
147
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="listes">
<html><body><ul>
<xsl:apply-templates match="*" />
</ul></body></html>
</xsl:template>
<xsl:template match="vendeur">
<xsl:apply-templates match="*" />
</xsl:template>
<xsl:template match="client">
<xsl:if test="generate-id(.)=generate-id(//client[nom=current()/nom][1])">
<li><xsl:value-of select="nom" />:
<xsl:value-of select="count(//client[nom=current()/nom])" /></li>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Le résultat de cette transformation donne une liste désordonnée de clients :
<html><body><ul>
<li>Jacques:
1</li>
<li>Sylvain:
2</li>
<li>Claude:
1</li>
<li>Yvon:
2</li>
<li>Arthur:
1</li>
<li>Claudette:
1</li>
</ul></body></html>
On peut trier le nom des clients en utilisant un élément xsl:sort :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
CC BY-NC-SA
Module 3 : Technologies XML
148
<xsl:template match="listes">
<html><body><ul>
<xsl:for-each select="//client" >
<xsl:sort select="nom" order="ascending" data-type="text" />
<xsl:if test="generate-id(.)=generate-id(//client[nom=current()/nom][1])">
<li><xsl:value-of select="nom" />:
<xsl:value-of select="count(//client[nom=current()/nom])" /></li>
</xsl:if>
</xsl:for-each>
</ul></body></html>
</xsl:template>
</xsl:stylesheet>
3.2.31
Un peu plus de performance avec la function XSLT « key »
Le
problème
avec
l’utilisation
d’expressions
XPath
telles
que
//client[nom=current()/nom] est qu’elles peuvent s’avérer coûteuses en temps de
calcul si on les utilisent à répétition. Afin d’accélérer les choses et simplifier un
peu nos programmes, on peut créer un tableau associatif avec l’élément xsl:key et
sa fonction correspondante key. Un tableau associatif est simplement une structure
de donnée qui associe à chaque clef ou au plusieurs valeurs. Puisque ce tableau est
construit une seule fois lorsque le processeur rencontre l’élément xsl:key, le processeur
XSLT n’a pas à visiter les nœuds du document plusieurs fois. L’élément xsl:key
comprend trois attributs incluant le nom du tableau associative (name), les clefs à
inclure (use) et les nœuds à traiter (match). L’instruction <xsl:key name="montableau"
match="client" use="nom"/> va créer un tableau associatif s’appelant montableau et
qui associe à chaque valeur client/nom l’élément nom correspondant. La fonction key
quant à elle prend deux paramètres incluant le nom du tableau et la valeur de la clef. À
titre d’exemple, la transformation suivante permet de calculer la fréquence de chaque
client comme à la question précédente, mais en utilisant un tableau associatif :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="montableau" match="client" use="nom"/>
<xsl:template match="listes">
<html><body><ul>
<xsl:for-each select="//client" >
<xsl:sort select="nom" order="ascending" data-type="text" />
<xsl:if test="generate-id(.)=generate-id(key(’montableau’,nom)[1])">
<li><xsl:value-of select="nom" />:
<xsl:value-of select="count(//client[nom=current()/nom])" /></li>
</xsl:if>
</xsl:for-each>
CC BY-NC-SA
XSLT
149
</ul></body></html>
</xsl:template>
</xsl:stylesheet>
3.2.32
Les variables
Il est possible, en XSLT, de définir des variables, mais elles sont « immutables » (« dont
la valeur ne peut être modifiée »). On peut se demander, à juste titre, si les mots
variables et immutables vont bien ensemble, mais c’est ainsi que les inventeurs du
XSLT se sont exprimés. Pour définir une variable nommée « test », on utilise l’élément
« <xsl:variable name="test" select="xxx" /> ». La variable contiendra alors le résultat de l’expression XPath contenue dans l’attribut « select ». L’exemple suivant peut
être utilisé pour afficher le contenu de tous les éléments « produit » immédiatement
contenus dans l’élément racine.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="test" select="/" />
<xsl:template match="$test/produit">
<xsl:value-of select="*" />
</xsl:template>
</xsl:stylesheet>
On peut aussi définir la valeur de la variable en omettant l’attribut « select » et en
ajoutant du contenu à l’élément « xsl:variable ». Ce contenu pourrait comprendre du
XSLT.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="test" >
<produit>x</produit>
</xsl:variable>
<xsl:template match="$test/produit">
<xsl:value-of select="*" />
</xsl:template>
</xsl:stylesheet>
On peut déclarer la variable localement au sein d’un élément template :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
CC BY-NC-SA
Module 3 : Technologies XML
150
<xsl:template match="/">
<xsl:variable name="test" >
<produit>x</produit>
</xsl:variable>
<xsl:value-of select="$test" />
</xsl:template>
</xsl:stylesheet>
3.2.33
Les paramètres
Un fichier XSLT peut être utilisé comme un programme dans la mesure où on peut lui
passer des paramètres. Rappelons qu’on appelle un fichier XSLT « xslt.xml » à partir
d’un fichier XML qu’on veut transformer de cette manière :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml"
type="application/xml"?>
<facture>
<montant>10.10</montant>
<personne>Jean Rochond</personne>
<raison>Achat d’ordinateur</raison>
</facture>
On peut enrichir cet appel avec les instructions « xslt-param » comme dans cet exemple.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xslt-param name="couleur" value="blue"?>
<?xslt-param name="taille" value="2"?>
<?xml-stylesheet href="xslt.xml"
type="application/xml"?>
<facture>
<montant>10.10</montant>
<personne>Jean Rochond</personne>
<raison>Achat d’ordinateur</raison>
</facture>
Selon votre processeur XSLT, il peut y avoir d’autres façons de passer des paramètres
à une feuille de style XSLT.
On reçoit alors les paramètres avec un élément « xsl:param ». L’attribut « select » est
utilisé pour spécifier une valeur par défaut.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
CC BY-NC-SA
XSLT
151
<xsl:param name="couleur" select="red">
<xsl:param name="taille" select="1">
<xsl:template match="facture">
<html>
<head>
<title>Facture de <xsl:value-of select="personne" /></title>
</head>
<body>
<p style="color:{$couleur}; font-size:{$taille}em">Ceci est
une facture pour <xsl:value-of select="personne" />
de <xsl:value-of select="montant" />$ pour:
<xsl:value-of select="raison" />.</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
On peut aussi passer des paramètres aux éléments « xsl:template » avec les éléments
« xsl:call-template » comme dans cet exemple qui est une façon équivalente, mais plus
compliquée, de formater notre document XML de type « facture » .
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="facture">
<xsl:call-template name="monmotif">
<xsl:with-param name="title" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="monmotif">
<xsl:param name="contenu" />
<html>
<head>
<title>Facture de <xsl:value-of select="$contenu/personne" /></title>
</head>
<body>
<p>Ceci est
une facture pour <xsl:value-of select="$contenu/personne" />
de <xsl:value-of select="$contenu/montant" />$ pour:
<xsl:value-of select="$contenu/raison" />.</p>
</body>
</html>
CC BY-NC-SA
Module 3 : Technologies XML
152
</xsl:template>
</xsl:stylesheet>
On peut aussi charger des documents distants avec la fonction XSLT « document » ,
cette instruction donne une copie du document situé à l’adresse @href : <xsl:copy-of
select="document(@href)"/>. (L’élément « xsl:copy-of » sert ici à faire une copies des
nœuds contenus dans le document distant.) Elle est cependant sujette à des contraintes
de sécurité lorsqu’on l’utilise dans un navigateur : il n’est pas permis de charger des
documents provenant d’autres serveurs que le serveur d’origine.
3.2.34
Générer un commentaire
Il arrive qu’on veuille produire un commentaire dans la sortie XML. Rien de plus
simple ! Il suffit d’utiliser l’instruction xsl:comment comme dans cet exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:comment>Ceci est un commentaire.</xsl:comment>
</xsl:stylesheet>
Le résultat devrait ressembler à ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--Ceci est un commentaire.-->
3.2.35
Créer des éléments dynamiquement avec « xsl:element »
Il est parfois utile de créer dynamiquement un élément avec « xsl:element » et de créer
des attributs avec « xsl:attribute ». Dans l’exemple suivant, on va créer un élément dont
le nom nous est fourni par un paramètre.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="ele" select="p">
<xsl:template match="/">
<xsl:element name="{$ele}" namespace="http://mondom.com/" >
<xsl:attribute name="couleur" namespace="http://mondom.com/">
bleu
</xsl:attribute>
CC BY-NC-SA
XSLT
153
</xsl:element>
</xsl:template>
</xsl:stylesheet>
3.2.36
Copier des nœuds avec « xsl:copy » et « xsl:copy-of »
Il est parfois nécessaire de dire au XSLT qu’on souhaite tout simplement recopier le
nœud courant dans le document sortant. L’élément « xsl:copy » copie l’élément (seul,
sans ses attributs mais avec son espace de noms) alors que l’élément « xsl:copy-of »
permet de copier un élément ainsi que tous les nœuds qu’il contient. XSLT ne transforme pas les nœuds ainsi copiés, ils sont insérés dans le résultat directement. Par
exemple, ce document XSLT va créer une copie intégrale du document:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
Dans le cas où l’on sélectionne plus d’un élément, notamment avec une expression du
type nom|prenom, tous les éléments sont copiés l’un après l’autre. Ce comportement
diffère de l’instruction value-of qui n’extrait le contenu textuel que du premier élément
rencontré.
Par contre, si on ne souhaite qu’un document XML qui contient le même élémentracine, mais sans le contenu de l’élément racine, on utilisera plutôt un élément
« xsl:copy », comme ceci :
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
Naturellement, on peut même définir le contenu de l’élément copié à l’aide d’un modèle :
CC BY-NC-SA
Module 3 : Technologies XML
154
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/*">
<xsl:copy >
<a>x</a>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Si on souhaite ne copier qu’une partie du contenu de l’élément ainsi reproduit, par
exemple ses attributs, on peut utiliser copy-of :
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/*">
<xsl:copy >
<xsl:copy-of select="@*"/>
<a>x</a>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
3.2.37
Union, intersection et différence en XSLT
Nous avons vu que le symbole « | » nous permet d’obtenir l’union de deux expressions
XPath. Prenons l’exemple de ce document :
<x>
<a s="1"
<b s="1"
<c s="0"
<d s="0"
</x>
t="0"
t="1"
t="1"
t="0"
/>
/>
/>
/>
L’expression « //*[@s="1"] » représente les éléments a et b, l’expression
« //*[@t="1"] » représente les éléments b et c, alors que l’expression
« //*[@s="1"]|//*[@t="1"] » représente les éléments a,b,c (une union de
« //*[@s="1"] » et « //*[@t="1"] »).
CC BY-NC-SA
XSLT
155
Supposons maintenant que nous désirions obtenir les éléments qui satisfont « @s="1" »
et « @t="1" » : on veut calculer l’intersection entre « //*[@s="1"] » et « //*[@t="1"] ».
On pourrait, bien sûr, obtenir ce résultat avec « //*[@s="1" and @t="1"] », mais il
existe une autre façon de le faire qui est d’application plus générale. Supposons que les
résultats des expressions « //*[@s="1"] » et « //*[@t="1"] » sont déjà stockés dans les
variables a1 et a2 respectivement. Alors l’expression « $a1[count(.|$a2)=count($a2)] »
sélectionne l’élément b (ou « //*[@s="1" and @t="1"] »). Ce motif particulier calcule
l’intersection entre le contenu des variables a1 et a2. Pour le comprendre, il suffit de
réaliser que la condition « count(.|$a2)=count($a2) » n’est vraie que pour les nœuds
appartenant déjà à l’ensemble a2.
Supposons maintenant que l’on souhaite trouver les éléments qui satisfont « @s="1" »
mais pas « @s="1" », c’est-à-dire l’élément a. En fait, on souhaite calculer la différence entre deux ensembles (« //*[@s="1"] » et « //*[@t="1"] »). On pourrait
obtenir ce résultat avec l’expression « //*[@s="1" and not(@t="1")] », mais encore une fois, il existe un motif plus général: « $a1[count(.|$a2)!=count($a2)] » ou
« //*[@s="1"][count(.|//*[@t="1"])!=count(//*[@t="1"])] ». Pour comprendre cette
expression, il suffit de réaliser que si et seulement si un nœud x n’appartient pas à
a2, alors l’expression « count(x|$a2)!=count($a2) » sera vraie.
3.2.38
Espaces de noms
Les espaces de noms sont supportés et ne posent pas de problème. Il suffit de définir
les préfixes, comme on le fait habituellement. Par exemple, considérons le code XML
suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="class2.xsl" type="text/xsl" ?>
<université>
<étudiant>
<n:nom xmlns:n="http://www.mondomaine.com/">Réjean Tremblay</n:nom>
</étudiant>
</université>
Pour afficher le nom de l’étudiant, il suffira d’utiliser le document XSLT suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n="http://www.mondomaine.com/">
<xsl:template match="université" >
<html><body>
<xsl:apply-templates match="étudiant/n:nom" />
</body></html>
</xsl:template>
CC BY-NC-SA
Module 3 : Technologies XML
156
<xsl:template match="n:nom" >
<p><xsl:value-of select="." /></p>
</xsl:template>
</xsl:stylesheet>
Observons que l’attribut « match="nom" » ne s’applique pas à l’élément « nom »
dans l’espace de noms « http://www.mondomaine.com/ », tel qu’il apparaît dans notre
document XML : il est obligatoire d’utiliser un préfixe correspondant au bon espace de noms. Tout comme « match="*" » permet de sélectionner tous les éléments,
« match="n:*" » permet de sélectionner tous les éléments qui sont dans un espace de
noms donné.
3.2.39
Les axes
Par défaut, l’expression XPath « nom » désigne les éléments « nom » qui sont des
enfants du nœud courant. On peut aussi écrire « child::nom ». De la même manière,
« nom[2] » ou « child::nom[2] » désigne le second enfant du nœud courant. Il est
possible de changer ce comportement en choisissant un axe différent.
– « child » : il s’agit de l’axe par défaut, « child::nom[3] » désigne le troisième élément
« nom » enfant du nœud courant.
– « parent » : l’axe « parent » est pratiquement inutile, « parent::nom » désigne l’élément parent si celui-ci se nomme « nom ». En général, il est plus simple d’utiliser la
syntaxe « .. » qui est équivalente à « parent::node() ».
– « attribute » : la syntaxe « attribute:: » n’est pas utilisée, on préfère la notation
« @nom » qui signifie la même chose que « attribute::nom ».
– « ancestor » : la syntaxe « ancestor::nom » désigne les éléments de nom « nom » dans
lesquels le nœud courant est contenu. On peut tester si le nœud courant est contenu
dans un paragraphe avec la syntaxe <xsl:if test="ancestor::paragraphe">...</xsl:if>.
– « ancestor-or-self » : idem que l’axe ancestor exception faite que l’on inclut le
nœud courant, on pourrait donc tester si nœud courant est contenu dans un paragraphe ou s’il est lui-même un paragraphe avec la syntaxe <xsl:if test="ancestor-orself::paragraphe">...</xsl:if>.
– « preceding-sibling » : cet axe consulte en séquence les frères du nœud courant,
c’est-à-dire les nœud ayant le même parent, qui apparaissent avant le nœud courant.
Par exemple, « preceding-sibling::nom[2] » cherche le second élément-frère apparaissant avant le nœud courant.
– « following-sibling » : voir l’axe « preceding-sibling », mais à l’envers (après le
nœud courant).
– « preceding » : cet axe est similaire à « preceding-sibling », mais on traverse tous les
nœuds qui se sont terminés avant nœud courant. Par exemple, « preceding::nom[2] »
cherche le second élément apparaissant avant le nœud courant, même s’il n’a pas le
même parent.
CC BY-NC-SA
XSLT
157
– « following » : voir l’axe « preceding », mais à l’envers.
– « descendant » : voir l’axe « ancestor », mais à l’envers.
– « descendant-or-self » : voir l’axe « ancestor-or-self », mais à l’envers.
3.2.40
L’étude d’un exemple: docbook.xslt
Lors du travail 3, je vous ai demandé d’utiliser un fichier XSLT appelé docbook.xslt qui
transforme des documents DocBook simple en HTML. Vous êtes maintenant en mesure
d’analyser et de comprendre cet exemple. Nous allons passer en revue brièvement les
éléments « xsl:template » qu’il contient.
Le premier élément « xsl:template » sert à capturer l’élément « book ». Comme il
s’agit de l’élément-racine, on en profite pour produire les éléments « html », « head »
et « body ». Le contenu de l’élément « head » sera rempli par l’élément « xsl:template »
traitant l’élément DocBook « bookinfo ». On affiche immédiatement le prénom et le
nom de l’auteur à l’aide des expressions XPath « bookinfo/author/firstname » et « bookinfo/author/surname ». Notez l’utilisation de l’élément <xsl:text> </xsl:text> pour
produire un espace entre le nom et le prénom. En effet, sans cet élément, il n’y aurait
pas d’espace puisque les espaces et retours de charriot sont ignorés dans les fichiers
XSLT. Le reste du document est produit avec les deux éléments « xsl:template » traitant les éléments « chapter » : on utilise le l’attribut mode « tdm » pour produire la
table des matières, et le reste du document est produit avec le traitement des éléments
« chapter » par défaut (sans attribut mode).
<xsl:template match="book"> <html>
<head><xsl:apply-templates select="bookinfo"/></head>
<body><h1><xsl:value-of select="bookinfo/title" /></h1>
<p style="text-indent:1em;">
<xsl:value-of select="bookinfo/author/firstname" />
<xsl:text> </xsl:text>
<xsl:value-of select="bookinfo/author/surname" />
&#169;
<xsl:value-of select="bookinfo/copyright/year" />
</p><h2>Table des matières</h2>
<ul><xsl:apply-templates select="chapter" mode="tdm"/></ul>
<xsl:apply-templates select="chapter"/>
</body></html>
</xsl:template>
L’élément « xsl:template » traitant l’élément DocBook « bookinfo » est simple : l’expression XPath « title » permet de trouver le titre du document puisqu’un élément
« title » doit être présent dans tout élément DocBook « bookinfo ». Comme on l’a fait
précédemment, on trouve le prénom et le nom de l’auteur, mais cette fois-ci, avec les
expressions XPath « author/firstname » et « author/surname » puisque nous sommes
maintenant au sein d’un élément « bookinfo ».
<xsl:template match="bookinfo">
CC BY-NC-SA
Module 3 : Technologies XML
158
<title><xsl:value-of select="title" />
par <xsl:value-of select="author/firstname" /><xsl:text>
</xsl:text><xsl:value-of select="author/surname" />
</title>
</xsl:template>
Les élément « xsl:template » avec attribut mode génèrent la table des matières. Les
éléments « xsl:number » permettent de numéroter automatiquement les chapitres et
sections. Afin de générer des hyperliens permettant de naviguer dans le document à
partir de la table des matières, on utilise des fragments générés à partir de la fonction
XSLT « generate-id ». Lorsque nous générons le contenu du document lui-même, on
utilise à nouveau la fonction XSLT « generate-id » pour placer des ancres dans le
document au bon endroit. L’avantage de la fonction XSLT « generate-id » est qu’elle
permet de générer facilement un identifiant unique pour chaque paragraphe.
<xsl:template match="chapter" mode="tdm">
<li><a href="#{generate-id(.)}">
<xsl:number format="digit" lang="fr" count="chapter"/>.
<xsl:value-of select="title" /></a></li>
<ul><xsl:apply-templates select="section" mode="tdm"/></ul>
</xsl:template>
<xsl:template match="section" mode="tdm">
<li><a href="#{generate-id(.)}">
<xsl:number format="digit" lang="fr" count="chapter"/>.
<xsl:number format="digit" lang="fr" count="section"/>
<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></li>
</xsl:template>
Les élément « xsl:template » sans attribut mode génèrent le document lui-même. La
principale différence avec la génération de la table des matières est la présence de
l’élément <xsl:apply-templates/> qui traite le contenu des éléments « section ».
<xsl:template match="chapter">
<h2><a name="{generate-id(.)}" >Chapitre
<xsl:number format="digit" lang="fr"
count="chapter"/>.<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></h2>
<div style="margin-left:1em">
<xsl:apply-templates select="section"/> </div>
</xsl:template>
<xsl:template match="section">
<h3><a name="{generate-id(.)}">
CC BY-NC-SA
XSLT
159
<xsl:number format="digit" lang="fr" count="chapter"/>.
<xsl:number format="digit" lang="fr" count="section"/>
<xsl:text> </xsl:text>
<xsl:value-of select="title" /></a></h3>
<div style="margin-left:1em">
<xsl:apply-templates/>
</div>
</xsl:template>
Le traitement des éléments DocBook « itemizedlist », « orderedlist » et « listitem » est
simple : il suffit de les convertir en éléments HTML « ul », « ol » et « li » respectivement.
<xsl:template match="itemizedlist">
<ul style="margin-left:1em"><xsl:apply-templates /></ul>
</xsl:template>
<xsl:template match="orderedlist">
<ol style="margin-left:1em"><xsl:apply-templates /></ol>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="listitem">
<li style="text-indent:0.5em"><xsl:apply-templates /></li>
</xsl:template>
Les éléments DocBook « programlisting » sont convertis en éléments HTML « pre »
(préformaté).
<xsl:template match="programlisting">
<pre
style="color:blue;background-color:rgb(200,200,200); margin-left:1em">
<code>
<xsl:apply-templates />
</code></pre>
</xsl:template>
Les éléments DocBook « para » sont convertis en éléments HTML « p » sauf lorsqu’ils
sont au sein d’un élément DocBook « listitem ».
<xsl:template match="para">
<xsl:choose>
<xsl:when test="name(..) = ’listitem’">
<xsl:apply-templates /></xsl:when>
<xsl:otherwise><p><xsl:apply-templates /></p>
</xsl:otherwise>
CC BY-NC-SA
Module 3 : Technologies XML
160
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Les éléments DocBook « title » ne doivent pas être traités directement lorsqu’on les
rencontre.
<xsl:template match="title" />
Comme vous pouvez le constater, en décomposant un document XSLT complexe, on
arrive facilement à en expliquer le fonctionnement. C’est d’ailleurs un avantage de la
programmation déclarative de pouvoir être ainsi décomposée et expliquée.
3.2.41
Activité suggérée
Essayez de refaire les exemples avec le moteur XSLT de Firefox. Vous devrez ajouter
les éléments « html » et « body » lorsqu’ils ont été omis. Essayez également de modifier
les exemples pour vous assurer d’avoir bien compris.
Enfin, pour mieux comprendre le XSLT, faites quelques exercices exploratoires. Vous
pouvez consulter les articles de mozilla.org sur XSLT (http://developer.mozilla.org/en/
docs/XSLT) et XPath (http://developer.mozilla.org/en/docs/XPath).
Pour avoir une vue d’ensemble, consultez le pense-bête XSLT.
3.2.42
Autres moteurs XSLT
Votre navigateur supporte XSLT, mais si vous désirez un moteur XSLT qui ne dépende
pas d’un navigateur, je vous suggère 4Suite (http://www.4suite.org/) ou Xalan (http://
xml.apache.org/xalan-j/). Si vous avez le temps d’installer un tel moteur, vous pourrez
sans doute plus rapidement faire les travaux et refaire les exemples de cette leçon, mais
l’utilisation de Firefox est suffisante.
3.2.43
Pour voir le résultat de la transformation XSLT
Avec Firefox .2.0 ou mieux, on peut voir le résultat de la transformation XSLT en enregistrant le fichier: il faut aller dans le menu « Fichier » puis sélectionner « Enregistrez
sous ». Normalement, on pourra alors enregistrer le fichier XML en fichier HTML (si
la transformation donne un fichier HTML). On peut ouvrir le fichier HTML avec un
éditeur comme Bloc-note pour voir le résultat.
CC BY-NC-SA
XSLT
3.2.44
161
SVG et XSLT
Une des applications intéressantes du XSLT est de transformer un document en image.
Par exemple, étant donné les données d’une entreprise, on pourrait automatiquement
générer un histogramme en SVG.
3.2.45
XPath, XPointer et XLink
En présentant le XSLT, nous avons couvert les expressions XPath qui nous permettent
de sélectionner des nœuds dans des documents XML. D’autres technologies XML utilisent XPath comme XLink et XPointer.
XPointer est tout simplement une façon d’ajouter à un URI une expression XPath
pour permettre de représenter un lien vers une partie d’un document XML. On
ajoute un fragment de la forme « #xpointer(...) » à l’URI où les trois petits points
sont remplacés par une expression XPath. Par exemple, si vous voulez représenter
le premier élément « cours » d’un document XML, vous pouvez utiliser la syntaxe
« http://x.com/doc.xml#xpointer(//cours[1]) ». Si vous omettez l’URI, par défaut, le
document XML dans lequel se trouve l’expression XPointer est sélectionné. Les navigateurs ne supportent pas encore correctement XPointer.
XLink est une généralisation des hyperliens du HTML pouvant être utilisé dans tous
les documents XML. On utilise XLink surtout pour mettre des hyperliens dans des
images SVG. L’espace de noms pour XLink est « http://www.w3.org/1999/xlink » et
on l’utilise surtout avec l’attribut « href ». Dans la figure SVG suivante, le texte « INF
6450 » est un hyperlien vers l’URI « http://www.teluq.ca/inf6450 ».
Voici le code de la figure.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="300" height="300" stroke="black" fill="red"/>
<circle cx="150" cy="150" r="150" stroke="black" fill="yellow"/>
<a xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="http://www.teluq.ca/inf6450">
<text x="150" y="150" style="text-anchor: middle">INF 6450</text>
</a>
<line x1="0" y1="0" x2="300" y2="300"
style="stroke:rgb(99,99,99);"/>
<line x1="300" y1="0" x2="0" y2="300"
style="stroke:rgb(99,99,99);"/>
CC BY-NC-SA
Module 3 : Technologies XML
162
</svg>
Voici le rendu de la figure dans votre navigateur avec l’hyperlien.
3.2.46
XPath 2.0
Une nouvelle version de XPath est disponible (XPath 2.0). À part quelques exceptions, tout ce qui fonctionnait en XPath 1.0, fonctionne toujours en XPath 2.0. Cependant, XPath 2.0 ajoute de nombreuses fonctions et opérateurs qui simplifient la vie du
programmeur tels que empty, exists, intersect, except (pour calculer le complément),
deep-equal (pour tester l’égalité entre deux séquences), index-of, reverse, subsequence,
insert-before, remove, distinct-values, avg, max, min, etc. Alors que XPath 1.0 ne traite
que des nombres, des chaînes de caractères, des valeurs booléennes et des ensembles de
nœuds, XPath 2.0 introduit la notion de séquence et plusieurs autres types de données
pour noter les notes, la durée, les entiers, les nombres à virgule flottante, etc. XPath
2.0 supporte aussi les expressions régulières avec les fonctions matches, replace, et tokenize. XPath 2.0 intègre maintenant la fonction « document » qui était une fonction
XSLT.
XPath 2.0 comprend maintenant un syntaxe if/then/else comme dans cet exemple : « if
( @sexe eq ’m’ ) then ’Monsieur’ else ’Madame’ ». On peut aussi utiliser des boucles :
CC BY-NC-SA
XSLT
163
« for $i in //etudiant return $i/note ». On peut vérifier si au moins un (some) ou tous
(every) les éléments d’une séquence satisfont une condition: « every $i in //etudiant
satisfies $i/note > 0 » ou « some $i in //etudiant satisfies $i/note < 100 ». En somme,
XPath 2.0 permet d’effectuer plusieurs traitement qui n’étaient possible qu’avec des
instructions XSLT auparavant.
3.2.47
XLT 2.0
Une nouvelle version du XSLT est disponible, nommée XLT 2.0. Elle ajoute notamment la possibilité de générer plusieurs documents plutôt qu’un seul avec l’instruction
xslt:result-document. On peut aussi traiter non seulement des fichiers XML, mais aussi
d’autres types de fichiers dont les fichiers CSV (comma-separated values) générés par
les chiffriers électroniques et bases de données. L’instruction « xsl:analyze-string »
permet de prendre appui sur les nouvelles possibilités du traitement des chaînes de caractères de XPath 2.0. L’instruction « xsl:function » permet quant à elle de définir de
nouvelles fonctions qui pourront être utilisées au sein des expressions XPath. L’instruction « xsl:for-each-group » permet de visiter les nœuds par groupes : on peut ainsi
visiter tous les éléments etudiant en les regroupant selon la valeur de leur attribut nom.
Elliotte Rusty Harold a publié une page sur XSLT 2.0 qui présente quelques exemples.
3.2.48
XQuery
XSLT peut servir pour extraire des informations d’un document XML. On peut trouver
tous les noms des étudiants répondant à certains critères. Dans un sens, XSLT peut être
utilisé comme langage dans le contexte des bases de données. Cependant, pour cette fin
spécifique, un nouveau langage appelé XQuery a été proposé. La syntaxe du XQuery
est un mélange de XPath et de SQL et ressemble davantage à ce que les spécialistes
des bases de données connaissent bien.
Pour tester les requêtes XQuery, Saxon est un outil pratique écrit en java. Pour utiliser
Saxon, chargez d’abord le fichier saxon9.jar. Vous devez mettre votre requête XQuery
dans un fichier texte (tel que « query ») et invoquez Saxon comme ceci :
java -cp saxon9.jar net.sf.saxon.Query query
Dans cet exemple, il faut que les fichiers saxon9.jar et query soient dans le dossier
où vous lancez la commande. Le fichier query doit contenir une requête XQuery. Une
requête XQuery n’est pas du XML.
Pour rendre nos exemples plus concrets, supposez que le fichier qui se trouve à l’URI
http://universite.com/etu.xml soit celui-ci :
<liste>
<etudiant>
<nom>Laroche</nom>
<prenom>Pierre</prenom>
CC BY-NC-SA
Module 3 : Technologies XML
164
<statut>inscrit</statut>
<cours>
<sigle>INF 6460</sigle>
<note>54</note>
</cours>
<cours>
<sigle>INF 6450</sigle>
<note>44</note>
</cours>
</etudiant>
<etudiant>
<nom>Aaron</nom>
<prenom>Jean</prenom>
<statut>inscrit</statut>
<cours>
<sigle>INF 6460</sigle>
<note>56</note>
</cours>
<cours>
<sigle>INF 6450</sigle>
<note>46</note>
</cours>
</etudiant>
<etudiant>
<nom>Pouf</nom>
<prenom>Jean</prenom>
<statut>non-inscrit</statut>
</etudiant>
</liste>
Vous pouvez créer un fichier etu.xml sur votre disque dans le même dossier que le
fichier query, et remplacer partout l’URI par le nom du fichier (tel que « etu.xml »).
Parce que XQuery, tout comme XSLT 2.0, s’appuie sur XPath 2.0, il est facile de calculer la liste des cours :
for $s in distinct-values(doc("etu.xml")//sigle)
return $s
Cette requête donnera « INF 6460 INF 6450 ».
Voici un exemple de requête XQuery pour extraire d’un document XML tous les étudiants inscrits :
<maliste>
{let $inscription := "inscrit"
for $b in doc("http://universite.com/etu.xml")/liste/etudiant
where $b/statut = $inscription
order by $b/nom ascending
CC BY-NC-SA
XSLT
165
return
<etudiant>
{ $b/prenom }
{ $b/nom }
</etudiant>}
</maliste>
Cet exemple est une requête de type FLWOR parce qu’elle ne contient que des instructions « for », « let », « where », « order by », et « return ». L’instruction « for » sert
à définir une boucle, l’instruction « where » sert à poser une condition, l’instruction
« order by » permet de trier le résultat, alors que l’instruction « return » définit le résultat. L’instruction « let » permet de définir une constante. Notez que XQuery utilise les
accolades pour distinguer les requêtes XQuery et XPath du texte. La requête considère
tous les éléments etudiant contenus dans l’élément-racine liste, pour chacun d’entre
eux, elle vérifie qu’il contient un élément statut contenant le texte « inscrit », puis elle
donne la liste des noms et prénoms triée selon le nom. Voici quel sera le résultat :
<maliste>
<etudiant>
<prenom>Jean</prenom>
<nom>Aaron</nom>
</etudiant>
<etudiant>
<prenom>Pierre</prenom>
<nom>Laroche</nom>
</etudiant>
</maliste>
On peut attribuer un compteur aux nœuds :
<maliste>
{
for $b at $pos in doc("http://universite.com/etu.xml")/liste/etudiant
order by $b/nom descending
return
<etudiant> $pos { $b/prenom }
{ $b/nom }
</etudiant>
}
</maliste>
Le résultat sera alors :
<maliste>
<etudiant>3<prenom>Jean</prenom>
<nom>Pouf</nom>
</etudiant>
<etudiant>1CC BY-NC-SA
Module 3 : Technologies XML
166
<prenom>Pierre</prenom>
<nom>Laroche</nom>
</etudiant>
<etudiant>2<prenom>Jean</prenom>
<nom>Aaron</nom>
</etudiant>
</maliste>
On peut combiner les requêtes FLWOR, comme dans cet exemple :
<maliste>
{for $e in doc("http://universite.com/etu.xml")//etudiant
return
<etudiant nom="{$e/nom}">
{ for $v in $e/cours return
<note>{number($v/note)}</note>
}
</etudiant>
}
</maliste>
Cette requête va considérer chaque élément etudiant du document XML et créer une
liste de notes obtenues pour cet étudiant, dans ce cas, le résultat sera :
<maliste>
<etudiant nom="Laroche">
<note>54</note>
<note>44</note>
</etudiant>
<etudiant nom="Aaron">
<note>56</note>
<note>46</note>
</etudiant>
<etudiant nom="Pouf"/>
</maliste>
L’expression suivante va calculer la moyenne de notes (50) :
<maliste>
avg(
for $n in doc("http://universite.com/etu.xml")//note
return $n
)
</maliste>
Par défaut, les documents XQuery utilisent le jeu de caractères Unicode UTF-8. On
peut stipuler un jeu de caractères différent dans la déclaration XQuery optionnelle
comme dans cet exemple :
CC BY-NC-SA
CSS
167
xquery version "1.0" encoding "utf-8";
for $s in distinct-values(doc("etu.xml")//sigle)
return $s
Certains moteurs de bases de données comme MonetDB ou eXist supportent les requêtes XQuery. Il y a aussi d’excellents tutoriels sur le web. Elliotte Rusty Harold nous
offre une excellente page sur XQuery qui résume bien les points essentiels avec des
exemples.
3.2.49
XPath versus XSLT
Les expressions XPath sont très utilisées en XSLT. Apprendre le XSLT, c’est aussi
apprendre XPath. Par contre, tout ce qui ressemble à une expression XPath, n’est pas
nécessairement une expression XPath. Par exemple, les fonctions current, document,
generate-id et key sont des fonctions XSLT qui ne sont pas disponibles en XPath, mais
qui s’utilisent au sein des expressions XPath. On peut aussi utiliser les expressions
XPath en Java, en ECMAScript, avec XQuery, etc. Avec XSLT 2.0, il est possible de
définir ses propres fonctions qui s’utilisent au sein des expressions XPath.
3.2.50
En terminant
Le langage XSLT est beaucoup plus riche que ce que nous venons de vous présenter.
Nous pouvons pratiquement tout faire avec le XSLT. En fait, le XSLT est un langage
complet (au sens de Turing) et, en principe, tout ce qui peut être fait comme transformation en Java, peut être fait en utilisant le XSLT. En pratique, le XSLT est particulièrement approprié si nous voulons faire des transformations simples.
Il est aussi possible d’utiliser le XSLT pour résoudre automatiquement des problèmes
intéressants. Supposons que vous deviez communiquer avec une institution qui utilise
aussi le XML, mais avec des fichiers XML légèrement différents. Il est possible qu’une
simple transformation XSLT permette de transformer les fichiers XML de l’autre institution en des fichiers similaires aux vôtres.
Le XSLT peut sembler un peu déroutant, mais il faut simplement prendre de l’expérience avec ce type de programmation.
3.2.51
Livres de référence
– Sal Mangano, XSLT Cookbook, O’Reilly Media, 2006, 751 pages.
– Jeni Tennison, Beginning XSLT, Apress, 2004, 800 pages.
CC BY-NC-SA
Module 3 : Technologies XML
3.3
3.3.1
168
CSS
Objectif
Utiliser des transformations XSLT et des instructions CSS.
3.3.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte porte
sur les CSS (Cascading StyleSheets).
3.3.3
Qu’est-ce que les CSS
La norme CSS a d’abord été proposée par Håkon Lie du CERN en Suisse en 1994
(environ 4 ans après l’apparition de la première page web). Cette norme a été acceptée
comme recommandation officielle du W3C deux ans plus tard, soit en 1996, et la seconde version (CSS 2.0) est devenue une recommandation du W3C l’année suivante,
soit en 1997. Une troisième version est en développement. À l’origine, les instructions CSS étaient destinées uniquement à indiquer aux navigateurs comment présenter le HTML (couleurs, polices, etc.); on s’est vite rendu compte qu’on pouvait aussi
l’appliquer au XML et on considère maintenant les CSS comme une technologie qui
s’applique autant au HTML qu’au XML (et aussi, évidemment, au XHTML).
Nous avons vu que le XSLT permettait de transformer du XML en HTML pour l’affichage dans un navigateur. En général, le XSLT permet de transformer tout document
XML en un autre format (HTML, XML ou autre).
Un fichier CSS est beaucoup plus limité dans la mesure où il ne transforme pas le document XML. Il permet seulement de spécifier comment le contenu du document XML
sera affiché. Le fichier XSLT est un outil de transformation, alors que le fichier CSS
est un outil de formatage. Un document CSS permet de rendre un document XML plus
lisible. D’un autre côté, le fichier CSS permet de contrôler avec beaucoup de finesse
la présentation du document XML, alors qu’il peut être difficile et fastidieux d’obtenir
le même résultat en XSLT, sans utiliser les CSS. Les fichiers CSS tendent aussi à être
plus simples que les fichiers XSLT; il peut donc être plus facile de les modifier et de
les garder à jour. Finalement, on peut utiliser à la fois des fichiers CSS et des fichiers
XSLT, en combinant les avantages des deux (présentation et transformation).
3.3.4
Point de vue critique
CSS est un langage déclaratif relativement limité. Il n’est pas possible de définir des
variables, des fonctions ou de faire de l’arithmétique en CSS. On peut, par contre,
CC BY-NC-SA
CSS
169
redéfinir à volonté des règles, ce qui peut rendre le comportement final difficile à comprendre pour un humain. Il n’est pas facile, en CSS, de détecter le navigateur utilisé
alors que tous les navigateurs ne traitent pas les règles de la même façon.
3.3.5
Notions de base
Pour l’essentiel, le langage CSS prend la forme d’une succession d’affirmations de la
forme élément propriété: valeur; autrepropriété: valeur;. Il s’agit d’une syntaxe très
simple.
Supposons un document XML comme celui-ci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<comptearecevoir>
<facture>
<personne>Jean Rochond</personne>
<montant>10.10</montant>
<raison>Achat d’ordinateur</raison>
</facture>
<facture>
<personne>Madeleine Bédard</personne>
<montant>20.10</montant>
<raison>Achat d’un crayon</raison>
</facture>
</comptearecevoir>
Certains navigateurs affichent le XML brut sans formatage, ce qui n’est pas très accessible. D’autres navigateurs affichent le document sans les balises :
Jean Rochond
10.10
Achat d’ordinateur
Madeleine Bédard
20.10
Achat d’un crayon
Ce document XML est difficile à lire, même sans les balises, surtout si vous n’êtes pas
un expert en XML. Sans le transformer, il est possible de l’afficher avec de la couleur
ou de l’italique, comme ceci :
– Jean Rochond 10.10 Achat d’ordinateur
– Madeleine Bédard 20.10 Achat d’un crayon
CC BY-NC-SA
Module 3 : Technologies XML
170
Voilà qui est nettement plus lisible! Nous pouvons obtenir ce résultat à l’aide du fichier
CSS suivant :
facture {
display: block;
margin-bottom: 30pt;
}
montant {
color: red;
}
raison {
display: block;
font-style: italic;
margin-left: 1cm;
}
Pour vérifier que c’est bien le cas, il suffit de créer un fichier « chap12.css » avec le
contenu CSS précédent et de modifier le fichier XML en y ajouter une ligne pointant
vers le fichier CSS (<?xml-stylesheet type="text/css" href="chap12.css"?>), comme
ceci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/css" href="chap12.css"?>
<comptearecevoir>
<facture>
<personne>Jean Rochond</personne>
<montant>10.10</montant>
<raison>Achat d’ordinateur</raison>
</facture>
<facture>
<personne>Madeleine Bédard</personne>
<montant>20.10</montant>
<raison>Achat d’un crayon</raison>
</facture>
</comptearecevoir>
Si le fichier XML est dans le même répertoire que le fichier CSS, Firefox devrait vous
présenter le document XML avec le montant en rouge et le commentaire (raison) en
italique, comme nous l’avons présenté plus haut.
Examinons maintenant les différentes instructions du fichier CSS.
CC BY-NC-SA
CSS
171
– L’instruction « display: block; » déclare que l’élément devrait former son propre
paragraphe. L’instruction « display: none; » rend l’élément invisible.
– Les instructions « margin-bottom: 30pt; » et « margin-left: 1cm; » définissent des
marges en bas et à gauche de 30 points et de 1 cm respectivement.
– L’instruction « color: red; » affirme que le contenu de l’élément devrait être écrit en
rouge, alors que « font-style: italic; » nous dit que le texte de l’élément devrait être
en italique. On pourrait aussi contrôler la couleur de fond avec un instruction comme
« background-color:red ».
Dans l’éventualité où nous voulons choisir une couleur très précise, et non les couleurs
courantes comme « red », « green », « blue », « yellow », « white », « black », etc., nous
pouvons la spécifier selon sa composition avec les couleurs de base (« red », « green ,
« blue ») avec une instruction comme « background-color:rgb(200,200,200); », où
chaque valeur numérique est entre 0 et 255 inclusivement.
3.3.6
Contenu en ligne ou en bloc ?
Par défault, les éléments s’affichent en ligne, un à la suite de l’autre. On peut contrôler
comment s’affiche un élément avec la propriété « display » qui peut prendre plusieurs
valeurs dont celles-ci :
– « display: none »: l’élément ne doit pas s’afficher. Par exemple, l’instruction « imgdisplay: none; » fait en sorte que les images ne s’affichent plus en HTML. Il est
fréquent qu’avec du ECMAScript, on cache et affiche tour à tour des éléments pour
donner l’impression que la page est dynamique.
– « display: inline »: l’élément s’affiche à la suite du précédent comme s’il s’agissait
d’un caractère.
– « display: block »: l’élément s’affiche dans un bloc distinct, comme un nouveau
paragraphe, par exemple.
– « display: list-item »: l’élément s’affiche comme un élément d’une liste.
Voici un exemple :
p { display: block }
strong { display: inline }
li { display: list-item }
img { display: none }
On peut aussi définir la propriété « float » d’un élément qui lui permet de sortir du flot
normal des éléments et de se placer à gauche ou à droite. Par exemple, une image en
XHTML s’affiche normalement comme un bloc. On peut forcer l’image à s’intégrer
au paragraphe suivant avec l’instruction « float: right » ou « float: left ». On peut aussi
utiliser la propriété « float » pour créer plusieurs colonnes de texte comme dans un journal. Je vous invite à faire différentes expériences pour mieux comprendre l’utilisation
de cette instruction.
CC BY-NC-SA
Module 3 : Technologies XML
3.3.7
172
Centrer un élément
Bien qu’on puisse changer la justification du texte avec une instruction comme « textalign: center », centrer un élément requiert plutôt une manipulation des marges avec la
valeur spéciale « auto », comme dans cet exemple :
p { width: 5cm;
margin-left: auto;
margin-right: auto;}
Il aurait été sans doute préférable d’avoir une instruction dédiée pour centrer les éléments comme il s’agit d’une opération courante.
3.3.8
Les commentaires
Tout comme en Java, on peut ajouter des commentaires à un fichier CSS qui sont systématiquement ignorés par la machine. Un bloc de commentaire débute par « /* » et se
termine par « */ ».
/* mon fichier css */
montant {
color: red; /* la couleur rouge */
}
3.3.9
Sélectionner le premier caractère ou la première ligne
On peut sélectionner la première ligne d’un élément s’affichant en mode « block » et
le premier caractère de tout élément avec les sélecteurs « :first-line » et :« :first-letter »
respectivement. Voici un exemple :
p:first-line {text-transform: uppercase}
p:first-letter {font-size: 200%;float: left;}
3.3.10
Ajouter du contenu avant et après un élément
Avec CSS, on peut demander qu’une certaine chaîne de caractères apparaisse avant
ou après un élément. Par exemple, si on veut ajouter automatiquement des guillemets
avant et après un élément, on peut procéder comme ceci :
blockquote:before {content:"«";}
blockquote:after {content:"»";}
CC BY-NC-SA
CSS
173
Nous ne sommes pas limités au texte cependant. Il est possible, par exemple, d’ajouter
automatiquement une image avant chaque élément comme ceci :
p:before {content:url("monimage.png";}
3.3.11
Qu’est-ce qu’un pseudo-élément?
Les instructions first-line, first-letter, before et after que nous venons de présenter sont
les principaux exemples de pseudo-éléments.
3.3.12
Sélecteurs d’intéraction
Certains sélecteurs n’agissent qu’en réponse aux comportements de l’utilisateur. Par
exemple, le sélecteur « p:hover » sélectionne les éléments « p » qui sont survolés par
le curseur de la souris. Il existe plusieurs sélecteurs d’intéraction dont « :link » (lien
non visité), « :visited » (lien visité), « active » (l’utilisateur utilise un élément), « :focus » (l’élément est sélectionné par l’utilisateur). On peut aussi combiner les sélecteurs
comme dans cet exemple : « a:hover:focus ». On appelle aussi ces sélecteurs de pseudoclasses.
3.3.13
Règles par défaut
Dans le cas du HTML ou du XHTML, les navigateurs utilisent une liste de règles par
défaut. Ces règles vont varier d’un navigateur à l’autre, mais voici un exemple de règles
utilisées par Firefox :
html, div {
display: block;
}
body {
display: block;
margin: 8px;
}
p, dl, multicol {
display: block;
margin: 1em 0;
}
blockquote {
display: block;
margin: 1em 40px;
CC BY-NC-SA
Module 3 : Technologies XML
174
}
h1 {
display: block;
font-size: 2em;
font-weight: bold;
margin: .67em 0;
}
h2 {
display: block;
font-size: 1.5em;
font-weight: bold;
margin: .83em 0;
}
pre {
display: block;
white-space: pre;
margin: 1em 0;
}
b, strong {
font-weight: bolder;
}
i, cite, em, var, dfn {
font-style: italic;
}
u, ins {
text-decoration: underline;
}
s, strike, del {
text-decoration: line-through;
}
big {
font-size: larger;
}
small {
font-size: smaller;
CC BY-NC-SA
CSS
175
}
sub {
vertical-align: sub;
font-size: smaller;
line-height: normal;
}
sup {
vertical-align: super;
font-size: smaller;
line-height: normal;
}
ul, menu, dir {
display: block;
list-style-type: disc;
margin: 1em 0;
}
ol {
display: block;
list-style-type: decimal;
margin: 1em 0;
}
li {
display: list-item;
}
area, base, basefont, head, meta, script, style, title,
noembed, param {
display: none;
}
3.3.14
L’astérisque
L’astérisque nous permet d’appliquer une règle à tous les éléments, comme dans cet
exemple : « * color:red; ».
3.3.15
Sélection sur la base des attributs
Avec les CSS, en utilisant les crochets, nous pouvons sélectionner tous les éléments
ayant un attribut donné. Par exemple, l’instruction « *[monattribut] color:red; » mettra
CC BY-NC-SA
Module 3 : Technologies XML
176
en rouge tous les éléments ayant un attribut portant le nom « monattribut ». Nous
pouvons aussi, bien sûr, limiter la sélection à des éléments portant un nom donné
comme dans cet exemple : « maman[monattribut] color:red; » où les éléments « maman » ayant un attribut « monattribut » seront en rouge. Finalement, nous pouvons de
plus limiter la sélection à des attributs ayant une certaine valeur, comme dans « maman[monattribut="papa"] color:red; ».
Il arrive fréquemment qu’une valeur d’attribut contiennent plusieurs mots, comme dans
« <amerique pays="États-Unis Canada" /> ». Pour séléctionner tous les élément dont
un attribut contiennent un mot particulier, on remplace « = » par « = » comme dans
l’instruction « *[pays ="Canada"] color:red; » qui mettra en rouge tout élément dont
l’attribut « pays » contient le mot « Canada ». Les mots doivent être séparés par
des espaces. Dans l’éventualité où les mots sont séparés par des tirets, comme dans
« <amerique pays="Mexique-Canada" /> », on peut obtenir le même résultat avec « |= »
comme dans « *[pays|="Canada"] color:red; ».
3.3.16
Les espaces de noms
Les espaces de noms ne sont pas supportés en CSS 1 ou CSS 2. Ainsi « monelement
color:red; » met en rouge le contenu de tous les éléments monelement, peu importe leur
espace de noms. Il est incorrect d’utiliser la syntaxe « xhtml:monelement color:red; ».
3.3.17
Sélection de la langue
On a vu qu’il est possible en XML de spécifier la langue dans laquelle est écrit un texte
avec l’attribut « xml:lang. ». On pourrait penser que pour mettre le texte déclaré comme
étant en anglais en rouge, il suffirait de l’instruction « *[lang="fr"] color:red; », mais
que se passera-t-il si on a utilisé un code de région avec la langue comme « fr-CA »?
Une solution plus élégante consiste alors à utiliser la sélection sur la langue avec une
instruction comme « :lang(en) color:red; ». Une alternative est d’utiliser « *[lang|="fr"]
color:red; ».
3.3.18
Sélection de plusieurs éléments
Supposons maintenant que nous voulions afficher en rouge tous les éléments « facture »
et « maison ». Nous pouvons le faire avec deux instructions :
facture { color:red;}
maison { color:red;}
En pratique cependant, il est préférable d’utiliser la virgule pour grouper les éléments,
comme ceci :
CC BY-NC-SA
CSS
177
facture, maison { color:red;}
Les deux instructions et cette dernière forme sont exactement équivalentes.
3.3.19
Sélection sur la base de la relation entre les éléments
Supposons maintenant que nous ne voulions pas afficher tous les éléments « personne »
en rouge, mais seulement les éléments « personne » contenus dans un élément « facture ». Nous obtiendrons ce résultat en plaçant les deux noms d’élément côte-à-côte
(séparé par un espace). Ainsi, l’instruction « facture personne color:red; » affichera
en rouge tous les éléments « personne » contenus dans un élément « facture », comme
dans l’exemple qui suit :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/css" href="chap12.css"?>
<comptearecevoir>
<facture>
<personne>Jean Rochond</personne>
</facture>
</comptearecevoir>
ou dans ce deuxième exemple...
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/css" href="chap12.css"?>
<comptearecevoir>
<facture>
<client><personne>Jean Rochond</personne></client>
</facture>
</comptearecevoir>
Nous pourrions vouloir que seuls les éléments immédiatement contenus dans l’élément
« facture », comme dans le premier exemple, soient en rouge, et non pas ceux qui
sont contenus dans des éléments eux-mêmes dans un élément « facture » (deuxième
exemple). Nous pouvons obtenir ce résultat avec l’instruction « facture > personne
color:red; ».
En somme, la règle « a b color:red; » s’applique à l’élément « b », si l’élément
« b » est contenu dans un élément « a » comme dans « <a><b></b></a> » ou
« <a><c><b></b></c></a> ».
Par contre, la règle « a > b color:red; » s’applique à l’élément « b », si et seulement
si l’élément « b » est immédiatement contenu dans un élément « a », comme dans
« <a><b></b></a> ». Elle ne s’applique toutefois pas si « b » est contenu dans un
élément lui-même contenu dans « a », comme dans « <a><c><b></b></c></a> ».
CC BY-NC-SA
Module 3 : Technologies XML
178
Supposons maintenant, dans l’exemple suivant, que nous voulions indenter le premier
paragraphe (élément « p ») suivant le titre (élément « titre ») :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<titre>Mon histoire</titre>
<p>C’est triste.</p>
<p>Oui, c’est triste.</p>
Ce résultat s’obtient avec l’instruction « titre + p text-indent: 0cm; ». La syntaxe « a
+ b ... » s’applique à l’élément « b » quand les éléments « a » et « b » sont contenus
dans le même élément, et que « b » est immédiatement après « a ». Notez que la règle
« a + b ... » s’applique à « b », mais ne s’applique pas à « a ».
Supposons que nous désirions indenter le premier paragraphe (élément « p ») dans
l’élément « section » :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<section titre="Mon histoire" >
<p>C’est triste.</p>
<p>Oui, c’est triste.</p>
</titre>
On peut obtenir ce résultat avec la sélecteur « section > p:firstchild ... » où « :firstchild » signifie que seuls les éléments « p » étant le premier élément au sein d’un autre
élément sont sélectionnés. En fait, dans cet exemple particulier, on obtiendrait aussi le
résultat voulu avec le sélecteur « p:firstchild ... ».
Par ailleurs, nous pouvons combiner les espaces, les « + », les virgules et les « > » dans
un même sélecteur. Par exemple, « a + b, c ... » s’applique aux éléments « c » et aux
éléments « b » qui suivent immédiatement un élément « a ».
3.3.20
Sélection d’élément par valeur ID
Si vous avez des éléments ayant des attributs ayant une valeur de type « ID », on sait
alors que leur valeur est un nom XML et qu’elle ne doit être utilisée qu’une seule
fois. C’est le cas des attributs de la forme « id="xxx" » que l’on peut utiliser avec
pratiquement tous les éléments XHTML. On peut sélectionner un élément basé sur la
valeur d’un tel attribut en utilisant le symbole « # » :
#xxx {
color: red;
}
Dans ce cas, le contenu d’un élément comme une balise XHTML « <p
id=’xxx’>test</p> » s’affichera en rouge. On peut combiner les sélecteurs « # » avec
les autres règles que nous avons traitées , par exemple, le code suivant ne mettra en
CC BY-NC-SA
CSS
179
rouge que les éléments « i » contenus dans un élément ayant un attribut de type « ID »
avec pour valeur « xxx » :
#xxx i{
color: red;
}
3.3.21
Mais que se passe-t-il en cas de conflit?
Plusieurs instructions peuvent s’appliquer en même temps: un texte peut être en rouge
et souligné. Il peut arriver cependant que deux instructions CSS se contredisent. Par
exemple, un texte ne peut être à la fois en rouge et en bleu. Dans ce cas, la sélection la
plus spécifique l’emporte. Ainsi, dans l’exemple qui suit...
* {
color: black;
}
montant {
color: red;
}
montant > montant {
color: yellow;
}
les éléments « montant » seront en rouge, sauf s’ils sont immédiatement contenus dans
un autre élément « montant », auquel cas ils seront en jaune.
Par ailleurs, si deux sélections de même spécificité sont rencontrées, c’est la dernière
qui l’emporte. Ainsi, dans l’exemple qui suit...
montant {
color: red;
}
montant {
color: black;
}
les éléments « montant » seront en noir.
CC BY-NC-SA
Module 3 : Technologies XML
180
On peut cependant forcer le navigateur à considérer une règle qui apparaît avant une
autre comme ayant tout de même priorité (à spécificité égale). Il suffit d’utiliser la
mention !important...
montant {
color: red !important;
}
montant {
color: black;
}
les éléments « montant » seront en rouge. Notez que la mention !important permet
souvent d’ignorer la spécificité de la règle: les règles avec cette mention l’emportent
toujours sur les autres. (Si une autre règle avec la mention !important a une plus grande
spécificité, elle aura bien sûr priorité.)
Les règles par défaut utilisées par votre navigateur dans le cas du HTML ou du XHTML
sont lues en premier. De cette manières, toutes les règles qui vous stipulez dans vos
propres fichiers CSS et à même le XML ou HTML ont priorité pour une même spécificité. On peut considérer que les règles avec la mention !important sont lues en dernier
dans la mesure où ils l’emportent toujours sur les autres.
Calculer la spécificité des règles n’est pas une mince affaire, mais c’est pourtant nécessaire dans certains cas difficiles. La spécificité se mesure avec une valeur à 4 chiffres
(a,b,c,d). Lorsqu’on compare deux spécificités (a1,b1,c1,d1) et (a2,b2,c2,d2), on utilise l’ordre lexicographique pour déterminer lequel est supérieur. Ainsi, si a1 est plus
grand que a2, alors (a1,b1,c1,d1) a une plus grande spécificité que (a2,b2,c2,d2), si a1
est égal à a2, alors on compare b1 et b2, et ainsi de suite.
– La première valeur (a) vaut 1 si et seulement si la règle apparaît dans le fichier
XML, HTML ou XHTML dans un attribut style. Par exemple, si on a un élément
paragraphe en HTML de cette forme <p style="color:red" >, alors la règle color:red
aura une très grande spécificité.
– La seconde valeur (b) est le nombre de sélections sur la valeur ID utilisée par la
règle. Ainsi, la règle #x color:red pourra avoir une spécificité de 0,1,0,0. En pratique,
la sélection par valeur ID l’emporte souvent sur les autres règles.
– La troisième valeur (c) est le nombre de valeurs d’attributs utilisées par la règle (excluant l’attribut ID). Ainsi, la règle *[monattribut] color:red; pourrait avoir comme
spécificité 0,0,1,0. Les pseudo-classes comptent comme des attributs.
– La quatrième valeur (c) est le nombre d’éléments utilisés par la règle. Ainsi, la règle
p[monattribut] color:red; pourrait avoir comme spécificité 0,0,1,1.
Pour mieux comprendre, prenons un exemple concret...
z[x] > a[i] {color: blue;}
z z[x] a {text-decoration: underline;}
CC BY-NC-SA
CSS
181
z > z a ,
z z z + a { color: red ;}
Il est plus facile de comptabiliser la spécificité si on écrit les règles individuellement
(sans la virgule). Voyez si vous êtes capable de voir pourquoi les différentes règles ont
les spécificités annoncées dans les commentaires...
/* spécificité: 0,0,2,2 */
z[x] > a[i] {color: blue;}
/* spécificité: 0,0,0,3 */
z > z a { color: red ; }
/* spécificité: 0,0,0,4 */
z z z + a { color: red; }
/* spécificité: 0,0,1,3 */
z z[x] a {text-decoration: underline;}
Prenons maintenant un fichier XML auquel on applique les instructions CSS précédente. L’élément a dans le fichier suivant est sélectionné par les 4 règles du fichier
CSS. Comment sera affiché le texte dans votre navigateur?
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/css" href="test.css"?>
<z><z x="x">
<z />
<a i="x">mon texte</a>
</z>
</z>
Le texte apparaîtra en bleu et sera souligné. Si on ajoute une instruction avec la mention !important comme « * color: black !important; » alors on peut faire en sorte que le
texte soit noir.
3.3.22
Le modèle de boîte CSS
En CSS, on peut spécifier la hauteur et la largeur d’un objet à l’aide des instructions
« width » et « height ». Par exemple, pour indiquer qu’un paragraphe devrait n’avoir
qu’une largeur de 20 pixels, on utilise un sélecteur comme celui-ci :
p{
width: 20px;
}
Le CSS supporte plusieurs unités de mesure outre les pixels dont les pouces (in), les
centimètres (cm), pourcentage (%), etc.
CC BY-NC-SA
Module 3 : Technologies XML
182
On peut ensuite définir une marge (margin en anglais) autour de tout objet. La marge
est une région où rien ne peut apparaître, incluant un autre objet. Mais la marge ne fait
pas partie de l’objet lui-même. Ainsi, si un objet fait 10 pixels de hauteur et de largeur,
et que vous définissez une marge de 10 pixels tout autour de l’objet, un espace d’une
superficie de 900 pixels sera occupée sur l’écran. Voici un exemple de marge :
p{
margin-top:10px;
margin-bottom:10px;
margin-right:10px;
margin-left:10px;
}
Outre la marge, on peut aussi définir une région d’espacement (padding en anglais).
Contrairement à la marge, la région d’espacement fait partie de l’objet dans la mesure
où, si vous définissez une couleur de fond pour l’objet, la région d’espacement sera
colorée, car elle fait partie de l’objet. Tout comme la marge, rien n’occupe cette région
et elle n’est pas comptabilisée dans la hauteur et la largeur de l’objet.
p{
padding-top:10px;
padding-bottom:10px;
padding-right:10px;
padding-left:10px;
}
On peut définir une bordure (border en anglais) afin de tracer un ligne tout autour de
l’objet. La bordure se place entre la région d’espacement et la marge. La bordure peut
prendre différente épaisseurs (telles que thin, medium, et thick) et aussi une couleur.
p{
border-color: black;
border-width: medium;
}
Voici un diagramme qui résume les différentes définitions :
CC BY-NC-SA
CSS
183
Contenu ici
padding−right
padding−left
margin−left
padding−top
rmargin−right
margin−top
hauteur de l’objet (height)
bordure (border)
espacement (padding): espace laissé
vacant
marge (margin): rien ne peut apparaître ici
margin:bottom
largeur de l’objet (width)
3.3.23
Quand le contenu excède le contenant
Il arrive qu’une image ou qu’un texte excède la taille de l’élément dans lequel il a été
placé. Par défaut, ce texte ou cet image s’affichera au-delà du cadre de sa boîte (« overflow:visible »). L’instruction « overflow:hidden » permet de faire disparaître la partie
d’un texte ou d’une image qui excède la boîte, alors que l’instruction « overflow:scroll »
va faire apparaître des barres de défilement pour permettre à l’utilisateur d’avoir accès
à tout le contenu sans pour autant avoir un dépassement..
3.3.24
Encodage des caractères
Il peut être utile de spécifier l’encodage des caractères utilisé pour créer le document
CSS. Il suffit d’inclure une instruction « @charset » au tout début du document. Voici
deux exemples :
@charset "UTF-8";
@charset "ISO-8859-1";
3.3.25
Différentes règles pour différents média
Il arrive qu’on veuille qu’une page s’affiche différemment selon qu’on utilise un écran,
qu’on l’imprime sur papier ou qu’on utilise un téléphone cellulaire. L’instruction
« @media » permet de préciser quel médium est concerné par la règle. Plusieurs média
sont reconnus dont « handheld » (appareil portable comme un téléphone cellulaire),
« screen » (à l’écran), « tv » (sur un téléviseur), « print » (sur papier), etc. Lorsque
l’instruction « @media » n’est pas précisée, la règle s’applique tout le temps. Voici un
exemple :
CC BY-NC-SA
Module 3 : Technologies XML
184
@media print, handheld {
img { display: none }
h1 {color: black }
}
@media screen, tv {
h1 {color: blue }
}
3.3.26
Inclure d’autres fichiers CSS
Il arrive parfois qu’on veuille adopter une approche modulaire et créer plusieurs petits
fichiers CSS. L’instruction « @import » apparaissant avant le début des règles, mais
après une éventuelle instruction « @charset » permet d’inclure un ou plusieurs fichiers
CSS. On peut aussi spécifier le type de médium concerné.
@import "mineure.css";
@import "print-mineure.css" print;
3.3.27
Indentation de la première ligne d’un paragraphe
On peut indenter la première ligne d’un paragraphe avec l’instruction « text-indent ».
Par exemple, pour indenter la première ligne de tous les paragraphes par 1 cm, on peut
utiliser l’instruction « text-indent: 1cm ».
3.3.28
Modifier la casse du texte
L’instruction « text-transform » permet de modifier la casse du texte ce qui est particulièrement utile avec les titres. Par exemple, « text-transform: capitalize » modifie le
texte de manière à ce que le premier caractère de chaque mot soit en majuscule. Les
instructions « text-transform: uppercase » et « text-transform: lowercase » permettent
de passer à une casse uniforme (majuscule ou minuscule). Finalement, l’instruction
« text-transform: capitalize » met le premier caractère de chaque mot en majuscule.
3.3.29
Autres variantes des polices
Il est possible de modifier de diverses façons les polices : « font-style:italic », « fontstyle:oblique » « font-family: sans-serif », « font-family: serif », « font-weight: bold »,
« font-weight: bolder », « font-weight: lighter ». On peut modifier la taille des caractères : « font-size: large », « font-size: small ». On peut ajouter des lignes sous, sur ou
CC BY-NC-SA
CSS
185
au dessus le texte, ou faire clignoter le texte : « text-decoration: underline », « textdecoration: overline », « text-decoration: line-through », « text-decoration: blink ».
Vous pouvez aussi spécifier l’apparence que prendra le curseur avec l’attribut « cursor » qui prend la valeur « text » par défaut, et la valeur « pointer » pour les hyperliens.
3.3.30
Ajouter des compteurs
On peut définir des compteurs pour, par exemple, numéroter des chapitres ou paragraphes. Ce premier exemple numérote les paragraphes (éléments « p ») contenus entre
chaque élément « h1 » avec des nombres romains :
p {counter-increment: par-num}
h1 {counter-reset: par-num}
p:before {content: counter(par-num, upper-roman) ". "}
Ce second exemple numérote les éléments « h1 » avec des nombres arabes :
h1 {counter-increment: h1-num}
h1:before {content: counter(h1-num, decimal) ". "}
Ce troisième exemple « numérote » les éléments « h1 » et « h2 » avec des lettres
(a,b,c,...) :
h1 {counter-reset: h2counter; counter-increment: h1counter}
h2 {counter-increment: h1counter}
h1:before {content: counter(h1counter, lower-latin) ". "}
h2:before {
content: counter(h1counter, lower-latin) "."
counter(h2counter, lower-latin) ". " }
3.3.31
Traitement des retours de chariot
Par défaut, le contenu textuel d’un élément est affiché sans tenir compte des retours
de chariot présents dans le fichier XML, mais en insérant plutôt des retours de chariot
au besoin. Avec l’instruction « white-space : pre », on force le maintient des retours
de chariot là où ils sont, ce qui est très utile pour présenter du code informatique.
L’instruction « white-space : nowrap » élimine toute utilisation des retours de chariot,
alors que l’instruction« white-space : normal » correspond au comportement pas défaut.
CC BY-NC-SA
Module 3 : Technologies XML
3.3.32
186
Des nouveautés en CSS 3
La prochaine version du CSS, CSS 3, apporte de nombreuses améliorations. En particulier, elle ajoute plusieurs sélecteurs. Voici un tableau qui résume certains des sélecteurs
les plus utilisés ainsi que le niveau CSS correspondant.
Sélecteur
Signification
Niveau CSS
*
tout élément
2
E
un élément de nom E
1
E[foo]
un élément E ayant un at- 2
tribut foo
E[foo="bar"]
un élément E ayant un at- 2
tribut foo dont la valeur
est « bar »
E[foo ="bar"]
un élément E ayant un at- 2
tribut foo dont la valeur
contient le mot « bar » séparé par des espaces
E[fooˆ="bar"]
un élément E ayant un at- 3
tribut foo débute par le
texte « bar »
E[foo$="bar"]
un élément E ayant un at- 3
tribut foo se termine par
le texte « bar »
E[foo*="bar"]
un élément E ayant un at- 3
tribut foo dont la valeur
contient le texte « bar »
E[foo|="bar"]
un élément E ayant un at- 2
tribut foo dont la valeur
contient le mot « bar » séparé par des tirets
EF
un élément F contenu 1
dans un élément E
E>F
un élément F contenu di- 2
rectement dans un élément E
E+F
un élément F précédé 2
immédiatement par un
élément-voisin E
E F
un élément F précédé par 3
un élément-voisin E
Avec CSS 3, il devient donc possible, par exemple, de sélectionner tous les hyperliens ayant une adresse (attribut « href ») débutant par « http » avec le sélecteur
« a[hrefˆ="http"] », ce qui pourrait être utilisé pour indiquer visuellement les liens
externes.
CC BY-NC-SA
CSS
3.3.33
187
Optimisation des fichiers CSS
Il y a plusieurs façons d’écrire un même ensemble d’instructions. Par exemple, ce fichier CSS est trop long et difficile à comprendre :
montant {
color: red;
font-weight: bold;
background:white;
font-style: normal;
text-align: center;
}
nom {
color: white;
background:white;
font-style: normal;
text-align: left;
}
texte {
color: black;
text-align: center;
font-style: normal;
background:white;
text-align: left;
}
On peut le réécrire dans un format plus concis et plus clair :
montant {
color: red;
font-weight: bold;
text-align: center;
}
nom {
color: white;
text-align: left;
}
texte {
color: black;
text-align: left;
}
montant, nom, texte {
background: white;
font-style: normal;
}
CC BY-NC-SA
Module 3 : Technologies XML
188
Il existe de nombreux outils pour optimiser les fichiers CSS dont CSSTidy qui est
disponible en ligne.
3.3.34
En terminant
La syntaxe CSS est beaucoup plus riche que ce que nous venons de voir. Pour
plus d’information, nous vous invitons à lire le document de référence http://
www.yoyodesign.org/doc/w3c/css2/ ou les articles du site mozilla.org (http://developer.mozilla.org/en/docs/CSS).
.
3.3.35
Livres de référence
– David Sawyer McFarland, CSS: The Missing Manual, O’Reilly Media, 2006, 476
pages.
– Charles Wyke-Smith, CSS 2, guide du designer, Pearson Education France, 2005,
268 pages.
3.4
3.4.1
Travail noté 4
Objectifs et pondération
Ce travail compte pour 10 % de la note globale du cours.
Il contribue à l’objectif suivant :
– Utiliser des transformations XSLT et des instructions CSS.
Le travail comprend cinq exercices : le premier vaut 3 points, le deuxième vaut 2 points,
le troisième vaut 2 points, le quatrième vaut 2 points, et le cinquième vaut 1 point.
3.4.2
Consignes
Faites les exercices et répondez aux questions en utilisant Firefox comme moteur XSLT
et comme navigateur; les exercices ont été conçus en fonction de ce navigateur. Certains étudiants trouvent pratique d’utiliser l’outil de traitement en ligne disponible sur
le blogue du cours (http://www.daniel-lemire.com/blogue/xsltprocessor.html). En effectuant les exercices, n’utilisez que des fonctions disponibles dans Firefox. De plus,
n’utilisez pas les éléments « xsl:key » ou la fonction XPath « key » dans vos solutions.
CC BY-NC-SA
Travail noté 4
189
Une fois votre travail terminé, transmettez à votre personne tutrice, par courriel, un
document (Word 97/2000/XP, ODF, PDF, RTF ou en format texte) en fichier attaché.
L’objet de votre courriel doit commencer par « [INF6450][TRAVAIL4] »; dans
le message, indiquez votre nom, votre numéro d’étudiant (8 chiffres), la date de
remise de votre travail et le nom de votre personne tutrice, ainsi que les mentions
« Travail noté 4 » et « INF 6450 ». Il s’agit d’un travail personnel et vous ne devez
pas partager vos solutions.
Bon travail!
3.4.3
Exercice 1
Étant donné le document XML suivant, rédigez le contenu du document CSS
« test.css », de telle sorte que les mots « Rouge » s’affichent en rouge, les mots « Noir »
s’affichent en noir, les mots « majuscule » s’affichent en majuscule et ainsi de suite.
Votre document CSS doit contenir au plus 5 instructions CSS de la forme « quelque
chose autre chose ».
Indice : Vous pouvez utiliser « color:red », « color:olive », « color:black », « color:blue », et ainsi de suite pour fixer la couleur du texte.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/css" href="test.css"?>
<a>
<b>Rouge</b>
<c><a>Olive</a>
<b>Bleu</b>
<a><a>Noir</a>
Olive
<b>Bleu</b>
<a>Rouge</a>
<a>Noir</a>
</a></c>
<b><a>Rouge</a>
<b>Noir</b></b>
<d>majuscule</d>
</a>
3.4.4
Exercice 2
Supposons que toutes les notes des étudiants, dans différents cours, se trouvent dans le
document XML suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="class.xsl" type="text/xsl" ?>
CC BY-NC-SA
Module 3 : Technologies XML
190
<université>
<étudiant><nom>Réjean Tremblay</nom>
<cours sigle="INF8430" note="89" />
<cours sigle="INF1030" note="69" />
<cours sigle="INF1230" note="75" /></étudiant>
<étudiant><nom>Martin Lambert</nom>
<cours sigle="INF8430" note="75" />
<cours sigle="INF1030" note="72" />
<cours sigle="INF1230" note="73" /></étudiant>
<étudiant><nom>Luc Alain</nom>
<cours sigle="INF9430" note="39" />
<cours sigle="INF1030" note="89" />
<cours sigle="INF1230" note="79" /></étudiant>
<étudiant><nom>Olive Saint-Amant</nom>
<cours sigle="INF8430" note="91" />
<cours sigle="INF1230" note="99" /></étudiant>
</université>
À partir de ce document XML, fournissez le document XSLT « class.xsl » qui calcule
les moyennes des étudiants, d’après les éléments « cours » associés aux éléments « étudiant », et qui trie les étudiants par ordre alphabétique de leur nom de famille. Votre
document XSLT doit fonctionner même si on change le nom des étudiants, l’ordre des
éléments et le nom des cours. En conséquence, le nom des étudiants ou le nom des
cours ne peuvent apparaître dans votre document XSLT. En outre, vous ne devez pas
utiliser les crochets « [ ] » dans votre solution.
Indices
1. Le tableau ci-dessous devrait vous permettre de vérifier votre réponse.
Étudiant
Moyenne
Luc Alain
69.0
Martin Lambert
73.3
Olive Saint-Amant
95.0
Réjean Tremblay
77.7
2. Vous pouvez trier les étudiants selon leur nom de famille, en remplaçant
« <xsl:apply-templates match="étudiant" /> » par :
<xsl:apply-templates match="étudiant" >
<xsl:sort select="substring-after(nom,’ ’)" order="ascending"/>
</xsl:apply-templates>
3. Vous pouvez formater les nombres à virgule flottante comme dans le tableau,
en utilisant des appels de fonction XSLT tels que « format-number(10.1324,
’##.0’) ».
CC BY-NC-SA
Travail noté 4
3.4.5
191
Exercice 3
Utilisez le même document XML qu’à l’exercice précédent. Cette fois-ci, comptez
le nombre d’étudiants dans chaque cours et calculez la moyenne par cours. Encore
une fois, les noms des cours ou des étudiants ne doivent pas apparaître dans votre
document XSLT.
Le tableau qui suit présente le résultat.
Sigle
Nombre d’étudiants
INF8430
3
INF1030
3
INF1230
4
INF9430
1
Moyenne du cours
85.0
76.7
81.5
39.0
Bien que cet exercice soit très similaire au précédent et que la solution soit de même
longueur, vous le trouverez probablement plus difficile.
Note. Si vous aviez le droit d’utiliser XSLT 2.0, la nouvelle instruction « xsl:for-eachgroup » rendrait ce problème plus facile. Mais rappelez-vous que vous devez vous
limiter à XSLT 1.0.
3.4.6
Exercice 4
Supposons que vous ayiez des documents contenant exclusivement une déclaration
XML, des éléments et des attributs. Il n’y a pas d’espace de noms. Vous souhaitez
filtrer les documents XML de telle manière que seuls les éléments dont le nom contient
la lettre a sont inclus. Naturellement, les éléments, peu importe leur nom, qui ne sont
pas contenus dans un élément dont le nom contient la lettre a doivent être omis. Le
document XML devra contenir une instruction xml-stylesheet, mais elle ne doit pas
être reproduite dans le document sortant.
Par exemple, si on prend cet exemple:
<?xml version="1.0" ?>
<?xml-stylesheet href="monfichier.xsl" type="text/xsl" ?>
<a>
<ab x="x"><b>Test</b><a>z</a></ab>
<z x="x"><a>z</a></z>
</a>
On souhaite que le document sortant soit celui-ci:
<?xml version="1.0" encoding="ISO-8859-1"?>
<a>
<ab x="x"><a>z</a></ab>
</a>
CC BY-NC-SA
Module 3 : Technologies XML
192
Vous devez proposer deux documents XSLT permettant de réaliser ce filtrage. Le premier document ne devra pas contenir d’élément « xsl:element », alors que le second ne
contiendra pas d’élément « xsl:copy ».
3.4.7
Exercice 5
Considérez le fichier XML de la question 2 comprenant les notes des étudiants. Écrivez
une requête XQuery qui calcule la moyenne des notes de chaque cours et la présente
sous cette forme :
<maliste>
<cours sigle="INF8430">85</cours>
<cours sigle="INF1030">76.66666666666667</cours>
<cours sigle="INF1230">81.5</cours>
<cours sigle="INF9430">39</cours>
</maliste>
Vous pouvez utiliser la fonction avg qui calcule la moyenne.
CC BY-NC-SA
Module 4 : Traitement du XML
en Java
4.1
4.1.1
Aperçu
Objectifs
Dans le premier module, nous avons appris ce qu’était le XML du point de vue technique. Dans le module 2, nous avons vu le rôle que jouait le XML dans l’organisation
et sur le web. Le module 3 portait sur les technologies propres aux XML pour la présentation et la transformation des documents. Le module 4 porte sur le traitement du
XML à partir d’un langage orienté objet, particulièrement Java.
En pratique, le XML n’opère pas en vase clos. Les entreprises ont déjà des bases de
données relationnelles, des logiciels spécialisés, des serveurs et ainsi de suite. Même
si nous le pouvions, il serait impossible d’utiliser uniquement du XML : il faut nécessairement utiliser d’autres technologies, telle la programmation orientée objet, Java par
exemple.
On pourrait écrire ses propres fonctions pour traiter le XML, mais on utilise plus souvent une API. Rappelons qu’une API (Application and Programming Interface en anglais ou Interface pour la programmation d’applications en français) est un ensemble
de fonctions et d’objets facilitant la programmation d’applications.
Pour le traitement du XML en Java, il y a deux aspects importants à prendre en compte.
Il faut d’abord bien connaître l’approche DOM (Document Object Model) qui sert de
référence à toutes les API orientées objets destinées au traitement du XML. En outre, il
faut acquérir suffisamment d’expérience dans ce domaine pour pouvoir juger convenablement de la quantité de travail nécessaire au développement d’une application Java
utilisant le XML.
Les objectifs spécifiques du module sont :
– Apprécier les coûts de développement de solutions XML au sein d’une organisation.
193
Module 4 : Traitement du XML en Java
194
– Appliquer la méthodologie orientée objet pour la consommation, la fusion et le filtrage des fichiers XML.
Une activité nécessitant de la programmation, le travail noté 5, nous permettra d’évaluer votre atteinte de cet objectif.
4.1.2
Démarche
Avant de commencer l’étude du module 4, vous devez avoir terminé les modules 1 et 3.
Il n’est toutefois pas nécessaire de terminer ce module avant de passer au module 5.
Nous vous invitons à étudier ce module dans l’ordre suivant :
–
–
–
–
Modèles de programmation
Rappel sur la programmation Java
Tutoriel sur DOM et AJAX
DOM (autoévaluation)
Lisez les textes et vérifiez vos connaissances en répondant aux questionnaires d’autoévaluation, s’il y a lieu; réalisez ensuite le travail noté 5 qui prend la forme d’une activité
de programmation.
Important.- Avant de réaliser le travail noté 5, vous devriez avoir répondu aux deux
questionnaires d’autoévaluation, en maîtriser le contenu et avoir terminé l’étude du
module 3.
4.2
4.2.1
Modèles de programmation
Objectif
Connaître des méthodologies de traitement du XML, dont l’approche DOM.
4.2.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation. Ce texte porte
sur les modèles de programmation en XML et présente les méthodologies communes
pour la programmation en vue de traiter du XML. Il conclut avec quelques problèmes
communs.
Il y a plusieurs façons de traiter du XML. Chaque méthode a ses avantages et ses inconvénients. Bien que ce module s’intéresse surtout à l’approche DOM, il est important
de connaître l’ensemble des méthodologies possibles et d’avoir une idée des forces et
faiblesses relatives de chacune.
CC BY-NC-SA
Modèles de programmation
4.2.3
195
Traitement du XML comme du texte
Un fichier XML est d’abord un fichier texte. Comme certains langages, tel Java, savent
bien traiter les fichiers en format texte, ils peuvent directement traiter le XML. En fait,
du moment où nous utilisons un éditeur de texte pour écrire du XML, c’est exactement
ce que nous faisons : nous utilisons, comme outil XML, un programme prévu pour
traiter du texte.
Par exemple, nous pouvons produire du XML à partir d’un programme Java avec des
instructions comme celles qui suivent :
int montant = 10;
String nom= "Gérard Beauford";
System.out.println("<?xml version="1.0" ?> <facture><montant>"+montant
+"</montant><nom>"+nom+"</nom></facture>");
Cependant, comment savoir si le XML produit est bien formé? Dans l’exemple précédent, le document XML affiché à l’écran avec l’instruction « System.out.println » ne
sera pas du XML bien formé. Pourquoi? Il y a un accent dans le nom et la plupart des
environnement de commande n’utilisent pas la norme UTF-8. En principe, il est possible d’écrire un programme Java qui génère du XML bien formé la plupart du temps;
mais, une fois de temps en temps, il se produira une erreur dans le XML. Cette erreur
pourrait toutefois être suffisamment sérieuse et entraîner un bogue important : Mozilla
Firefox refusera d’afficher du XML qui n’est pas bien formé. Pour cette raison, il est
préférable, quand cela en vaut la peine, d’utiliser des librairies ou outils dédiés au XML
pour une meilleure productivité.
De la même façon, lire du XML sans avoir recours à des librairies peut être difficile;
par exemple, supposons qu’il faille écrire un programme Java sans utiliser des librairies
capables d’extraire le nom et le montant du fichier XML suivant :
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <facture>
<montant>432</montant>
<nom>Gérard Beauford</nom></facture>
Un tel programme peut être relativement difficile à écrire. Nous pouvons toutefois bien
y arriver avec les expressions régulières (voir le paquetage « java.util.regex » en Java),
mais dans le cas de fichiers XML plus complexes, le programme risque de devenir long
et fastidieux.
Illustrons comment les choses peuvent se corser davantage en étudiant l’exemple suivant :
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE facture [
<!ELEMENT facture (montant, nom)>
<!ELEMENT montant (#PCDATA)>
CC BY-NC-SA
Module 4 : Traitement du XML en Java
196
<!ELEMENT nom (#PCDATA)>
<!ATTLIST nom surnom CDATA "Joe">
]>
<facture><montant>432</montant><nom>Gérard Beauford</nom></facture>
Supposons maintenant que vous deviez écrire un programme Java pour déterminer la
valeur de l’attribut « surnom » de l’élément « nom » de ce document XML. Nous
constatons qu’il faut traiter non seulement le XML, mais aussi la DTD. Et nous savons
que les DTD sont le plus souvent externes, ce qui rend le problème encore plus difficile.
Supporter l’ensemble des normes XML devient rapidement très fastidieux : pensons
aux entités, déclarations XML, et ainsi de suite.
Donc, le traitement du XML en tant que texte est une méthode qui, sans être inappropriée, a ses limites.
4.2.4
Traitement événementiel
Le traitement événementiel est une approche très simple pour traiter le XML, mais
qui peut être difficile pour le programmeur. En fait, une API, souvent l’API SAX,
est utilisée pour lire le XML en séquence. Une alternative à SAX est XNI (Xerces
Native Interface). Chaque fois qu’une nouvelle balise ou tout autre élément significatif
(instruction XML, contenu XML, etc.) est rencontré, un « événement » est généré.
C’est le même type de traitement qui est utilisé pour gérer l’interface graphique avec
boutons, fenêtres, etc.; dans ce type de traitement toutefois, l’événement « presse le
bouton » est plutôt du type « nouvel élément rencontré ».
Par exemple, avec le document XML qui suit...
<facture><montant>432</montant><nom>Maman</nom></facture>
nous aurons les « événements » suivants (avec la librairie Sax) :
1. Début du document
2. Début d’un élément « facture »
3. Début d’un élément « montant »
4. Texte « 432 »
5. Fin d’un élément « montant »
6. Début d’un élément « nom »
7. Texte « Maman »
8. Fin d’un élément « nom »
9. Fin d’un élément « facture »
10. Fin du document
CC BY-NC-SA
Modèles de programmation
197
La programmation événementielle peut être plus facile et plus fiable que le traitement
du XML en tant que texte parce qu’au lieu de traiter chaque caractère, nous n’avons
qu’à traiter ce qui est significatif pour le XML (balises de début et de fin, texte, etc.). Par
exemple, les commentaires en XML seront automatiquement reconnus par un parseur
événementiel. En fait, le parseur peut parfaitement omettre de générer un événement
quand un commentaire est rencontré : c’est pourquoi les commentaires ne doivent jamais contenir des informations importantes. Les valeurs d’attributs par défaut, comme
« surnom » dans l’exemple précédent, peuvent être traitées automatiquement.
Le traitement événementiel implique quand même beaucoup de travail de la part du
programmeur, particulièrement s’il doit prendre en compte plusieurs informations dans
le document. Par exemple, s’il est nécessaire de connaître le contenu de tous les éléments du document XML, il faut enregistrer toutes ces informations, car le traitement
événementiel ne permet pas les retours en arrière : le fichier est lu en séquence et nous
devons faire le reste.
Il y a des cas où le traitement événementiel est la meilleure solution. Lorsque nous
devons traiter des fichiers XML très lourds, faisant plusieurs Mo, ou que l’on travaille
sur des machines avec peu de mémoire (comme un téléphone cellulaire), ce type de
traitement permet de faire une utilisation judicieuse de la mémoire vive. Un cas intéressant est celui où seuls quelques éléments d’un document XML nous intéressent. Par
exemple, nous cherchons la valeur des éléments « nom » : le traitement événementiel
permet de parcourir tout le document, mais de ne retenir que l’information voulue.
En général, nous pouvons dire que la programmation événementielle du XML est réservée à des cas particuliers, tels les documents lourds, et aux experts.
L’utilisation de SAX2 est fort simple à la base comme le montre le
programme MonApplicationSAX. Il suffit de créer une classe dérivée de
org.xml.sax.helpers.DefaultHandler où l’on surcharge des méthodes comme « startElement », « endElement » et « characters » qui nous permettent de gérer les événements
« début d’un élément », « fin d’un élément » et « nœud de texte » respectivement. On
peut aussi gérer d’autres événements comme le début du document (méthode « startDocument ») et sa fin (méthode « endDocument »). Ce type de programmation orientéeobjet correspond au motif de l’observateur : on construit une classe qui est chargée de
recevoir les différents événements et d’y réagir. Même les programmeurs expérimentés
utilisent peu souvent ce type de motif.
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
/**
* INF 6450
* Daniel Lemire
*/
public class MonApplicationSAX extends DefaultHandler {
/**
CC BY-NC-SA
Module 4 : Traitement du XML en Java
198
* Événement correspondant au début d’un élément
*/
public void startElement (String uri, String name, String qName,
Attributes atts) {
if(uri.length()>0)
System.out.println("Début de l’élément "+uri+":"+qName);
else
System.out.println("Début de l’élément "+name);
}
/**
* Événement correspondant à la
*/
public void endElement (String
if(uri.length()>0)
System.out.println("Fin de
else
System.out.println("Fin de
fin d’un élément
uri, String name, String qName)
l’élément "+uri+":"+qName);
l’élément "+name);
}
/**
* Ici on traite l’événement correspondant à un noeud de texte
*/
public void characters (char charac[], int debut, int longueur) {
for (int i = debut; i < longueur+debut; ++i)
System.out.print(charac[i]);
System.out.println();
}
/**
* on traite un fichier offert en ligne de commande.
* Utilisation: java MonApplicationSAX nomdufichier.xml
*/
public static void main (String args[]) throws Exception {
XMLReader xr = XMLReaderFactory.createXMLReader();
xr.setContentHandler(new MonApplicationSAX());
xr.parse(new InputSource(new FileReader(args[0])));
}
}
CC BY-NC-SA
{
Modèles de programmation
4.2.5
199
Traitement avec itérateurs
Le traitement événementiel n’est pas très intuitif. Par contre, la plupart des programmeurs Java connaissent le traitement itératif. Voici un exemple très simple de programmation avec un itérateur :
import java.util.*;
public class myvec {
public static void main(String[] arg) {
Vector<String> v= new Vector<String>();
v.add("parent");
v.add("enfant");
Iterator i = v.iterator();
while(i.hasNext())
System.out.println(i.next());
}
}
Au lieu de créer une classe qui attend passivement de recevoir des événements, on fait
une simple boucle. La Streaming API for XML (StAX) permet de faire un peu la même
chose avec du XML. Voici un exemple, observez bien la présence d’une seule boucle
et l’absence de plusieurs méthodes :
// ce programme nécessite l’installation d’une
// librairie StAX
// voir http://dev2dev.bea.com/xml/stax.html
//
import javax.xml.stream.*;
import java.net.*;
import java.io.*;
public class staxex {
public static void main(String[] args) {
String input = args[0];
try {
URL u = new URL(input);
InputStream in = u.openStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader parser = factory.createXMLStreamReader(in);
for (int event = parser.next();
event != XMLStreamConstants.END_DOCUMENT;
event = parser.next()) {
switch (event) {
case XMLStreamConstants.START_ELEMENT:
System.out.println(parser.getLocalName());
break;
case XMLStreamConstants.END_ELEMENT:
CC BY-NC-SA
Module 4 : Traitement du XML en Java
200
System.out.println(parser.getLocalName());
break;
case XMLStreamConstants.CDATA:
System.out.print(parser.getText());
break;
}
}
parser.close();
}
catch (XMLStreamException ex) {
System.out.println(ex);
}
catch (IOException ex) {
System.out.println(ex);
}
}
}
StAX est une norme Java officielle (JSR 173). La librairie open source Woodstox offre
une implémentation de l’API StAX.
4.2.6
Traitement avec modèle en arbre
Un document XML peut être vu comme un arbre avec un élément-racine contenant luimême des éléments, qui eux-mêmes contiennent des éléments, et ainsi de suite. Ainsi,
en utilisant le traitement événementiel par exemple, une librairie peut d’abord lire le
document XML et créer un modèle en arbre. Le modèle en arbre XML le plus connu
et qui sert de référence est le Document Object Model (DOM). Il est facile de trouver
des librairies qui supportent le DOM ou une variante. Nous traiterons du DOM dans
un prochain texte.
Ainsi, étant donné le document XML suivant...
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE facture [
<!ELEMENT facture (montant, nom)>
<!ELEMENT montant (#PCDATA)>
<!ELEMENT nom (#PCDATA)>
<!ATTLIST nom surnom CDATA "Joe">
]>
<facture><montant>432</montant>
<nom>Gérard Beauford</nom></facture>
un modèle en arbre aura comme objet-racine un objet représentant le document luimême ayant comme enfant l’élément « facture ». Cet objet aura lui-même une liste
CC BY-NC-SA
Modèles de programmation
201
d’enfants, c’est-à-dire deux objets représentant les éléments « montant » et « nom ». La
valeur d’attribut de « surnom » se trouvera dans l’objet représentant l’élément « nom ».
De façon simpliste, nous pouvons représenter le document XML précédent avec le
diagramme en arbre suivant :
Document - déclaration de type
|
facture
|
|
montant
nom (surnom="Joe")
|
|
"432"
"Gérard Beauford"
La programmation avec des modèles en arbre n’est pas toujours facile. Il y a un grand
nombre d’objets à manipuler (un pour chaque élément de l’arbre) et donc beaucoup
d’appels de fonctions. De plus, ce type de programmation exige beaucoup de mémoire
parce que, généralement, le parseur va d’abord visiter le document en entier, le transformer en objets, puis tout stocker en mémoire.
D’un autre côté, ce type de programmation (avec modèle en arbre) est sans doute
l’une des façons les plus conviviales de traiter de petits fichiers XML à partir d’un
langage orienté-objet comme Java. Il est relativement facile d’apprendre à écrire des
programmes en Java pour traiter le XML, en utilisant le DOM.
De la même façon, à partir d’un modèle en arbre, nous pouvons produire un document XML. Si nous utilisons une bonne librairie, nous sommes certains que le document XML généré sera bien formé et conforme à notre intention. Il faut par contre bien
comprendre que le même modèle en arbre peut correspondre à plusieurs fichiers XML
différents. Dans l’exemple précédent, il est possible qu’une librairie, qui a comme paramètre l’arbre que nous avons dessiné, génère un fichier XML comme celui-ci :
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<facture><montant>432</montant>
<nom surnom="Joe">Gérard Beauford</nom></facture>
4.2.7
Transformations
Le XSLT est une autre façon de traiter le XML par la programmation. Dans les cas les
plus simples, c’est probablement le meilleur outil. Cependant, pour un traitement plus
complexe, avec intégration dans un système d’information, il ne suffira généralement
pas. Par exemple, le XSLT n’est pas conçu pour aller chercher des informations dans
une base de données et les transformer en XML bien formé.
CC BY-NC-SA
Module 4 : Traitement du XML en Java
4.2.8
202
XPath
Si nous devons extraire de l’information d’un document XML à partir d’un langage
comme Java, il sera souvent plus simple d’utiliser une API qui supporte XPath. C’est
le cas notamment du « SDK Java 1.5 ». Nous avons étudié les expressions XPath dans le
module 3. Comme nous pouvons le voir avec l’exemple suivant, l’utilisation de XPath
en Java requiert la création de plusieurs objets intermédiaires, ce qui n’est pas toujours
très pratique. Le traitement XPath se fait sur un document chargé complètement en
mémoire ce qui rend son application prohibitive sur de gros documents. Par contre, la
syntaxe XPath est très expressive et peut éviter d’avoir à écrire de longs programmes
Java.
/* on doit toujours importer ces deux paquetages: */
import javax.xml.parsers.*;
import javax.xml.xpath.*;
/* on doit construire une instance du document XML */
DocumentBuilderFactory dbfact = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbfact.newDocumentBuilder();
/* on peut traiter directement un URL */
Document document =
builder.parse("http://www.mondomaine.com/monfichier.xml");
/* on construit un objet XPath */
XPathFactory fact = XPathFactory.newInstance();
XPath xpath = fact.newXPath();
/* finalement, on peut émettre sa requête XPath sur le document */
String title = xpath.evaluate("//nom/text()", document);
4.2.9
XML comme extension d’un langage
Tout comme les structures de données simples, tel que les tableaux, font souvent partie
intégrante des langages de programmation, on choisit parfois d’intégrer le traitement
du XML à même le langage. À titre d’exemple, EAX (ECMAScript for XML) est une
norme qui définit une extension du langage ECMAScript pour le traitement du XML.
Avec ce type d’intégration, on peut définir un document XML directement dans le code
comme dans cet exemple.
var sales = <sales vendor="John">
<item type="peas" price="4" quantity="6"/>
<item type="carrot" price="3" quantity="10"/>
<item type="chips" price="5" quantity="3"/>
</sales>;
On peut aussi traiter les documents XML comme s’ils étaient des structures de données
intégrées au langage, comme dans cet exemple.
CC BY-NC-SA
Modèles de programmation
203
for each( var price in sales..@price ) {
alert( price );
}
EAX est supporté par les implémentations du ECMAScript de Firefox (JavaScript)
et de Flash (ActionScript). Ce n’est pas le seul exemple d’intégration du XML à un
langage.
4.2.10
Traitement par abstraction
Nous pouvons utiliser des outils et des librairies qui n’exigent aucune connaissance du
XML, mais qui peuvent utiliser et générer du XML. Par exemple, la plupart des bases
de données relationnelles permettent d’importer et d’exporter des données en XML,
sans jamais devoir manipuler le XML directement. Une entreprise pourra écrire sa
propre librairie de traitement du XML dans le contexte d’une application XML spécifique. Par exemple, imaginons une application XML pour les factures; nous pourrions
écrire une fonction qui prend en paramètre le montant et la personne à qui est destinée
la facture, et qui génère le XML, sans que nous n’ayons même à savoir ce qu’est le
XML.
4.2.11
Sérialisation XML
Comme exemple de traitement par abstraction, on a la sérialisation XML des objets en
Java. On définit le terme sérialisation XML comme la transformation d’un objet Java
en un fichier XML de manière à ce qu’on puisse reconstuire l’objet par la suite. On
peut utiliser la sérialisation pour rapidement enregistrer des informations sur le disque
ou transmettre des objets vers un autre programme au travers un réseau. Par exemple,
le programme Serialization.java enregistre sur le disque un fichier XML contenant la
description complète d’un objet « java.lang.String ».
import java.beans.*;
import java.io.*;
/**
* INF 6450
* Daniel Lemire
*/
public class Serialization {
/**
* Écrit l’objet en XML dans le fichier spécifié
* (ce qu’on appelle une "sérialisation")
*/
public static void ecrireObjet(Object o, File f) throws IOException
CC BY-NC-SA
{
Module 4 : Traitement du XML en Java
204
XMLEncoder e = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream(f)));
e.writeObject(o);
e.close();
}
/**
* Lit un objet "sérialisé" en XML dans le fichier spécifié
*/
public static Object lireObjet(File f) throws IOException {
XMLDecoder e = new XMLDecoder(
new BufferedInputStream(
new FileInputStream(f)));
Object o = e.readObject();
e.close();
return o;
}
/**
* lit un fichier et l’affiche à l’écran!
*/
public static void affiche(File f) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(f));
String ligne;
while((ligne = br.readLine()) != null) {
System.out.println(ligne);
}
br.close();
}
public static void main(String[] args) throws IOException {
// je crée un objet java, dans ce cas, une chaîne de carac.
String o = new String("Un objet java");
// je vais enregistrer le résultat dans un fichier XML
File fichier = new File("test.xml");
ecrireObjet(o,fichier);
affiche(fichier);
Object lu = lireObjet(fichier);
// ensuite, je vérifie que l’objet lu est bien identique
// à l’objet écrit
assert(lu.equals(o));
}
}
Après l’exécution de ce programme, le contenu du fichier XML « test.xml » est :
CC BY-NC-SA
Modèles de programmation
205
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_05" class="java.beans.XMLDecoder">
<string>Un objet java</string>
</java>
On peut aussi utiliser la sérialisation avec ses propres objets à la condition qu’il s’agisse
de « Beans » : tous les attributs de votre objet doivent être modifiés et lus par des
méthodes qui débutent par « set » et « get » respectivement. Voici un exemple typique
d’objet Bean qui peut facilement être sérialisé :
public
int x,
public
}
public
public
public
public
}
class UneClasse {
y;
UneClasse() {
int getX() {return x;}
int getY() {return y;}
void setX(int i) {x=i;}
void setY(int i) {y=i;}
Voici un exemple de sérialisation XML de cet objet :
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_05" class="java.beans.XMLDecoder">
<object class="UneClasse">
<void property="x">
<int>1</int>
</void>
<void property="y">
<int>2</int>
</void>
</object>
</java>
Il faut, bien entendu, que le programme qui lit vos objets sérialisés ait accès aux classes
de vos objets.
4.2.12
Services web
Bien qu’il ne s’agisse pas d’une façon de traiter du XML, les services web font partie
intégrante des méthodes de programmation utilisant le XML. La définition même de ce
qu’est un service web peut varier, mais pour l’essentiel, il s’agit d’un service pouvant
être utilisé au sein d’application logicielle. Le service est généralement accessible sur
le web et répond aux requêtes par du XML. On peut transmettre les requêtes sous
diverses formes : requêtes HTTP simples (GET), transmission de documents XML,
CC BY-NC-SA
Module 4 : Traitement du XML en Java
206
etc. De nombreux sites web nous permettent d’utiliser des services web. Par exemple,
Amazon, la librairie en ligne, vous permet d’utiliser un service web pour récupérer
automatiquement les descriptions de produits. En principe, on peut combiner plusieurs
services web pour composer des applications riches et originales, ou simplement pour
ajouter une fonction particulière à un site web. Plusieurs protocoles peuvent être utilisés
dont le Simple Object Access Protocol (SOAP) ou le Search/Retrieve via URL (SRU).
On distingue généralement deux types de services web. Les services web « REST »
tels que SRU se servent exclusivement du protocole HTTP et il est toujours possible
de faire des requêtes en entrant simplement un URL dans un navigateur. Les services
web REST font l’objet d’une spécification Java (Java Specification Request 311: Java
API for RESTful Web Services). Les autres services web, dont ceux utilisant SOAP,
exigent plutôt souvent que toutes les requêtes prennent la forme d’un fichier XML et
ils ne tiennent pas compte particulièrement du protocole HTTP.
Le protocole HTTP (RFC 2616) est relativement simple. Toutes les requêtes se font du
client vers le serveur et se distinguent par un URI et une méthode. Votre navigateur fait
des requêtes GET à chaque fois que vous chargez une page. La plupart des formulaires
que vous utilisez sur le web emploie la méthode POST. On choisit généralement une
des méthodes suivantes :
Méthode
Explication
GET
Requête visant à obtenir la ressource
(par exemple, un document XML)
identifié par l’URI. Il s’agit du type de
requête le plus utilisé: c’est celui utilisé généralement par les navigateurs
pour charger les pages web. Une telle
requête ne doit pas modifier l’état de la
ressource.
POST
Ajouter une nouvelle ressource (un document, une image, un texte) en lien
avec l’URI ou annoter ou modifier une
ressource existante. L’URI fourni ne
sera pas l’URI de la ressource si une
nouvelle ressource est créée.
PUT
Créer ou remplacer une ressource ayant
l’URI fourni. En général, les requêtes
PUT sont utilisées pour remplacer les
ressources (comme un fichier XML).
DELETE
Supprimer une ressource (comme un
document).
Les méthodes GET, PUT et DELETE sont idempotentes : on peut répéter la requête
autant de fois qu’on le désire, et on obtiendra le même résultat qu’une seule requête.
La méthode POST, par contre, n’est pas idempotente : sa répétition pourrait entraîner
la création ou la modification de ressources. La méthode GET est sécuritaire : on peut
l’employer sans crainte de créer ou de modifier une ressource.
CC BY-NC-SA
Modèles de programmation
207
Un exemple de service web REST simple, utilisant le protocole SRU, est offert par la
librairie du congrès du gouvernement américain. À l’aide d’une simple requêtre prenant
la forme d’un URL, on peut demander de recevoir un fichier XML décrivant n’importe
quel livre connu de la librairie. Voici un exemple de code Java fonctionnel permettant
de faire une telle requête :
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
public class example {
public static void main(String[] args) throws Exception {
String base = "http://z3950.loc.gov:7090/voyager?";
String autre =
"operation=searchRetrieve&version=1.1&recordPacking=xml";
String autre2 =
"&startRecord=1&maximumRecords=20&query=";
String requete ="(dc.title=%22First Impressions of the New World%22) and
(dc.creator all %22Trotter Isabella Strange%22)";
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(base+autre+autre2+requete);
Element racine = doc.getDocumentElement();
XPathFactory fact = XPathFactory.newInstance();
XPath xpath = fact.newXPath();
System.out.println("code: "+xpath.evaluate("//leader/text()", doc));
}
}
En examinant le code, on peut voir qu’on cherche de l’information sur tous les livres
ayant pour titre « First Impressions of the New World » et écrits par « Trotter Isabella
Strange ». Le résultat de la requête SRU est plutôt incompréhensible dans ce cas précis.
Il est surtout destiné aux spécialistes en bibliothéconomie :
<?xml version="1.0"?>
<zs:searchRetrieveResponse xmlns:zs="http://www.loc.gov/zing/srw/">
<zs:version>1.1</zs:version><zs:numberOfRecords>1</zs:numberOfRecords>
<zs:records><zs:record>
<zs:recordSchema>info:srw/schema/1/marcxml-v1.1</zs:recordSchema>
<zs:recordPacking>xml</zs:recordPacking><zs:recordData><record
xmlns="http://www.loc.gov/MARC21/slim">
<leader>01007cam a2200265u 4500</leader>
<controlfield tag="001">8662129</controlfield>
<controlfield tag="005">20011206111958.0</controlfield>
<controlfield tag="008">830108s1859
enkb
a
000 0 eng
</controlfield>
CC BY-NC-SA
Module 4 : Traitement du XML en Java
208
<datafield tag="035" ind1=" " ind2=" ">
<subfield code="9">(DLC)
02002686</subfield>
</datafield>
<datafield tag="906" ind1=" " ind2=" ">
<subfield code="a">0</subfield>
<subfield code="b">cbc</subfield>
<subfield code="c">premunv</subfield>
<subfield code="d">u</subfield>
<subfield code="e">ncip</subfield>
<subfield code="f">19</subfield>
<subfield code="g">y-gencatlg</subfield>
</datafield>
<datafield tag="010" ind1=" " ind2=" ">
<subfield code="a">
02002686 </subfield>
</datafield>
<datafield tag="040" ind1=" " ind2=" ">
<subfield code="a">DLC</subfield>
<subfield code="c">CarP</subfield>
<subfield code="d">DLC</subfield>
</datafield>
<datafield tag="043" ind1=" " ind2=" ">
<subfield code="a">n-cn---</subfield>
<subfield code="a">n-us---</subfield>
</datafield>
<datafield tag="050" ind1="1" ind2="0">
<subfield code="a">E166</subfield>
<subfield code="b">.T85</subfield>
</datafield>
<datafield tag="050" ind1="0" ind2="0">
<subfield code="a">Microfilm 32043 E</subfield>
</datafield>
<datafield tag="100" ind1="1" ind2=" ">
<subfield code="a">[Trotter, Isabella (Strange)],</subfield>
<subfield code="d">1816-1878. [from old catalog]</subfield>
</datafield>
<datafield tag="245" ind1="1" ind2="0">
<subfield code="a">First impressions of the New world on two travellers
from the Old, in the autumn of 1858.</subfield>
</datafield>
<datafield tag="260" ind1=" " ind2=" ">
<subfield code="a">London,</subfield>
<subfield code="b">Longman, Brown, Green, Longmans, &amp;
Roberts,</subfield>
<subfield code="c">1859.</subfield>
</datafield>
<datafield tag="300" ind1=" " ind2=" ">
CC BY-NC-SA
Rappel sur la programmation Java
209
<subfield code="a">xi, 308 p.</subfield>
<subfield code="b">front. (fold. map)</subfield>
<subfield code="c">20 cm.</subfield>
</datafield>
<datafield tag="583" ind1=" " ind2=" ">
<subfield code="a">Replace;</subfield>
<subfield code="z">LC copy replaced by preservation microfilm</subfield>
<subfield code="5">DLC</subfield>
</datafield>
<datafield tag="651" ind1=" " ind2="0">
<subfield code="a">United States</subfield>
<subfield code="x">Description and travel. [from old catalog]</subfield>
</datafield>
<datafield tag="651" ind1=" " ind2="0">
<subfield code="a">Canada</subfield>
<subfield code="x">Description and travel. [from old catalog]</subfield>
</datafield>
<datafield tag="985" ind1=" " ind2=" ">
<subfield code="g">pmosl</subfield>
</datafield>
<datafield tag="985" ind1=" " ind2=" ">
<subfield code="e">mvp</subfield>
<subfield code="f">zz01</subfield>
</datafield>
<datafield tag="991" ind1=" " ind2=" ">
<subfield code="b">c-MicRR</subfield>
<subfield code="h">Microfilm 32043 E</subfield>
<subfield code="t">Copy 1</subfield>
<subfield code="w">PREM</subfield>
</datafield>
</record></zs:recordData><zs:recordPosition>1</zs:recordPosition>
Pour une description, des services web utilisant SOAP, vous pouvez consulter la rubrique correspondante sur wikipédia. Ils sont généralement plus complexes que les
services web REST.
4.3
4.3.1
Rappel sur la programmation Java
Objectif
Ramener à votre mémoire les notions que vous connaissez déjà sur le langage de programmation Java.
CC BY-NC-SA
Module 4 : Traitement du XML en Java
4.3.2
210
Activité
Lisez les définitions qui suivent, puis compilez et exécutez les programmes suggérés
dans la section « Exemples ».
4.3.3
Définitions
Notion d’objet
Java est un langage orienté objet. Le terme « orienté objet » signifie que l’on modélise
le problème en utilisant des « objets ». Les objets possèdent des données (les attributs)
et des comportements (les méthodes). Dans la plupart des langages orientés objets, les
objets appartiennent à une « classe » qui en définit le type.
Notion de classe
Une classe est un modèle pour créer des objets qui ont des caractéristiques communes.
La classe comporte la structure d’un objet (ses attributs et ses méthodes). On dit qu’un
objet est l’instance d’une classe et on parle d’instanciation. En Java, tous les objets sont
créés à partir d’une classe.
Notion de méthode
Une méthode est une fonction qui peut être appliquée aux objets ou qui est appliquée
par les objets. Par exemple, pour une classe « Voiture », une méthode pourrait être
« Freiner » ou « Accélérer ».
Notion d’interface
Une interface est définie par un ensemble de méthodes et de variables à la manière
d’une classe; mais, à la différence d’une classe, on ne peut l’utiliser comme modèle
pour créer un objet. On dit d’une classe qui contient toutes les méthodes spécifiées par
l’interface qu’elle implémente l’interface en question.
En pratique, l’interface peut se traiter comme une classe : si la classe « Voiture » implémente l’interface « Vehicule », alors tous les objets instanciés à partir de « Voiture »
peuvent être traités comme des objets de type « Vehicule ». Une même classe peut
implémenter plusieurs interfaces.
CC BY-NC-SA
Rappel sur la programmation Java
211
Notion d’héritage
L’héritage est un lien entre des classes. Si une classe est créée à partir d’une classe
déjà existante, elle « hérite » de ses attributs et de ses méthodes. Par exemple, la classe
« voiture » pourrait hériter de la classe « engin ».
Notion d’encapsulation
L’encapsulation consiste à protéger un objet, en empêchant l’accès à ses données par
un autre moyen que les méthodes proposées.
4.3.4
Exemples
Les deux exemples proposés sont très simples. Toutefois, faites-les pour vous remémorer la programmation Java.
Commençons par le commencement. Créons un programme qui affichera « Bonjour ! ».
Tapez le texte suivant, avec Notepad/Bloc-notes, et enregistrez-le sous le nom « bonjour.java ».
public class bonjour{
public static void main (String[] args){
System.out.println("Bonjour !");
}
}
Pour tester ce programme, ouvrez une fenêtre de commande et placez-vous dans le
dossier où vous avez enregistré le fichier « bonjour.java », puis tapez « javac bonjour.java » pour compiler le programme. N’oubliez pas d’indiquer le chemin du fichier « javac.exe »; au besoin, par exemple, tapez, dans la fenêtre de commande,
« PATH=C:/j2sdk1.4.2_06/bin », suivi d’un retour du chariot. Cette commande va
créer un fichier « bonjour.class » qui contient le programme compilé. Pour exécuter
le programme, il suffit de taper « java bonjour ». Normalement, le texte « Bonjour ! »
s’affichera.
Créons maintenant un autre programme qui prend comme argument le nom d’une personne et qui affiche « Bonjour nom ! ». Il suffit de modifier le programme précédent.
Nommons ce programme « bonjourbis » et le fichier « bonjourbis.java ».
public class bonjourbis{
public static void main (String[] args){
String nom = new String(args[0]);
System.out.println("Bonjour "+nom+" !");
}
}
CC BY-NC-SA
Module 4 : Traitement du XML en Java
212
Pour compiler le fichier, il suffit de taper « javac bonjourbis.java ». Pour l’exécuter
avec « Lucie » comme argument, il suffit d’ajouter l’argument à la fin de la ligne de
commande : « java bonjourbis Lucie ». Et le texte « Bonjour Lucie ! » s’affichera.
4.3.5
Exemples avancés
Supposons que Voiture et Bicyclette sont des classes qui héritent de Vehicule ou alors,
des classes qui implémentent l’interface Vehicule. Supposons que vous avez un objet
de type Vehicule, comment savoir s’il s’agit d’un objet de classe Voiture ou Bicyclette ?
Vous pouvez tester son type avec le mot-clef « instanceof », comme ceci :
public void afficheType (Vehicule v){
if(v instanceof Voiture) {
System.out.println("Objet de classe Voiture!");
} else if (v instanceof Bicyclette) {
System.out.println("Objet de classe Bicyclette!");
} else {
System.out.println("Erreur!");
}
}
Supposons maintenant qu’on vous passe un objet de type Vehicule alors que vous savez
très bien que c’est un objet de classe Voiture, ça peut être bien embêtant surtout si
l’objet Voiture a des méthodes ou attributs que le type Vehicule n’a pas ! Vous pouvez
dire à Java, explicitement, que vous voulez qu’il traite l’objet comme ayant la classe
Voiture comme ceci :
public void traiteType (Vehicule v){
Voiture w = (Voiture) v;
(...)
}
Attention cependant ! Si l’objet n’est pas de la classe Voiture, une exception sera générée (ClassCastException).
4.3.6
Lecture de fichiers
On peut lire un fichier au format text en Java, ligne par ligne, en utilisant la classe
BufferReader du paquetage java.io.
import java.io.*;
(...)
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(nomdufichier)));
String ligne;
while ((ligne = br.readLine()) != null) {
CC BY-NC-SA
Tutoriel sur DOM
213
(...)
}
br.close();
4.3.7
Astuces
– La casse est importante en Java. La variable « i » n’est pas la même que la variable
« I ».
– Votre fichier java ne peut contenir qu’une seule classe « public » et le fichier doit
avoir le même nom que cette classe.
– Les instructions, dans une fonction, doivent être séparées par le point-virgule ( ; ).
4.3.8
Retour sur l’activité
Est-ce que vous avez pu compiler et exécuter les programmes en java? Si oui, passez
aux autres activités, sinon contactez la personne tutrice ou cherchez encore un peu.
4.4
4.4.1
Tutoriel sur DOM
Objectifs
– Apprendre à lire et à écrire du XML à partir de Java.
– Comprendre le modèle DOM, en particulier sa structure en arbre.
4.4.2
Activité
Ce tutoriel vous fournira une compréhension pratique de DOM (version 2.0) en Java.
Lisez attentivement le texte qui suit et, au fur et à mesure, faites les exemples proposés.
4.4.3
Le tutoriel pour se familiariser avec le DOM
Introduction
Nous supposons que vous disposez d’un environnement de développement Java et que
vous ferez les exemples de ce tutoriel afin de mieux comprendre. Notre objectif est
avant tout de vous rendre suffisamment à l’aise avec DOM pour pouvoir l’utiliser; nous
vous invitons toutefois à naviguer dans le web pour en apprendre davantage sur le sujet,
au besoin.
CC BY-NC-SA
Module 4 : Traitement du XML en Java
214
L’API Java elle-même est disponible sur le site de Sun Microsystems. Pour pouvoir
faire vos propres programmes, consultez l’API Java qui comprend tous les objets et
fonctions du tutoriel.
4.4.4
Notions de base
On dit qu’un modèle DOM est une structure en arbre. En informatique, un arbre est
un graphe ou une structure constituée de nœuds, de façon telle que chaque nœud a un
et un seul parent - ou aucun -, lequel a un seul ou plusieurs enfants. Un seul nœud est
autorisé à ne pas avoir de parent, c’est le nœud-racine. Pour illustrer notre propos, nous
pouvons penser à une cellule qui se divise : chaque cellule a une et une seule celluleparente, et chaque cellule peut se diviser (souvent en deux) ou mourir avant de pouvoir
se diviser. On dit d’un nœud qui n’a pas d’enfant qu’il est un nœud-feuille.
Comme nous allons le voir, dans un arbre DOM, tous les éléments, les déclarations
XML, etc., sont représentés par un nœud. Le nœud-racine est le document lui-même
qui peut contenir la déclaration XML, la déclaration de type de document et l’élémentracine, comme ses enfants.
4.4.5
Point de vue critique
L’API DOM est très utilisée. Elle est supportée dans plusieurs langages, dont ECMAScript, Java, C#, C++, etc. parce qu’elle a été spécifiée avec l’Interface description language. Par contre, comme c’est un traitement du XML en arbre, les implémentations
de l’API DOM consomment beaucoup de mémoire. En plus, l’API DOM fait travailler
le programmeur en exigeant beaucoup de lignes de code pour faire les choses les plus
simples. Il arrive aussi qu’une implémentation de l’API DOM soit beaucoup plus lente
que des alternatives plus simples. Malgré tous ces défauts, le fait que l’API DOM soit
si bien supportée en fait une référence incontournable.
4.4.6
Un document XML
Créons d’abord un document XML, que nous nommerons « test.xml », et un répertoire
pour y déposer le fichier en question, ainsi que le code Java pour ce tutoriel.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<liste>
<joueur>
<nom surnom="jojo">Jean</nom>
<buts>32</buts>
</joueur>
<joueur>
<nom surnom="Ma">Marie</nom>
<buts>54</buts>
CC BY-NC-SA
Tutoriel sur DOM
215
</joueur>
</liste>
4.4.7
Charger un document XML en Java
Écrivons maintenant un programme en Java qui va lire ce fichier XML. Pour ce
faire, créons avec Notepad/Bloc-notes ou avec tout autre éditeur approprié, un fichier
« test.java » contenant le texte suivant :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
}
}
Ensuite, compilons et exécutons le programme :
javac test.java
java test test.xml
Si tout se passe bien, vous ne devriez rien voir s’afficher sur votre écran. En effet, les
trois lignes de code Java utilisées plus haut ne font que créer l’objet « Document » qui
contient, selon un modèle en arbre, notre document « test.xml ».
Java utilise un traitement événementiel (SAX) pour charger le fichier. Cependant, une
fois que l’objet doc a été créé, vous pourriez effacer le fichier du disque sans mal. Le
traitement du document se fait entièrement en mémoire.
4.4.8
Accès à l’élément-racine
Le premier élément que nous voulons consulter est l’élément-racine qui, dans notre
cas, est un élément « liste ». Nous obtiendrons le résultat désiré en utilisant la méthode
« getDocumentElement », comme ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
CC BY-NC-SA
Module 4 : Traitement du XML en Java
216
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
}
}
Cet exemple n’est pas très intéressant puisque, encore une fois, rien ne s’affiche à
l’écran. Par contre, nous avons maintenant un objet « racine » qui est un modèle de
l’élément-racine du document XML et qui a le type d’une interface « Element ».
L’interface « Element » est l’interface la plus importante en DOM. Notre nouvel objet « racine » a une méthode « getTagName() » qui permet de connaître le nom de
l’élément. Par exemple, le code suivant devrait afficher le texte « liste » à l’écran.
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
System.out.println(racine.getTagName());
}
}
Voici deux des méthodes importantes de l’interface « Element » :
Méthode
Résultat
getTagName()
Donne le nom de l’élément
getAttribute(String nom)
Donne la valeur d’un attribut
Point technique : Dans le cas où vous devez faire afficher du texte en ligne de commande sous un environnement Windows, il arrive que les accents ne passent pas. En
effet, le jeu de caractère utilisé par l’outil de ligne de commande Windows est souvent
Cp850. Il faut donc en informer Java en ajouter la ligne « System.setOut(new PrintStream(System.out, true, "Cp850")); » avant d’utiliser la méthode System.out.
4.4.9
L’interface « Node »
Dans le modèle DOM, l’arbre est un arbre fait de nœuds ou « nodes », en anglais.
Plusieurs choses sont représentées par l’interface « Node » : du texte, un élément,
une instruction de traitement, une déclaration de type de document, une entité, etc.
L’arbre DOM commence à la racine par le document lui-même. Les attributs peuvent
être traités comme des « Node », même s’ils ne font pas partie de l’arbre DOM : un
CC BY-NC-SA
Tutoriel sur DOM
217
attribut est une propriété d’un élément de l’arbre. Le modèle en arbre DOM peut être
décrit ainsi : un document contient des « Node », et chaque « Node » contient d’autres
« Node », etc.
L’interface « Node » possède deux méthodes très importantes : « getNodeName() »
et « getNodeValue() ». La valeur donnée par l’une ou l’autre de ces deux méthodes
dépend du type de nœud représenté. Le tableau suivant résume le comportement de ces
méthodes pour différents types importants :
type de nœud
nom DOM
valeur de getNo- valeur de getNodeName()
deValue()
attribut
Attr
nom de l’attribut
valeur de l’attribut
élément
Element
nom de l’élément
null
instruction de trai- ProcessingInstructioncible de l’instruc- contenu entier de
tement
tion
l’instruction sans
la cible
texte
Text
la chaîne « #text » le texte
Une autre méthode importante est « getNodeType ». Par exemple, si « e » est un nœud
et que nous voulons vérifier s’il s’agit d’un élément, nous pouvons le faire comme ceci :
if( e.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(" Ce noeud est un élément!!! ");
}
Demandons maintenant à DOM de nous fournir tous les sous-éléments « joueur » de
l’élément-racine, comme ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getElementsByTagName("joueur");
}
}
Nous avons utilisé la méthode « getElementsByTagName » qui nous permet d’obtenir
la liste des sous-éléments ayant le nom XML donné. Une alternative est d’utiliser la
méthode « getElementById » qui donne le seul élément ayant un attribut de type « ID »
correspondant à la chaîne de caractères founie. En XHTML, par exemple, on peut ajouter un attribut nommé « id » qui a comme une valeur « ID ». Rappelons qu’un attribut
a une valeur de type « ID » si elle est un nom XML et si toutes les valeurs de type
CC BY-NC-SA
Module 4 : Traitement du XML en Java
218
« ID » dans le document sont différentes. L’avantage sur la méthode « getElementsByTagName » est qu’on peut rapidement sélectionner un unique élément.
L’interface « NodeList » est, quant à elle, très simple. Elle n’a que deux méthodes :
« getLength() », qui retourne le nombre de « Node », et « item(int) », qui nous donne
accès au « Node » en question. Donc, pour visiter tous les sous-éléments de l’élémentracine, nous pouvons faire comme ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getChildNodes();
for (int i = 0; i < nl.getLength(); ++i) {
Node n = nl.item(i);
}
}
}
Les deux sous-éléments « joueur » de l’élément « liste » sont visités. Parce que les
deux « Node » en question sont des éléments, nous aurions très bien pu écrire :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getChildNodes();
for (int i = 0; i < nl.getLength(); ++i) {
Element n = (Element) nl.item(i);
}
}
}
CC BY-NC-SA
Tutoriel sur DOM
219
Supposons maintenant que nous voulions afficher le contenu des deux éléments
« joueur ». Nous pouvons y arriver en commençant comme ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getElementsByTagName("joueur");
for (int i = 0; i < nl.getLength(); ++i) {
Element joueur = (Element) nl.item(i);
NodeList listedenoms = joueur.getElementsByTagName("nom");
Element nom = (Element) listedenoms.item(0);
}
}
}
En principe, nous avons maintenant les éléments « nom » des joueurs, mais comment faire pour obtenir le contenu textuel d’un élément? Nous devons savoir que
le texte est lui-même un « Node ». Il suffit donc de sélectionner le premier et seul
« Node » contenu dans l’élément « nom » et d’aller en chercher la valeur (getFirstChild().getNodeValue()), comme ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getElementsByTagName("joueur");
for (int i = 0; i < nl.getLength(); ++i) {
Element joueur = (Element) nl.item(i);
NodeList listedenoms = joueur.getElementsByTagName("nom");
Element nom = (Element) listedenoms.item(0);
System.out.println(nom.getFirstChild().getNodeValue());
}
CC BY-NC-SA
Module 4 : Traitement du XML en Java
220
}
}
Essayez maintenant ce programme. Vous devriez voir les noms des joueurs qui s’affichent. Si vous souhaitez ajouter le nombre de buts correspondant à chaque joueur,
rien de plus facile! Il suffit de répéter le code comme dans l’exemple qui suit :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getElementsByTagName("joueur");
for (int i = 0; i < nl.getLength(); ++i) {
Element joueur = (Element) nl.item(i);
NodeList listedenoms = joueur.getElementsByTagName("nom");
Element nom = (Element) listedenoms.item(0);
System.out.println(nom.getFirstChild().getNodeValue());
NodeList listedebuts = joueur.getElementsByTagName("buts");
Element buts = (Element) listedebuts.item(0);
System.out.println(buts.getFirstChild().getNodeValue());
}
}
}
Dans l’éventualité ou un élément nom ne contiendrait pas de texte, la méthode getFirstChild() retourne la valeur null. Il faudrait donc cette éventualité
(buts.getFirstChild()==null) afin d’éviter un plantage du programme.
Vous vous rappelez sans doute que les éléments « nom » ont un attribut « surnom ».
Pour aller en chercher la valeur, il suffit d’utiliser la méthode « getAttribute » comme
ceci :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class test {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
CC BY-NC-SA
Tutoriel sur DOM
221
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
NodeList nl = racine.getElementsByTagName("joueur");
for (int i = 0; i < nl.getLength(); ++i) {
Element joueur = (Element) nl.item(i);
NodeList listedenoms = joueur.getElementsByTagName("nom");
Element nom = (Element) listedenoms.item(0);
System.out.println(nom.getFirstChild().getNodeValue());
System.out.println(nom.getAttribute("surnom"));
NodeList listedebuts = joueur.getElementsByTagName("buts");
Element buts = (Element) listedebuts.item(0);
System.out.println(buts.getFirstChild().getNodeValue());
}
}
}
Nous constatons que les attributs ne sont pas des « Node » et qu’ils sont donc plutôt
traités comme faisant partie d’un élément. C’est logique; puisqu’un attribut ne peut
contenir d’autres attributs, il ne forme donc pas un élément essentiel d’une structure en
arbre, contrairement aux éléments.
Et c’est tout ce qu’il nous faut pour lire complètement le fichier XML « test.xml ».
Vous pouvez bien sûr créer un programme plus sophistiqué!
4.4.10
Création de documents
À partir d’une structure DOM, nous pouvons créer un document XML en Java à l’aide
de quelques lignes et du paquetage « javax.xml.transform » et de ses sous-paquetages.
L’écriture d’une structure DOM se fait vers un objet de type « Writer ». Si nous voulons
écrire dans un fichier, nous devons créer un « FileWriter » et si nous voulons afficher à
l’écran, nous passerons en paramètre l’objet « System.out ».
Par exemple, pour lire le document « test.xml », en faire une structure DOM et l’enregistrer, nous pouvons utiliser le programme suivant :
import
import
import
import
import
import
org.w3c.dom.*;
javax.xml.parsers.*;
java.io.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class construction {
public static void main(String[] args) throws Exception {
// lecture d’un document
DocumentBuilderFactory factory =
CC BY-NC-SA
Module 4 : Traitement du XML en Java
222
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
// écriture d’un document
TransformerFactory tfact =
TransformerFactory.newInstance();
Transformer transformer =
tfact.newTransformer();
DOMSource source = new DOMSource(doc);
FileWriter fw = new FileWriter(args[1]);
StreamResult result = new StreamResult(fw);
transformer.transform(source, result);
}
}
Pour afficher à l’écran, nous aurions pu utiliser la syntaxe « new StreamResult(System.out); ».
Si nous enregistrons ce code Java dans un fichier nommé « construction.java », il suffira
ensuite de taper :
javac construction.java
java construction test.xml copy.xml
Le fichier qui en résulte, « copy.xml », devrait être pratiquement identique à
« test.xml ». Nous pouvons évidemment utiliser cette approche pour créer des documents XML.
Nous allons maintenant créer un document XML « vide », avant de lui ajouter du
contenu. Nommons le fichier du programme « construction2.java ». Nous utilisons la
méthode « newDocument » :
import
import
import
import
import
import
org.w3c.dom.*;
javax.xml.parsers.*;
java.io.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class construction2 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.newDocument();
}
}
CC BY-NC-SA
Tutoriel sur DOM
223
Si nous enregistrons ce document, il n’y aura que la déclaration XML. Créons maintenant un élément « liste » et ajoutons-le à notre document. Pour ce faire, nous utiliserons
la méthode « createElement » de l’interface « Document »
et la méthode « appendChild », comme ceci :
import
import
import
import
import
import
org.w3c.dom.*;
javax.xml.parsers.*;
java.io.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class construction2 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.newDocument();
Element liste = doc.createElement("liste");
doc.appendChild(liste);
}
}
Il est important de noter qu’on ne peut créer un élément ou autre nœud sans avoir
d’abord un document. Un nœud DOM contient toujours une référence au document
auquel il appartient, même si on ne l’a pas encore inséré dans le document avec une
fonction « appendChild ». Il est impossible de prendre un élément d’un document et de
l’insérer dans un autre document : vous risquez ainsi de vous retrouver avec un document dysfonctionnel. On peut cependant copier un nœud d’un document pour l’amener
dans un nouveau document avec la méthode « importNode » de l’interface « Document ».
Nous pouvons donc créer un nouveau fichier avec le contenu de « test.xml », entièrement à partir de fonctions en Java. À chaque nœud, nous pouvons ajouter des enfants
à l’aide de la méthode « appendChild ». Nous pouvons aussi créer des nœuds de texte
à partir de la méthode « createTextNode » de l’interface « Document ». Finalement,
l’interface « Element » a une méthode « setAttribute » pour créer un attribut.
Comme nous utilisons souvent « ISO-8859-1 » pour l’encodage de caractères, nous
vous suggérons de spécifier l’attribut « encoding » du document XML, comme ceci :
TransformerFactory tfact =
TransformerFactory.newInstance();
Transformer transformer =
tfact.newTransformer();
transformer.setOutputProperty("encoding", "ISO-8859-1");
CC BY-NC-SA
Module 4 : Traitement du XML en Java
224
Le programme suivant va créer un document « nouveaufichier.xml » équivalent au
fichier « test.xml » défini plus haut. Nous appellerons le fichier « construction3.java ».
import
import
import
import
import
import
org.w3c.dom.*;
javax.xml.parsers.*;
java.io.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class construction3 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.newDocument();
Element liste = doc.createElement("liste");
doc.appendChild(liste);
Element joueur1 = doc.createElement("joueur");
Element joueur2 = doc.createElement("joueur");
liste.appendChild(joueur1);
liste.appendChild(joueur2);
Element nom1 = doc.createElement("nom");
nom1.appendChild(doc.createTextNode("Jean"));
Element nom2 = doc.createElement("nom");
nom2.appendChild(doc.createTextNode("Marie"));
joueur1.appendChild(nom1);
joueur2.appendChild(nom2);
Element but1 = doc.createElement("buts");
but1.appendChild(doc.createTextNode("32"));
Element but2 = doc.createElement("buts");
but2.appendChild(doc.createTextNode("54"));
joueur1.appendChild(but1);
joueur2.appendChild(but2);
nom1.setAttribute("surnom","jojo");
nom2.setAttribute("surnom","Ma");
TransformerFactory tfact =
TransformerFactory.newInstance();
Transformer transformer =
tfact.newTransformer();
transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
FileWriter fw = new FileWriter("nouveaufichier.xml");
StreamResult result = new StreamResult(fw);
transformer.transform(source, result);
CC BY-NC-SA
Tutoriel sur DOM
225
}
}
Testez ce programme et modifiez-le pour explorer différentes possibilités. Il peut être
utile de vérifier les fonctions disponibles dans le cadre de l’API Java.
Il est intéressant d’observer qu’il est possible d’ajouter à plusieurs reprises un nœud de
texte à même un élément :
e.appendChild(doc.createElement("a"));
e.appendChild(doc.createElement("b"));
e.appendChild(doc.createElement("c"));
Le contenu de l’élément, dans cet exemple, sera tout simplement le texte « abc » décomposé en 3 nœud.
4.4.11
Modifier un « Document »
Nous observons que l’écriture d’un document XML se fait à partir d’un objet « Document ». Rien ne nous empêche donc de charger un document XML, de le modifier et
de l’enregistrer à nouveau.
Voici un tableau qui donne quelques fréquentes opérations de modification :
Code
Résultat
e.getParentNode().removeChild(e);
Permet d’éliminer un nœud
e.getParentNode().replaceChild(e,f);
Permet de remplacer un nœud par un
autre
e.setAttribute(String nom, String va- Permet de modifier un attribut
leur)
e.removeAttribute(String nom)
Permet d’éliminer un attribut
Par exemple, le programme suivant, « Modif.java », permet d’ajouter un attribut à
l’élément-racine de tout document XML :
import
import
import
import
import
import
org.w3c.dom.*;
java.io.*;
javax.xml.parsers.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class Modif {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
CC BY-NC-SA
Module 4 : Traitement du XML en Java
226
factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
racine.setAttribute("unattribut","une valeur");
TransformerFactory tfact =
TransformerFactory.newInstance();
Transformer transformer =
tfact.newTransformer();
transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
FileWriter fw = new FileWriter(args[0]);
StreamResult result = new StreamResult(fw);
transformer.transform(source, result);
}
}
Il suffit de l’appeler avec la syntaxe « java Modif monfichier.xml ».
4.4.12
Les espaces de noms
L’utilisation des espaces de noms est prévue en DOM (version 2.0). Par exemple, pour
créer un élément appartenant à un espace de noms, il faut utiliser la syntaxe « createElementNS(String espace, String nom) », où « espace » prend la valeur de l’URI
et « nom » contient le préfixe et le nom de l’élément. Cette nouvelle méthode vient
remplacer le simple « createElement(String nom) ». Il existe aussi une méthode correspondante « setAttributeNS(String espace, String nom, String valeur) ».
Considérons l’exemple de document XML suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<md:racine xmlns:md="http://www.mondomaine.com/">
<md:element md:unattribut="sa valeur"/></md:racine>
Pour le produire en DOM, il faudrait utiliser un code comme celui-ci :
import
import
import
import
import
import
org.w3c.dom.*;
java.io.*;
javax.xml.parsers.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class Espace {
public static void main(String[] args) throws Exception {
String uri= "http://www.mondomaine.com/";
DocumentBuilderFactory factory =
CC BY-NC-SA
Tutoriel sur DOM
227
DocumentBuilderFactory.newInstance();
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.newDocument();
Element racine = doc.createElementNS(uri,"md:racine");
racine.setAttribute("xmlns:md",uri);
doc.appendChild(racine);
Element e = doc.createElementNS(uri,"md:element");
racine.appendChild(e);
e.setAttributeNS(uri,"md:unattribut","sa valeur");
TransformerFactory tfact =
TransformerFactory.newInstance();
Transformer transformer =
tfact.newTransformer();
transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
}
Il faut nommer le fichier « Espace.java ».
Nous pouvons aussi retrouver l’espace de noms d’un élément à l’aide de la méthode
« getNamespaceURI() » de l’interface « Node ». Cependant, par défaut, la classe « DocumentBuilderFactory » ignore les espaces de noms et il faut, par conséquent, ajouter la
ligne « factory.setNamespaceAware(true); ». L’exemple du code qui suit donne l’espace
de noms (URI), le préfixe et le nom de l’élément (avec le préfixe) de tout fichier XML
saisi dans une ligne de commande :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class LireEspace {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
Element racine = doc.getDocumentElement();
System.out.println(racine.getNamespaceURI()+" "
+racine.getPrefix()+" "+ racine.getTagName());
}
}
CC BY-NC-SA
Module 4 : Traitement du XML en Java
228
Il faut nommer le fichier « LireEspace.java », et l’exécuter avec la syntaxe « java LireEspace monfichier.xml ».
4.4.13
Deux problèmes avec solution
Pour vous aider à maîtriser le modèle DOM, nous vous proposons deux problèmes et
une solution possible pour chacun.
Problème 1
Créez une classe « Arbre » (fichier « Arbre.java ») qui donne l’arbre DOM d’un document XML. Pour chaque nœud, donnez son nom et sa valeur (indices : « getNodeName », « get NodeValue »). Enfin, indentez les nœuds selon le nombre de parents
qu’ils ont.
Ainsi, étant donné le fichier « test.xml » suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<joueur><nom surnom="jojo">Jean</nom><buts>32</buts></joueur>
La commande « java Arbre test.xml » devrait afficher à l’écran le résultat suivant :
Nom: #document Valeur: null
Nom: joueur Valeur: null
Nom: nom Valeur: null
Nom: #text Valeur: Jean
Nom: buts Valeur: null
Nom: #text Valeur: 32
Solution du problème 1
Voici une solution possible :
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class Arbre {
public static void traite(Node node, int i) {
String s= ""; for (int k = 0; k < i; ++k) s+=" ";
System.out.println(s+"Nom: "+ node.getNodeName() +
" Valeur: "+node.getNodeValue());
NodeList nl = node.getChildNodes();
if(nl != null) {
for (int k = 0; k < nl.getLength(); ++k) {
traite( nl.item(k),i+2);
CC BY-NC-SA
Tutoriel sur DOM
229
}
}
}
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse(args[0]);
traite(doc,0);
}
}
Problème 2
Nous pouvons utiliser un fichier XML comme archive d’une base de données primitive.
Cette fois-ci, nous vous demandons d’écrire un programme qui permet de chercher,
d’effacer et d’ajouter des noms dans un bottin téléphonique.
Stockez les numéros dans un fichier XML nommé « bottin.xml » et ayant le contenu
qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<bottin>
<personne nom="Jean Réjean" téléphone="432-4421" />
<personne nom="Jules Desche" téléphone="432-4332" />
</bottin>
Concevez un programme dont le code source sera contenu dans un fichier nommé
« Bottin.java ». Votre programme doit posséder les trois fonctions suivantes :
– « java Bottin efface "Jean Réjean" » : élimine du fichier « bottin.xml » tout élément
« personne » ayant comme attribut « nom="Jean Réjean" ».
– « java Bottin cherche "Jean Réjean" » : donne le numéro de téléphone correspondant
au nom donné à partir du contenu du fichier « bottin.xml », et ne retourne rien si le
nom donné n’est pas trouvé.
– « java Bottin ajoute "Jean Réjean" 432-4421 » : fait en sorte que le nom « Jean
Réjean » soit associé au seul numéro de téléphone « 432-4421 ».
Vous pouvez supposer que le fichier « bottin.xml » existe et se trouve dans le même répertoire que le fichier « Bottin.java ». Vous pouvez également supposer que l’élémentracine est « bottin ».
Solution du problème 2
Voici une solution possible :
CC BY-NC-SA
Module 4 : Traitement du XML en Java
import
import
import
import
import
import
230
org.w3c.dom.*;
java.io.*;
javax.xml.parsers.*;
javax.xml.transform.*;
javax.xml.transform.dom.*;
javax.xml.transform.stream.*;
public class Bottin {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder parser =
factory.newDocumentBuilder();
Document doc = parser.parse("bottin.xml");
Element racine = doc.getDocumentElement();
NodeList nl = racine.getChildNodes();
if(args[0].equals("efface")) {
for (int k = 0; k < nl.getLength(); ++k) {
if(nl.item(k).getNodeType()==Node.ELEMENT_NODE) {
Element e = (Element) nl.item(k);
if(e.getAttribute("nom").equals(args[1])) {
e.getParentNode().removeChild(e);
}
}
}
} else if (args[0].equals("cherche")) {
for (int k = 0; k < nl.getLength(); ++k) {
if(nl.item(k).getNodeType()==Node.ELEMENT_NODE) {
Element e = (Element) nl.item(k);
if(e.getAttribute("nom").equals(args[1])) {
System.out.println(e.getAttribute("téléphone"));
}
}
}
} else if (args[0].equals("ajoute")) {
boolean ajout = false;
for (int k = 0; k < nl.getLength(); ++k) {
if(nl.item(k).getNodeType()==Node.ELEMENT_NODE) {
Element e = (Element) nl.item(k);
if(e.getAttribute("nom").equals(args[1])) {
e.setAttribute("téléphone",args[2]);
ajout=true;
}
}
}
CC BY-NC-SA
Tutoriel sur DOM
231
if( ! ajout) {
Element p = doc.createElement("personne");
p.setAttribute("nom", args[1]);
p.setAttribute("téléphone", args[2]);
racine.appendChild(p);
}
}
TransformerFactory tfact = TransformerFactory.newInstance();
Transformer transformer = tfact.newTransformer();
transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
FileWriter fw = new FileWriter("bottin.xml");
StreamResult result = new StreamResult(fw);
transformer.transform(source, result);
}
}
4.4.14
DOM et ECMAScript
ECMAScript est un langage similaire au Java quant à sa syntaxe de base et qui s’exécute souvent dans un navigateur. Il fut inventé par Netscape en 1995 sous le nom de
JavaScript. Il s’agit d’une norme de l’European Computer Manufacturers Association
(ECMA) depuis 1997. L’implémentation du ECMAScript que l’on retrouve dans le
navigateur Firefox se nomme toujours JavaScript, alors que Microsoft nomme son implémentation JScript. L’ECMAScript n’est pas une forme de Java, même s’ils ont une
ressemblance superficielle, adoptant tous les deux une syntaxe proche du langage C. Il
existe de nombreux tutoriels sur le ECMAScript incluant le tutoriel de Jean-Paul Davalan se trouvant à l’URL http://perso.wanadoo.fr/jean-paul.davalan/lang/jsc/ ou encore
le tutoriel de commentcamarche.net. Le site xul.fr offre un résumé du langage, le site
mozilla.org offre une description complète du langage (en anglais).
Si vous ne connaissez pas le langage ECMAScript, vous devriez prendre quelques instants pour en faire un survol.
Les implémentations ECMAScript supportent bien l’API DOM en général. La documentation de l’API DOM pour l’implémentation de ECMAScript de Firefox se trouve à
l’adresse http://developer.mozilla.org/en/docs/Gecko_DOM_Reference. La principale
différence entre DOM en ECMAScript et DOM en Java est que certaines méthodes en
Java deviennent des attributs en ECMAScript (getNodeValue() devient nodeValue).
ECMAScript peut donc lire et traiter des documents XML avec l’API DOM. En particulier, si ECMAScript est utilisé au sein d’une page XHTML, le script peut modifier la
page dynamiquement en utilisant l’API DOM. La principale différence entre l’utilisation de DOM en Java et ECMAScript est qu’à l’exception des méthodes getAttribute,
setAttribute, getAttributeNS, setAttributeNS, getAttributeNode, setAttributeNode, getAttributeNodeNS, setAttributeNodeNS, getElementsByTagName et getElementById,
CC BY-NC-SA
Module 4 : Traitement du XML en Java
232
toutes les méthodes dont le nom commence par « get » ou « set » sont remplacées par un
attribut de l’objet (ou « property » en anglais). Au lieu d’écrire « e.getChildNodes(); »,
on écrit « e.childNodes; », au lieu d’écrire « e.setNodeValue("texte"); », on écrit
« e.nodeValue="texte"; », et ainsi de suite.
Par exemple, le script suivant va ajouter du texte lorsque la souris passera sur l’élément
ayant un attribut « id=’javatest’ »..
monele=document.getElementById(’javatest’);
monele.childNodes.item(0).nodeValue+=’ (passage de souris) ’;
4.4.15
Asynchronous JavaScript And XML (AJAX)
Normalement, sur un site web, pour aller chercher de l’information supplémentaire sur
le serveur, tel que la description d’un produit ou l’horaire d’un film, il faut charger une
nouvelle page web. Cependant, si l’information en question est disponible au format
XML, un script ECMAScript peut la récupérer sans forcer le chargement d’une nouvelle page ce qui donne l’impression à l’utilisateur que l’application web est rapide, car
il ne voit pas de chargement de pages. Le fait de pouvoir charger un fichier XML du
serveur d’origine à partir d’un script ECMAScript constitue l’essentiel d’une technique
appelée Asynchronous JavaScript And XML (AJAX) (JavaScript asynchrone et XML).
Notons qu’à cause du modèle de sécurité ECMAScript, le fichier XML doit être sur le
même serveur et être du même nom de domaine que la page HTML.
Vous avez sans doute déjà utilisé une application AJAX. Les sites de courriel en ligne
comme Google Mail l’utilisent presque tous pour charger le contenu d’un message sans
forcer le chargement d’une nouvelle page.
Si vous connaissez l’API DOM, la programmation d’une application AJAX n’est pas
bien difficile. Il vous suffit d’apprendre un peu de ECMAScript. La classe XMLHttpRequest rend AJAX facile parce qu’elle permet d’aller chercher un fichier XML sur
le serveur en quelques lignes de code. Voici un exemple simple de page web comportant un script ECMAScript et chargeant du contenu XML, en l’occurence, deux des
pages web du cours:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Exemple AJAX</title>
<script language="JavaScript">
/* Cette fonction va chercher un document XML sur
le serveur et appelle la fonction afficherTitre lorsque
c’est fait! */
function chargeDocument(URI) {
xmlhttp = new XMLHttpRequest();
CC BY-NC-SA
Tutoriel sur DOM
233
xmlhttp.open("GET", URI,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
afficheTitre(xmlhttp.responseXML);
}
}
xmlhttp.send(null);
}
/* Cette fonction est appelée lorsque le document XML est
chargé */
function afficheTitre(doc) {
// on récupère le contenu de l’unique élément titre
titreele = doc.getElementsByTagName("title").item(0);
if(titreele.firstChild != null)
titre=titreele.nodeValue;
else
titre = "";
// on ajoute un élément au document courant
// "document" est le document XHTML, à ne pas confondre avec "doc"
elementp = document.createElement("p");
elementp.appendChild(document.createTextNode(titre));
body = document.getElementsByTagName("body").item(0);
body.appendChild(elementp);
}
</script>
</head>
<body>
<p>Vous pouvez cliquer sur les liens suivants plus d’une fois.
À chaque fois, votre navigateur charge un document XHTML et en
affiche le titre.</p>
<ul>
<li><a href="javascript:chargeDocument(’domtutoriel.xhtml’);">
Récupère et affiche
le titre du document domtutoriel.xhtml.</a></li>
<li><a href="javascript:chargeDocument(’travail5.xhtml’);">
Récupère et affiche
le titre du document travail5.xhtml.</a></li>
</ul>
</body>
</html>
Le code ECMAScript n’est pas très long comme vous pouvez le constater. L’attribut
readyState de l’objet xmlhttp nous permet de déterminer quand le document XML a
CC BY-NC-SA
Module 4 : Traitement du XML en Java
234
été chargé (xmlhttp.readyState==4). La propriété onreadystatechange est quant à elle
appelée chaque fois que l’objet de type XMLHttpRequest change d’état. Lorsque le
document XML est chargé, on peut donc appeler une fonction qui manipule le contenu
de la page web (fonction afficheTitre).
Voici un exemple similaire, mais qui récupère, cette fois-ci, le fichier RSS du journal
le Devoir et en affiche les principales manchettes (le fichier RSS est une représentation
en XML du contenu du journal). Il faut au préalable charger le fichier ledevoir.xml et le
déposer dans le même répertoire que le fichier XHTML contenant le script AJAX, sur
votre disque.Le fil de nouvelles du devoir se trouve normalement à l’adresse « http://
www.ledevoir.com/rss/ledevoir.xml ».
<?xml version="1.0" encoding="ISO-8859-1" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Exemple plus avancé en AJAX</title>
<script language="JavaScript">
/* Cette fonction va chercher un document XML sur
le serveur et appelle la fonction afficherTitres lorsque
c’est fait! */
function chargeDocument(URI) {
try {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", URI,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
afficheTitres(xmlhttp.responseXML);
}
}
xmlhttp.send(null);
} catch(o) {alert(o);}
}
/* Cette fonction est appelé lorsque le document XML est
chargé */
function afficheTitres(doc) {
titres = doc.getElementsByTagName("title");
elementol = document.createElement("ol");
var longueur = titres.length;
for ( k = 0; k &lt; longueur ; ++k) {
elementli = document.createElement("li");
elementli.appendChild(
document.createTextNode(
titres[k].firstChild.nodeValue
CC BY-NC-SA
Tutoriel sur DOM
235
)
);
elementol.appendChild(elementli);
}
body = document.getElementsByTagName("body").item(0);
body.appendChild(elementol);
}
</script>
</head>
<body>
<ul>
<li><a href="javascript:chargeDocument(’ledevoir.xml’);">Récupère
et affiche les nouvelles du devoir.</a></li>
</ul>
</body>
</html>
Finalement, si on souhaite insérer non pas seulement du texte, mais des éléments provenant d’un autre document, on peut obtenir ce résultat avec la fonction importNode :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Exemple AJAX avec importNode</title>
<script language="JavaScript">
/* Cette fonction va chercher un document XML sur
le serveur et appelle la fonction afficheListe lorsque
c’est fait! */
function chargeDocument(URI) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", URI,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
afficheListe(xmlhttp.responseXML);
}
}
xmlhttp.send(null);
}
/* Cette fonction est appelé lorsque le document XML est
chargé */
function afficheListe(doc) {
ule = doc.getElementsByTagName("ul").item(0);
// on récupère l’élément ul avec tout son contenu:
body = document.getElementsByTagName("body").item(0)
CC BY-NC-SA
Module 4 : Traitement du XML en Java
236
body.appendChild(document.importNode(ule,true));
}
</script>
</head>
<body>
<p>Vous pouvez cliquer sur les liens suivants plus d’une fois.
À chaque fois, votre navigateur charge un document XHTML et en
affiche une partie du contenu.</p>
<ul>
<li><a href="javascript:chargeDocument(’domtutoriel.xhtml’);">Récupère et affiche
une liste du document domtutoriel.xhtml.</a></li>
<li><a href="javascript:chargeDocument(’travail5.xhtml’);">Récupère et affiche
une liste du document travail5.xhtml.</a></li>
</ul>
</body>
</html>
La classe XMLHttpRequest fait l’objet d’une spécification du W3C. La construction
d’un objet XMLHttpRequest est simple (xmlhttp = new XMLHttpRequest();) et généralement suivie de l’appel xmlhttp.open qui prend de 2 à 5 paramètres dont la méthode,
l’URL, une valeur booléenne stipulant si l’appel est synchrone ou asynchrone, un nom
d’utilisateur et un mot de passe. Les deux derniers paramètres sont utilisés si la ressource est protégée par mot de passe. On utilise généralement des appels asynchrone,
pour éviter que le navigateur ne fige en attendant la réponse du serveur. La méthode est
une des méthodes définie par le protocole HTTP (RFC 2616) dont GET, PUT, POST,
et DELETE.
On utilise le plus souvent AJAX avec des requêtes GET. Comme les requêtes
GET ne nécessitent pas la transmission d’un document, on termine la requête avec
« xmlhttp.send(null); ». Puisque la requête est asynchrone (le plus souvent) on doit
définir une fonction qui sera appelée lorsque la réponse arrivera du serveur (onreadystatechange). Si la réponse du serveur est un fichier XML, on peut le récupérer avec
l’attribut « responseXML ». Le document responseXML s’utilise comme tout document DOM. On peut aussi manipuler le document XHTML qui a fait l’appel AJAX
avec l’API DOM.
En somme, si on connaît bien l’API DOM, et si on connaît un peu d’ECMAScript,
il est facile de développer des applications AJAX si on cible un navigateur comme
Firefox. Par contre, les navigateurs diffèrent souvent beaucoup les uns des autres et, en
particulier, Internet Explorer ne respecte pas les recommandations du W3C ce qui rend
le développement plus difficile.
Voici quelques sites qui utilisent AJAX :
CC BY-NC-SA
DOM
237
– http://www.objectgraph.com/dictionary/
– http://www.google.com/webhp?complete=1&hl=en
– http://maps.google.com/
Le site mozilla.org a plusieurs articles sur AJAX (en anglais). Depuis mai 2006,
Google rend disponible gratuitement son Google Web Toolkit qui permet de construire
des applications AJAX en Java fonctionnant avec tous les principaux navigateurs. Il
existe d’autres librairies AJAX telles que Dojo, Rico, et la Yahoo! User Interface
Library. Une librairie particulièrement intéressante est la librairie Prototype (http://
www.prototypejs.org/) qui est constituée d’un seul fichier ECMAScript.
Malheureusement, le traitement d’un document XML en ECMAScript est parfois inutilement lourd. Pour cette raison, on remplace souvent le XML par du JavaScript Object
Notation (JSON) ou par du HTML.
4.4.16
DOM et autres langages
L’API DOM est supportée en C++ (voir Xerces-C), en Python (paquetage xml.dom),
en Perl (voir Xerces-P), en ECMAScript, etc. C’est d’ailleurs la principale force de
cette API : peu importe le contexte, il y a fort à parier que vous aurez accès à l’API
DOM. Ce n’est sans doute pas la meilleure API possible, mais son ubiquité fait en sorte
qu’il vaut la peine d’apprendre à la connaître.
4.4.17
Conclusion
Dans ce tutoriel, nous avons appris à lire et à écrire du XML à partir du Java. Nous
avons aussi appris à mieux comprendre le modèle DOM et, en particulier, sa structure
en arbre. Vous devriez maintenant être en mesure de commencer à créer des applications Java, de filtrer, fusionner et modifier du XML.
4.4.18
Livres de référence
– Elliotte Rusty Harold, Processing XML with Java: A Guide to SAX, DOM, JDOM,
JAXP, and TrAX, Addison-Wesley Professional, 2002, 1120 pages.
– Frank W. Zammetti, Practical Ajax Projects with Java Technology, Apress, 2006,
504 pages.
– Brett McLaughlin, Head Rush AJAX, O’Reilly Media, 2006, 413 pages.
CC BY-NC-SA
Module 4 : Traitement du XML en Java
4.5
4.5.1
238
DOM
Objectif
Comprendre l’approche DOM.
4.5.2
Activité
Lisez le texte qui suit, puis répondez au questionnaire d’autoévaluation en vous référant
au tutoriel sur DOM que vous venez d’utiliser.
On peut définir DOM comme un ensemble d’API (Application Program Interface) :
un ensemble de fonctions et d’objets que l’on peut utiliser en Java (ou autres langages
similaires) pour manipuler le XML selon un modèle en arbre. Dans ce cours, nous
allons nous pencher plus particulièrement sur l’incarnation Java de DOM.
Note.- Le terme DOM désigne aussi un type de modèle en arbre représentant le XML.
Il y a donc deux significations au terme « DOM » : un ensemble d’API utilisant un
modèle en arbre ou un certain modèle en arbre.
Un des avantages de DOM est qu’il est indépendant du langage ou de la plate-forme.
Ainsi, si vous connaissez DOM, vous pourrez l’utiliser dans plusieurs contextes différents. Ce qui est peut-être le plus important, c’est que les concepts propres à DOM se
retrouvent dans d’autres API pour traiter le XML, qu’elles soient produites par Microsoft, Sun Microsystems ou d’autres auteurs.
Dans une API DOM, tous les éléments sont immédiatement accessibles : on lit le fichier
une fois et il est ensuite totalement en mémoire. La contrepartie de cet avantage est que
DOM utilise beaucoup de mémoire parce qu’il doit charger la totalité des fichiers XML.
Notez toutefois que, dans le contexte DOM, il serait possible, en principe, de ne pas
tout charger en mémoire.
Comme nous l’avons vu, l’API DOM permet de créer des documents XML, de
naviguer dans des documents XML, d’ajouter, de modifier ou d’éliminer des éléments XML.
4.6
4.6.1
Travail noté 5
Objectifs et pondération
Le travail noté 5, une activité de programmation Java, compte pour 15 % de la note
globale du cours.
Il contribue à l’atteinte des objectifs suivants :
CC BY-NC-SA
Travail noté 5
239
– Apprécier les coûts de développement de solutions XML au sein d’une organisation.
– Appliquer la méthodologie orientée objet pour la consommation, la fusion et le filtrage des fichiers XML.
Le travail comporte cinq exercices, valant respectivement 3, 4, 4, 2 et 2 points, pour un
total de 15 points.
4.6.2
Consignes générales
1. Utilisez les noms des fichiers spécifiés dans chaque exercice.
2. Vous n’avez droit qu’à un seul fichier « .java » par exercice et il ne doit pas
contenir plus de 500 lignes de code. Tous les problèmes peuvent être résolus en
moins de 100 lignes! Rappelons qu’une « ligne » de code comprend un maximum
de 80 caractères.
3. Chaque fichier doit débuter par un commentaire donnant le sigle du cours et votre
nom comme ceci :
/**
* INF 6450 */
Travail noté 5 - Votre nom,
fait avec SDK 1.5.0_06
4. Vous devriez pouvoir accéder à la version de votre SDK, en tapant « javac version » ou « java -version » dans une ligne de commande.
5. Ne traitez pas les cas d’exception, comme les fichiers qui n’existent pas ou ne
peuvent être ouverts. Par contre, votre code doit produire un résultat correct dans
des conditions normales. Par exemple, si on vous demande de produire du XML,
il doit s’agir de XML bien formé. Si on vous demande de lire du XML, vous
devez pouvoir lire tout XML qui se conforme aux spécifications décrites dans
l’exercice. Vous devez utiliser l’API DOM.
6. Il est impératif que vos fichiers compilent avec le SDK (le plus récent), sans
utiliser de librairies particulières. Un fichier Java qui ne compile pas ne sera
pas noté.
7. Lorsque vous aurez terminé les exercices, vous devez transmettre à votre personne tutrice, par courriel, l’ensemble des fichiers avec l’extension Java comme
fichiers attachés. Vous devez aussi remettre un fichier XML ainsi qu’un document (Word 97/2000/XP, ODF, PDF, RTF ou en format texte) clairement identifié à votre nom contenant l’analyse demandée à la première question du travail.
L’objet de votre courriel doit commencer par « [INF6450][TRAVAIL5] »;
dans le message, indiquez votre nom, votre numéro d’étudiant (8 chiffres),
la date de remise de votre travail et le nom de votre personne tutrice, ainsi
que les mentions « Travail noté 5 » et « INF 6450 ». Ne transmettez pas une
archive compressée (zip ou autre). Il s’agit d’un travail personnel et vous ne
devez pas partager vos solutions.
CC BY-NC-SA
Module 4 : Traitement du XML en Java
4.6.3
240
Exercice 1
Supposons une liste de transactions avec un attribut « montant » pour chaque client,
comme dans le document XML suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<liste>
<client nom="Jean Charles">
<transaction montant="500" />
<question>Quelle est la dernière marque?</question>
<transaction montant="1200" />
</client>
<client nom="Pierre Élisabeth">
<transaction montant="600" />
<transaction montant="800" />
<question>Où puis-je trouver le modèle 2002?</question>
<transaction montant="2000" />
</client>
</liste>
Supposons que le fichier se nomme « transactions.xml ».
Nous ne savons pas combien de transactions il peut y avoir par client; nous ne savons pas combien de clients nous avons; de plus, nous ne connaissons pas les noms
des clients d’avance. Nous supposons que l’élément-racine est toujours « liste »; que
tous les éléments « transaction » ont un attribut « montant »; que tous les éléments
« transaction » sont dans des éléments « client »; que les éléments « client » sont tous
dans l’élément-racine et ont tous un attribut « nom ». Nous supposons également qu’il
n’y aura pas deux attributs « nom » avec la même valeur (même nom). Enfin, nous
supposons que toutes les valeurs d’attribut de « montant » sont des entiers (« int » en
Java).
Écrivez un programme qui calcule la somme des valeurs de l’attribut « montant » pour
chaque client (seuls les attributs « montant » des éléments « transaction »). Nous supposons qu’il s’agit de nombres entiers, des dollars par exemple. Le code source de votre
programme sera dans un fichier nommé « Transactions.java ».
Ainsi, la commande « java Transactions transactions.xml » devra donner :
Nom du
Somme:
Nom du
Somme:
client: Jean Charles
1700
client: Pierre Élisabeth
3400
Comparez la solution que vous obtenez en utilisant DOM avec ce qui est possible
de faire avec XSLT, en fonction du temps de développement. Donnez au moins un
avantage de l’approche DOM sur l’approche XSLT et un avantage de l’approche XSLT
sur DOM. Vous devez remettre une solution XSLT sous la forme d’un document XML.
CC BY-NC-SA
Travail noté 5
241
Vous pouvez mettre des commentaires dans votre code Java, mais la comparaison entre
DOM et XSLT doit être faite dans un document à part.
4.6.4
Exercice 2
Avec XSLT, nous pouvons combiner plusieurs documents en utilisant la fonction « document » qui permet de charger plusieurs documents XML. Mais que se passe-t-il
lorsque nous devons combiner plusieurs documents, dont certains ne sont pas en XML?
À ce moment, l’utilisation d’un langage comme Java et de DOM peut être très avantageuse.
Supposons qu’un serveur enregistre les achats effectués sur le site, dans un fichier texte,
en plaçant chaque achat sur une ligne avec des informations séparées par des virgules.
Le fichier se nomme « achats.txt » :
Jean Charles, 3214324565, 321, 2
Yvan Richard, 5435435545, 321, 1
Yvette Gagnon, 4324324243, 1, 12
Sur chaque ligne, se trouvent le nom du client, son numéro de carte de crédit, le code
du produit acheté et la quantité achetée. Nous supposons que le serveur est un logiciel
commercial et qu’il n’est pas possible de le modifier pour obtenir le format des données
en XML.
Par ailleurs, nous avons un document XML contenant notre inventaire; le fichier se
nomme « inventaire.xml ». Le voici :
<?xml version="1.0" encoding="ISO-8859-1"?>
<inventaire>
<produit code="1" prix="432.00" quantité= "43" />
<produit code="32" prix="32.00" quantité= "100" />
<produit code="321" prix="31.00" quantité= "200" />
</inventaire>
Écrivez un programme qui met à jour l’inventaire en tenant compte des achats de la
journée, contenus dans le fichier « achats.txt ». Votre code source devra se trouver
dans le fichier « Inventaire.java » et la commande « java Inventaire achats.txt inventaire.xml » va modifier le fichier « inventaire » pour y soustraire les produits achetés
ce qui, dans le cas qui nous concerne, donnera un fichier « inventaire.xml » ayant le
contenu suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<inventaire>
<produit code="1" prix="432.00" quantité= "31" />
<produit code="32" prix="32.00" quantité= "100" />
<produit code="321" prix="31.00" quantité= "197" />
</inventaire>
CC BY-NC-SA
Module 4 : Traitement du XML en Java
242
Nous pouvons supposer que le fichier « inventaire.xml » ne contient qu’un seul élément
« produit » pour chaque valeur d’attribut « code ». Nous pouvons aussi supposer qu’aucun code invalide n’apparaît dans le fichier « achats.txt ». Par contre, nous ne savons
pas combien de produits nous avons et combien d’achats il y aura. Évidemment, il est
possible d’avoir un nombre négatif de produits dans notre inventaire.
Indice.- Il est parfaitement possible d’écrire un tel programme en moins de 50 lignes.
4.6.5
Exercice 3
Il arrive que les données initiales ne soient pas en XML. Dans cet exercice, nous vous
demandons de concevoir une calculatrice qui affiche ses résultats en XML (MathML
pour être plus précis).
Tout d’abord, pour vous convaincre qu’on peut écrire des équations en XML, transcrivez le contenu XML suivant dans un fichier nommé « math.xml » :
<?xml version="1.0" encoding="ISO-8859-1"?>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mn>1</mn>
<mo>+</mo>
<mn>2</mn>
<mo>=</mo>
<mn>3.0</mn>
</mrow>
</math>
Si vous ouvrez ce ficher dans Mozilla Firefox, vous devriez voir s’afficher le texte « 1 +
2 = 3 ». Cela signifie que Firefox reconnaît la syntaxe MathML. Vous pouvez constater
que cette syntaxe n’est pas très complexe, du moins pour des exemples simples. Sachez
que l’espace de noms de MathML est « http://www.w3.org/1998/Math/MathML ». Il
faut utiliser comme élément-racine un élément « math », lui-même contenant un élément « mrow ». L’élément « mrow » pourra contenir un succession d’éléments « mn »
(pour les nombres) et d’éléments « mo » (pour les opérateurs, comme « + », « < »,
« > », « - »). Si le résultat attendu est du texte, comme « vrai » ou « faux », il faut
utiliser l’élément « mrow » contenant un élément « mtext » qui lui contient le texte, par
exemple <mrow><mtext>vrai</mtext></mrow>).
Vous devez créer un programme dont le code source se trouvera dans un fichier nommé
« Calculatrice.java Votre programme doit utiliser l’API DOM. La calculatrice ne
saura faire que 4 opérations : addition, soustraction et deux opérations de comparaison
(< et >) dont la réponse est « vrai » ou « faux ». Ainsi, toutes les opérations se retrouvent
dans la forme : 1 + 2, 1 - 2, 1 < 2 et 2 > 1.
Par exemple, la commande « java Calculatrice 1.5 "<" 2 » devrait produire à l’écran
(dans la fenêtre de commande) ceci :
CC BY-NC-SA
Travail noté 5
243
<?xml version="1.0" encoding="ISO-8859-1"?>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mn>1.5</mn>
<mo>&lt;</mo>
<mn>2</mn>
<mo>=</mo>
<mrow><mtext>vrai</mtext></mrow>
</mrow>
</math>
Notez qu’on remplace < et > par « "<" » et « ">" » dans une ligne de commande parce
que ces deux symboles ont des significations particulières et que votre environnement
de commande pourrait les interpréter comme une demande de rediriger la sortie vers
un fichier.
D’autre part, « java Calculatrice 2 - 1 » devrait donner :
<?xml version="1.0" encoding="ISO-8859-1"?>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mn>2</mn>
<mo>-</mo>
<mn>1</mn>
<mo>=</mo>
<mn>1.0</mn>
</mrow>
</math>
4.6.6
Exercice 4
Il est parfois pénible d’utiliser l’interface DOM quand on cherche une seule information précise. Écrivez un programme Java qui permet d’extraire le prix correspondant à
l’item ayant le code de produit 321 dans un fichier XML ayant la forme suivante en
utilisant une expression XPath.
<?xml version="1.0" encoding="ISO-8859-1"?>
<inventaire>
<produit code="1" prix="432.00" quantité= "43" />
<produit code="32" prix="32.00" quantité= "100" />
<produit code="321" prix="31.00" quantité= "200" />
</inventaire>
CC BY-NC-SA
Module 4 : Traitement du XML en Java
4.6.7
244
Exercice 5
En utilisant AJAX, on peut rendre une page web dynamique. Malheureusement, pour
des raisons de sécurité, un script dans une page web ne peut charger un fichier qui se
trouve dans un domaine autre que celui d’origine. On vous demande donc de déposer
le fichier ledevoir.xml (il faut suivre l’hyperlien) sur votre machine et de créer une
page web AJAX capable de charger le fichier XML en question et d’afficher tant le
titre des nouvelles que leur description complète. Attention, il ne faut récupérer que le
contenu des éléments au sein des éléments item. Vous pouvez supposer que les titres et
descriptions ne contiennent que du texte, sans éléments HTML. Si vous préférez, vous
pouvez aussi utiliser le dernier fil de nouvelle du devoir, disponible à l’adresse « http:/
/www.ledevoir.com/rss/ledevoir.xml ».
Si les descriptions contiennent du texte sous la forme &lta href="..."&gt;, il n’est pas
nécessaire de les afficher sous la forme d’hyperliens.
Certains étudiants trouvent utile d’utiliser la syntaxe « try catch(e) » de l’ECMAScript
(qui fonctionne comme en Java) pour traiter les erreurs. Cependant, cette syntaxe n’est
pas nécessaire.
CC BY-NC-SA
Module 5 : Resource
Description Framework (RDF)
5.1
5.1.1
Aperçu
Objectifs
Les graphes annotés sont un outil puissant de représentation des connaissances; en
XML, on utilise certains graphes dirigés et annotés. Le module 5 porte sur le « Resource Description Framework (RDF) », une forme de représentation des connaissances; le modèle RDF est un modèle de graphe pouvant s’écrire en XML.
Bien qu’il s’agisse d’une norme qui fait appel à des concepts abstraits, dans la pratique,
le RDF est très utilisé. Il suffit de faire une recherche sur le web sur des sujets comme
« Dublin Core, Creative Commons, FOAF, RSS 1.0 » pour constater à quel point le
RDF est présent. Le résultat d’une recherche sur Google pour « Dublin Core » donne
1,2 million de pages; la recherche sur « Creative Commons » annonce 5,5 millions de
pages et celle sur « FOAF » donne 1,5 million de pages. De plus, le RDF est intimement
lié au XML, car très souvent des données RDF sont écrites en format XML.
L’objectif spécifique du module est :
– Interpréter un fichier RDF comme un tableau sujet/verbe/objet.
Une activité, le travail noté 6, nous permettra d’évaluer votre atteinte de cet objectif.
Avant d’entreprendre votre démarche, lisez le texte qui suit.
5.1.2
Représentation des connaissances et graphes
Le cours porte sur le XML en tant qu’outil pour la gestion des connaissances. Nous
avons vu, dans les modules précédents, le rôle que peut jouer le XML comme outil
dans la gestion des données, qui sont une forme de connaissances de premier niveau : le
245
Module 5 : Resource Description Framework (RDF)
246
XML rend plus facile l’échange et la transformation des données. De plus, notamment
dans le module 2, nous avons vu que le XML permet le marquage « sémantique »
des informations; le XML s’impose donc naturellement comme outil de gestion des
connaissances. En effet, prenons cet exemple de marquage sémantique :
<?xml version="1.0" encoding="ISO-8859-1"?>
<personne>
<nomdefamille>Jean</nomdefamille>
<datedenaissance>3 février 1971</datedenaissance>
</personne>
Ce document XML contient non seulement l’information souhaitée, mais en plus, à un
niveau élémentaire, il nous permet de comprendre le sens de cette information, grâce
aux noms des balises.
Cependant, utiliser le nom des balises pour représenter les connaissances n’est pas
toujours très pratique. Supposons que nous ayons deux documents XML semblables à
celui de l’exemple précédent. Comment pouvons-nous représenter le fait que les deux
personnes sont amies?
Une façon plus naturelle de représenter les connaissances est d’utiliser des graphes.
Un graphe est un ensemble de nœuds liés par des relations d’un nœud à un autre. Par
exemple, l’ensemble des pages web forme un graphe avec la relation « contient un
lien vers ». On dit que le graphe est « dirigé » si les relations sont à sens unique.
Le web est un exemple de graphe dirigé : une page web peut avoir un lien vers une
autre page web, qui elle-même ne contient pas un lien de retour vers la page d’origine.
On dit qu’un graphe est « annoté » si les relations entre deux nœuds peuvent être de
différentes natures. Par exemple, une communauté d’humains forme un graphe dirigé
avec les relations « est ami avec » et « est parent avec ». Supposons que les relations
« est ami avec » et « est parent avec » soient réflexives, alors le graphe d’humains
est annoté, mais pas dirigé. Par contre, si nous acceptons qu’une personne puisse être
l’ami de quelqu’un sans que cette personne soit son ami, alors le graphe d’humains
sera annoté et dirigé.
Pour des raisons pratiques, nous représentons les graphes avec des tableaux en trois
colonnes.
5.1.3
Démarche
Il faut avoir terminé le premier module avant de s’attaquer au module 5; en outre,
il sera très utile d’avoir commencé les modules 2, 3 et 4 afin d’avoir suffisamment
d’expérience avec le XML.
Nous vous suggérons d’étudier, dans l’ordre, les deux textes proposés et de répondre
aux questionnaires d’autoévaluation les accompagnant :
– Introduction au RDF;
– Le RDF par l’exemple, Dublin Core, Creative Commons, FOAF, RSS/Atom.
CC BY-NC-SA
Introduction au RDF
247
Le module se termine par le travail noté 6, qui prend la forme d’une activité de synthèse.
Il est recommandé de répondre d’abord aux deux questionnaires d’autoévaluation avant
de réaliser ce travail.
5.1.4
Préparation à l’examen
Une fois les activités du module terminées, vous devrez vous préparer à l’examen. Pour
vérifier si vous êtes prêt, vous pouvez télécharger l’examen factice (PDF, 79 Ko). Si
vous pouvez faire cet examen sans problème, tout va bien. Pour vérifier vos réponses,
consultez le corrigé (PDF, 195 Ko).
5.1.5
Évaluation du cours
Lorsque vous aurez terminé le cours, répondez au questionnaire d’évaluation du cours
(Microsoft Word, 163 Ko) , afin de nous aider à l’améliorer. Votre opinion et vos commentaires sont très importants pour nous. Nous vous remercions à l’avance de votre
collaboration.
5.2
5.2.1
Introduction au RDF
Introduction
Le Resource Description Framework (RDF) est un langage pour les métadonnées sur
le web, c’est-à-dire un langage pour énoncer ce que l’on sait sur quelque chose ou
quelqu’un. Par exemple, le RDF est idéal pour indiquer qui est l’auteur d’un document
ou quel est le titre du document. De plus, le langage RDF est prévu pour être à la fois
simple (mais tout est relatif), suffisamment puissant pour « tout » décrire, et facilement
utilisable par des logiciels. Dans le deuxième texte que nous proposons, Le RDF par
l’exemple, nous verrons quelques applications intéressantes. Pour l’instant, nous ne
présentons dans ce texte que les concepts de base.
5.2.2
Point de vue critique
Le RDF demeure relativement peu utilisé dans des applications complexes, même s’il
s’agit d’une idée simple et élégante. Une des raisons qui contribue sans aucun doute à
ce manque de popularité du RDF, est la syntaxe RDF/XML qui n’est pas très jolie.
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
5.2.3
248
Notions de base
Le RDF a été normalisé en 1999 (par une recommandation W3C) et est un effort commun de plusieurs experts. Le RDF se veut suffisamment riche pour représenter de façon
formelle la connaissance tout en étant simple à utiliser. Une des prémisses du format
RDF est que tout peut être énoncé en utilisant des triplets : sujet, verbe et objet. Notez
que certains auteurs utiliseront le terme « prédicat » au lieu du terme « verbe ». Par
exemple, pour décrire « Jean », nous dirons que « Jean est un garçon » et nous décomposerons ainsi cette affirmation : <Jean><est><garçon>, ou l’afficherons dans un
tableau :
Sujet
Verbe
Objet
Jean
est
garçon
Nous ne faisons pas de la grammaire, mais bien de la représentation : le verbe n’a pas
à être un verbe de la langue française ou anglaise. L’important est que le verbe soit un
lien, une relation, entre une première chose (sujet) et une seconde (objet). Par exemple,
si nous voulons affirmer que le titre de la page web « http://www.daniel-lemire.com/ »
est « Daniel Lemire’s blog », nous pouvons le faire à l’aide du tableau suivant :
Sujet
Verbe
Objet
http://www.danieltitre
Daniel Lemire’s blog
lemire.com/
Ces exemples de représentation ne sont pas encore des exemples de données « RDF »,
car en RDF, le verbe doit être un URI. Le RDF, tout comme le XML, est fait pour
être traité par des machines et les machines sont bêtes. Elles ne savent pas ce que
signifie le mot « titre » dans le tableau précédent. Est-ce un titre à la Bourse, le titre
d’une fonction (comme docteur) ou le titre d’une page? Pour régler ce problème, il
faut utiliser des URI (Uniform Resource Identifier), c’est-à-dire des adresses fictives
qui identifient une ressource Internet.
Un URI contient un protocole (http, mailto, ftp, etc.), un domaine comme « fichiers.com » et un chemin comme « /mesfichiers/index.html ». Dans ce cours, nous
adoptons la norme RFC2396 et nous permettons que les URI comportent le symbole
du dièse ( # ), comme « ftp://fichiers.com#maman » : tout ce qui apparaît après ce symbole forme le « fragment ». Notons que les accents ne peuvent pas être utilisés dans
un URI; ainsi, « http://école.com » n’est pas un URI valable. Un protocole particulier,
« urn », est parfois utilisé dans les URI. Par exemple, pour identifier un livre par son
code ISBN, nous pouvons utiliser l’URI « urn:ISBN:0-123-12345-1 ». La casse est significative dans un URI sauf pour le nom du protocole (HTTP ou http) et le nom du
domaine (xerox.com ou XEROX.COM).
Toutes les URL (Uniform Resource Locator) utilisées sur le web, comme
« http://www.google.com », « mailto:[email protected] », « ftp://fichiers.com »,
ainsi que d’autres adresses ayant la même syntaxe, mais qui ne pointent pas nécessairement vers une ressource Internet existante, sont des exemples d’URI. Ainsi, si l’on vous
donne l’URI « http://www.mydomain.com/daniel », il n’est pas certain qu’une page
CC BY-NC-SA
Introduction au RDF
249
web se trouve à cette adresse. Le seul but des URI est d’identifier des ressources. Le mot
« ressource » a un sens très, très large : tout peut être considéré comme une ressource.
Par exemple, pour identifier l’humoriste « Daniel Lemire », nous pouvons adopter
l’URI « http://www.daniellemire.com/luimeme »; ce sera un bon choix si l’humoriste
en question est propriétaire du nom de domaine (daniellemire.com) et compte le garder
longtemps. Par ailleurs, on pourra utiliser l’URI « http://www.daniel-lemire.com/fr/ »
pour identifier le professeur « Daniel Lemire » qui est responsable d’un cours portant
sur le XML. Dans ce dernier exemple, l’URI est aussi un URL qui pointe vers la page
personnelle du professeur. Nous voyons immédiatement l’avantage des URI : alors que
l’ordinateur ne saura pas toujours faire la différence entre « Daniel Lemire » l’humoriste et « Daniel Lemire » le professeur, nous pourrons, en utilisant des URI, analyser
automatiquement l’information, à la condition que tous utilisent le même URI pour
représenter la même ressource. Pour distinguer les individus, nous pourrions utiliser
leur numéro d’assurance sociale... Mais comme le concept de ressource est général, il
faut aussi pouvoir distinguer les différentes significations que peuvent prendre le mot
« titre », et ainsi de suite. La langue française (ou anglaise) permet à un mot d’avoir
plusieurs sens, alors que chaque URI représente un concept et un concept seulement.
Supposons maintenant que nous voulions décrire l’affirmation suivante en RDF :
« Il y a une personne appelée Daniel Lemire dont l’adresse de courriel est [email protected] et qui est professeur. » Cette phrase peut être très difficile à
analyser par un ordinateur. Commençons par la décomposer en affirmations simples :
sujet/verbe/objet. D’abord, pour qu’il n’y ait pas de confusion, nous allons identifier
l’individu s’appelant Daniel Lemire par l’URI « http://www.daniel-lemire.com/fr/ ».
– http://www.daniel-lemire.com/fr/ est une personne.
– http://www.daniel-lemire.com/fr/ s’appelle Daniel Lemire.
– http://www.daniel-lemire.com/fr/ peut être joint par courriel à [email protected].
– http://www.daniel-lemire.com/fr/ a le titre de professeur.
Rappelons ici que tous les verbes et tous les sujets doivent être identifiés par des URI.
En ce qui nous concerne, il n’y a qu’un seul sujet identifié par « http://www.daniellemire.com/fr/ ». Il reste à trouver des URI pour les verbes et certains objets. Prenons d’abord la première affirmation : « http://www.daniel-lemire.com/fr/ est une personne ». Le verbe « être », dans cette phrase, associe la classe « personne » (au même
sens que dans la programmation orientée objet) à la ressource « http://www.daniellemire.com/fr/ ». Nous pourrions inventer un URI ayant ce sens, mais il en existe déjà
un : « http://www.w3.org/1999/02/22-rdf-syntax-ns#type ». Chaque fois que nous rencontrons cet URI, cela signifie qu’une ressource appartient à une certaine classe. Quant
à l’objet « personne », il existe au moins un URI pour noter la classe « personne »,
soit « http://www.w3.org/2000/10/swap/pim/contact#Person ». Nous verrons que dans
d’autres contextes, d’autres URI peuvent être utilisés avec un sens similaire.
Finalement, l’affirmation « http://www.daniel-lemire.com/fr/ est une personne » peut
s’écrire comme ceci :
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
Sujet
http://www.daniellemire.com/ en/
Verbe
http://www.w3.org/1999/
02/22-rdf-syntax-ns#type
250
Objet
http://www.w3.org/
2000/
10/swap/pim/
contact#Person
Passons maintenant à la deuxième affirmation : « http://www.daniel-lemire.com/fr/
s’appelle Daniel Lemire ». Le verbe « s’appelle » peut être identifié par l’URI
« http://www.w3.org/2000/10/swap/pim/contact#fullName ». Encore une fois, nous aurions pu inventer notre propre URI, en autant que nous utilisons toujours le même avec
la même signification. L’objet, « Daniel Lemire », n’a pas de signification particulière
et n’est qu’une chaîne de caractères; nous ne sommes donc pas tenus d’utiliser un URI.
Cela n’est vrai que pour les objets : les sujets et les verbes doivent toujours être représentés par des URI en RDF. Nous obtenons le tableau suivant :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/
"Daniel Lemire"
lemire.com/ en/
2000/
10/swap/pim/
contact#fullName
Nous notons les chaînes de caractères avec les guillemets : alors que
« http://www.unuri.org » est un URI, « "http://www.unuri.org" » est une chaîne
de caractères.
Dans l’affirmation « http://www.daniel-lemire.com/fr/ peut être joint par
courriel à [email protected] », nous pouvons remplacer le verbe par
« http://www.w3.org/2000/10/swap/pim/contact#mailbox ». Quant à l’objet « [email protected] », c’est une adresse de courriel; afin qu’un ordinateur puisse
comprendre qu’il s’agit d’une adresse de courriel et non d’une chaîne de caractères,
nous utiliserons l’URL « mailto:[email protected] » pour le représenter. Nous
avons donc le tableau suivant :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/
mailto:[email protected]/ en/
2000/
10/swap/pim/ luq.uqam.ca
contact#mailbox
L’affirmation « http://www.daniel-lemire.com/fr/ a le titre de professeur » se traite de
la même manière, de telle sorte que nous obtenons finalement le tableau suivant :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/1999/ http://www.w3.org/
lemire.com/ en/
02/22-rdf-syntax-ns#type 2000/
10/swap/pim/
contact#Person
http://www.danielhttp://www.w3.org/
"Daniel Lemire"
lemire.com/ en/
2000/
10/swap/pim/
contact#fullName
CC BY-NC-SA
Introduction au RDF
Sujet
http://www.daniellemire.com/ en/
http://www.daniellemire.com/ en/
251
Verbe
http://www.w3.org/
2000/
10/swap/pim/
contact#mailbox
http://www.w3.org/
2000/
10/swap/pim/
contact#personalTitle
Objet
mailto:[email protected]
"Professeur"
Précisons qu’en RDF, l’ordre des affirmations est sans importance. Ainsi, l’ordre des
rangées dans le tableau est sans importance.
Ce tableau est une description formelle de notre phrase d’origine « Il y a une personne
appelée Daniel Lemire dont l’adresse de courriel est [email protected] et qui est
professeur. »; cette description peut être traitée par un ordinateur.
Comme nous le verrons plus loin, ce tableau RDF peut s’écrire en XML de la façon
suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#">
<contact:Person rdf:about="http://www.daniel-lemire.com/fr/">
<contact:fullName>Daniel Lemire</contact:fullName>
<contact:mailbox rdf:resource="mailto:[email protected]"/>
<contact:personalTitle>Professeur</contact:personalTitle>
</contact:Person>
</rdf:RDF>
On peut aussi représenter graphiquement le tableau RDF :
http://www.daniel-lemire.com/fr/
Type
Person
Daniel Lemire
fullName
mailbox
personalTitle
[email protected]
Professeur
Nous pouvons également spécifier dans quelle langue une chaîne de caractères est
écrite; par exemple, le mot « professeur » n’a de sens qu’en français. Pour ce faire,
nous utiliserons un attribut « xml:lang » ayant pour valeur un code ISO à deux caractères pour représenter la langue : « fr » pour français, « en » pour anglais, et ainsi de
suite. Notre exemple modifié se lit comme suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#">
<contact:Person rdf:about="http://www.daniel-lemire.com/fr/">
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
252
<contact:fullName>Daniel Lemire</contact:fullName>
<contact:mailbox rdf:resource="mailto:[email protected]"/>
<contact:personalTitle xml:lang="fr">Professeur</contact:personalTitle>
</contact:Person>
</rdf:RDF>
Le choix de la langue ne constitue pas une nouvelle relation RDF, mais vient simplement annoter l’objet : dans un tableau sujet/verbe/objet, nous nous contenterons, par
exemple, de remplacer « "Professeur" » par « "Professeur" (français) ».
Nous pouvons résumer le RDF comme ceci :
–
–
–
–
Le RDF peut être utilisé pour représenter tout objet, tant un site web qu’un individu.
Le RDF peut être traité par une machine.
Le RDF est composé de triplets : sujet/verbe/objet.
Le sujet est toujours identifié par un URI; mais dans certains cas, on peut omettre
l’URI et alors, un URI factice sera généré dynamiquement.
– Le verbe est toujours identifié par un URI, sans aucune exception.
– L’objet est soit un URI, soit une valeur explicite (une chaîne de caractères, par
exemple).
– Le RDF peut être représenté en XML.
5.2.4
Le RDF en XML
Avertissement.- Tous les contenus RDF ne peuvent être représentés en XML selon la
méthode que nous venons de présenter. La grande majorité du contenu RDF peut l’être,
mais il y a des exceptions. Pour éviter les problèmes, nous supposerons ici que l’URI du
verbe prend la forme « http://www.domaine.com/blabla/bla#vvv ». En d’autres termes,
l’URI du verbe contient le symbole du dièse ( # ) et le texte après ce symbole est un
nom XML valable (pouvant être utilisé comme balise).
Il existe plusieurs façons de représenter le RDF en XML, mais nous n’étudierons que
l’approche préconisée par le W3C, qui est l’approche la plus courante. Par ailleurs,
nous n’étudierons pas toute la syntaxe RDF/XML, mais seulement ce qui est nécessaire
pour comprendre la majorité du RDF qui se trouve actuellement sur le web.
En règle générale, les documents XML représentant du contenu RDF n’ont pas de
DTD, mais utilisent les espaces de noms. Nous commençons habituellement un document par une déclaration XML qui sera soit « <?xml version="1.0"?> », soit « <?xml
version="1.0" encoding="ISO-8859-1"?> » pour permettre l’utilisation des accents
français. Ensuite, viendra toujours l’élément RDF comme élément-racine. Ainsi, un
des documents XML les plus simples possibles représentant du contenu RDF est :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
</rdf:RDF>
CC BY-NC-SA
Introduction au RDF
253
Observez l’utilisation de l’espace de noms identifié par l’URI
« http://www.w3.org/1999/02/22-rdf-syntax-ns# ». Le fait de noter l’espace de
noms par les trois lettres « rdf » est sans conséquence et nous pourrions aussi écrire :
<?xml version="1.0" encoding="ISO-8859-1"?>
<nimportequoidautre:RDF
xmlns:nimportequoidautre="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
</nimportequoidautre:RDF>
L’important, c’est que l’élément-racine RDF soit dans l’espace de nom
« http://www.w3.org/1999/02/22-rdf-syntax-ns# ». Supposons maintenant que
nous voulions décrire l’affirmation RDF suivante :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/
mailto:[email protected]/fr/
2000/
10/swap/pim/ luq.uqam.ca
contact#mailbox
La première étape consiste à décomposer l’URI du verbe en
deux parties : l’URI jusqu’au symbole « # » inclusivement, soit
« http://www.w3.org/2000/10/swap/pim/contact# », et le reste du texte, soit « mailbox ». La première partie devient un espace de noms, et la deuxième, appelée fragment,
deviendra un nom d’élément. On utilise ensuite habituellement une balise « Description » dans l’espace de noms « http://www.w3.org/1999/02/22-rdf-syntax-ns# » avec
le nom d’attribut « about » comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description about="http://www.daniel-lemire.com/fr/">
<mailbox rdf:resource="mailto:[email protected]" />
</rdf:Description>
</rdf:RDF>
Dans cet exemple, le sujet est la valeur d’attribut de « about », soit « http://www.daniellemire.com/fr/ », le verbe est le nom de l’élément contenu dans l’élément
« rdf:Description », ici « mailbox », auquel on ajoute en préfixe l’espace de
noms auquel il appartient, soit « http://www.w3.org/2000/10/swap/pim/contact# ».
L’URI de l’objet est la valeur de l’attribut « rdf:resource », soit
« mailto:[email protected] ».
Pour nous assurer de bien comprendre, voyons un autre exemple, quoique plus abstrait.
Supposons que nous ayons le contenu RDF suivant :
Sujet
Verbe
Objet
http://domaine.com/
http://dohttp://www.objet.com/
page/
maine.com#unverbe
Nous pourrions utiliser la représentation XML suivante :
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
254
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://domaine.com#" >
<rdf:Description rdf:about="http://domaine.com/page/">
<unverbe rdf:resource="http://www.objet.com/" />
</rdf:Description>
</rdf:RDF>
Que devons-nous faire si l’objet n’est pas un URI, mais une chaîne de caractères? Dans
ce cas, nous omettrons l’attribut « rdf:resource » et nous placerons notre valeur dans
l’élément. Ainsi, pour représenter le contenu RDF suivant :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/
"Professeur"
lemire.com/fr/
2000/
10/swap/pim/
contact#personalTitle
nous pourrons utiliser le code XML qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<personalTitle>Professeur</personalTitle>
</rdf:Description>
</rdf:RDF>
Encore une fois, les conventions relatives aux espaces de noms s’appliquent et nous
pourrions remplacer le XML de l’exemple précédent par celui-ci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:espacedenom="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<espacedenom:personalTitle>Professeur</espacedenom:personalTitle>
</rdf:Description>
</rdf:RDF>
Donc, pour représenter l’ensemble des données RDF suivantes :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/
"Daniel Lemire"
lemire.com/fr/
2000/
10/swap/pim/
contact#fullName
http://www.danielhttp://www.w3.org/
mailto:[email protected]/fr/
2000/
10/swap/pim/ luq.uqam.ca
contact#mailbox
CC BY-NC-SA
Introduction au RDF
Sujet
http://www.daniellemire.com/fr/
255
Verbe
http://www.w3.org/
2000/
10/swap/pim/
contact#personalTitle
Objet
"Professeur"
nous utiliserons plusieurs éléments, les uns à la suite des autres, comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:espacedenom="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<espacedenom:fullName>Daniel Lemire</espacedenom:fullName>
</rdf:Description>
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<espacedenom:mailbox rdf:resource="mailto:[email protected]" />
</rdf:Description>
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<espacedenom:personalTitle>Professeur</espacedenom:personalTitle>
</rdf:Description>
</rdf:RDF>
En pratique toutefois, nous ne répétons pas l’élément « Description » avec la même
valeur d’attribut « about »; nous préférons la syntaxe qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:espacedenom="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<espacedenom:fullName>Daniel Lemire</espacedenom:fullName>
<espacedenom:mailbox rdf:resource="mailto:[email protected]" />
<espacedenom:personalTitle>Professeur</espacedenom:personalTitle>
</rdf:Description>
</rdf:RDF>
Et comme l’ordre est sans importance en RDF, nous pourrions aussi avoir le XML
suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:espacedenom="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
256
<espacedenom:personalTitle>Professeur</espacedenom:personalTitle>
<espacedenom:fullName>Daniel Lemire</espacedenom:fullName>
<espacedenom:mailbox rdf:resource="mailto:[email protected]" />
</rdf:Description>
</rdf:RDF>
5.2.5
Les classes en RDF
Jusqu’à présent, nous n’avons pas représenté en XML l’affirmation suivante :
Sujet
Verbe
Objet
http://www.danielhttp://www.w3.org/1999/ http://www.w3.org/
lemire.com/fr/
02/22-rdf-syntax-ns#type 2000/
10/swap/pim/
contact#Person
Évidemment, nous pouvons tout simplement écrire ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/10/swap/pim/contact#" >
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<rdf:type
rdf:resource="http://www.w3.org/2000/10/swap/pim/contact#Person" />
</rdf:Description>
</rdf:RDF>
Mais,
avouons-le,
c’est
assez
peu
lisible.
Dans
« http://www.w3.org/2000/10/swap/pim/contact#Person », « Person » est un fragment.
Dans les cas où l’URI contient un fragment, nous représentons l’affirmation de la
façon suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/10/swap/pim/contact#" >
<Person rdf:about="http://www.daniel-lemire.com/fr/">
</Person>
</rdf:RDF>
Nous remplaçons « rdf:Description » par le nom de la classe, soit « Person », avec
le préfixe « http://www.w3.org/2000/10/swap/pim/contact# ». En pratique, cette dernière approche est presque toujours utilisée et son avantage devient évident quand on
combine toutes les affirmations RDF de la première section :
CC BY-NC-SA
Introduction au RDF
257
Sujet
http://www.daniellemire.com/ en/
Verbe
http://www.w3.org/1999/
02/22-rdf-syntax-ns#type
http://www.daniellemire.com/ en/
http://www.w3.org/
2000/
10/swap/pim/
contact#fullName
http://www.w3.org/
2000/
10/swap/pim/
contact#mailbox
http://www.w3.org/
2000/
10/swap/pim/
contact#personalTitle
http://www.daniellemire.com/ en/
http://www.daniellemire.com/ en/
Objet
http://www.w3.org/
2000/
10/swap/pim/
contact#Person
"Daniel Lemire"
mailto:[email protected]
"Professeur"
Nous savons maintenant que nous pouvons représenter toutes ses informations par le
XML suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/10/swap/pim/contact#">
<Person rdf:about="http://www.daniel-lemire.com/fr/">
<fullName>Daniel Lemire</fullName>
<mailbox rdf:resource="mailto:[email protected]" />
<personalTitle>Professeur</personalTitle>
</Person>
</rdf:RDF>
C’est comme ça que nous pouvons écrire « Il y a une personne appelée Daniel Lemire dont l’adresse de courriel est [email protected] et qui est professeur. » en
RDF/XML.
5.2.6
Et s’il n’y a pas de symbole « # » dans l’URI?
Dans les exemples précédents, nous supposions que l’URI (du verbe) contenait un symbole « # », ce qui nous permettait de la décomposer en deux
parties (nom et préfixe). Mais quoi faire si l’URI prend plutôt la forme
« http://www.ondelette.com/employeur »? Dans un tel cas, nous pouvons choisir de
retenir « http://www.ondelette.com/ » comme préfixe et « employeur » comme nom.
Nous pourrons donc représenter les données RDF suivantes :
Sujet
Verbe
Objet
http://www.danielhttp://
http://www.uquebec.ca/
lemire.com/fr/
www.ondelette.com/
employeur
par le XML suivant :
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
258
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.ondelette.com/">
<rdf:Description rdf:about="http://www.daniel-lemire.com/fr/">
<employeur rdf:resource="http://www.uquebec.ca/" />
</rdf:Description>
</rdf:RDF>
5.2.7
Des objets qui sont eux-mêmes des sujets
Supposons que nous voulons dire que la pièce de théatre Othello a comme auteur
William Shakespeare. En fait, nous voulons faire quatre affirmations : « Othello est
une pièce de théatre », « Shakespeare est une personne », « Shakespeare est l’auteur
d’Othello » et « Shakespeare a pour nom "William Shakespeare" ». Nous pourrions
choisir de représenter en RDF ces quatre affirmations selon le tableau qui suit :
Sujet
Verbe
Objet
http://www.othello.org/
http://www.w3.org/1999/ http://unuri.org/PieceDe02/22-rdf-syntax-ns#type Theatre
http://www.othello.org/
http://unuri.org/auteur
http://
www.shakespeare.org
http://
http://www.w3.org/1999/ http://unuri.org/Personne
www.shakespeare.org
02/22-rdf-syntax-ns#type
http://
http://unuri.org/nom
"William Shakespeare"
www.shakespeare.org
Nous pouvons utiliser la représentation XML suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://unuri.org/">
<PieceDeTheatre rdf:about="http://www.othello.org/">
<auteur rdf:resource="http://www.shakespeare.org" />
</PieceDeTheatre>
<Personne rdf:about="http://www.shakespeare.org">
<nom>William Shakespeare</nom>
</Personne>
</rdf:RDF>
La représentation graphique du tableau RDF est :
CC BY-NC-SA
Introduction au RDF
259
http://www.othello.org/
type
PieceDeTheatre
auteur
http://www.shakespeare.org
type
Personne
nom
William Shakespeare
Nous pouvons cependant le faire plus brièvement. Considérons d’abord le modèle suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://unuri.org/">
<PieceDeTheatre rdf:about="http://www.othello.org/">
<auteur>
(...)
</auteur>
</PieceDeTheatre>
</rdf:RDF>
Nous avons vu que si nous mettons un nœud de texte là où les points « (...) » apparaissent, nous associerons « http://www.othello.org/ » avec un objet texte par le verbe
« http://unuri.org/auteur ». Cependant, si nous mettons plutôt un élément muni d’un
attribut « rdf:about », ce sera l’URI contenu dans l’attribut qui deviendra l’objet; nous
gagnons alors la possibilité d’utiliser ce même objet comme sujet à son tour, comme
dans cet exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://unuri.org/">
<PieceDeTheatre rdf:about="http://www.othello.org/">
<!-- le verbe est http://unuri.org/auteur -->
<auteur> <!-- début de l’objet -->
<Personne rdf:about="http://www.shakespeare.org">
<!-- l’objet devient un sujet à son tour -->
<nom>William Shakespeare</nom>
</Personne><!-- fin de l’objet -->
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
260
</auteur>
</PieceDeTheatre>
</rdf:RDF>
Ce nouveau document RDF est équivalent aux trois affirmations RDF du début, mais il
est un peu plus court.
Nous pourrions pousser l’expérience plus loin - ce qui peut devenir absurde - comme
dans l’exemple qui suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://unuri.org/">
<PieceDeTheatre rdf:about="http://www.othello.org/">
<auteur rdf:resource="http://www.shakespeare.org" />
</PieceDeTheatre>
<Personne rdf:about="http://www.shakespeare.org">
<nom>
<Texte rdf:about="http://www.texte.org/william">
<contenu>
William Shakespeare
</contenu>
</Texte>
</nom>
</Personne>
</rdf:RDF>
Ce document est maintenant équivalent au tableau suivant :
Sujet
Verbe
Objet
http://www.othello.org/
http://www.w3.org/1999/ http://unuri.org/PieceDe02/22-rdf-syntax-ns#type Theatre
http://www.othello.org/
http://unuri.org/auteur
http://
www.shakespeare.org
http://
http://www.w3.org/1999/ http://unuri.org/Personne
www.shakespeare.org
02/22-rdf-syntax-ns#type
http://www.texte.org/
http://www.w3.org/1999/ http://unuri.org/Texte
william
02/22-rdf-syntax-ns#type
http://www.texte.org/
http://unuri.org/contenu
"William Shakespeare"
william
http://
http://unuri.org/nom
http://www.texte.org/
www.shakespeare.org
william
CC BY-NC-SA
Introduction au RDF
5.2.8
261
Les contenants en RDF
Il arrive fréquemment, en pratique, que l’on doive donner comme valeur à un objet,
non pas une chaîne de caractères, mais plutôt un ensemble de chaînes de caractères.
Par exemple, nous pouvons vouloir affirmer que « les étudiants du cours 101 sont Jean
Roberge, Alexandre Coma et Julie LeChat ». Comment le faire? Supposons que l’URI
du cours est « http://www.teluq.uqam.ca/101 » et que le verbe correspondant à « être
inscrit à un cours » est identifié par l’URI « http://www.education.com#inscription ».
Nous pouvons alors essayer ceci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.education.com#">
<rdf:Description rdf:about="http://www.teluq.uqam.ca/101">
<inscription>Jean Roberge</inscription>
<inscription>Alexandre Coma</inscription>
<inscription>Julie LeChat</inscription>
</rdf:Description>
</rdf:RDF>
Cela équivaut à remplacer l’affirmation « les étudiants du cours 101 sont Jean Roberge,
Alexandre Coma et Julie LeChat » par les trois affirmations « le cours 101 a comme
étudiant Jean Roberge », « le cours 101 a comme étudiant Alexandre Coma », « le
cours 101 a comme étudiant Julie LeChat ». Il n’est pas certain qu’une telle décomposition de l’affirmation préserve toujours le sens original. Par exemple, nous pourrions
vouloir donner la liste complète de tous les étudiants dans le cours. RDF nous permet
de regrouper tous les étudiants dans un seul élément « Bag » (sac, en anglais) comme
ceci :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.education.com#">
<rdf:Description rdf:about="http://www.teluq.uqam.ca/101">
<inscription>
<rdf:Bag>
<rdf:li>Jean Roberge</rdf:li>
<rdf:li>Alexandre Coma</rdf:li>
<rdf:li>Julie LeChat</rdf:li>
</rdf:Bag>
</inscription>
</rdf:Description>
</rdf:RDF>
Les éléments dans un « Bag » ne sont pas ordonnés. Nous pourrons remplacer le XML
précédent par celui-ci, sans problème :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
262
xmlns="http://www.education.com#">
<rdf:Description rdf:about="http://www.teluq.uqam.ca/101">
<inscription>
<rdf:Bag>
<rdf:li>Julie LeChat</rdf:li>
<rdf:li>Jean Roberge</rdf:li>
<rdf:li>Alexandre Coma</rdf:li>
</rdf:Bag>
</inscription>
</rdf:Description>
</rdf:RDF>
Si l’ordre importe, alors nous utiliserons un élément « Seq » (pour séquence), comme
dans l’exemple suivant qui énonce les jours de la semaine, dans l’ordre :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.jourdelasemaine.com#">
<rdf:Description rdf:about="http://www.jourdelasemaine.com/">
<journees>
<rdf:Seq>
<rdf:li>dimanche</rdf:li>
<rdf:li>lundi</rdf:li>
<rdf:li>mardi</rdf:li>
<rdf:li>mercredi</rdf:li>
<rdf:li>jeudi</rdf:li>
<rdf:li>vendredi</rdf:li>
<rdf:li>samedi</rdf:li>
</rdf:Seq>
</journees>
</rdf:Description>
</rdf:RDF>
Finalement, nous pourrions ne pas connaître exactement la valeur de l’objet, mais savoir que la valeur appartient à un ensemble fini de possibilités. Par exemple, si nous
jouons à un jeu de détective et qu’il n’y a que trois coupables possibles (le majordome,
la princesse et le seigneur), nous écrirons :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.jeududetective.com#">
<rdf:Description
rdf:about="http://www.jeududetective.com/partie/2004/10/">
<suspects>
<rdf:Alt>
<rdf:li>majordome</rdf:li>
<rdf:li>princesse</rdf:li>
<rdf:li>seigneur</rdf:li>
CC BY-NC-SA
Le RDF par l’exemple
263
</rdf:Alt>
</suspects>
</rdf:Description>
</rdf:RDF>
5.2.9
RDFa
Il peut sembler un peut lourd de créer des fichiers XML distincts pour stocker le RDF.
Heureusement, il existe donc plusieurs approches pour inscrire le RDF à même des
fichiers XHTML. La spécification RDFa permet d’inscrire du RDF directement au sein
d’un document XHTML avec les attributs about et property. Voici un exemple d’annotation RDFa ajoutée à un élément XHTML :
<ul xmlns:dc="http://purl.org/dc/elements/1.1/"
about="http://www.example.com/books/wikinomics">
<li property="dc:title">Wikinomics</li>
<li property="dc:author">Don Tapscott</li>
<li property="dc:date">2006-10-01</li>
</ul>
5.2.10
Conclusion
Nous avons vu que le modèle RDF sert à décrire pratiquement n’importe quoi en associant des URI à tous les objets et relations. Les données RDF peuvent généralement
être représentées en XML selon l’approche que nous avons décrite, ce qui permet de
combiner les avantages du XML (format entièrement normalisé et non propriétaire, outils très disponibles, etc.), tout en gardant les avantages du RDF (contenu pouvant être
traité par des machines, relative simplicité). Pour plus de détails, on peut consulter les
articles du site mozilla.org sur le sujet (http://developer.mozilla.org/en/docs/RDF).
Certains logiciels gratuits comme 4Suite (http://4suite.org/) peuvent traiter le contenu
RDF/XML, mais ce n’est pas le cas des navigateurs web ou de la majorité des logiciels.
Les graphiques de cette leçon furent générés avec 4Suite et inclus au texte en tant que
SVG.
5.3
5.3.1
Le RDF par l’exemple
Introduction
Avant de lire ce texte, vous devez avoir lu « Introduction au RDF », car nous supposons
que vous comprenez la syntaxe RDF de base.
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
264
Le RDF se retrouve un peu partout sur le web, parfois de façon « invisible », c’est-à-dire
qu’il est souvent utilisé dans les échanges automatiques entre les logiciels. En outre,
il est utilisé au sein des portails, par exemple. Voyons maintenant quatre applications
RDF bien établies :
Dublin Core Il s’agit sans doute de l’utilisation la plus connue et la plus répandue
du RDF. La norme Dublin Core est assez simple et vise à décrire les travaux
rendus disponibles sur le web (auteur, titre, date, etc.). Cette norme s’inspire de
la bibliothéconomie.
Creative Commons Il s’agit d’une façon de décrire les droits accordés sur le contenu
placé sur le web. Par exemple, vous voulez savoir si vous pouvez recopier telle
ou telle page web; si l’auteur a utilisé la norme Creative Commons, alors vous
devriez pouvoir savoir ce qui est permis par l’auteur.
FOAF La norme FOAF (« Friend Of A Friend » - « ami d’un ami ») permet de décrire un individu et les gens qu’il connaît. Cette norme sert à traiter les réseaux
sociaux.
RSS/RDF La norme RSS est utilisée par les blogues et sites de nouvelles. Le site
mozilla.org a plusieurs articles sur le sujet (http://developer.mozilla.org/en/docs/
RSS). En gros, un document RSS/RDF contient une version XML des dernières
nouvelles. Par la suite, plusieurs de ces fichiers XML peuvent être combinés pour
créer un portail de nouvelles ou utilisés avec un outil-client de type « RSS aggregator » pour obtenir automatiquement les dernières nouvelles (voir, par exemple,
blogbridge).
5.3.2
Un exemple : Dublin Core
La norme Dublin Core définit plusieurs « verbes » (au sein du RDF); on peut en consulter la liste à l’adresse http://dublincore.org/documents/dcmi-terms/ (en anglais). Cette
norme a été publiée pour la première fois en juillet 1999.
Le préfixe de la norme Dublin Core est « http://purl.org/dc/elements/1.1/ », du moins
pour les éléments de base présentés ici. Voici les URI complets et leur signification :
http://purl.org/dc/elements/1.1/creator Personne ou organisme qui est l’auteur du
travail.
http://purl.org/dc/elements/1.1/contributor Personne ou organisme qui a contribué
à un travail, mais sans en être l’auteur.
http://purl.org/dc/elements/1.1/coverage Lieu et période correspondant au travail.
http://purl.org/dc/elements/1.1/date Date associée au travail, généralement sous la
forme AAAA-MM-JJ. Il peut s’agir de la date de publication, de création ou de
la dernière révision.
http://purl.org/dc/elements/1.1/description Brève description du travail.
CC BY-NC-SA
Le RDF par l’exemple
265
http://purl.org/dc/elements/1.1/format Format sous lequel est publié le travail. Si le
travail est publié en HTML, alors on utilisera souvent « text/html » pour décrire
le format.
http://purl.org/dc/elements/1.1/identifier Code ou URI qui correspond de façon
unique au travail. Si un travail est publié à une adresse web, on peut utiliser
cette adresse comme URI; si c’est un livre avec un ISBN, on peut utiliser un URI
de la forme « urn:ISBN:0-123-12345-1 ».
http://purl.org/dc/elements/1.1/language Code ISO-639/ISO-3166 décrivant le travail. Si le travail est publié en français, on peut utiliser « fr-CA »; sinon, en
anglais, ce serait « en-CA » (CA signifie Canada).
http://purl.org/dc/elements/1.1/publisher Organisme responsable de la publication
du travail.
http://purl.org/dc/elements/1.1/relation Ressource liée au travail. Par exemple,
pour un travail fait en classe, on peut établir un lien avec l’exposé du travail.
http://purl.org/dc/elements/1.1/rights Contient souvent une affirmation permettant
de savoir qui est propriétaire du travail (détenteur du droit d’auteur).
http://purl.org/dc/elements/1.1/source Résumé du travail de quelqu’un d’autre. Cet
URI permet de pointer vers la source originale.
http://purl.org/dc/elements/1.1/subject Généralement, une liste de mots clés.
http://purl.org/dc/elements/1.1/title Titre du travail.
http://purl.org/dc/elements/1.1/type Type de la ressource (texte, image, etc.). Notons que le « type » est différent du « format ». Par exemple, une image peut être
en format Jpeg ou Gif, un texte peut être en format Word ou ASCII.
Voyons comment nous pouvons décrire ce texte que vous êtes en
train de lire, en utilisant la norme Dublin Core. Attribuons-lui l’URI
« http://www.uqam.ca/rdfexemples.html ».
Sujet
Verbe
Objet
http://www.uqam.ca/ rd- http://purl.org/
dc/ http://www.danielfexemples.html
elements/1.1/creator
lemire.com/fr/
http://www.uqam.ca/ rd- http://purl.org/
dc/ "2004-07-27"
fexemples.html
elements/1.1/date
http://www.uqam.ca/ rd- http://purl.org/
dc/ "Introduction au RDF"
fexemples.html
elements/1.1/title
http://www.uqam.ca/ rd- http://purl.org/
dc/ "text"
fexemples.html
elements/1.1/type
http://www.uqam.ca/ rd- http://purl.org/
dc/ "fr-CA"
fexemples.html
elements/1.1/Language
http://www.uqam.ca/ rd- http://purl.org/
dc/ "RDF, Dublin Core,
fexemples.html
elements/1.1/subject
Creative
Commons,
FOAF, RSS/RDF"
http://www.uqam.ca/ rd- http://purl.org/
dc/ "Copyright 2005 Daniel
fexemples.html
elements/1.1/rights
Lemire"
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
Sujet
http://www.uqam.ca/ rdfexemples.html
Verbe
http://purl.org/
dc/
elements/1.1/description
http://www.uqam.ca/ rdfexemples.html
http://www.uqam.ca/ rdfexemples.html
http://purl.org/
dc/
elements/1.1/format
http://purl.org/
dc/
elements/1.1/identifier
266
Objet
"Un document comprenant des exemples d’utilisation du RDF en gestion
des connaissances."
"text/html"
http://www.uqam.ca/ rdfexemples.html
Nous pouvons aussi représenter ce tableau en XML comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://www.uqam.ca/rdfexemples.html">
<dc:creator rdf:resource="http://www.daniel-lemire.com/fr/" />
<dc:date>2004-07-27</dc:date>
<dc:title>Introduction au RDF</dc:title>
<dc:type>text</dc:type>
<dc:Language>fr-CA</dc:Language>
<dc:subject>RDF, Dublin Core, Creative Commons,
FOAF, RSS/RDF</dc:subject>
<dc:rights>Copyright 2005 Daniel Lemire</dc:rights>
<dc:description>Un document comprenant des exemples
d’utilisation du RDF en gestion des connaissances.</dc:description>
<dc:format>text/html</dc:format>
<dc:identifier
rdf:resource="http://www.uqam.ca/rdfexemples.html" />
</rdf:Description>
</rdf:RDF>
Nous pouvons aussi représenter ce tableau sous la forme d’un graphe :
CC BY-NC-SA
Le RDF par l’exemple
267
http://www.daniel−lemire.com/fr/
creator
2004−07−27
date
Introduction au RDF
title
identifier
rdfexemples.html
text
type
Language
fr−CA
subject
rights
RDF
description
Copyright 2005 Daniel Lemire
format
Un document comprenant des exemples
d’utilisation du RDF en gestion des connaissances.
html
Évidemment, Dublin Core est une norme RDF et non pas une norme XML. Il est donc
possible d’exprimer du contenu Dublin Core sans passer par le XML. Nous pourrions
très bien nous en tenir au tableau sujet/verbe/complément ou utiliser une autre syntaxe.
Notons aussi que les conventions d’espace de noms s’appliquent et que l’ordre n’est
pas important. Nous pouvons donc remplacer le XML précédent par celui-ci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://www.uqam.ca/rdfexemples.html">
<creator rdf:resource="http://www.daniel-lemire.com/fr/" />
<title>Introduction au RDF</title>
<date>2004-07-27</date>
<type>text</type>
<subject>RDF, Dublin Core, Creative Commons,
FOAF, RSS/RDF</subject>
<rights>Copyright 2005 Daniel Lemire</rights>
<description>Un document comprenant des exemples
d’utilisation du RDF en gestion des connaissances.</description>
<format>text/html</format>
<identifier
rdf:resource="http://www.uqam.ca/rdfexemples.html" />
<Language>fr-CA</Language>
</rdf:Description>
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
268
</rdf:RDF>
Il existe des applications plus sophistiquées de la norme Dublin Core, mais nous avons
ici l’essentiel. Vous pouvez dès maintenant cataloguer les ressources d’une entreprise
en utilisant simplement ce que nous venons de présenter. Comme la norme est utilisée
partout dans le monde, il sera possible d’échanger ces descriptions ou d’utiliser des
logiciels communs pour le traitement ou l’affichage des informations.
5.3.3
Un exemple : Creative Commons
Une des limites apparentes de la norme Dublin Core est son incapacité à spécifier
de façon précise les droits accordés sur un travail. Le problème est particulièrement
fréquent sur le web : a-t-on le droit d’utiliser telle ou telle image gratuitement, de la
reproduire, de la modifier, et ainsi de suite.
Pour résoudre cette difficulté, les gens font appel à la norme Creative Commons, qui utilise le préfixe « http://web.resource.org/cc/ ». Cette norme définit une classe « Work »
(travail, en anglais, ici au sens d’oœuvre), mais emprunte pratiquement tout le reste
à Dublin Core qu’elle vient compléter. La norme Creative Commons a été proposée
en 2001 par James Boyle, Michael Carroll, Lawrence Lessig, Hal Abelson, Eric Saltzman et Eric Eldred.
Voici un exemple très simple d’une description utilisant la norme Creative Commons :
Sujet
Verbe
Objet
http://www.uqam.ca/ rd- http://www.w3.org/1999/ http://web.resource.org/
fexemples.html
02/22-rdf-syntax-ns#type cc/Work
http://www.uqam.ca/ rd- http://purl.org/
dc/ "Le RDF par l’exemple"
fexemples.html
elements/1.1/title
Et voici la version XML correspondante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="http://www.uqam.ca/rdfexemples.html">
<dc:title>Le RDF par l’exemple</dc:title>
</Work>
</rdf:RDF>
Tout ce que nous avons affirmé dans ce dernier document, c’est que la page actuelle
appartient à la classe « Work ». Dans l’état actuel des choses, nous affirmons par défaut
qu’il n’est pas permis d’utiliser cette page, car nous n’avons attribué aucune permission.
Supposons que l’auteur désire accorder le droit au lecteur de redistribuer, de modifier et de partager cette page, pour autant qu’il utilise la même licence. Nous
CC BY-NC-SA
Le RDF par l’exemple
269
pourrions alors utiliser la licence « Attribution-ShareAlike 2.0 » dont l’URI est
« http://creativecommons.org/licenses/by-sa/2.0/ ». Évidemment, nous pouvons aussi
créer notre licence de toute pièce, mais dans l’exemple, nous utiliserons la licence
« Attribution-ShareAlike 2.0 ». Pour faire un lien entre notre travail et une licence,
nous utilisons le verbe dont l’URI est « http://web.resource.org/cc/license », comme ce
qui suit; observez bien la dernière ligne du tableau.
Sujet
Verbe
Objet
http://www.uqam.ca/ rd- http://www.w3.org/1999/ http://web.resource.org/
fexemples.html
02/22-rdf-syntax-ns#type cc/Work
http://www.uqam.ca/ rd- http://purl.org/
dc/ "Le RDF par l’exemple"
fexemples.html
elements/1.1/title
http://www.uqam.ca/ rd- http://web.resource.org/
http://creativecomfexemples.html
cc/license
mons.org/licenses/by-sa/
2.0/
Nous pouvons aussi utiliser le XML correspondant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="http://www.uqam.ca/rdfexemples.html">
<dc:title>Le RDF par l’exemple</dc:title>
<license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
</Work>
</rdf:RDF>
Voici la représentation sous la forme d’un graphe :
title
Le RDF par l’exemple
rdfexemples.html
{Work}
license
http://creativecommons.org/licenses/by−sa/2.0/
Nous avons alors un document Creative Commons complet. Cependant, un problème demeure. Supposons qu’un logiciel fasse automatiquement une recherche
pour vous et que vous ne désiriez obtenir que les textes que vous pouvez modifier librement. Il n’est pas évident pour une machine de comprendre que l’URI
« http://creativecommons.org/licenses/by-sa/2.0/ » vous donne ce droit; d’ailleurs, une
telle recherche n’est peut-être pas très simple pour un humain...
Creative Commons définit trois verbes et des objets permettant de décrire une licence et une classe. Toutes les licences appartiennent à la classe ayant pour URI
« http://web.resource.org/cc/License ». Les URI des trois verbes sont :
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
270
http://web.resource.org/cc/permits La licence le permet. Creative Commons définit trois URI pouvant être utilisés comme objet de ce
verbe. Il y a d’abord « http://web.resource.org/cc/Reproduction », le
droit de reproduire en tout ou en partie le travail. Il y a ensuite
« http://web.resource.org/cc/Distribution », le droit de redistribuer le travail. Finalement, il y a « http://web.resource.org/cc/DerivativeWorks », le droit
de modifier le travail. Évidemment, il est possible de définir ses propres objets.
http://web.resource.org/cc/requires La licence pose comme condition. Creatives Commons définit quatre URI pouvant être utilisés comme objet de
ce verbe : « http://web.resource.org/cc/Notice » pour spécifier qu’il faut
reproduire intégralement les notes légales (licence et droits d’auteurs);
« http://web.resource.org/cc/Attribution » pour spécifier qu’il faut attribuer à
l’auteur le crédit du travail; « http://web.resource.org/cc/ShareAlike » pour spécifier que si l’on redistribue le travail, il faut le faire en gardant la même licence;
« http://web.resource.org/cc/SourceCode » pour spécifier que le code source doit
être redistribué.
http://web.resource.org/cc/prohibits La licence interdit. Il n’y a qu’un seul
URI défini par Creative Commons qui peut être utilisé avec ce verbe :
« http://web.resource.org/cc/CommercialUse »; cela permet d’interdire l’utilisation à des fins commerciales. Encore une fois, il est possible de définir ses
propres objets.
Dans le cas de la licence «
comme suit :
Sujet
http://creativecommons.org/ licenses/by-sa/
2.0/
http://creativecommons.org/ licenses/by-sa/
2.0/
http://creativecommons.org/ licenses/by-sa/
2.0/
http://creativecommons.org/ licenses/by-sa/
2.0/
http://creativecommons.org/ licenses/by-sa/
2.0/
http://creativecommons.org/ licenses/by-sa/
2.0/
Attribution-ShareAlike 2.0 », nous pouvons la décrire
Verbe
http://www.w3.org/1999/
02/22-rdf-syntax-ns#type
Objet
http://web.resource.org/
cc/License
http://web.resource.org/
cc/permits
http://web.resource.org/
cc/Reproduction
http://web.resource.org/
cc/permits
http://web.resource.org/
cc/Distribution
http://web.resource.org/
cc/requires
http://web.resource.org/
cc/Notice
http://web.resource.org/
cc/requires
http://web.resource.org/
cc/Attribution
http://web.resource.org/
cc/permits
http://web.resource.org/
cc/DerivativeWorks
CC BY-NC-SA
Le RDF par l’exemple
Sujet
http://creativecommons.org/ licenses/by-sa/
2.0/
271
Verbe
http://web.resource.org/
cc/requires
Objet
http://web.resource.org/
cc/ShareAlike
Nous pouvons aussi utiliser le XML suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF xmlns="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<permits rdf:resource="http://web.resource.org/cc/Reproduction" />
<permits rdf:resource="http://web.resource.org/cc/Distribution" />
<requires rdf:resource="http://web.resource.org/cc/Notice" />
<requires rdf:resource="http://web.resource.org/cc/Attribution" />
<permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
</License>
</rdf:RDF>
En pratique, nous combinons souvent le tout (description du travail et description de la
licence) pour obtenir le XML suivant :
<rdf:RDF xmlns="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="http://www.uqam.ca/rdfexemples.html">
<dc:title>Le RDF par l’exemple</dc:title>
<license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
</Work>
<License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<permits rdf:resource="http://web.resource.org/cc/Reproduction" />
<permits rdf:resource="http://web.resource.org/cc/Distribution" />
<requires rdf:resource="http://web.resource.org/cc/Notice" />
<requires rdf:resource="http://web.resource.org/cc/Attribution" />
<permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
</License>
</rdf:RDF>
Voilà! De cette manière, une machine pourra automatiquement déterminer quels droits
l’utilisateur a sur une œuvre. Un logiciel pourrait automatiquement avertir l’utilisateur
de ses obligations si jamais il tentait d’enregistrer sur son disque une copie de l’œuvre.
Dans le cas d’une entreprise qui utilise beaucoup de contenu multimédia, l’utilisation
de cette norme pourrait être très utile pour détecter automatiquement les violations des
droits d’auteur.
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
5.3.4
272
Un exemple : FOAF
Les personnes sont souvent ce qu’il y a de plus important dans une organisation; il
n’est donc pas étonnant qu’on veuille utiliser le RDF pour les décrire. Pour ce faire, on
utilise souvent la norme FOAF pour « Friend-Of-A-Friend », ou un ami d’un ami, en
français, (préfixe http://xmlns.com/foaf/0.1/) qui définit la classe « Person » (personne,
en anglais).
Le projet FOAF a été lancé de façon informelle par Daniel Brickley en 1998. À
l’époque, il avait mis un texte RDF ressemblant à ceci sur sa page personnelle :
(Attention.- Il ne s’agit pas de RDF/XML valable.)
<RDF:RDF
xmlns="vocabdemo.rdf">
xmlns:rdf="http://www.w3.org/TR/WD-rdf-syntax#">
<Person ID="dan">
<name> Dan Brickley </name>
<Email> [email protected] </Email>
<telephone rdf:resource = "phone:+44-1-+44(0)117-9287493" />
<pager rdf:resource = "phone:+44-1-+44(0)2523-1781115" />
<homePage
rdf:resource= "http://purl.org/net/danbri/" />
<homePage
rdf:resource= "http://www.ilrt.bris.ac.uk/about/staff/dan.html"/>
</Person>
</RDF:RDF>
La norme FOAF est très riche; mais à la base, on trouve les verbes suivants :
http://xmlns.com/foaf/0.1/name Verbe pointant vers le nom de la personne (John
Smith)
http://xmlns.com/foaf/0.1/nick Verbe pointant vers le surnom informel de la personne (joblo).
http://xmlns.com/foaf/0.1/title Verbe pointant vers le titre de la personne (docteur,
monsieur, madame).
http://xmlns.com/foaf/0.1/homepage Verbe pointant vers la page personnelle de la
personne.
http://xmlns.com/foaf/0.1/mbox Verbe pointant vers l’adresse électronique de la personne.
http://xmlns.com/foaf/0.1/img Verbe pointant vers une image de la personne, la représentant spécifiquement.
http://xmlns.com/foaf/0.1/depiction Verbe pointant vers une image représentant la
personne. Contrairement à « img », l’image peut être une photo de groupe.
http://xmlns.com/foaf/0.1/family_name Verbe pointant vers le nom de famille de la
personne (Smith).
CC BY-NC-SA
Le RDF par l’exemple
273
http://xmlns.com/foaf/0.1/givenname Verbe pointant vers le prénom de la personne
(John).
En XML, une description de l’auteur de ce document pourrait se présenter comme suit :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<foaf:Person>
<foaf:givenname>Daniel</foaf:givenname>
<foaf:family_name>Lemire</foaf:family_name>
<foaf:homepage rdf:resource="http://www.daniel-lemire.com/fr/" />
<foaf:mbox>[email protected]</foaf:mbox>
<foaf:img
rdf:resource="http://www.daniel-lemire.com/fr/images/GIF/zel2p.gif" />
</foaf:Person>
</rdf:RDF>
Voici le graphe équivalent :
Daniel
givenname
Lemire
family_name
Anonymous
Person
homepage
http://www.daniel−lemire.com/fr/
mbox
img
[email protected]
zel2p.gif
Notez que la balise « Person » n’a pas d’attribut « rdf:about ». Actuellement, il existe
un débat sur cette question : Peut-on attribuer un URI unique à chaque individu et si
oui, comment le choisir? C’est un cas où l’URI du sujet est « implicite » : cela signifie
que dans les triplets sujet/verbe/objet, le sujet a un URI « fictif », qui n’est valable que
dans le cadre du document que l’on traite. Autrement dit, le programme qui traite le
document doit allouer dynamiquement un URI au sujet pour la durée du traitement.
Rappelons-nous, en effet, que la norme RDF permet d’omettre le sujet, mais que si le
sujet est spécifié, il doit être un URI.
Nous pouvons imaginer que la norme FOAF sera éventuellement utilisée pour représenter les réseaux sociaux, les organisations, et ainsi de suite. Une fois l’information
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
274
sociale représentée de façon formelle, nous pouvons croire qu’il sera possible de poser
des questions à un ordinateur de l’ordre suivant : Est-ce que je connais quelqu’un qui
connaît quelqu’un travaillant chez IBM?
5.3.5
Un exemple : RSS/RDF
La version 1.0 de la norme RSS est un exemple de RDF. Cette norme dont l’acronyme
n’a pas de définition établie, sert à représenter des fils de nouvelles. Elle a été imaginée
par la compagnie Netscape et servait alors à la production du portail Netscape (1999).
Elle est devenue très populaire et on trouve maintenant des milliers de fils de nouvelles
en format RSS dans le monde. Par exemple, sur http://www.yulblog.org/, il y a des
centaines de blogues écrits par des Montréalais et la plupart ont un fil de nouvelles en
format RSS.
Une nouvelle, appelée « item » en RSS, prend la forme suivante :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/">
<item rdf:about="http://www.nouvelles.com/nouvelles1">
<title>La bourse fait faillite</title>
<link>http://www.nouvelles.com/nouvelles1.html</link>
<description>
Aujourd’hui, on a appris que la bourse a fait faillite.
</description>
</item>
</rdf:RDF>
Nous constatons qu’il y a une classe (item) et trois verbes (title, link, description) qui
représentent respectivement le titre, l’URL et le contenu de la nouvelle.
Un document RSS est une liste d’items. Voici un document RSS :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="http://www.nouvelles.com/nouvelles.rss">
<title>Un site de nouvelles</title>
<link>http://www.nouvelles.com/</link>
<description>
Nouvelles.com est un superbe site de nouvelles
</description>
<!-- Ensuite, on place une séquence de nouvelles,
les unes après les autres-->
<items>
CC BY-NC-SA
Le RDF par l’exemple
275
<rdf:Seq>
<!-- chaque nouvelle a un URI -->
<rdf:li resource="http://www.nouvelles.com/nouvelles1" />
<rdf:li resource="http://www.nouvelles.com/nouvelles2" />
</rdf:Seq>
</items>
</channel>
</rdf:RDF>
Nous constatons une classe « channel » (canal, en anglais) qui contient un titre, un
URL (link) et une description. Il y a aussi une liste de nouvelles (item). Généralement,
nous combinons le tout dans un seul fichier, comme ceci :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="http://www.nouvelles.com/nouvelles.rss">
<title>Un site de nouvelles</title>
<link>http://www.nouvelles.com/</link>
<description>
Nouvelles.com est un superbe site de nouvelles
</description>
<!-- Ensuite, on place une séquence de nouvelles,
les unes après les autres-->
<items>
<rdf:Seq>
<!-- chaque nouvelle a un URI -->
<rdf:li resource="http://www.nouvelles.com/nouvelles1" />
<rdf:li resource="http://www.nouvelles.com/nouvelles2" />
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://www.nouvelles.com/nouvelles1">
<title>La bourse fait faillite</title>
<link>http://www.nouvelles.com/nouvelles1.html</link>
<description>
Aujourd’hui, on a appris que la bourse a fait faillite.
</description>
</item>
<item rdf:about="http://www.nouvelles.com/nouvelles2">
<title>Rien ne va plus à l’école</title>
<link>http://www.nouvelles.com/nouvelles2.html</link>
<description>
Un étudiant se serait rendu coupable d’apprentissage.
</description>
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
276
</item>
</rdf:RDF>
Les applications du RSS sont multiples. Supposons que votre organisation collabore
avec plusieurs autres organisations et que vous vouliez rendre disponibles, sur une seule
page web, toutes les nouvelles de toutes les organisations dont vous faites partie. Si
chaque organisation rend disponible sur le web un document RSS toujours mis à jour,
vous pouvez facilement récupérer les nouvelles de chacun et les afficher à un seul
endroit. Au lieu de solliciter tous les membres par courriel, les fils de nouvelles RSS
permettent à une machine de faire un tri et de personnaliser le contenu.
La norme RSS est en voie d’être remplacée par la norme Atom. Un des avantages du
nouveau format Atom est que chaque nouvelle doit avoir un identifiant unique ce qui
permet d’éviter les doublons. Cependant, la norme RSS risque d’être toujours utile
pendant bien des années. Atom n’est pas en RDF/XML. En voici un exemple :
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Un site de nouvelles</title>
<subtitle>Nouvelles.com est un superbe site de nouvelles</subtitle>
<link href="http://www.nouvelles.com/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
<email>[email protected]</email>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
<entry>
<title>La bourse fait faillite</title>
<link href="http://www.nouvelles.com/nouvelles1.html"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Aujourd’hui, on a appris que la bourse a fait faillite.
</summary>
</entry>
</feed>
5.3.6
Conclusion
Nous avons étudié quatre applications importantes du RDF sur le web. Le nombre
d’applications est toutefois beaucoup plus important.
CC BY-NC-SA
Travail noté 6
277
Il faut garder à l’esprit que le RDF n’est pas le XML et que le XML ne sert qu’à
représenter le RDF (et encore, ce n’est pas toujours possible). Il est probable que la
syntaxe utilisée pour représenter le RDF en XML va encore évoluer.
Pour en apprendre davantage sur le RDF, nous vous suggérons le livre de Shelley Powers, Practical RDF, publié chez O’Reilly en juillet 2003 (350 pages), en anglais seulement et coûtant environ 60 $.
5.4
5.4.1
Travail noté 6
Objectifs et pondération
Ce travail porte principalement sur le RDF et compte pour 10 % de la note globale du
cours. Il contribue à l’atteinte de l’objectif suivant :
– Interpréter un fichier RDF comme un tableau sujet/verbe/objet.
Le travail comporte sept exercices : les cinq premiers valent un point chacun et le
sixième, qui porte sur le XSLT et contribue ainsi à renforcer les apprentissages du
module 3, vaut 4 points, alors que le dernier compte pour un point, pour un total de
10 points.
5.4.2
Consignes
Nous vous recommandons d’avoir terminé les activités d’autoévaluation du module 5
avant de faire ce travail noté. De plus, comme le sixième exercice exige une bonne compréhension du XSLT, vous devriez avoir terminé le module 3 avant de l’entreprendre.
Lorsque vous aurez terminé le travail, transmettez à votre personne tutrice, par courriel,
un seul document (Word 97/2000/XP, ODF, PDF, RTF ou en format texte) comprenant,
pour chaque exercice, le tableau, le code XML ou le contenu de votre document XSLT.
Ne transmettez pas vos solutions en plusieurs fichiers. Ne transmettez pas une
archive compressée (zip ou autre). L’objet de votre courriel doit commencer par
« [INF6450][TRAVAIL6] »; dans le message, indiquez votre nom, votre numéro
d’étudiant (8 chiffres), la date de remise de votre travail et le nom de votre personne tutrice, ainsi que les mentions « Travail noté 6 » et « INF 6450 ». Il s’agit
d’un travail personnel et vous ne devez pas partager vos solutions.
Dans un tableau de triplets, les objets qui ne sont pas des URI, doivent être placés entre
guillements (" ").
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
5.4.3
278
Exercice 1
Représentez, dans un tableau de triplets (sujet, verbe, objet), le document RDF/XML
suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:md="http://www.mondomaine.com/">
<rdf:Description rdf:about="http://www.uqam.ca/">
<md:titre>Site de l’UQÀM</md:titre>
<md:autre rdf:resource="http://www.uqam.ca/index.html" />
</rdf:Description>
</rdf:RDF>
5.4.4
Exercice 2
Écrivez un programme Java qui utilise l’API DOM pour extraire tous les titres des
items d’un document RSS 1.0. Vous pouvez supposer que le fichier réside sur votre
disque. Ne joignez pas un fichier à l’extension java.
5.4.5
Exercice 3
Représentez, dans un tableau de triplets (sujet, verbe, objet), l’exemple en RDF qui suit
et qui provient de la norme PRISM.
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:pcv="http://prismstandard.org/namespaces/pcv/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://wanderlust.com/2000/08/Corfu.jpg">
<dc:identifier rdf:resource="http://wanderlust.com/content/2357845" />
<dc:creator>
<pcv:Descriptor rdf:about="http://wanderlust.com/emp3845">
<pcv:label>John Peterson </pcv:label>
</pcv:Descriptor>
</dc:creator>
<dc:coverage>
<pcv:Descriptor
rdf:about="http://prismstandard.org/vocabs/ISO-3166/GR">
<pcv:label xml:lang="en">Greece</pcv:label>
<pcv:label xml:lang="fr">Grece</pcv:label>
</pcv:Descriptor>
</dc:coverage>
</rdf:Description>
CC BY-NC-SA
Travail noté 6
279
</rdf:RDF>
5.4.6
Exercice 4
Ecrivez un document XML/RDF correspondant au tableau suivant :
Sujet
Verbe
Objet
http://www.uqam.ca
http://www.uquebec.ca/
"UQÀM"
nom
5.4.7
Exercice 5
La licence identifié par l’URI « http://www.mondomaine.ca/licence » permet la reproduction, la distribution et la modification des œuvres. Décrivez cette licence en utilisant
Creative Commons et le format RDF/XML.
5.4.8
Exercice 6
Note.- Cet exercice vaut 4 points et est substantiellement plus difficile que les exercices
précédents.
Avant de réaliser l’exercice...
Il peut arriver qu’on veuille annoter un document XHTML avec Dublin Core ou avec
un autre vocabulaire RDF, mais sans vouloir utiliser la notation RDF/XML. L’annotation est particulièrement facile si aucun des objets n’est un URI. Pour y arriver, nous
utiliserons des éléments « meta » et « link » placés dans l’élément « head » du document. Considérons l’exemple qui suit :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />
<meta name="DC.title" content="le titre de mon document" />
<meta name="DC.description" content="la description" />
<meta name="DC.date" content="2004-11-08" />
<meta name="DC.format" content="text/html" />
<meta name="DC.language" content="fr" />
<meta name="DC.publisher" content="L’Université du Québec" />
<title>un petit document</title>
</head>
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
280
<body>
<p>Ceci est un document XHTML annoté avec Dublin Core.</p>
</body>
</html>
Cette façon de faire est documentée par le mémo disponible à l’adresse http://
www.ietf.org/rfc/rfc2731.txt. Il n’est toutefois pas nécessaire de consulter ce mémo.
Aux fins de cet exercice, nous allons supposer que seuls deux types de structures sont
utilisés. D’abord, l’élément « link » peut être utilisé pour définir un préfixe, comme
ceci :
<link rel= "schema.PREFIXE" href="URI" />
D’autre part, le préfixe peut être utilisé pour faire un lien entre le document courant et
un sujet :
<meta name="PREFIXE.NOM" content="VALEUR" />
Prenons comme exemple les quatres éléments suivants placés dans un document
XHTML à l’adresse « http://www.uqam.ca/index.html » :
<link
<meta
<link
<meta
rel="schema.d" href="http://www.mondomaine.com/">
name= "d.a" content = "c">
rel="schema.e" href="http://www.mondomaine.com/2/">
name= "e.g" content = "f">
Cette notation aura alors la signification suivante en RDF :
Sujet
Verbe
Objet
http://www.uqam.ca
http://
"c"
www.mondomaine.com/
a
http://www.uqam.ca
http://
"f"
www.mondomaine.com/
2/g
En notation RDF/XML, nous avons :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:d="http://www.mondomaine.com/"
xmlns:e="http://www.mondomaine.com/"
>
<rdf:Description about="http://www.uqam.ca/index.html">
<d:a>c</d:a>
<e:g>f</e:g>
</rdf:Description>
</rdf:RDF>
CC BY-NC-SA
Travail noté 6
281
Notez qu’aucun des objets n’est un URI.
Exercice à réaliser...
Écrivez un document XSLT qui, étant donné un document XHTML annoté selon cette
méthode, donne le document RDF/XML correspondant, en supposant que le document
courant possède l’URI « http://mondocument.org ». Pour que l’on puisse voir la solution dans Firefox, produisez un document HTML qui contient le code du document
RDF/XML comme dans l’exemple qui suit :
<html>
<body><pre>
&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" &gt;
&lt;rdf:Description rdf:about="http://mondocument.org"&gt;
&lt;title
xmlns="http://purl.org/dc/elements/1.1/"&gt;
le titre de mon document
&lt;/title &gt;
&lt;/rdf:Description&gt;
&lt;/rdf:RDF&gt;
</pre></body></html>
En somme, votre document XSLT doit produire un document débutant par la balise
html et contenant le document RDF/XML écrit avec des appels d’entités (&lt;,&gt;).
Toute solution qui utilisera les éléments XSLT « xsl:key », « xsl:param » et
« xsl:variable » sera refusée; une note de zéro sera accordée.
Voici quelques indices...
– Les
documents
XHTML
utilisent
l’espace
de
noms
« http://www.w3.org/1999/xhtml ». Pour pouvoir les traiter en XSLT, il vous
faut définir cet espace de noms comme dans cet exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
>
<xsl:template match="xhtml:html" >
&lt;rdf:RDF>&lt;/rdf:RDF>
</xsl:template>
CC BY-NC-SA
Module 5 : Resource Description Framework (RDF)
282
– Les fonctions XPath « substring-before » et « substring-after » peuvent vous
être utiles. La valeur de l’expression XPath « substring-before(’meta.dc’,’.’) » est
« meta », alors que la valeur de l’expression « substring-after(’meta.dc’,’.’) » est
« dc ».
5.4.9
Exercice 7
Le site flickr permet de chercher des photographies publiées avec une licence Creative Commons. Visitez la page http://www.flickr.com/photos/guppiecat/1351724368/
in/set-72157601927001088/ et trouvez la licence Creative Commons. Écrivez-la en
XML.
CC BY-NC-SA
Annexe A : Glossaire
Appel d’entité : Un appel d’entité est une suite de caractères (bout de texte) qui commence par une esperluette ( & ) et se termine par un point-virgule ( ; ). Les appels
d’entité suivants font partie de la définition du XML :
appel d’entité
résultat
&lt;
<
&amp;
&
&gt;
>
&quot;
"
&apos;
’
Attribut : Un attribut est un nom XML qui doit respecter les mêmes règles que les
noms XML des balises; il est immédiatement suivi d’un signe d’égalité ( = ) et d’une
valeur placée entre guillemets. Par exemple, la balise <lavie age="5"> a un attribut
(age="5") dont le nom XML est "age". Une balise peut avoir plusieurs attributs, comme
<lavie age="5" sexe="M">, mais chacun doit avoir un nom XML différent; la balise
<lavie age="5" age="7"> n’est pas autorisée.
Balise : Une balise est un texte commençant par le signe < et se terminant par le signe
>, délimitant un élément. Il existe trois types de balises en XML : les balises qui commencent un élément, les balises qui terminent un élément et les balises d’élément vide.
Par exemple, <lavie> est une balise qui ouvre un élément. Une balise qui commence
par </ est une balise de fin, qui termine un élément, comme </lavie>. Finalement, une
balise qui se termine par /> marque que l’élément est vide, comme <lavie />. Une déclaration de type de document (<!DOCTYPE>), une déclaration XML (<?xml?>), un
commentaire (<!-- -->) ou une région CDATA (<![CDATA[ ]]>) ne sont pas des balises.
283
Glossaire
284
Bien formé : Un document XML bien formé respecte la grammaire XML et il peut
être lu par n’importe quel parseur XML générique.
Commentaire : Un commentaire commence par <!-- et se termine par -->; entre ces
deux bornes, il ne peut y avoir deux tirets successifs (--), mais n’importe quoi d’autre
peut s’y retrouver.
CSS : Cascading StyleSheet.
Déclaration de type de document : Une déclaration de type de document prend la
forme <!DOCTYPE ... SYSTEM ... > , où l’on met à la place des premiers trois
points le nom XML de l’élément-racine que le document doit avoir, et à la place des
deuxièmes trois points, une URL vers le document DTD.
Déclaration XML : La déclaration XML ressemble à s’y méprendre à une instruction de traitement et prend la forme <?xml ... ?>. Le contenu d’une déclaration XML
comporte généralement au maximum trois attributs : version="...", encoding="..." et
standalone="...". La version du XML la plus utilisée est la 1.0; bien que la version 1.1 existe, elle est fort peu utilisée. On utilisera souvent une déclaration XML
avec « encoding="ISO-8859-1" » pour pouvoir utiliser les accents dans le document;
par défaut, on ne peut pas utiliser les accents dans un document XML, sans des outils
supportant les normes UTF-8/UTF-16. L’attribut « standalone » prend les valeurs yes
ou no, selon que l’on veut que la DTD externe soit lue ou pas. La déclaration XML
doit obligatoirement être au tout début du document ou être carrément absente : même
un espace avant n’est pas permis.
DocBook : C’est un format de document souvent utilisé pour la documentation technique.
DOM (Document Object Model) : Le terme « DOM » a deux significations : un ensemble d’API utilisant un modèle en arbre ou un certain modèle en arbre.
DTD (Définition de Type Document) : Une DTD permet de définir un type de document XML en spécifiant des contraintes sur les éléments, les attributs et leur contenu.
Un document XML qui satisfait ces contraintes et qui est bien formé est dit valable.
Élément : Un élément est l’ensemble du texte borné par deux balises ayant le même
nom XML, comme <lavie> et </lavie>. On dit que l’élément <lavie></lavie> a le nom
XML « lavie ». L’élément hérite des attributs de sa balise de départ : l’élément <lavie
age="5"></lavie> possède l’attribut « age="5" ». Il est à noter que la casse est significative en XML : les balises < A > et < a > n’ont pas le même nom XML. Lorsque l’élément est vide, c’est-à-dire sans contenu, on peut remplacer <lavie></lavie> par <lavie
/>, pour être plus bref. Par ailleurs, un élément peut contenir d’autres éléments, comme
dans <lavie><a></a></lavie>, ou du texte ou du texte et des éléments, comme <lavie>fd<a>fsd</a>fd</lavie>. Si un élément contient l’élément de début ou de fin d’un
élément, alors il doit aussi contenir l’autre. Ainsi, un élément peut être contenu par un
autre ou non, mais deux éléments ne peuvent se chevaucher, comme <b><a></b></a>,
qui est du XML mal formé.
CC BY-NC-SA
Glossaire
285
Élément-racine : Tout document XML bien formé doit avoir un élément-racine, et un
seul. Tous les autres éléments doivent être contenus dans cet élément-racine.
Espace de noms : Les espaces de noms permettent d’utiliser plusieurs vocabulaires
XML en même temps.
Extensible : Voir Métalangage.
Graphe : Un graphe est un ensemble de nœuds liés par des relations d’un nœud à un
autre.
Graphe dirigé : Un graphe est dirigé si les relations sont à sens unique.
Graphe annoté : Un graphe est annoté si les relations entre deux nœuds peuvent être
de différentes natures.
HTML (HyperText Markup Language) : Le HTML est un langage à base de balises.
La majorité des documents sur le web sont écrits en HTML.
Instruction de traitement : L’instruction de traitement ne fait rien en soit, mais peut
indiquer aux programmes comment obtenir un certain résultat. Une instruction de traitement débute par « <? » et se termine par « ?> »; immédiatement après le « <? », un
nom XML valable doit apparaître et tous les noms XML valables sont autorisés à l’exception de xml, Xml, XMl, XML, XmL, xMl, xML et xmL. Ainsi n’importe quel autre
texte peut être utilisé, mais il faut faire des appels d’entités pour « < » et « & », comme
pour n’importe quel contenu textuel XML.
Métalangage : Le XML est un « métalangage » permettant d’échanger de l’information, principalement sur le web. On dit que c’est un « métalangage » parce qu’il permet
de créer de nouveaux langages pour l’échange d’informations, mais qu’il ne constitue
pas un langage en soi. On dit donc que le XML est « extensible » (peut être étendu) et
que c’est un métalangage : les deux affirmations ont le même sens et notent la capacité
du XML à s’adapter à des besoins différents.
Nom XML : Le nom XML d’une balise est le texte suivant le symbole « < » ou
« </ » pour une balise de fin; il peut contenir n’importe quelle lettre (a, b,...) ou chiffre
(0,1,2,...) et les signes de ponctuation suivants : la barre de soulignement ( _ ), le trait
d’union ( - ) et le point ( . ); il ne peut contenir ni les autres signes de ponctuation ni un
espace. En outre, un nom XML ne peut pas commencer par un nombre, un trait d’union
ou un point. Par exemple, le nom XML de la balise <lavie> est « lavie », alors que la
balise <7lavie> ne serait pas autorisée.
RDF (Resource Description Framework) : Le RDF est un langage pour les métadonnées sur le web, c’est-à-dire un langage pour énoncer ce que l’on sait sur quelque chose
ou quelqu’un.
SGML : Standard Generalized Markup Language.
Syntaxe : La syntaxe XML est la manière d’écrire les informations dans un document XML. Les notions importantes de la syntaxe de base du XML sont la balise,
l’élément, l’élément-racine et l’attribut.
CC BY-NC-SA
Glossaire
286
URI : C’est une adresse Internet fictive. L’URI agit un peu comme le numéro d’assurance sociale des vocabulaires XML.
Valable :: Un document est valable s’il répond à certains critères de base de l’application XML. Un document XML qui est bien formé, qui en plus satisfait aux contraintes
dictant quels éléments et attributs peuvent être utilisés, et dans quel ordre et avec quel
contenu, est dit valable.
Vocabulaire XML : Un « vocabulaire XML » est un ensemble de noms de balises et
d’attributs ayant une signification donnée. Un vocabulaire XML peut être associé à un
document DTD.
XHTML : Le XHTML est un format hybride : il tient à la fois du HTML et du XML.
XML : eXtensible MarkupLanguage.
XSL : eXtensible Stylesheet Language.
XSLT : XSL Transformations.
XSL-FO : eXtensible Stylesheet Language Formatting Objects.
CC BY-NC-SA
Annexe B : Webographie XML
Tous les liens ont été vérifiés en février 2007.
1
Blogues
– http://www.daniel-lemire.com/blogue/category/xml/ (blogue du cours)
– http://www.tbray.org/ongoing/
– http://formats-ouverts.org/blog/
2
Cours en ligne, en français
– http://www.commentcamarche.net/xml/xmlintro.php3
– http://www.laltruiste.com/coursxml/sommaire.html
3
Cours en ligne, en anglais
– http://www.w3schools.com/
– http://www.w3schools.com/xml/default.asp
– http://www.w3schools.com/xml/xml_examples.asp
4
Liens généraux, en français
– L’espace XML francophone : www.xmlfr.org
– Rubrique XML chez Wikipedia
287
Webographie XML
5
288
Articles, en français
– A. Crochet-Damais, Microsoft Office 2003 : le format XML pointé du doigt
6
Articles, en anglais
– J. Hunt, et al. Why use DITA to produce HTML deliverables?
– D. Terdiman, Weather Data for the Masses
7
Références tirées du site Wikipedia (anglais)
7.1
–
–
–
–
–
Spécification XML
Spécification XML annotée : http://www.xml.com/axml/testaxml.htm
Site du World Wide Web Consortium : http://www.w3.org/
Page d’accueil XML du World Wide Web Consortium : http://www.w3.org/XML/
Spécification XML 1.1 : http://www.w3.org/TR/xml11
Spécification XML 1.0 : http://www.w3.org/TR/REC-xml
7.2
Software
– Éditeur XML open : http://www.philo.de/xmledit/
– Librairie XML open pour Delphi/Kylix : http://www.philo.de/xml/
– Éditeur jEdit : http://jedit.org
7.3
Ressources pour les développeurs
–
–
–
–
–
–
–
–
–
FAQ XML : http://www.ucc.ie/xml/
xml.com, développement et ressources : http://www.xml.com/
Cafe con Leche, nouvelles et ressources XML : http://www.cafeconleche.org/
XML Cover Pages : http://xml.coverpages.org/
Page web des développeurs IBM : http://www-106.ibm.com/developerworks/xml/
Site de nouvelles pour les développeurs XML : http://www.xmlhack.com/
Mailing liste XML-L : http://listserv.heanet.ie/xml-l.html
DTD et schemas XML : http://www.XMLPatterns.com/
Tutoriel sur Relax NG : http://www.oasis-open.org/committees/relax-ng/tutorial20010810.html (traduit en français : http://xmlfr.org/oasis/committees/relax-ng/
tutorial-20011203-fr.html)
– Les problèmes du XML : http://c2.com/cgi/wiki?XmlSucks
– XML : http://www.ericdigests.org/2000-4/xml.htm
CC BY-NC-SA
Liens vers des livres portant sur le XML, en anglais
289
– XML Linking : état de l’art : http://chinese-school.netfirms.com/xlink.html
– Un outil XSLT (Markup of XML contents) : http://www.ultra-fluide.com/ressources/
en/semark/presentation.htm
8
Liens vers des livres portant sur le XML, en anglais
–
–
–
–
–
–
XML: Managing Data Exchange (wikibook)
XML in a Nutshell, by Harold and Means
Beginning XML, 3rd Edition, by David Hunter, Andrew Watt, Jeff Rafter.
Learning XML, by Erik T. Ray.
XML Schema, by Eric Van Der Vlist.
Processing XML with Java(TM): A Guide to SAX, DOM, JDOM, JAXP, and TrAX,
by Elliotte Rusty Harold.
CC BY-NC-SA
Annexe C : Pense-bête DTD
<!DOCTYPE nomXML_élémentRacine SYSTEM "URL"> : Déclaration de type
de document
<!ELEMENT ... > : Instruction
? : Élément optionnel
* : Élément pouvant être présent plus d’une fois (de 0 à l’infini)
+ : Élément présent au moins une fois et qui peut être présent plusieurs fois
| : Ou
#PCDATA : Que du texte
<!ATTLIST nomElementX nomAttributY...> : Spécifie que l’élément « X » a l’attribut « Y »
CDATA : Attribut contient du texte
#REQUIRED : Attribut obligatoire
#IMPLIED : Attribut optionnel
#FIXED : Attribut fixé avec une valeur
<!ENTITY nomEntiteX "Yvaleur"> : L’entité « nomEntiteX » prend la valeur
« Yvaleur »
<!ENTITY % nomEntiteX "Yvaleur"> : Localement, l’entité « nomEntiteX » prend
la valeur « Yvaleur » dans la DTD
291
Annexe D : Pense-bête HTML
Balise
Signification
<p> </p>
paragraphe
<ul>
<li> </li>
</ul>
liste non ordonnée
élément de la liste
<ol>
<li> </li>
</ol>
liste ordonnée
élément de la liste
<table border="1">
<tr>
<td>
</td>
</tr>
</table>
tableau
ligne
cellule
<i> </i>
italique
<em> </em>
italique (généralement)
<b> </b>
gras
<strong> </strong>
gras (généralement)
<u> </u>
souligné
293
Pense-bête HTML
294
Balise
Signification
<dl>
<dt> </dt>
<dd> </dd>
</dl>
liste de définitions
terme à définir
définition du terme
<hr />
ligne horizontale
<image src="URL" alt="description
de l’image" />
affiche une image
<a href="URL">texte</a>
hyperlien
<a name="URL">texte</a>
marqueur
CC BY-NC-SA
Annexe E : Pense-bête XSLT
Document XSLT de base
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>
« xsl:template » : Permet de définir un modèle avec un élément comme <xsl:template
match="facture">; à chaque élément facture trouvé, le processeur XSLT applique le
modèle correspondant.
« xsl:apply-templates » : Cet élément donne le résultat obtenu par l’application de
modèles (éléments « xsl:template »).
« xsl:value-of » : Donne la valeur textuelle d’une expression XPath. Par exemple,
l’instruction <xsl:value-of select="..." /> où « ... » est le nom de l’élément donne le
texte contenu dans l’élément, les balises en moins.
« <xsl:value-of select="@nas" /> » : Pour effectuer la sélection des attributs. Ici,
l’attribut « nas » de l’élément « personne » (<personne nas="432444333">).
Expression XPath avec « . » (un point) : Indique le nœud courant. Par exemple,
l’instruction <xsl:value-of select="." /> donne le contenu textuel de l’élément courant.
Expression XPath avec « / » (barre oblique) : Permet d’effectuer la sélection de nœuds contenus dans des éléments. L’instruction « <xsl:value-of select="nom/prenom" /> » donne le contenu textuel des éléments « prenom » contenus
dans les éléments « nom » de l’élément courant. La barre oblique ( / ) peut aussi représenter le nœud-racine; ainsi, l’expression « /maison » sélectionne l’élément-racine, si
et seulement s’il se nomme « maison ».
Expression XPath avec « @ » : Permet d’effectuer la sélection des attributs. L’instruction « <xsl:value-of select="@nas" /> » donne le contenu textuel de l’attribut
« nas » de l’élément courant.
295
Pense-bête XSLT
296
(accolades) : Pour spécifier la valeur d’un attribut; par exemple, avec l’expression
<facture montant="..." />, le processeur XSLT va remplacer ... par la valeur de l’expression XPath « ... » et s’il s’agit du nom d’un élément, le contenu textuel de l’élément
y sera inséré.
Expression XPath avec « .. » (deux points successifs) : Permet d’obtenir la valeur
de l’élément dans lequel le nœud courant est situé. On peut aller chercher le parent du
parent avec l’instruction <xsl:value-of select="../.." />.
Expression XPath avec « // » (deux barres obliques) : Permet de sélectionner tous les
éléments et sous-éléments qui sont dans l’élément ou nœud courant. Par exemple, l’instruction <xsl:value-of select="count(//cours)" /> donne le nombre total d’éléments
« cours » contenus dans l’élément ou nœud courant, incluant les éléments « cours »
contenus dans les sous-éléments.
Expression XPath avec « * » (astérisque) : Permet de sélectionner tous les éléments
(mais pas les attributs ou les nœuds de texte) qui sont dans l’élément courant. Une
expression avec « @* » sélectionne tous les attributs d’un élément.
Expression XPath avec « | » (barre verticale) : Permet de sélectionner en utilisant plusieurs expressions à la fois; cette expression signifie « ou ». L’expression
« nom|prenom » sélectionnera tous les éléments « nom » et « prenom » dans l’élément courant.
« <xsl:value-of select="name(.)" /> » : Permet de sélectionner le nom d’un élément
(et pas son contenu). Pour sélectionner le nom du parent, il faut utiliser « .. » au lieu de
« . ».
Fonction XPath « count » : Permet de compter le nombre de nœuds (éléments) sélectionnés; par exemple « count(montant) » compte le nombre d’éléments « montant ».
Fonction XPath « sum » : Permet de faire la somme des valeurs numériques dans
les nœuds (éléments) sélectionnés; par exemple « sum(montant) » fait la somme des
valeurs numériques dans les éléments « montant ».
« xsl:number » : Permet de numéroter des éléments correspondant à une expression
avec l’attribut « count »; un exemple d’utilisation : <xsl:number count="montant"
/> donnera le chiffre 3 pour le troisième élément « montant » contenu dans un même
élément.
Attribut « mode » : Permet d’avoir plusieurs modèles pour une même expression;
s’applique aux éléments « xsl:apply-templates » et « xsl:template »; par exemple,
<xsl:template match="cours" mode="initial"> ou <xsl:template match="cours"
mode="complet">.
Fonction XPath « generate-id » : Permet de générer un identifiant unique pour chaque
nœud d’un document XML comme dans l’expression « generate-id(.) ».
« xsl:choose » et « xsl:if » : permet de tester des conditions avec les symboles « < »,
« = », « != », « or », « and », « > », « >= », « <= ». Par exemple, l’instruction XSLT
<xsl:choose>
CC BY-NC-SA
Pense-bête XSLT
297
<xsl:when test="name(.)=’montant’">montant</xsl:when>
<xsl:otherwise>? </xsl:otherwise>
</xsl:choose>
donne le nom de l’élément si l’élément courant est un élément « montant » ou alors, le
symbole « ? ». L’instruction XSLT
<xsl:if test="count(maison) = 2">2 maisons</xsl:if>
donne le chiffre 2, s’il y a deux éléments « maison » dans l’élément courant.
Notion de liste d’éléments en XPath : Équivalent des tableaux en Java ou C/C++,
mais la numérotation des éléments débute à 1; on utilise les crochets pour accéder aux
éléments de la liste. L’expression XPath « para[1] » sélectionne le premier élément
nommé « para ». L’expression « para[1]/em[2] » sélectionne le second élément « em »
contenu dans le premier élément nommé « para ».
Utilisation de XSLT comme base de données : Par exemple, l’expression XPath
client[nom=’Sylvain’] nous donne les éléments « client » pour lesquels le contenu
du sous-élément « nom » est « Sylvain ».
« xsl:for-each » : Lorsqu’il y a un ensemble de résultats, on itère sur la séquence de
tous les éléments « client » ayant comme nom « Sylvain » avec l’expression XPath
//client[nom=’Sylvain’]. Par exemple, l’instruction « <xsl:for-each select="client"
><xsl:value-of select="." />,</xsl:for-each> » donnera une liste, séparée par des virgules, du contenu textuel de tous les éléments « client » contenus dans l’élément courant.
Fonction XPath current() : Représente toujours l’élément XSLT courant. L’expression « //client[nom=current()/nom] » donne tous les éléments « client » qui ont un
attribut « nom » dont la valeur est la même que l’élément courant. Par contre, l’expression « //client[nom=./nom] » a la même signification que « //client[nom] », c’est-àdire qu’on sélectionne tous les éléments « client » contenus dans l’élément courant ou
ses sous-éléments qui ont un attribut « nom ».
Fonctions arithmétiques XPath : On peut faire des calculs simples en XPath comme
dans les expressions « 1+1 », « 2*1 » et « 5 div 2 ». On aussi les fonctions « floor »,
« ceiling » et « round ».
CC BY-NC-SA
Bibliographie
[1] « IT 4247 XML fundamentals (course outline) ».
[2] « Xml, xsl and web applications » – http://www.infosys.tuwien.ac.at/teaching/
courses/XML/.
[3] « Draft standard for learning object metadata » – Tech. Report 1484.12.1-2002,
IEEE, July 2002.
[4] « Dublin core metadata element set, version 1.1: Reference description » – Tech.
report, DCMI, 2003.
[5] « W3 schools » – http://www.w3schools.com/, 2004.
[6] A. B. ET AL . – XML: la synthèse, Dunod, 2003.
[7] H. A. ET AL . – Building corporate portals using XML, McGraw Hill, 1999.
[8] J. P. ET AL . – Professional XML, Wrox, 2001.
[9] L. B IRKEDAL – « Advanced XML / data on the web (course outline) », http:
//www.itu.dk/~birkedal/teaching/data-on-the-web-Fall-2002/.
[10] H. B OLEY – « Auszug vorlesungsverzeichnis informatik », http://www.dfki.
uni-kl.de/~boley/lexml/.
[11] H. B OLEY et B. S PENCER – « CS 6905 semantic web techniques (course outline) », http://www.cs.unb.ca/~bspencer/cs6905swt/syllabus.html.
[12] H. B OLEY, S. TABET et G. WAGNER – « Design Rationale of RuleML: A Markup Language for Semantic Web Rules », Proc. Semantic Web Working Symposium (SWWS’01), Stanford University, July/August 2001, p. 381–401.
[13] M. D EAN et G. S CHREIBER – « OWL Web Ontology Language – Reference »,
W3C Candidate Recommendation, W3C, August 2003.
[14] S. D OWNES – « Topic representation and learning object metadata », http://www.
downes.ca/post/99, 2002.
[15] E. R. H AROLD – XML bible, John Wiley & Sons, 2001.
[16] E. R. H AROLD et W. S COTT – XML in a nutshell, O’Reilly, 2003.
[17] J. H JELM – Creating the semantic web with RDF: Professional developer’s guide,
John Wiley & Sons, 2001.
299
Bibliographie
300
[18] J. H UNT, D. DAY, E. H ENNUM , M. P RIESTLEY et D. A. S CHELL – « Why use
DITA to produce HTML deliverables? », http://www-106.ibm.com/developerworks/
xml/library/x-dita6/index.html.
[19] S. L UCAS – « CC432-G-SP: XML and related technologies (course outline) »,
http://www2.essex.ac.uk/courses/result.asp?coursecode=CC432&level=G&period=
SP&yearofcourse=03.
[20] B. M C L AUGHLIN – Java & XML, O’Reilly, 2001.
[21] E. T. R AY – Learning XML, O’Reilly, 2001.
[22] K. M. TADIOU – « IFT-62399 web sémantique ».
[23] E. T ITTEL – XML, Schaum’s, Dunod, 2003.
CC BY-NC-SA

Documents pareils