Cours XML
Olivier Carton
iii
L'essentiel de XML
6.4. Listes ........................................................................................................................ 6.5. Comparaisons ............................................................................................................. 6.6. Structures de contrle ................................................................................................... 6.7. Syntaxe abrge .......................................................................................................... 6.8. Motifs ....................................................................................................................... 6.9. Utilisation interactive de xmllint .................................................................................... 6.10. Rcapitulatif des oprateurs XPath ................................................................................ 7. Schematron ........................................................................................................................... 7.1. Introduction ................................................................................................................ 7.2. Premier exemple ......................................................................................................... 7.3. Fonctionnement ........................................................................................................... 7.4. Structure globale d'un schematron .................................................................................. 7.5. Rgles ....................................................................................................................... 7.6. Rgles abstraites .......................................................................................................... 7.7. Blocs abstraits ............................................................................................................. 7.8. Phases de validations ................................................................................................... 8. XSLT .................................................................................................................................. 8.1. Principe ..................................................................................................................... 8.2. Premier programme : Hello, World! ........................................................................ 8.3. Modle de traitement ................................................................................................... 8.4. Entte ........................................................................................................................ 8.5. Dfinition et application de rgles .................................................................................. 8.6. Construction de contenu ............................................................................................... 8.7. Structures de contrle ................................................................................................... 8.8. Tris ........................................................................................................................... 8.9. Variables et paramtres ................................................................................................ 8.10. Fonctions d'extension XPath ........................................................................................ 8.11. Modes ...................................................................................................................... 8.12. Indexation ................................................................................................................ 8.13. Documents multiples .................................................................................................. 8.14. Analyse de chanes .................................................................................................... 8.15. Import de feuilles de style ........................................................................................... 9. XSL-FO ............................................................................................................................... 9.1. Premier exemple ......................................................................................................... 9.2. Structure globale ......................................................................................................... 10. CSS ................................................................................................................................... 10.1. Principe .................................................................................................................... 10.2. Rgles ...................................................................................................................... 10.3. Hritage et cascade .................................................................................................... 10.4. Modle de botes ....................................................................................................... 10.5. Style et XML ............................................................................................................ 10.6. Attachement de rgles de style ..................................................................................... 10.7. Principales proprits .................................................................................................. 11. SVG .................................................................................................................................. 11.1. Un premier exemple ................................................................................................... 11.2. lments de dessins ................................................................................................... 11.3. Transformations ......................................................................................................... 11.4. Indications de style .................................................................................................... 11.5. Courbes de Bzier et B-splines ..................................................................................... 12. Programmation XML ............................................................................................................ 12.1. SAX ........................................................................................................................ 12.2. DOM ....................................................................................................................... 12.3. Comparaison ............................................................................................................. 12.4. AJAX ...................................................................................................................... A. Acronymes ........................................................................................................................... Bibliographie ............................................................................................................................ Index .......................................................................................................................................
132 135 138 140 141 142 143 145 145 145 146 147 148 150 151 154 155 155 157 157 159 161 166 182 188 189 195 197 198 201 202 203 205 205 205 206 206 206 210 211 211 212 213 215 215 215 218 218 219 222 222 224 227 227 230 232 233
iv
1.1. Historique
L'historique suivant retrace les grandes tapes qui ont conduit la naissance de XML. L'anctre de XML est le langage SGML qui a t introduit en 1986 par C. Goldfarb. SGML a t conu pour des documentations techniques de grande ampleur. Sa grande complexit a frein son utilisation en dehors des projets de grande envergure. En 1991, T. Berners-Lee a dfini le langage HTML pour le WEB. Ce langage est une version simplifie l'extrme de SGML, destine une utilisation trs cible. XML est, en quelque sorte, intermdiaire entre SGML et HTML. Il vite les aspects les plus complexes de SGML tout en gardant suffisamment de souplesse pour une utilisation gnraliste. La version 1.0 de XML a t publie en 1998 par le consortium W3C (World Wide Web Consortium). Une redfinition XHTML de HTML 4.0 travers XML a t donne en 1999. Un seconde version 1.1, qui est simplement une mise jour pour les caractres spciaux en lien avec Unicode, a, ensuite, t publie en 2004.
1.2. Intrts
XML est devenu omniprsent dans le monde de l'informatique. De nombreux standards sont apparus et permettent des applications diffrentes de stocker mais surtout de partager des documents. L'exemple le plus emblmatique et le plus connu est le format OpenDocument qui est utilis par OpenOffice, maintenant appel LibreOffice, mais aussi par d'autres suites bureautiques comme KOffice. Un autre exemple est le format de dessins vectoriels SVG [Chapitre 11] utilis par Inkscape. Ce succs de XML est en grande partie du ses qualits. Nous allons d'abord numrer ces caractristiques essentielles qui ont conduit ce dveloppement puis nous allons les dtailler plus en profondeur. Sparation stricte entre contenu et prsentation Simplicit, universalit et extensibilit Format texte avec gestion des caractres spciaux Structuration forte Modles de documents (DTD [Chapitre 3] et Schmas XML [Chapitre 5]) Format libre Une des ides directrices de XML est la sparation entre contenu et prsentation. Il faut bien distinguer le contenu d'un document et la prsentation qui en est donne. Un mme contenu peut tre rendu de faons trs diffrentes. Cet ouvrage peut, par exemple, se prsenter comme un livre imprim ou comme une collections de pages WEB. Le contenu est constitu, au dpart, de textes et d'illustrations mais aussi de liens entre ces lments. L'organisation du texte en chapitres, sections et sous-sections ainsi que les renvois entre chapitres font partie intgrante du contenu du document. La prsentation est au contraire la faon de prsenter ce contenu au lecteur. Un des premiers principes de XML est d'organiser le contenu de manire indpendante de la prsentation. Ce principe de sparation est dj prsent dans HTML. Le rendu d'une page HTML est globalement confi au navigateur. Les paragraphes des documents HTML sont, par exemple, crits au kilomtre, sans indication de fins de lignes. Il appartient au navigateur de les dcouper en lignes en fonction de la taille de la page. C'est trs diffrent d'un document PDF
Prsentation de XML
o le dcoupage en pages et en lignes est fige par le document. La sparation n'est cependant pas totale en HTML. Certaines balises comme <ul> et <li> sont destines la structuration du document. Pour ces deux balises, il s'agit d'crire une numration. La prsentation de cette numration (marges, symbole marquant chaque entre, ) est dlgue au navigateur. D'autre balises comme <i> ou <b> donnent davantage des indications de prsentation. Cette sparation entre contenu et prsentation a t accrue en HTML par l'introduction de CSS [Chapitre 10]. Une feuille de style CSS est charge de donner au navigateur toutes les informations relatives la prsentation. Le document HTML peut alors se recentrer sur la structuration du contenu de faon indpendante de la prsentation. Cette sparation entre contenu et prsentation est difficile obtenir. Le rdacteur d'un document a souvent une prsentation en tte et il est tentant pour lui d'essayer de l'imposer. La sparation est encore plus marque en XML car la signification des balises n'est pas fige comme en HTML. La rgles est alors de choisir les balises pour organiser le document en privilgiant la structure de celui-ci par rapport une ventuelle prsentation. Un second principe de XML est une structuration forte du document. Pour illustrer ce principe, la mme adresse est donne ci-dessous dans un style HTML puis dans un style XML. Olivier Carton<br/> 175, rue du Chevaleret<br/> 75013 Paris<br/> <tt>Olivier.Carton@liafa.jussieu.fr</tt> <address> <personname> <firstname>Olivier</firstname> <surname>Carton</surname> </personname> <street> <streetnumber>175</streetnumber> <streetname>rue du Chevaleret</streetname> </street> <zipcode>75013</zipcode><city>Paris</city> <email>Olivier.Carton@liafa.jussieu.fr</email> </address> Les deux adresses contiennent les mmes informations purement textuelles. La suppression des balises comme <br/> ou <firstname> donne le mme rsultat pour les deux adresses. Les balises <br/> prsentes dans la premire adresse permettent le dcoupage en ligne et la balise <tt> indique une police de caractres approprie pour l'adresse lectronique. Le rle de ces balises est seulement d'assurer un rendu correct de l'adresse. Les balises dans la premire adresse relvent de la prsentation alors que les balises dans la seconde adresse comme <firstname> ont un rle smantique. Ces dernires structurent les donnes textuelles et ajoutent ainsi de l'information. Le nom est, par exemple, dcompos en prnom et nom. Cette information supplmentaire facilite le traitement des donnes. Il devient, par exemple, trs facile de mettre le nom en majuscule. En revanche, le rendu exact de l'adresse lectronique est la charge de l'application traitant l'adresse. L'adresse lectronique peut, par exemple, tre supprime si l'adresse est utilise pour une lettre. Une des caractristiques essentielles de XML est son extensibilit et sa flexibilit. Contrairement HTML, le vocabulaire, c'est--dire l'ensemble des balises autorises, n'est pas fig. La norme HTML fixe les balises pouvant apparatre dans un document ainsi que leur imbrication possible. titre d'exemple, la balise <li> peut uniquement apparatre dans le contenu d'une balise <ul> ou <ol>. En revanche, les noms des balises XML sont libres. Il appartient aux auteurs de documents de fixer les balises utilises. Il est seulement ncessaire que les auteurs s'entendent sur le vocabulaire, c'est--dire la liste des balises utilises, lorsque des documents sont changs. Cette libert dans les noms de balises permet de dfinir des vocabulaires particuliers adapts aux diffrentes applications. Il existe ainsi des vocabulaires pour dcrire des dessins vectoriels, des changes commerciaux ou des programmes de tlvision. Ces vocabulaires particuliers sont appels dialectes XML. Il en existe des centaines voire des milliers pour couvrir tous les champs d'application de XML. La libert dans le choix des noms de balises implique une contrepartie. Il devient ncessaire de fixer des rgles que doivent respecter les documents. Sans ces rgles, il n'est pas possible d'changer et de traiter de manire automatique ces documents. Ces rgles doivent d'abord fixer le vocabulaire mais aussi les relations entre les
Prsentation de XML
balises. Les rgles peuvent, par exemple, imposer qu'une balise <address> (cf. exemple ci-dessus) contiennent exactement une balise <zipcode> et une balise <city> sans pour autant fixer l'ordre de ces deux balises. Ces ensembles de rgles portant sur les documents XML sont appels modles de documents. Plusieurs langages ont t dvelopps pour dcrire ces modles. Le premier de ces langages est celui des DTD (Document Type Definition) qui est hrit de SGML. Des langages plus puissants, parmi lesquels les schmas ou relax NG, ont t introduits depuis pour remplacer les DTD. L'intrt principal de ces modles de documents est de pouvoir dcrire explicitement les rgles respecter pour un document et de pouvoir vrifier si un document donn les respecte effectivement. Avant ces modles de documents, il n'tait pas rare que les donnes fournir un logiciel ne fussent pas dcrites de faon trs prcise. Il n'tait alors pas toujours facile de prvoir si des donnes seraient acceptes par le logiciel, et si ce n'tait pas le cas de dterminer lequel des donnes ou du logiciel tait en cause. Les modles de document tels que les DTD ou les schmas peuvent servir une vrification automatique des documents. Il existe plusieurs implmentations de ces modles. Cela autorise la vrification qu'un document donn satisfait ou non les contraintes spcifies par une DTD ou un schma. Lorsque les entres possibles d'un logiciel sont dcrites par un tel modle, il est possible de vrifier de faon indpendante du logiciel que les donnes sont correctes. Cette possibilit est particulirement intressante lors d'changes de documents. Bien que les donnes prsentes dans un document XML soient fortement structures, le format XML est un format bas sur du texte. Il est ainsi possible de manipuler un document XML l'aide d'un simple diteur de texte. Il n'est pas ncessaire d'utiliser un logiciel spcialis. Il existe bien sr des logiciels spcialement conus pour l'dition de documents XML. Ceux-ci peuvent grandement faciliter la tche de l'auteur mais ils ne sont pas indispensables. Cet ouvrage a, par exemple, t rdig avec l'diteur Emacs. Un des atouts d'XML est sa prise en charge native des caractres spciaux grce Unicode. De plus, il est possible d'utiliser les diffrents codages (UTF-8, Latin-1, ) possibles puisque l'entte d'un document spcifie le codage. De nombreuses technologies se sont dveloppes autour de XML et en facilitent l'utilisation. Un des champs d'application est la manipulation et la transformation de documents XML. Il s'agit, par exemple, de rorganiser un document ou d'en extraire des fragments ou de le transformer compltement dans un autre format comme PDF. Comme tous les documents XML partagent la mme syntaxe quel que soit leur vocabulaire, des outils permettent de manipuler ces documents de manire gnrale en s'affranchissant des aspects syntaxiques. Des langages de haut niveau comme XSLT [Chapitre 8] autorisent la description simple et concise de transformations. Le grand intrt de ces langages est qu'ils sont indpendants du vocabulaire utiliss et qu'ils s'adaptent tous les dialectes XML. Le langage XSLT manipule chaque document XML sous la forme d'un arbre issu de la structure des donnes. Les transformations sont dcrites en XSLT par des rgles qui s'appliquent aux fragments dlimits par les balises. Ce langage XSLT est doublement intressant. D'une part, il constitue un outil la fois pratique et puissant et donc d'une grande utilit face de nombreux problmes concrets. D'autre part, il reprsente une approche originale de la programmation car il n'est pas bas sur la programmation imprative ou fonctionnelle de la grande majorit des langages. ce titre, il est digne d'intrt en soi. Le langage XSLT est lui-mme un dialecte XML car il utilise la syntaxe XML. Des programmes XSLT peuvent tre eux-mmes manipuls et crs par d'autres programmes XSLT. Ce mcanisme est d'ailleurs mis en uvre par les schematrons [Chapitre 7]. Le langage XML est totalement libre car il est dvelopp par le W3C. Chacun peut l'utiliser sans devoir acheter une quelconque licence. Cette absence de droits favorise le dveloppement de logiciels libres mis disposition de la communaut. Il existe ainsi une trs grande varit de logiciels libres autour de XML qui en couvrent les diffrents aspects.
Prsentation de XML
XPath [ ] (langage de slection) XPath est un langage d'expressions permettant de slectionner des lments dans un document XML. Il est la pierre angulaire du langage XSLT pour la transformation de documents. Il est abord au chapitre 6 de cet ouvrage. XQuery [ ] (langage de requte) XQuery est un langage permettant d'extraire des informations partir d'un ou plusieurs documents XML et de synthtiser de nouvelles informations partir de celles extraites. Il s'apparente un langage d'interrogation de bases de donnes et joue le rle de SQL pour les documents XML. Schmas XML [ ] (modles de documents) Les schmas XML remplacent les DTD hrites de SGML pour dcrire des modles de documents. Ils sont beaucoup plus souples et beaucoup plus puissants que les DTD. Ils sont abords en dtail au chapitre 5 de cet ouvrage. XSLT [ ] (transformation de documents) XSLT est un langage permettant d'exprimer facilement des transformations complexes entre documents XML. Il s'appuie sur la structuration forte des documents XML vus comme des arbres. Chaque transformation est dcrite par des rgles pour chacun des lments du document. Il est tudi en profondeur au chapitre 8 de cet ouvrage.
1.4. Dialectes
De trs nombreux dialectes ont t dfinis pour appliquer XML des domaines trs varis. Le grand avantage est que ces diffrents dialectes partagent la mme syntaxe de base et que tous les outils XML peuvent tre utiliss pour spcifier et manipuler ces documents. Il n'y a nul besoin de dvelopper des outils spcifiques ces diffrents dialectes. La liste ci-dessous numre quelques uns de ces dialectes. RSS [ ] (Really Simple Syndication) Abonnement des flux de donnes XUL [ ] (XML-based User interface Language) Langage de description d'interfaces graphiques dvelopp par le projet Mozilla. SVG [ ] (Scalable Vector Graphics) Description de dessins vectoriels SMIL [ ] (Synchronized Multimedia Integration Language) Description de contenus multimdia MathML [ ] (Mathematical Markup Language) Description de formules mathmatiques WSDL [ ] (Web Services Description Language) Description de services WEB XML Signature [ ] Format pour les signatures lectroniques SAML [ ] (Security Assertion Markup Language) Langage d'change d'authentifications et d'autorisations UBL [ ] (Universal Business Language)
Prsentation de XML
Bibliothque de documents standards pour les changes commerciaux OpenDocument [ ] Format de document pour les applications bureautiques dvelopp au dpart pour OpenOffice mais aussi utilis par d'autres logiciels libres comme KOffice DocBook [ ] Format de documentation technique De nombreux projets informatiques, comme Ant ou Android utilisent XML pour le stockage de donnes et en particulier pour les fichiers de configuration.
1.5. DocBook
DocBook est un exemple typique d'utilisation de XML. Il s'agit d'un format pour crire des documents techniques. Il est particulirement adapt la rdaction de documentations de logiciels. Il est d'ailleurs utilis par de nombreux projets de logiciels libres, ventuellement de grande ampleur, comme le projet KDE. Cet ouvrage a t rdig en utilisant DocBook. L'intgralit du texte est rpartie en plusieurs fichiers XML. Afin d'obtenir une mise en page de qualit, les documents XML sont convertis, avec le langage XSLT, en un document LaTeX qui peut alors produire un document PDF. DocBook tait au dpart bas sur SGML mais il s'appuie maintenant sur XML dont il est un des dialecte. Il contient de nombreuses balises permettant de dcrire et de structurer le contenu de faon trs prcise. Il existe ensuite diffrents outils permettant de traduire un document DocBook, en une seule page HTML, en plusieurs pages HTML avec des liens ou encore en un document PDF. DocBook met l'accent sur l'organisation et la structure du document. Son vocabulaire contient de trs nombreuses balises permettant de transcrire trs finement la smantique de chaque fragment, la manire de la seconde adresse donne au dbut de cette introduction. Cet exemple est, en fait, trs inspir de DocBook. En revanche, DocBook ne permet pas de spcifier le rendu du document. Il n'est pas possible de donner, par exemple, la couleur ou la police de caractres utiliser pour le texte. L'ide directrice est qu'un document DocBook doit permettre la production de plusieurs documents finaux partir d'un mme document original : document PDF, pages WEB. Comme les contraintes de ces diffrents mdia sont trs diverses, il est impossible de pouvoir les spcifier dans le document. Le choix de DocBook est de donner suffisamment d'indications sur le contenu aux applications qui ralisent les transformations pour obtenir un rsultat de qualit. Les documents DocBook font souvent partie d'un ensemble de documentations, comme celle de KDE, dont la prsentation est uniforme et donc dtermine de manire globale.
1.6. Conventions
Certaines conventions sont utilises tout au long de cet ouvrage afin d'en faciliter la lecture. Tous les exemples et plus gnralement, tous les fragments de texte pouvant apparatre dans un document XML sont crits en utilisant une police de caractres fixe comme l'exemple d'entte ci-dessous. Les noms des balises sont en particulier crits avec cette police. <?xml version="1.0" encoding="iso-8859-1"?> Lorsqu'un fragment de texte comporte des parties gnriques qui doivent tre remplaces pour obtenir un vritable exemple, ces parties sont crites avec une police de caractres fixe et italique. L'exemple de dclaration de DTD ci-dessous signifie qu'une telle dclaration doit commencer par <!DOCTYPE suivi du nom de l'lment racine du document qui peut tre un nom quelconque, diffrent de root-element. <!DOCTYPE root-element ... > L'criture ... signifie qu'une partie sans importance a t omise pour rendre la description plus concise et plus claire. Un exemple concret est obtenu en remplaant root-element par simple et en compltant la partie omise.
Prsentation de XML
<!DOCTYPE simple [ <!ELEMENT simple (#PCDATA)> ]> Les rfrences croises entre les diffrents chapitres et sections de cet ouvrage jouent un rle important. chaque fois qu'un concept important est mentionn, le numro de section o celui-ci est introduit est indiqu entre crochets de cette faon [Section 2.2]. Ces indications de navigation facilitent la comprhension des liens entre les diffrentes notions. Il a quelques fois t pris la libert de mentionner des liens avec des concepts introduits plus tard dans l'ouvrage. Ces indications peuvent tre ignores dans une premire lecture. Les nombres sont gnralement crits en base dcimale comme 123 ou 8364. Lorsque l'criture d'un nombre est en base hexadcimale, celle-ci commence par x ou 0x comme 0x231 ou x20AC. L'exception cette rgle est l'criture des points de code des caractres Unicode [Section 2.2] qui sont toujours crits en hexadcimal prcds de U+ comme U+2023 ou U+20AC.
2.2. Caractres
Un document XML est une suite de caractres. Les caractres qui peuvent tre utiliss sont ceux dfinis par la norme Unicode ISO 10646 [ ] aussi appele UCS pour Universal Character Set. Cette norme recense tous les
Syntaxe de XML
caractres des langues connues et tous les symboles utiliss dans les diffrentes disciplines. Elle nomme tous ces caractres et symboles et leur attribue un code sur 32 bits (4 octets) appel simplement code Unicode ou point de code dans la terminologie Unicode. Dans la pratique, tous les points de code attribus des caractres se situent dans l'intervalle de 0 0x10FFFF et ils utilisent donc au plus 21 bits. Cette longueur maximale ne sera pas dpasse avant longtemps car il reste encore de nombreux points de code non attribus dans cet intervalle pour des usages futurs. Unicode peut tre vu comme un catalogue de tous les caractres disponibles. Un caractre dont le point de code est n est dsign par U+n o le nombre n est crit en hexadcimal. L'criture hexadcimale de n n'est pas prfixe du caractre 'x' car c'est implicite aprs les deux caractres 'U+'. Le caractre Euro '' est, par exemple, dsign par U+20AC car son point de code est 8364 = 0x20AC. Le sous-ensemble des caractres Unicode dont les points de code tiennent sur 16 bits (2 octets), c'est--dire entre 0 et 65535 = 0xFFFF est appel BMP pour Basic Multilingual Plane. Il couvre largement la trs grande majorit des langues usuelles et les symboles les plus courants.
Syntaxe de XML
Le caractre ':' est rserv l'utilisation des espaces de noms [Chapitre 4]. De fait, il ne peut apparatre qu'une seule fois pour sparer un prfixe du nom local dans les noms des lments et des attributs. Les espaces de noms amnent distinguer les noms ayant un caractre ':', appels noms qualifis et les autres, appels par opposition noms non qualifis. Les noms commenant par les trois lettres xml en minuscule ou majuscule, c'est--dire par une chane de [xX][mM][lL] sont rservs aux usages internes de XML. Ils ne peuvent pas tre utiliss librement dans les documents mais ils peuvent cependant apparatre pour des utilisations spcifiques prvues par la norme. Les noms commenant par xml: comme xml:base font partie de l'espace de noms XML [Section 4.7]. Quelques exemples d'identificateurs sont donns ci-dessous. Noms XML valides : name, id-42, xsl:template, sec.dtd-3.1 et _special_ Jetons qui ne sont pas des noms : -name, 42, 42-id et .sect. Noms rservs : xml:id et xml-stylesheet La norme XML 1.1 prvoit que tout caractre Unicode de catgorie lettre peut apparatre dans les identificateurs. Il est, par exemple, possible d'avoir des noms d'lments avec des caractres accentus. Il est cependant conseill de se limiter aux caractres ASCII de [a-zA-Z] pour assurer une meilleure compatibilit. Beaucoup de logiciels ne grent pas les autres caractres dans les identificateurs.
2.2.4. Codage
Chaque caractre possde un point de code sur 32 bits mais un document ne contient pas directement ces points de code des caractres. Ce codage serait inefficace puisque chaque caractre occuperait 4 octets. Chaque document utilise un codage pour crire les points de code des caractres. Il existe diffrents codages dont le codage par dfaut UTF-8. Certains codages permettent d'crire tous les points de code alors que d'autres permettent seulement d'crire un sous-ensemble comme le BMP. Le codage utilis par un document est indiqu dans l'entte [Section 2.6.1] de celui-ci. Les principaux codages utiliss par les documents XML sont dcrits ci-dessous. US-ASCII Ce codage permet uniquement de coder les points de code de 0 0x7F des caractres ASCII. UCS-4 ou UTF-32 [ ] Chaque caractre est cod directement par son point de code sur quatre octets. Ce codage permet donc de coder tous les caractres Unicode. UCS-2 [ ] Chaque caractre est cod par son point de code sur deux octets. Ce codage permet donc uniquement de coder les caractres du BMP. UTF-16 [ ] Ce codage concide essentiellement avec UCS-2 l'exception de la plage de 2048 positions de 0xD800 0xDFFF qui permet de coder des caractres en dehors du BMP dont le point de code utilise au plus 20 bits. L'exclusion de cette plage ne pose aucun problme car elle ne contient aucun point de code attribu un caractre. Un point de code ayant entre 17 et 20 bits est scind en deux blocs de 10 bits rpartis sur une paire de mots de 16 bits. Le premier bloc de 10 bits est prfix des 6 bits 110110 pour former un premier mot de 16 bits et le second bloc de 10 bits est prfix des 6 bits 110111 pour former un second mot de 16 bits. Reprsentation UTF-16 xxxxxxxx xxxxxxxx 110110zz zzxxxxxx Signification 2 octets codant 16 bits 4 octets codant 20 bits
Syntaxe de XML
10
Syntaxe de XML
Les logiciels manipulant des documents XML doivent obligatoirement grer les codages UTF-8 et UTF-16. Les autres codages sont facultatifs. Il est essentiel que le codage d'un document soit indiqu dans l'entte [Section 2.6.1] du document. Si un navigateur interprte, par exemple, la suite d'octets du codage UTF-8 du mot Htrogne comme un codage en ISO-8859-1, il affiche la chane Htrogne. Bien que certains codages ne permettent pas de coder tous les points de code, il est nanmoins possible d'insrer n'importe quel caractre Unicode en donnant explicitement son point de code avec une des deux syntaxes suivantes. Ces syntaxes peuvent tre utilises pour n'importe quel point de code mme si celui-ci peut tre crit avec le codage du document. Elles sont, en particulier, pratiques lorsque les diteurs de texte affichent mal certains caractres. Les deux syntaxes prennent les formes &#point de code dcimal; ou &#xpoint de code hexadcimal;. Le caractre Euro '' peut par exemple tre insr par € ou €. Pour ces deux syntaxes, c'est le point de code du caractre qui est crit en dcimal ou en hexadcimal et non pas sa transcription dans le codage du document.
2.2.5. Collations
Certaines ligatures comme le caractre '' U+153 sont considres par Unicode comme un seul caractre plutt que comme la fusion des deux caractres 'oe'. Il s'ensuit que les deux mots cur et coeur sont, a priori, considrs comme distincts. Ce problme est rsolu par l'utilisation de collations lors du traitement des documents. Une collation est une collection de rgles qui tablissent des quivalences entre des caractres ou des suites de caractres. Une collation peut, par exemple, dclarer que le caractre '' U+153 est quivalent aux deux caractres 'oe' ou que la lettre '' U+DF est quivalente aux deux lettres 'ss'. Une collation tablit aussi l'ordre des caractres utilis pour l'ordre lexicographique. Elle peut, par exemple, dclarer que le caractre '' se place entre les caractres 'e' et 'f'. La collation par dfaut est base sur les points de code des caractres. Le caractre '' U+E9 se trouve, pour cette collation, aprs le caractre 'z' U+7A et le mot zbre est donc avant le mot talon dans l'ordre lexicographique.
11
Syntaxe de XML
2.2.6. Normalisation
Le mme caractre peut avoir plusieurs points de code. Cette ambigut provient du fait qu'Unicode a t construit en fusionnant plusieurs codages et qu'il tente de rester compatible avec chacun d'eux. Le caractre '' est en mme temps le caractre U+B5 qui provient de Latin-1 et le caractre U+3BC qui provient du bloc des caractres grecs. D'autres caractres peuvent avoir un point de code mais peuvent, en mme temps, correspondre une suite de plusieurs points de code. Le caractre '' est, par exemple, le caractre U+EF mais il correspond galement la suite U+69 U+A8 forme du caractre 'i' suivi du caractre spcial trma '' U+A8. Ce codage multiple conduit des problmes, en particulier pour la comparaison des chanes de caractres. Pour palier ce problme, Unicode introduit des normalisations qui transforment les diffrents codages en un codage canonique. La normalisation la plus standard est la normalisation C. Celle-ci transforme, par exemple, la suite de caractres U+69 U+A8 en le caractre '' U+EF. La normalisation d'une chane de caractres peut tre obtenue avec la fonction XPath normalize-unicode() [Section 6.3.3].
12
Syntaxe de XML
sftp://carton@liafa.jussieu.fr tel:+33-1-57-27-92-54 sip:0957279254@freephonie.net file://home/carton/Enseignement/XML/Cours/XSLT urn:oasis:names:tc:docbook:dtd:xml:docbook:5.1 urn:publicid:-:W3C:DTD+HTML+4.0:EN Dans la pratique, la plupart des URI utilises sont des URL et les deux termes peuvent (presque) tre considrs comme synonymes.
Rpertoire
Fichier
Protocole
Adresse Internet
Chem in d'accs
Rpertoire
Fichier
Protocole
Chem in d'accs
13
Syntaxe de XML
3. Si l'URL url est un chemin relatif ne commenant pas par le caractre '/', le rsultat est obtenu en remplaant le nom du fichier de l'URL base par l'URL url. Le chemin relatif est donc concatn avec le nom du rpertoire. Les exemples ci-dessous illustrent les diffrents cas. On suppose que l'URL base est fixe gale l'URL http://www.somewhere.org/Teaching/index.html. Pour chacune des valeurs de l'URL url, on donne la valeur de l'URL obtenue par combinaison de l'URL base avec l'URL url. url="" (chane vide) http://www.somewhere.org/Teaching/index.html url="XML/chapter.html" (chemin relatif) http://www.somewhere.org/Teaching/XML/chapter.html url="XML/XPath/section.html" (chemin relatif) http://www.somewhere.org/Teaching/XML/XPath/section.html url="/Course/section.html" (chemin absolu) http://www.somewhere.org/Course/section.html url="http://www.elsewhere.org/section.html" (URL complte) http://www.elsewhere.org/section.html
14
Syntaxe de XML
Corps du document C'est le contenu mme du document. Commentaires et instructions de traitement Ceux-ci peuvent apparatre partout dans le document, dans le prologue et le corps. Le document se dcoupe en fait en deux parties conscutives qui sont le prologue et le corps. Les commentaires et les instructions de traitement sont ensuite librement insrs avant, aprs et l'intrieur du prologue et du corps. La structure globale d'un document XML est la suivante. <?xml ... ?> ... <root-element> ... </root-element> Corps Prologue
Dans l'exemple donn au dbut de ce chapitre, le prologue comprend les trois premires lignes du fichier. La premire ligne est l'entte XML et la deuxime est simplement un commentaire utilis par Emacs pour mmoriser le nom du fichier et sa date de dernire modification. La troisime ligne est la dclaration d'une DTD externe contenue dans le fichier bibliography.dtd. Le corps du document commence la quatrime ligne du fichier avec la balise ouvrante <bibliography>. Il se termine la dernire ligne de celui-ci avec la balise fermante </bibliography>.
2.6. Prologue
Le prologue contient deux dclarations facultatives mais fortement conseilles ainsi que des commentaires [Section 2.7.5] et des instructions de traitement [Section 2.7.6]. La premire dclaration est l'entte XML qui prcise entre autre la version de XML et le codage du fichier. La seconde dclaration est la dclaration du type du document (DTD) qui dfinit la structure du document. La dclaration de type de document est omise lorsqu'on utilise des schmas XML [Chapitre 5] ou d'autres types de modles qui remplacent les DTD. La structure globale du prologue est la suivante. Dans le prologue, tous les caractres d'espacement [Section 2.2.2] sont interchangeables mais l'entte est gnralement place, seule, sur la premire ligne du fichier. <?xml ... ?> <!DOCTYPE root-element [ ... ]> ] DTD Entte XML Prologue
Les diffrentes parties du prologue sont dtailles dans les sections suivantes.
15
Syntaxe de XML
L'attribut version prcise la version d'XML utilise. Les valeurs possibles actuellement sont 1.0 ou 1.1. L'attribut encoding prcise le codage des caractres [Section 2.2.4] utilis dans le fichier. Les principales valeurs possibles sont US-ASCII, ISO-8859-1, UTF-8, et UTF-16. Ces noms de codage peuvent aussi tre crits en minuscule comme iso-8859-1 ou utf-8. L'attribut standalone prcise si le fichier est autonome, c'est-dire s'il existe des dclarations externes qui affectent le document. La valeur de cet attribut peut tre yes ou no et sa valeur par dfaut est no. Les dclarations externes peuvent provenir d'une DTD externe [Section 3.2.2] o d'entits paramtres [Section 3.5.2]. Elles peuvent affecter le contenu du document en donnant, par exemple, des valeurs par dfaut [Section 3.7.3] des attributs. La valeur de l'attribut standalone influence galement la prise en compte des caractres d'espacement dans les contenus purs [Section 3.6.1.1] lors de la validation par une DTD. L'attribut version est obligatoire et l'attribut encoding l'est aussi ds que le codage des caractres n'est pas le codage par dfaut UTF-8. Quelques exemples d'entte XML sont donns ci-dessous. <?xml version="1.0"?> <?xml version='1.0' encoding='UTF-8'?> <?xml version="1.1" encoding="iso-8859-1" standalone="no"?> Lorsqu'un document est scind en plusieurs fragments dans diffrents fichiers inclus par des entits externes [Section 3.5.1.4] ou par XInclude [Section 2.9], chacun des fragments peut commencer par une entte. L'intrt est de pouvoir spcifier un codage des caractres diffrent.
2.7.1. lments
Contenu de l'lm ent n a me
16
Syntaxe de XML
Dans la balise ouvrante, le caractre '<' doit tre immdiatement suivi du nom de l'lment. En revanche, il peut y avoir des espaces entre le nom et le caractre '>'. La balise fermante ne peut pas contenir d'espace.
ou Contenu vide
<t a g 1 >
</ t a g 1 >
<t a g 2 >
</ t a g 2 >
... </sibling1> ... </sibling2> ... <desc1></desc1> ... <desc2></desc2> ... </child1> ... </child2> ... <desc3><desc4> ... </desc4></desc3> ... </child3> ... </sibling3>
pa r e nt
s i bl i ng1
s i bl i ng2
s el f
s i bl i ng3
c hi l d1
c hi l d2
c hi l d3
de s c 1
de s c 2
de s c 3
de s c 4
17
Syntaxe de XML
Dans l'exemple ci-dessus, le contenu de l'lment self s'tend de la balise ouvrante <child1> jusqu' la balise fermante </child3>. Ce contenu comprend tous les lments child1, child2 et child3 ainsi que les lments desc1, desc2, desc3 et desc4. Tous les lments qu'il contient sont appels descendants de l'lment self. Parmi ces descendants, les lments child1, child2 et child3 qui sont directement inclus dans self sans lment intermdiaire sont appels les enfants de l'lment self. Inversement, l'lment parent qui contient directement self est appel le parent de l'lment self. Les autres lments qui contiennent l'lment self sont appels les anctres de l'lment self. Les autres enfants sibling1, sibling2 et sibling3 de l'lment parent sont appels les frres de l'lment self. Ces relations de parent entre les lments peuvent tre visualises comme un arbre gnalogique (cf. figure). Tout le corps du document doit tre compris dans le contenu d'un unique lment appel lment racine. Le nom de cet lment racine est donn par la dclaration de type de document [Section 3.2] si celle-ci est prsente. L'lment bibliography est l'lment racine de l'exemple donn au dbut du chapitre. ... <root-element> ... ... </root-element> ... ] ] ] ] Commentaires et instructions de traitement Balise ouvrante de l'lment racine lments, commentaires et instructions de traitement Balise fermante de l'lment racine Commentaires et instructions de traitement Corps du document
2.7.3. Attributs
Les balises ouvrantes peuvent contenir des attributs associs des valeurs. L'association de la valeur l'attribut prend la forme attribute='value' ou la forme attribute="value" o attribute et value sont respectivement le nom et la valeur de l'attribut. Chaque balise ouvrante peut contenir zro, une ou plusieurs associations de valeurs des attributs comme dans les exemples gnriques suivants. <tag attribute="value"> ... </tag> <tag attribute1="value1" attribute2="value2"> ... </tag> Voici ci-dessous d'autres exemples concrets de balises ouvrantes avec des attributs. Ces exemples sont respectivement tirs d'un document XHTML, d'un schma XML [Chapitre 5] et d'une feuille de style XSLT [Chapitre 8]. <body background='yellow'> <xsd:element name="bibliography" type="Bibliography"> <a href="#{$node/@idref}">
18
Syntaxe de XML
Lorsque le contenu de l'lment est vide et que la balise ouvrante et la balise fermante sont contractes en une seule balise [Section 2.7.1], celle-ci peut contenir des attributs comme la balise ouvrante. <hr style="color:red; height:15px; width:350px;" /> <xsd:attribute name="key" type="xsd:NMTOKEN" use="required"/> Le nom de chaque attribut doit tre un nom XML [Section 2.2.3]. La valeur d'un attribut peut tre une chane quelconque de caractres dlimite par une paire d'apostrophes ''' ou une paire de guillemets '"'. Elle peut contenir les caractres spciaux '<', '>', '&', ''' et '"' mais ceux-ci doivent ncessairement tre introduits par les entits prdfinies [Section 3.5.1.2]. Si la valeur de l'attribut est dlimite par des apostrophes ''', les guillemets '"' peuvent tre introduits directement sans entit et inversement. <xsl:value-of select="key('idchapter', @idref)/title"/> <xsl:if test='@quote = "'"'> Comme des espaces peuvent tre prsents dans la balise aprs le nom de l'lment et entre les attributs, l'indentation est libre pour crire les attributs d'une balise ouvrante. Aucun espace ne peut cependant sparer le caractre '=' du nom de l'attribut et de sa valeur. Il est ainsi possible d'crire l'exemple gnrique suivant. <tag attribute1="value1" attribute2="value2" ... attributeN="valueN"> ... </tag> L'ordre des attributs n'a pas d'importance. Les attributs d'un lment doivent avoir des noms distincts. Il est donc impossible d'avoir deux occurrences du mme attribut dans une mme balise ouvrante. Le bon usage des attributs est pour les meta-donnes plutt que les donnes elles-mmes. Ces dernires doivent tre places de prfrence dans le contenu des lments. Dans l'exemple suivant, la date proprement dite est place dans le contenu alors que l'attribut format prcise son format. La norme ISO 8601 [ ] spcifie la reprsentation numrique de la date et de l'heure. <date format="ISO-8601">2009-01-08</date> C'est une question de style de mettre les donnes dans les attributs ou dans les contenus des lments. Le nom complet d'un individu peut, par exemple, tre rparti entre des lments firstname et surname regroups dans un lment personname comme dans l'exemple ci-dessous. <personname id="I666"> <firstname>Gaston</firstname> <surname>Lagaffe</surname> </personname> Les lments firstname et surname peuvent tre remplacs par des attributs de l'lment personname comme dans l'exemple ci-dessous. Les deux solutions sont possibles mais la premire est prfrable. <personname id="I666" firstname="Gaston" surname="Lagaffe"/>
19
Syntaxe de XML
pour le traitement l'lment mais aussi de ses descendants l'exception, bien sr, de ceux qui donnent une nouvelle valeur cet attribut. Autrement dit, la valeur de l'attribut xml:lang prendre en compte pour le traitement d'un lment est celle donne cet attribut par l'anctre (y compris l'lment lui-mme) le plus proche. Pour illustrer le propos, le document suivant contient plusieurs occurrences de l'attribut xml:lang. La langue du texte est, chaque fois, donne par la valeur de l'attribut xml:lang le plus proche. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <book xml:lang="fr"> <title>Livre en Franais</title> <chapter> <title>Chapitre en Franais</title> <p>Paragraphe en Franais</p> <p xml:lang="en">Paragraph in English</p> </chapter> <chapter xml:lang="en"> <title>Chapter in English</title> <p xml:lang="fr">Paragraphe en Franais</p> <p>Paragraph in English</p> </chapter> </book> Ce qui a t expliqu pour l'attribut xml:lang vaut galement pour deux autres attributs xml:space et xml:base. C'est cependant un peu diffrent pour l'attribut xml:base car la valeur prendre en compte doit tre calcule partir de toutes les valeurs des attributs xml:base des anctres.
20
Syntaxe de XML
multimdia (images, sons, vido). Dans le fragment de document XHTML ci-dessous, l'lment img rfrence un fichier image element.png par son attribut src. <img src="element.png" alt="lment"/> L'attribut de xml:base permet de prciser l'URI de base d'un lment. Par dfaut, l'URI de base d'un lment est hrit de son parent. L'URI de base de la racine du document est appele URI de base du document. Elle est souvent fixe par l'application qui traite le document mais elle peut aussi provenir d'un attribut xml:base de l'lment racine. Lorsque le document provient d'un fichier local, c'est souvent le chemin d'accs celui-ci dans l'arborescence des fichiers, comme file:/home/carton/Teaching/XML/index.html. Lorsque le document est, au contraire, tlcharg, l'URI de base du document est l'adresse Internet de celui-ci comme http://www.liafa.jussieu.fr/~carton/index.html. Pour chaque lment, l'attribut xml:base permet de fixer une URI de base de faon absolue ou, au contraire, de la construire partir de l'URI de base du parent. Le comportement dpend de la forme de la valeur de l'attribut. La valeur est combine avec l'URI de base du base en suivant les rgles de combinaison de celles-ci [Section 2.3.1]. L'attribut xml:base est de type xsd:anyURI [Section 5.5.1.2]. L'attribut xml:base est indispensable pour raliser des inclusions de fichiers externes avec XInclude [Section 2.9] lorsque ces fichiers sont situs dans un rpertoire diffrent de celui ralisant l'inclusion. Le document suivant illustre les diffrents cas pour la combinaison d'une URI avec une adresse. Pour chacun des lments, l'URI de base est donne. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <book xml:base="http://www.somewhere.org/Teaching/index.html"> <chapter xml:base="XML/chapter.html"> <section xml:base="XPath/section.html"/> <section xml:base="/Course/section.html"/> <section xml:base="http://www.elsewhere.org/section.html"/> </chapter> </book> http://www.somewhere.org/Teaching/index.html http://www.somewhere.org/Teaching/XML/chapter.html http://www.somewhere.org/Teaching/XML/XPath/section.html http://www.somewhere.org/Course/section.html http://www.elsewhere.org/section.html L'URI de base d'un lment est retourne par la fonction XPath base-uri().
2.7.5. Commentaires
Les commentaires sont dlimits par les chanes de caractres '<!--' et '-->' comme en HTML. Ils ne peuvent pas contenir la chane '--' forme de deux tirets '-' et ils ne peuvent donc pas tre imbriqus. Ils peuvent tre prsents dans le prologue et en particulier dans la DTD [Section 3.4]. Ils peuvent aussi tre placs dans le contenu de n'importe quel lment et aprs l'lment racine. En revanche, ils ne peuvent jamais apparatre l'intrieur
21
Syntaxe de XML
d'une balise ouvrante ou fermante. Un exemple de document XML avec des commentaires partout o ils peuvent apparatre est donn ci-dessous. <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!-- Commentaire dans le prologue avant la DTD --> <!DOCTYPE simple [ <!-- Commentaire dans la DTD --> <!ELEMENT simple (#PCDATA) > ]> <!-- Commentaire entre le prologue et le corps du document --> <simple> <!-- Commentaire au dbut du contenu de l'lment simple --> Un exemple simplissime <!-- Commentaire la fin du contenu de l'lment simple --> </simple> <!-- Commentaire aprs le corps du document -->
Les caractres spciaux '<', '>' et '&' peuvent apparatre dans les commentaires. Il est en particulier possible de mettre en commentaire des lments avec leurs balises comme dans l'exemple ci-dessous. <!-- <tag type="comment">lment mis en commentaire</tag> -->
L'entte XML [Section 2.6.1] <?xml version=... ?> ressemble une instruction de traitement de nom xml avec des paramtres version, encoding et standalone. Elle utilise en effet la mme syntaxe. Elle n'est pourtant pas une instruction de traitement et elle ne fait pas partie du document.
22
Syntaxe de XML
2.9. XInclude
Il est possible de rpartir un gros document en plusieurs fichiers afin d'en rendre la gestion plus aise. Il existe essentiellement deux mthodes pour atteindre cet objectif. Le point commun de ces mthodes est de scinder le document en diffrents fichiers qui sont inclus par un fichier principal. Les deux mthodes se diffrencient par leurs faons de raliser l'inclusion. La mthode la plus ancienne est hrite de SGML et elle est base sur les entits externes [Section 3.5.1.4]. La mthode, plus rcente, base sur XInclude [ ] est utiliser de prfrences aux entits externes. XInclude dfinit un lment xi:include dans un espace de noms [Chapitre 4] associ l'URL http://www.w3.org/2001/ XInclude. Cet lment a un attribut href qui contient le nom du fichier inclure et un attribut parse qui prcise le type des donnes. Cet attribut peut prendre les valeurs xml ou text. Le fichier source principal de cet ouvrage inclut, par exemple, les fichiers contenant les diffrents chapitres grce des lments include comme ci-dessous. <book version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"> ... <!-- Inclusion des diffrents chapitres --> <xi:include href="introduction.xml" parse="xml"/> <xi:include href="Syntax/chapter.xml" parse="xml"/> ... </book> Le fragment de document contenu dans un fichier inclus doit tre bien form. Il doit, en outre, tre entirement contenu dans un seul lment qui est l'lment racine du fragment. Il faut prendre garde au fait que certaines applications ne grent pas XInclude. La solution est d'ajouter la chane de traitement une tape consistant construire un document global entirement contenu dans un seul fichier. Le logiciel xmllint peut, par exemple, raliser cette opration. Avec l'option --xinclude, il crit sur la sortie standard un document o les lments xi:include sont remplacs par le contenu des fichiers rfrencs. Cette option peut tre combine avec l'option --noent pour supprimer les entits dfinies dans la DTD. L'opration consistant remplacer un lment xi:include par le contenu du fichier doit mettre jour l'attribut xml:base [Section 2.7.4.3] de l'lment racine du document dans le fichier. Cet attribut contient une URL qui
23
Syntaxe de XML
permet de rsoudre les liens relatifs. Le chemin d'accs au fichier doit donc tre ajout la valeur de l'attribut xml:base. Il faut, en particulier, ajouter cet attribut s'il est absent et si le chemin d'accs est non vide. Le chemin d'accs au fichier est rcupr dans l'attribut href de l'lment xi:include. La mise jour des attributs xml:base garde une trace des inclusions et permet aux liens relatifs de rester valides. La prise en compte des valeurs de ces attributs xml:base incombe en revanche aux applications qui traitent le document et utilisent ces liens. Si chacun des fichiers introduction.xml et Syntax/chapter.xml a comme lment racine un lment chapter sans attribut xml:base, le rsultat de l'inclusion de ces fichiers doit donner un document ressemblant ceci. <book version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"> ... <!-- Inclusion des diffrents chapitres --> <chapter xml:id="chap.introduction" xml:base="introduction.xml"> ... </chapter> <chapter xml:id="chap.syntax" xml:base="Syntax/chapter.xml"> ... </chapter> ... </book>
24
Chapitre 3. DTD
Le rle d'une DTD (Document Type Definition) est de dfinir prcisment la structure d'un document. Il s'agit d'un certain nombre de contraintes que doit respecter un document pour tre valide. Ces contraintes spcifient quelles sont les lments qui peuvent apparatre dans le contenu d'un lment, l'ordre ventuel de ces lments et la prsence de texte brut. Elles dfinissent aussi, pour chaque lment, les attributs autoriss et les attributs obligatoires. Les DTD ont l'avantage d'tre relativement simples utiliser mais elles sont parfois aussi un peu limites. Les schmas XML [Chapitre 5] permettent de dcrire de faon plus prcise encore la structure d'un document. Ils sont plus sophistiqus mais plus difficiles mettre en uvre. Les DTD sont donc particulirement adaptes pour des petits modles de documents. En revanche, leur manque de modularit les rend plus difficiles utiliser pour des modles plus consquents.
Dclaration de l'lment bibliography devant contenir une suite non vide d'lments book. Dclaration de l'lment book devant contenir les lments title, author, , isbn et url. Dclarations des attributs obligatoires key et lang de l'lment book. Dclaration de l'lment title devant contenir uniquement du texte.
25
DTD
<!DOCTYPE root-element ... > Le nom de l'lment racine est suivi du contenu de la DTD dans le cas d'une DTD interne ou de l'URL du fichier contenant la DTD dans le cas d'une DTD externe.
Le premier caractre type du FPI est soit le caractre '+' si le propritaire est enregistr selon la norme ISO 9070 soit le caractre '-' sinon. Le FPI continue avec le propritaire owner et la description desc du document. Cette description est forme d'un mot cl suivi d'un texte libre. Ce mot cl est DTD pour les DTD mais il peut aussi tre DOCUMENT, ELEMENTS ou ENTITIES. Le FPI se termine par un code de langue lang de la norme ISO 639 [Section 2.7.4.1]. Lorsque le document appartient une norme ISO, le premier caractre '+' ainsi que la chane '//' suivante sont supprims. Des exemples de FPI sont donns ci-dessous. -//W3C//DTD XHTML 1.0 Strict//EN -//OASIS//DTD Entity Resolution XML Catalog V1.0//EN ISO/IEC 10179:1996//DTD DSSSL Architecture//EN
Un FPI peut tre converti en URI en utilisant l'espace de noms publicid des URN et en remplaant chaque chane '//' par le caractre ':' et chaque espace par le caractre '+' comme dans l'exemple ci-dessous. urn:publicid:-:W3C:DTD+XHTML+1.0+Strict:EN
26
DTD
La dclaration d'une DTD externe peut utiliser un FPI pour dsigner la DTD. La rfrence un FPI est introduite par le mot cl PUBLIC suivi du FPI et d'une URL dlimite par des apostrophes ''' ou des guillemets '"'. L'URL est utilise dans le cas o le FPI ne permet pas l'application de retrouver la DTD. <!DOCTYPE root-element PUBLIC "fpi" "url"> L'exemple suivant est la dclaration typique d'une page HTML qui utilise une des DTD de XHTML. <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
27
DTD
<!ELEMENT year (#PCDATA)> <!ELEMENT publisher (#PCDATA)> <!ELEMENT isbn (#PCDATA)> Le document suivant a une DTD mixte dont la partie externe est la DTD prcdente. La partie interne de la DTD contient la dclaration de l'lment url. Elle contient galement des nouvelles dclarations de l'entit paramtre book.entries et de l'attribut lang de l'lment book, qui devient ainsi obligatoire. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <!DOCTYPE bibliography SYSTEM "mixed.dtd" [ <!-- Ajout d'un enfant url l'lment book --> <!ENTITY % book.entries ", url?"> <!-- Redclaration de l'attribut key de l'lment book --> <!-- L'attribut devient obligatoire --> <!ATTLIST book lang (fr | en) #REQUIRED> <!-- Dclaration de l'lment url --> <!ELEMENT url (#PCDATA)> ]> <bibliography> <book key="Michard01" lang="fr"> <title>XML langage et applications</title> <author>Alain Michard</author> <year>2001</year> <publisher>Eyrolles</publisher> <isbn>2-212-09206-7</isbn> <url>http://www.editions-eyrolles/livres/michard/</url> </book> <book key="Marchal00" lang="fr"> <title>XML by Example</title> <author>Benot Marchal</author> <year>2000</year> <publisher>Macmillan Computer Publishing</publisher> <isbn>0-7897-2242-9</isbn> </book> </bibliography> Comme la valeur donne l'entit paramtre book.entries est la chane ", url?" (sans les guillemets '"'), la dclaration de l'lment book dans le fichier mixed.dtd devient quivalente la dclaration suivante qui autorise un enfant url optionnel. <!ELEMENT book (title, author, year, publisher, isbn, url?)>
3.4. Commentaires
Une DTD peut contenir des commentaires qui utilisent la syntaxe des commentaires XML [Section 2.7.5] dlimits par les chanes de caractres '<!--' et '-->'. Ceux-ci sont placs au mme niveau que les dclarations d'lments, d'attributs et d'entits. Ils ne peuvent pas apparatre l'intrieur d'une dclaration. <!-- DTD pour les bibliographies --> <!ELEMENT bibliography (book)+>
28
DTD
<!-- Dclaration de l'lment book avec des enfants title, ..., isbn et url --> <!ELEMENT book (title, author, year, publisher, isbn, url?)> ...
3.5. Entits
Les entits constituent un mcanisme hrit de SGML. Elles sont des macros semblables aux #define du langage C. Elles permettent galement de raliser des inclusions de documents comme la directive #include du langage C. Les entits sont dfinies dans la DTD du document. Il existe deux types d'entits. Les entits gnrales, appeles simplement entits dans cet ouvrage, sont destines tre utilises dans le corps du document. Les entits paramtres sont destines tre utilises au sein de la DTD. Une entit est, en quelque sorte, un nom donn un fragment de document. Ce fragment peut tre donn explicitement la dfinition de l'entit dans la DTD. Il peut galement provenir d'un fichier externe. Dans ce cas, la dfinition de l'entit donne un FPI et/ou une URL permettant d'accder au document. Le fragment de document peut tre insr dans le document en utilisant simplement le nom de l'entit. Lorsque le fragment provient d'un autre fichier, l'utilisation de l'entit provoque l'inclusion du fichier en question. Le nom de chaque entit gnrale ou paramtre doit tre un nom XML [Section 2.2.3].
29
DTD
30
DTD
31
DTD
<!ATTLIST section %langatt;> Les entits paramtres ajoutent de la modularit qui est surtout ncessaire dans l'criture de DTD de grande taille. Dans l'exemple prcdent, l'attribut id pourrait tre remplac partout par un attribut xml:id en changeant uniquement la dfinition de l'entit paramtre idatt. Un autre exemple d'utilisation des entits paramtres est donn avec les DTD mixtes [Section 3.2.3]. Les entits externes permettent d'inclure une partie de DTD provenant d'un document externe comme dans l'exemple suivant. <!-- Entit paramtre pour inclure la DTD principale --> <!ENTITY % main SYSTEM "main.dtd"> <!-- Inclusion du fichier main.dtd --> %main;
32
DTD
Oprateur | ? * +
Signification Choix 0 ou 1 occurrence Rptition d'un nombre quelconque d'occurrences Rptition d'un nombre non nul d'occurrences
33
DTD
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <!DOCTYPE list SYSTEM "standalone.dtd"> <list> <item>Item 1</item> <item>Item 2</item> </list>
34
DTD
Dans l'exemple suivant, l'lment book possde un contenu mixte. Il peut contenir du texte et des lments em et cite en nombre quelconque et dans n'importe quel ordre. <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE book [ <!ELEMENT book (#PCDATA | em | cite)*> <!ELEMENT em (#PCDATA)> <!ELEMENT cite (#PCDATA)> ]> <book> Du <em>texte</em>, une <cite>citation</cite> et encore du <em>texte</em>. </book>
35
DTD
36
DTD
entre des lments d'un mme document. La norme XLink gnralise ce mcanisme. Elle permet de crer des liens entre deux, voire mme plus de fragments de documents XML provenant ventuellement de documents diffrents. La valeur d'un attribut de type ID doit tre un nom XML [Section 2.2.3]. La valeur de cet attribut doit tre unique dans tout le document. Ceci signifie qu'un autre attribut de type ID d'un autre lment ne peut pas avoir la mme valeur pour que le document soit valide. Un lment ne peut avoir qu'un seul attribut de type ID. Les attributs id de type ID sont utiliss par la fonction XPath id(). La valeur d'un attribut de type IDREF doit tre un nom XML. Ce nom doit, en outre, tre la valeur d'un attribut de type ID d'un (autre) lment pour que le document soit valide. La valeur d'un attribut de type IDREFS doit tre une suite de noms spars par des espaces. Chacun de ces noms doit, en outre, tre la valeur d'un attribut de type ID d'un lment pour que le document soit valide. Le document suivant illustre l'utilisation des attributs de type ID, IDREF et IDREFS qui est faite par DocBook pour les rfrences internes. Son contenu est scind en sections dlimites par les lments section. Chacun de ces lments a un attribut id de type ID. Le contenu des lments section est constitu de texte et d'lments ref et refs ayant respectivement un attribut idref de type IDREF et un attribut idrefs de type IDREFS. Ces lments permettent, dans le contenu d'une section, de rfrencer une (par ref) ou plusieurs (par refs) autres sections. Il faut remarquer que les lments ref et refs n'ont jamais de contenu. Ils sont dclars vides en utilisant le mot cl EMPTY. Il appartient l'application qui gnre le document final d'ajouter du contenu qui peut tre par exemple le numro ou le titre de la section rfrence. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <!DOCTYPE book [ <!ELEMENT book (section)*> <!ELEMENT section (#PCDATA | ref | refs)*> <!ATTLIST section id ID #IMPLIED> <!ELEMENT ref EMPTY> <!ATTLIST ref idref IDREF #REQUIRED> <!ELEMENT refs EMPTY> <!ATTLIST refs idrefs IDREFS #REQUIRED> ]> <book> <section id="sec0">Une rfrence <ref idref="sec1"/></section> <section id="sec1">Des rfrences <refs idrefs="sec0 sec2"/></section> <section id="sec2">Section sans rfrence</section> <section id="sec3">Une auto-rfrence <refs idrefs="sec3"/></section> </book> Les attributs de type ID et IDREF permettent galement de structurer un document. Si l'adresse et d'autres informations sont ajoutes l'diteur dans le document bibliography.xml, celles-ci sont recopies dans chaque livre publi par l'diteur. Cette duplication de l'information est bien sr trs mauvaise. Une meilleure approche consiste scinder la bibliographie en deux parties. Une premire partie contient les livres et une seconde partie les diteurs avec les informations associes. Ensuite chaque livre se contente d'avoir une rfrence sur son diteur. Un attribut id de type ID est ajout chaque lment publisher de la seconde partie. Chaque lment publisher contenu dans un lment book est remplac par un lment published ayant un attribut by de type IDREF. <?xml version="1.0" encoding="iso-8859-1"?> <bibliography> <books> <book key="Michard01" lang="fr"> <title>XML langage et appplications</title> <author>Alain Michard</author> <year>2001</year> <isbn>2-212-09206-7</isbn> <url>http://www.editions-eyrolles/livres/michard/</url> <published by="id2680397"/>
37
DTD
</book> <book key="Marchal00" lang="en"> <title>XML by Example</title> <author>Benot Marchal</author> <year>2000</year> <isbn>0-7897-2242-9</isbn> <published by="id2680427"/> </book> ... </books> <publishers> <publisher id="id2680397"> <name>Eyrolles</name> <address>Paris</address> </publisher> <publisher id="id2680427"> <name>Macmillan Computer Publishing</name> <address>New York</address> </publisher> ... </publishers> </bibliography> Beaucoup d'applications ne prennent pas en compte la DTD pour traiter un document. Il leur est alors impossible de savoir quels attributs sont de type ID, IDREF ou IDREFS. Elles utilisent souvent la convention qu'un attribut de nom id est implicitement de type ID. Une meilleure solution consiste utiliser l'attribut xml:id [Section 2.7.4.4] qui est toujours de type ID (de type xml:ID [Section 5.5.1.4] en fait).
3.7.4. Exemples
Voici quelques exemples de dclarations d'attributs avec, pour chacune d'entre elles, des valeurs valides et non valides pour l'attribut.
38
DTD
<!ATTLIST tag meta CDATA "default"> La valeur de l'attribut meta peut tre une chane quelconque et sa valeur par dfaut est la chane default Les exemples illustrent l'utilisation des entits prdfinies [Section 3.5.1.2] pour inclure des caractres spciaux dans les valeurs d'attribut. Attribut dans le document <tag meta="Hello World!"> <tag> <tag meta=""> <tag meta="=='"=="> <tag meta='=='"=='> <tag meta="==<&>=="> <tag meta="==<&>=="> Valeur Hello World! Valeur par dfaut default Chane vide =='"== =='"== ==<&>== ==<&>==
<!ATTLIST book lang (fr | en) "fr"> La valeur de l'attribut lang peut tre soit le jeton fr soit le jeton en et sa valeur par dfaut est le jeton fr. Attribut dans le document <book> <book lang="fr"> <book lang="en"> <book lang="de"> Valeur Valeur par dfaut fr Valeur par dfaut fr Jeton en non valide car la valeur de n'est pas numre
<!ATTLIST book name NMTOKEN #IMPLIED> L'attribut name est optionnel et sa valeur doit tre un jeton. Il n'a pas de valeur par dfaut. Attribut dans le document <book> <book name="en"> <book name="-id234"/> <book name="Hello World!"> Valeur Pas de valeur Jeton en Jeton -id234 non valide car Hello World! n'est pas un jeton
<!ATTLIST entry id ID #REQUIRED> L'attribut id est obligatoire et sa valeur doit tre un nom unique. Il n'a pas de valeur par dfaut. Attribut dans le document <entry> <entry id="id-234"> <entry id="Hello World!"> Valeur non valide attribut absent Nom id-234 non valide car Hello World! n'est pas un nom
<!ATTLIST xref ref IDREF #REQUIRED> L'attribut ref est obligatoire et sa valeur doit tre un nom XML. Pour que le document soit valide, ce nom doit tre la valeur d'un attribut de type ID d'un (autre) lment. Cet attribut n'a pas de valeur par dfaut. Attribut dans le document <xref ref="id-234"/> <xref ref="-id234"/> Valeur id-234 non valide car -id234 n'est pas nom.
<!ATTLIST xrefs refs IDREFS #REQUIRED> L'attribut refs est obligatoire et sa valeur doit tre une suite de noms XML spars par des espaces. Pour que le document soit valide, chacun des noms de la liste doit tre la valeur d'un attribut de type ID d'un (autre) lment. Il n'a pas de valeur par dfaut.
39
DTD
<!ATTLIST rule style CDATA #FIXED "free"> La valeur de l'attribut style de l'lment rule est fixe la valeur free. Attribut dans le document <rule> <rule style="free"> <rule style="libre"> Valeur Valeur fixe free Valeur fixe free non valide car valeur diffrente
40
Comme en C++, les espaces de noms vitent les conflits de noms entre diffrents vocabulaires. Le dialecte DocBook dispose d'un lment title de mme nom que l'lment title du Dublin Core. Ces deux lments ne sont pas confondus dans le document prcdent, car l'lment title du Dublin Core a le prfixe dc.
41
Espaces de noms
42
Espaces de noms
</html:body> </html:html> C'est l'URI associ au prfixe qui dtermine l'espace de noms. Le prfixe est juste une abrviation pour l'URI. Deux prfixes associs au mme URI dterminent le mme espace de noms. Dans l'exemple suivant, les deux lments firstname et surname font partie du mme espace de noms. L'exemple suivant est uniquement donn pour illustrer le propos mais il n'est pas suivre. C'est une mauvaise pratique d'associer deux prfixes au mme URI. <name xmlns:foo="http://www.somewhere.org/uri" xmlns:bar="http://www.somewhere.org/uri"> <!-- Les deux lments firstname et surname appartiennent au mme espace de noms. --> <foo:firstname>Gaston<foo:firstname> <bar:surname>Lagaffe<bar:surname> </name>
43
Espaces de noms
<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"> <mml:apply> <mml:eq/> ... </mml:apply> </mml:math> ... </body> </html> Comme la dclaration de l'espace de noms est locale l'lment, l'exemple prcdent aurait pu tre crit de faon encore plus simplifie en changeant localement dans l'lment math l'espace de noms par dfaut. <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Espaces de noms</title> </head> <body> ... <math xmlns="http://www.w3.org/1998/Math/MathML"> <apply> <eq/> ... </apply> </math> ... </body> </html> Tant que l'espace de noms par dfaut n'a pas t spcifi, les lments dont le nom n'est pas qualifi ne font partie d'aucun espace de noms. Leur proprit espace de noms n'a pas de valeur. Il est possible de revenir l'espace de noms par dfaut non spcifi en affectant la chane vide l'attribut xmlns comme dans l'exemple suivant. <html xmlns="http://www.w3.org/1999/xhtml"> <!-- L'espace de noms par dfaut est spcifi --> <!-- Tous les lments html, head, title, body, ... appartiennent l'espace de noms par dfaut. --> <head> <title>Espaces de noms</title> </head> <body> ... <name xmlns=""> <!-- L'espace de noms par dfaut n'est plus spcifi --> <!-- Les trois lments name, firstname et surname n'appartiennent aucun espace de noms. --> <firstname>Gaston<firstname> <surname>Lagaffe<surname> </name> ... </body> </html> Une consquence de la remarque prcdente est que dans un document XML sans dclaration d'espace de noms, tous les lments ne font partie d'aucun espace de noms. Ce comportement assure une compatibilit des applications avec les documents sans espace de noms.
4.6. Attributs
44
Espaces de noms
Les attributs peuvent galement avoir des noms qualifis forms d'un prfixe et d'un nom local. Ils font alors partie de l'espace de noms auquel est associ le prfixe. Dans l'exemple suivant, l'attribut noNamespaceSchemaLocation fait partie de l'espace de noms des instances de schmas identifi par l'URI http://www.w3.org/2001/XMLSchema-instance. Le nom de l'attribut noNamespaceSchemaLocation doit donc avoir un prfixe associ cette URI. La dclaration de l'espace de noms peut avoir lieu dans le mme lment, comme dans l'exemple ci-dessous, puisque la porte de celle-ci est l'lment tout entier. <?xml version="1.0" encoding="iso-8859-1"?> <bibliography xsi:noNamespaceSchemaLocation="bibliography.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> ... En revanche, les attributs dont le nom n'est pas qualifi ne font jamais partie de l'espace de noms par dfaut. Cette rgle s'applique que l'espace de noms par dfaut soit spcifi ou non. Dans l'exemple ci-dessous, l'lment book appartient l'espace de noms DocBook puisque celui-ci est dclar comme l'espace de noms par dfaut. L'attribut id appartient l'espace de noms XML et l'attribut version n'appartient aucun espace de noms. <book version="5.0" xml:id="course.xml" xmlns="http://docbook.org/ns/docbook">
45
Espaces de noms
Schematron [Chapitre 7] http://purl.oclc.org/dsdl/schematron XSLT [Chapitre 8] http://www.w3.org/1999/XSL/Transform XSL-FO [Chapitre 9] http://www.w3.org/1999/XSL/Format DocBook [Section 1.5] http://docbook.org/ns/docbook Dublin Core http://purl.org/dc/elements/1.1/
46
47
Schmas XML
l'esprit des espace de noms o le prfixe est juste une abrviation interchangeable pour l'URI de l'espace de noms. Les schmas, au contraire, prennent en compte les espaces de noms [Section 5.13]. Un schma dclare d'abord un espace de noms cible. Les lments et les attributs sont ensuite dclars, dans le schma, avec leur nom local. Un document qui mlange des lments et des attributs provenant d'espaces de noms diffrents peut encore tre valid l'aide des diffrents schmas pour les espaces de noms.
48
Schmas XML
Comme pour les DTD, il existe des sites WEB permettant de valider un document vis vis d'un schma. Cette validation peut galement tre effectue avec le logiciel xmllint. L'option --schema permet de passer en paramtre un schma en plus du document XML.
49
Schmas XML
restriction et substitution. Les valeurs possibles pour finalDefault sont #all ou une liste de valeurs parmi les valeurs extension, restriction, list et union. Dans l'exemple suivant, le schma dclare que l'espace de noms cible est http:// www.liafa.jussieu.fr/~carton et que tous les lments doivent tre qualifis dans les documents valides. L'espace de noms par dfaut est dclar gal l'espace de noms cible afin de simplifier l'criture du schma. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.liafa.jussieu.fr/~carton"> ...
5.3.3. Documentation
L'lment xsd:annotation permet d'ajouter des commentaires dans un schma. Il peut tre enfant de l'lment xsd:schema pour des commentaires globaux. Il peut galement tre enfant des lments xsd:element, xsd:attribute pour ajouter des commentaires aux dclarations d'lments et d'atttributs ainsi que de xsd:simpleType et xsd:complexType pour ajouter des commentaires aux dfinitions de type. Contrairement aux commentaires XML [Section 2.7.5], ces commentaires font partie part entire du schma XML et constituent sa documentation.
50
Schmas XML
<xsd:annotation> <xsd:documentation xml:lang="fr"> Commentaire en franais </xsd:documentation> <xsd:appInfo> Information destine aux applications </xsd:appInfo> </xsd:annotation>
51
Schmas XML
52
Schmas XML
<strings> <local>Une chane</local> <local>A string</local> </strings> <integers> <local>-1</local> <local>1</local> </integers> </lists>
x s d : a n y Ty p e
x s d : s i mp l e Ty p e
x s d : c o mp l e x Ty p e
x s d : a n y At o mi c Ty p e
xs d: l i s t
xs d: e xt e ns i on
xs d: s e que nc e
xs d: e xt e ns i on
xs d: uni on
xs d: r e s t r i c t i on
xs d: c hoi c e
xs d: r e s t r i c t i on
xs d: a l l
53
Schmas XML
54
Schmas XML
Nombre entier positif ou nul sans limite de prcision xsd:float Nombre flottant sur 32 bits conforme la norme IEEE 754 [ ] xsd:double Nombre flottant sur 64 bits conforme la norme IEEE 754 [ ] xsd:decimal Nombre dcimal sans limite de prcision
55
Schmas XML
Donnes binaires reprsentes par une chane au format Hex. Les types xsd:normalizedString et xsd:token mritent quelques explications. D'une part, il faut bien distinguer le type xsd:token du type xsd:NMTOKEN. Le type xsd:token accepte des valeurs contenant ventuellement des espaces alors que le type xsd:NMTOKEN accepte uniquement un jeton [Section 2.2.3] qui ne contient jamais d'espace. D'autre part, les deux types xsd:normalizedString et xsd:token ne restreignent pas les valeurs possibles pour un document valide mais modifient le traitement des caractres d'espacement [Section 2.2.2] l'analyse lexicale. Le type xsd:normalizedString n'interdit pas de mettre des caractres d'espacement autres que des espaces. En revanche, tous les caractres d'espacement sont convertis en espaces par l'analyseur lexical. De la mme faon, le type xsd:token n'interdit pas de mettre des caractres d'espacement en dbut ou en fin ou des caractres d'espacement conscutifs. En revanche, les caractres d'espacement en dbut ou en fin sont supprims et les suites de caractres d'espacement sont remplaces par un seul espace par l'analyseur lexical.
56
Schmas XML
xsd:gMonthDay Jour et mois du calendrier grgorien au format MM-DD comme 12-25 pour le jour de Nol. xsd:gDay Jour (dans le mois) du calendrier grgorien au format DD comme 01 pour le premier de chaque mois.
x s d : a n y At o mi c Ty p e
xs d: bool e a n
x s d : d e c i ma l
xs d: doubl e
xs d: f l oa t
xs d: s t r i ng
x s d : d a t e Ti me
xs d: da t e
x s d : t i me
xs d: dur a
xs d: i nt e ge r x s d : n o n Po s i t i v e I n t e g e r xs d: ne ga t i ve I nt e ge r
x s d : y e a r M n t h Du r a t i o n o
x s d : d a y Ti me Du r a t i o n
x s d : a n y At o mi c Ty p e
x s d : a n y URI
x s d : QNa me
x s d : b a s e 6 4 Bi n a r y
x s d : h e x Bi n a r y
x s d : g Ye a r
x s d : g Ye a r M n t h o
xs d: gM nt h o
x s d : g M n t h Da y o
x s d : g Da y
57
Schmas XML
58
Schmas XML
La construction explicite d'un type se fait en utilisant les oprateurs de squence xsd:sequence, de choix xsd:choice ou d'ensemble xsd:all. La construction du type se fait directement dans le contenu de l'lment xsd:complexType et prend donc la forme suivante. <!-- Type explicite --> <xsd:complexType ...> <!-- Construction du type avec xsd:sequence, xsd:choice ou xsd:all --> ... </xsd:complexType> Si le type est obtenu par extension ou restriction d'un autre type, l'lment xsd:complexType doit contenir un lment xsd:simpleContent ou xsd:complexContent qui prcise si le contenu est purement textuel ou non. La dclaration d'un type complexe prend alors une des deux formes suivantes. <!-- Type driv contenu textuel --> <xsd:complexType ...> <xsd:simpleContent> <!-- Extension ou restriction --> ... </xsd:simpleContent> </xsd:complexType> <!-- Type driv contenu pur ou mixte --> <xsd:complexType ...> <xsd:complexContent> <!-- Extension ou restriction --> ... </xsd:complexContent> </xsd:complexType>
59
Schmas XML
<person> Prnom : <firstname>Albert</firstname>, Nom : <lastname>Einstein</lastname>. </person> Le schma prcdent n'a pas d'quivalent dans les DTD. Ds que le contenu d'un lment est dclar mixte dans une DTD [Section 3.6.3], il n'y a plus aucun contrle sur l'ordre et le nombre d'occurrences de ses enfants. Le schma suivant donne un exemple de contenu mixte quivalent un contenu mixte d'une DTD. <xsd:element name="book"> <xsd:complexType mixed="true"> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="em"/> <xsd:element ref="cite"/> </xsd:choice> </xsd:complexType> </xsd:element> L'exemple prcdent est quivalent au fragment suivant de DTD. <!ELEMENT book (#PCDATA | em | cite)* >
60
Schmas XML
Cette dclaration est quivalente la dclaration suivante dans une DTD. <!ELEMENT book (title, author, year, publisher)> Un fragment de document ci-dessous est valide pour la dclaration de l'lment book. <book> <title>XML langage et applications</title> <author>Alain Michard</author> <year>2001</year> <publisher>Eyrolles</publisher> </book> Un autre exemple de type construit avec l'oprateur xsd:sequence est donn comme exemple de type mixte [Section 5.5.4]. Le nombre d'occurences de chaque lment dans la squence est 1 par dfaut mais il peut tre modifi par les attributs minOccurs et maxOccurs [Section 5.6.7].
61
Schmas XML
</xsd:sequence> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1"?> <bibliography> <!-- Livre un seul auteur --> <book key="Michard01" lang="fr"> <title>XML langage et applications</title> <author>Alain Michard</author> <year>2001</year> <publisher>Eyrolles</publisher> </book> <!-- Livre deux auteurs --> <book key="ChagnonNolot07" lang="fr"> <title>XML</title> <authors> <author>Gilles Chagnon</author> <author>Florent Nolot</author> </authors> <year>2007</year> <publisher>Pearson</publisher> </book> </bibliography>
Le document suivant est un document valide o l'lment book a la dclaration prcdente. L'ordre des enfants de l'lment book peut tre variable. <?xml version="1.0" encoding="iso-8859-1"?> <bibliography> <book key="Michard01" lang="fr"> <author>Alain Michard</author> <title>XML langage et applications</title> <publisher>Eyrolles</publisher> <year>2001</year> </book> <book key="Zeldman03" lang="en"> <title>Designing with web standards</title> <author>Jeffrey Zeldman</author> <year>2003</year> <publisher>New Riders</publisher> </book>
62
Schmas XML
... </bibliography> L'utilisation de l'lment xsd:all doit respecter quelques contraintes qui limitent fortement son intrt. Un oprateur xsd:all ne peut pas tre imbriqu avec d'autres constructeurs xsd:sequence, xsd:choice ou mme xsd:all. D'une part, les seuls enfants possibles de xsd:all sont des lments xsd:element. D'autre part, l'lment xsd:all est toujours enfant de xsd:complexType ou xsd:complexContent. Les attributs minOccurs et maxOccurs des lments apparaissant sous l'oprateur xsd:all ne peuvent pas avoir des valeurs quelconques. La valeur de l'attribut minOccurs doit tre 0 ou 1 et la valeur de l'attribut maxOccurs doit tre 1 qui est la valeur par dfaut. Les attributs minOccurs et maxOccurs peuvent aussi apparatre comme attribut de xsd:all. Dans ce cas, leurs valeurs s'appliquent tous les lments xsd:element enfants de xsd:all. Les valeurs autorises pour minOccurs sont 0 et 1 et la seule valeur autorise pour maxOccurs est 1. Dans la dclaration suivante de l'lment book, ses enfants peuvent apparatre dans n'importe quel ordre et chacun d'eux peut avoir 0 ou 1 occurrence. <xsd:element name="book"> <xsd:complexType> <xsd:all minOccurs="0"> <xsd:element name="title" <xsd:element name="author" <xsd:element name="year" <xsd:element name="publisher" </xsd:all> </xsd:complexType> </xsd:element>
63
Schmas XML
</xsd:simpleType>
5.6.7. Rptitions
Les attributs minOccurs et maxOccurs permettent de prciser le nombre minimal ou maximal d'occurrences d'un lment ou d'un groupe. Ils sont l'quivalent des oprateurs ?, * et + des DTD. Ils peuvent apparatre comme attribut des lments xsd:element, xsd:sequence, xsd:choice et xsd:all. L'attribut minOccurs prend un entier comme valeur. L'attribut maxOccurs prend un entier ou la chane unbounded comme valeur pour indiquer qu'il n'y a pas de nombre maximal. La valeur par dfaut de ces deux attributs est la valeur 1. L'utilisation des attributs minOccurs et maxOccurs est illustre par l'quivalent en schma de quelques fragments de DTD <!ELEMENT elem (elem1, elem2?, elem3*) > <xsd:element name="elem"> <xsd:complexType> <xsd:sequence> <xsd:element ref="elem1"/> <xsd:element ref="elem2" minOccurs="0"/> <xsd:element ref="elem3" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <!ELEMENT elem (elem1, (elem2 | elem3), elem4) > <xsd:element name="elem"> <xsd:complexType> <xsd:sequence> <xsd:element ref="elem1"/> <xsd:choice> <xsd:element ref="elem2"/> <xsd:element ref="elem3"/> <xsd:choice> <xsd:element ref="elem4"/> </xsd:sequence> </xsd:complexType> </xsd:element>
64
Schmas XML
<!ELEMENT elem (elem1, elem2, elem3)* > <xsd:element name="elem"> <xsd:complexType> <xsd:sequence minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="elem1"/> <xsd:element ref="elem2"/> <xsd:element ref="elem3"/> </xsd:sequence> </xsd:complexType> </xsd:element> <!ELEMENT elem (elem1 | elem2 | elem3)* > <xsd:element name="elem"> <xsd:complexType> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="elem1"/> <xsd:element ref="elem2"/> <xsd:element ref="elem3"/> </xsd:choice> </xsd:complexType> </xsd:element> <!ELEMENT elem (elem1, elem2, elem3)+ > <xsd:element name="elem"> <xsd:complexType> <xsd:sequence minOccurs="1" maxOccurs="unbounded"> <xsd:element ref="elem1"/> <xsd:element ref="elem2"/> <xsd:element ref="elem3"/> </xsd:sequence> </xsd:complexType> </xsd:element>
65
Schmas XML
</xsd:complexType> </xsd:element> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="utf-8"?> <person> <firstname>Elizabeth II Alexandra Mary</firstname> <lastname>Windsor</lastname> <title>Queen of England</title> </person> L'attribut namespace de l'lment xsd:any permet de prciser les espaces de noms auxquels doivent appartenir les lments externes. Sa valeur doit tre une suite d'URI identifiant des espaces de noms spars par des espaces. Les valeurs particulires ##any, ##other, ##local et ##targetNamepspace peuvent aussi apparatre dans la liste des espace de noms. La valeur par dfaut ##any n'impose aucune restriction sur l'espace de noms des lments externes. Les valeurs ##targetNamepspace et ##other autorisent respectivement des lments dont l'espace de noms est gal ou diffrent de l'espace de noms cible du schma. La valeur ##local autorise des lments ayant des noms non qualifis et n'appartenant aucun espace de noms. Dans le schma suivant, l'lment externe ajout dans le contenu de l'lment person doit appartenir l'espace de noms XHTML. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="person"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> <xsd:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="utf-8"?> <person> <firstname>Victor</firstname> <lastname>Hugo</lastname> <html:ul xmlns:html="http://www.w3.org/1999/xhtml"> <li>Romancier</li> <li>Pote</li> <li>Dramaturge</li> </html:ul> </person> Il existe galement un lment xsd:anyAttribute [Section 5.7.4] pour autoriser des attributs externes au schma.
5.6.9. Validation
Cette section aborde deux aspects techniques de la validation du contenu d'lments purs. Ces deux aspects sont la prsence des caractres d'espacement [Section 2.2.2] et le dterminisme des contenus. Ils ont dj t abords pour les DTD [Section 3.6.1.1].
66
Schmas XML
Lorsque le contenu d'un lment d'un lment pur est valid, les caractres d'espacement qui se trouvent hors de ses enfants sont ignors. Ceci autorise l'indentation des documents XML sans perturber la validation. Le contenu des lments purs et mixtes doit tre dterministe. Ceci signifie que la prsence d'une balise ouvrante dans le contenu doit compltement dterminer d'o provient celle-ci dans la dfinition du type. Cette restriction est identique celle portant sur les expressions dfinissant le contenu d'un lment pur dans une DTD. Le schma suivant n'est pas valable car le contenu de l'lment item n'est pas dterministe. Une balise ouvrante <item1> peut provenir de la premire ou de la seconde dclaration d'lment item1. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="item"> <xsd:complexType> <xsd:choice> <xsd:sequence> <xsd:element name="item1" type="xsd:string"/> <xsd:element name="item2" type="xsd:string"/> </xsd:sequence> <xsd:sequence> <xsd:element name="item1" type="xsd:string"/> <xsd:element name="item3" type="xsd:string"/> </xsd:sequence> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema>
5.7.1. Localisation
Les dclarations d'attributs se placent normalement dans les dfinitions de types complexes qui peuvent tre globaux ou locaux. Les types simples ne peuvent pas avoir d'attributs. La dfinition d'un type complexe se compose de la description du contenu suivie de la dclaration des attributs. L'ordre de dclarations des attributs est sans importance puisque l'ordre des attributs dans une balise n'est pas fixe.
67
Schmas XML
Dans l'exemple suivant, le type complexe List dclare deux attributs form et lang. Les dclarations de ces deux attributs se situent aprs la description du contenu du type List constitu d'une suite d'lments item. Le type de l'attribut form est le type prdfini xsd:string alors que le type de l'attribut lang est le type global et simple Lang dfini dans la suite du schma. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="List"> <!-- Contenu du type List --> <xsd:sequence maxOccurs="unbounded"> <xsd:element name="item" type="xsd:string"/> </xsd:sequence> <!-- Dclaration des attributs locaux form et lang du type List --> <xsd:attribute name="form" type="xsd:string"/> <xsd:attribute name="lang" type="Lang"/> </xsd:complexType> <!-- Type global et simple Lang pour l'attribut lang --> <xsd:simpleType name="Lang"> <xsd:restriction base="xsd:string"> <xsd:length value="2"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="list" type="List"/> </xsd:schema> Un attribut peut aussi tre global lorsque sa dclaration est enfant direct de l'lment xsd:schema. Cet attribut peut alors tre ajout diffrents types complexes. La dfinition du type utilise l'lment xsd:attribute avec un attribut ref qui remplace les deux attributs name et type. Cet attribut ref contient le nom de l'attribut global ajouter. La dclaration globale d'un attribut est justifie lorsque celui-ci a des occurrences multiple. Elle accrot la modularit en vitant de rpter la mme dclaration dans plusieurs types. Le schma suivant dclare un attribut global lang de type xsd:language. Cet attribut est ajout deux reprises dans le type global Texts et dans le type anonyme de l'lment text. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Dclaration de l'attribut global lang --> <xsd:attribute name="lang" type="xsd:language"/> <xsd:element name="texts" type="Texts"/> <xsd:complexType name="Texts"> <xsd:sequence> <xsd:element name="text" maxOccurs="unbounded"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:string"> <!-- Ajout de l'attribut lang au type anonyme --> <xsd:attribute ref="lang"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> </xsd:sequence> <!-- Ajout de l'attribut lang au type Texts --> <xsd:attribute ref="lang"/> </xsd:complexType> </xsd:schema> Lorsqu'un schma dclare un espace de noms cible [Section 5.13], les attributs globaux appartiennent automatiquement cet espace de noms. Ceci signifie d'abord qu'ils doivent tre rfrencs par leur nom qualifi
68
Schmas XML
dans le schma. L'ajout d'un attribut de nom name un type complexe prend alors la forme suivante o le prfixe tns est associ l'espace de noms cible du schma. <xsd:attribute ref="tns:name"/> Cela signifie aussi qu'ils doivent avoir un nom qualifi dans les documents instance comme dans l'exemple suivant. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <tns:texts tns:lang="fr" xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <text>Texte en franais</text> <text tns:lang="en">Text in english</text> </tns:texts>
69
Schmas XML
les dclarations d'attribut des DTD. Dans le premier exemple suivant, la valeur par dfaut de l'attribut lang est fr et dans le second exemple, sa valeur est fixe la valeur en. <xsd:attribute name="lang" type="xsd:NMTOKEN" default="fr"/> <xsd:attribute name="lang" type="xsd:NMTOKEN" fixed="en"/>
70
Schmas XML
xsd:extension est toujours enfant d'un lment xsd:simpleContent. Les dclarations des attributs qui sont ajouts sont places dans le contenu de l'lment xsd:extension. Le fragment de schma suivant dfinit un type Price qui tend le type prdfini xsd:decimal en lui ajoutant un attribut currency de type xsd:string <xsd:complexType name="Price"> <xsd:simpleContent> <xsd:extension base="xsd:decimal"> <!-- Attribut ajout --> <xsd:attribute name="currency" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> <xsd:element name="price" type="Price"/> Un fragment de document valide peut tre le suivant. <price currency="euro">3.14</price>
Schmas XML
L'extension d'un type complexe contenu complexe consiste ajouter du contenu et/ou des attributs. Le contenu est ajout aprs le contenu du type de base. L'ajout d'attribut est semblabe au cas des types complexes contenu simple. Dans le schma suivant le type Fullname tend le type Name en lui ajoutant un lment title et un attribut id. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base --> <xsd:complexType name="Name"> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <!-- Extension du type de base --> <xsd:complexType name="Fullname"> <xsd:complexContent> <xsd:extension base="Name"> <xsd:sequence> <!-- Ajout de l'lment title aprs firstname et lastname --> <xsd:element name="title" type="xsd:string"/> </xsd:sequence> <!-- Ajout de l'attribut id --> <xsd:attribute name="id" type="xsd:ID"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> ... </xsd:schema> L'lment title est ajout aprs le contenu du type Name qui est constitu des deux lments firstname et lastname. Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <names> <fullname id="id40"> <firstname>Alexander III Alexandrovich</firstname> <lastname>Romanov</lastname> <title>Tsar of Russia</title> </fullname> <fullname id="id52"> <firstname>Elizabeth II Alexandra Mary</firstname> <lastname>Windsor</lastname> <title>Queen of England</title> </fullname> </names>
72
Schmas XML
xsd:restriction est enfant direct de l'lment xsd:simpleType. Dans le cas d'un type complexe, il est enfant d'un lment xsd:simpleContent ou xsd:complexContent, lui-mme enfant de l'lment xsd:complexType.
73
Schmas XML
conforme l'expression rationnelle. Dans l'exemple suivant, le type ISBN dcrit explicitement toutes les formes possibles des numros ISBN. <xsd:simpleType name="ISBN"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d-\d{2}-\d{6}-[\dX]"/> <xsd:pattern value="\d-\d{3}-\d{5}-[\dX]"/> <xsd:pattern value="\d-\d{4}-\d{4}-[\dX]"/> <xsd:pattern value="\d-\d{5}-\d{3}-[\dX]"/> </xsd:restriction> </xsd:simpleType> Le type suivant Identifier dfinit un type pour les noms XML [Section 2.2.3]. Il aurait aussi pu tre dcrit avec l'expression rationnelle \i\c*. <xsd:simpleType name="Identifier"> <xsd:restriction base="xsd:string"> <xsd:pattern value="[:_A-Za-z][-.:_0-9A-Za-z]*"/> </xsd:restriction> </xsd:simpleType> Pour que la contenu soit valide, il faut que le contenu, pris dans son intgralit, soit conforme l'expression rationnelle. Il ne suffit pas qu'un fragment (une sous-chane) de celui-ci soit conforme. Le contenu abc123xyz n'est, par exemple, pas conforme l'expression \d{3} bien que le fragment 123 le soit. Les ancres '^' et '$' [Section 6.3.4] sont implicitement ajoutes l'expression. Pour avoir une expression qui accepte ventuellement un fragment du contenu, il suffit d'ajouter .* au dbut et la fin de celle-ci. Le contenu abc123xyz est, par exemple, conforme l'expression .*\d^{3}.*.
74
Schmas XML
Ces quatre facettes donnent des valeurs minimale et maximale en incluant ou non la borne donne. Ces facettes s'appliquent tous les types numriques [Section 5.5.1.1] ainsi qu' tous les types de date et d'heure [Section 5.5.1.3]. xsd:fractionDigits et xsd:totalDigits Ces deux facettes fixent respectivement le nombre maximal de chiffres de la partie fractionnaire ( droite de la virgule) et le nombre maximal de chiffres en tout. Il s'agit de valeurs maximales. Il n'est pas possible de spcifier des valeurs minimales. De mme, il n'est pas possible de spcifier le nombre maximal de chiffres de la partie entire ( gauche de la virgule). Ces deux facettes s'appliquent uniquement aux types numriques drivs de xsd:decimal. Ceci inclut tous les types entiers mais exclut les types xsd:float et xsd:double. xsd:whiteSpace Cette facette est particulire. Elle ne restreint pas les valeurs valides mais elle modifie le traitement des caractres d'espacement [Section 2.2.2] l'analyse lexicale. Cette facette peut prendre les trois valeurs preserve, replace et collapse qui correspondent trois modes de fonctionnement de l'analyseur lexical. preserve Dans ce mode, les caractres d'espacement sont laisss inchangs par l'analyseur lexical. replace Dans ce mode, chaque caractre d'espacement est remplac par un espace #x20. Le rsultat est donc du type prdfini xsd:normalizedString [Section 5.5.1.2]. collapse Dans ce mode, le traitement du mode prcdent replace est d'abord appliqu puis les espaces en dbut et en fin sont supprims et les suites d'espaces conscutifs sont remplaces par un seul espace. Le rsultat est donc du type prdfini xsd:token [Section 5.5.1.2] Cette facette ne s'applique qu'aux types drivs de xsd:string. Une drivation ne peut que renforcer le traitement des caractres d'espacement en passant d'un mode un mode plus strict (preserve replace collapse). Les changements dans l'autre sens sont impossibles.
75
Schmas XML
</xsd:complexType> <!-- Restriction du type de base --> <xsd:complexType name="Derived"> <xsd:simpleContent> <xsd:restriction base="Base"> <!-- Nouveau type pour le contenu du type Derived --> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="32"/> </xsd:restriction> </xsd:simpleType> </xsd:restriction> </xsd:simpleContent> </xsd:complexType> ... </xsd:schema> La restriction peut aussi changer les types des attributs et leur utilisation. Les attributs dont certaines proprits changent sont redclars dans le nouveau type. Les autres restent implicitement inchangs. Le type d'un attribut peut tre remplac par un type obtenu par restriction. Ce type peut, bien sr, tre nomm ou anonyme. L'utilisation des attributs aussi tre restreinte. Un attribut optionnel peut devenir interdit avec use="prohibited" ou obligatoire avec use="required". L'inverse est en revanche interdit. Il est galement impossible d'ajouter de nouveaux attributs. Si un attribut possde une valeur par dfaut ou une valeur fixe, celle-ci ne peut tre ni modifie ni supprime. Dans le schma suivant, le type de base Base possde plusieurs attributs dont le type driv Derived modifie l'utilisation. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base --> <xsd:complexType name="Base"> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="decimal" type="xsd:decimal"/> <xsd:attribute name="string" type="xsd:string"/> <xsd:attribute name="optional" type="xsd:string"/> <xsd:attribute name="required" type="xsd:string" use="required"/> <xsd:attribute name="fixed" type="xsd:string" fixed="Fixed"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> <xsd:complexType name="Derived"> <xsd:simpleContent> <xsd:restriction base="Base"> <!-- Restriction du type de l'attribut --> <xsd:attribute name="decimal" type="xsd:integer"/> <!-- Le nouveau type doit tre driv du type initial --> <xsd:attribute name="decimal" type="xsd:string"/> <!-- Restriction du type de l'attribut avec un type anonyme --> <xsd:attribute name="string"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="32"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> <!-- Restriction de l'utilisation de l'attribut --> <xsd:attribute name="optional" type="xsd:string" use="required"/>
76
Schmas XML
<!-- Impossible d'tendre l'utilisation de l'attribut --> <xsd:attribute name="required" type="xsd:string" /> <!-- Impossible de changer ou supprimer la valeur fixe --> <xsd:attribute name="fixed" type="xsd:string"/> <!-- Impossible d'ajouter un nouvel attribut --> <xsd:attribute name="newattr" type="xsd:string"/> </xsd:restriction> </xsd:simpleContent> </xsd:complexType> ... </xsd:schema> Il est encore possible de changer simultanment le type du contenu et certaines proprits des attributs. Dans le schma suivant, le type est restreint au chanes d'au plus 32 caractres et le type de l'attribut decimal est chang en le type xsd:integer. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base --> <xsd:complexType name="Base"> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="decimal" type="xsd:decimal"/> <xsd:attribute name="unchanged" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> <xsd:complexType name="Derived"> <xsd:simpleContent> <xsd:restriction base="Base"> <xsd:simpleType> <!-- Nouveau type pour le contenu du type Derived --> <xsd:restriction base="xsd:string"> <xsd:maxLength value="32"/> </xsd:restriction> </xsd:simpleType> <!-- Restriction du type de l'attribut --> <xsd:attribute name="decimal" type="xsd:integer"/> <!-- Attribut unchanged inchang --> </xsd:restriction> </xsd:simpleContent> </xsd:complexType> ... </xsd:schema>
77
Schmas XML
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="names"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="name" type="Name"/> <xsd:element name="shortname" type="Shortname"/> </xsd:choice> </xsd:complexType> </xsd:element> <!-- Type de base --> <xsd:complexType name="Name"> <xsd:sequence> <!-- Nombre illimit d'occurrences de l'lment firstname --> <xsd:element name="firstname" type="xsd:string" maxOccurs="unbounded"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:ID"/> </xsd:complexType> <!-- Restriction du type Name --> <xsd:complexType name="Shortname"> <xsd:complexContent> <xsd:restriction base="Name"> <xsd:sequence> <!-- Nombre limit d'occurrences de l'lment firstname --> <xsd:element name="firstname" type="xsd:string" maxOccurs="1"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> <!-- Attribut id obligatoire --> <xsd:attribute name="id" type="xsd:ID" use="required"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="no" ?> <names xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <name> <firstname>Elizabeth II</firstname> <firstname>Alexandra</firstname> <firstname>Mary</firstname> <lastname>Windsor</lastname> </name> <shortname id="id-42"> <firstname>Bessiewallis</firstname> <lastname>Warfield</lastname> </shortname> </names> Il est aussi possible de restreindre un type complexe en remplaant le type d'un lment par un type driv. Dans l'exemple suivant, le type de l'lment integer est xsd:integer dans le type Base. Ce type est remplac par le type xsd:nonNegativeInteger dans le type Restriction. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="Base"> <xsd:sequence> <xsd:element name="integer" type="xsd:integer"/>
78
Schmas XML
</xsd:sequence> </xsd:complexType> <xsd:complexType name="Restriction"> <xsd:complexContent> <xsd:restriction base="Base"> <xsd:sequence> <xsd:element name="integer" type="xsd:nonNegativeInteger"/> </xsd:sequence> </xsd:restriction> </xsd:complexContent> </xsd:complexType> ... </xsd:schema> Une restriction d'un type complexe contenu complexe peut aussi supprimer un des choix possibles dans un lment xsd:choice. Dans l'exemple suivant, le choix integer a t supprim dans le type Float. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base --> <xsd:complexType name="Number"> <xsd:choice> <xsd:element name="integer" type="xsd:integer"/> <xsd:element name="float" type="xsd:float"/> <xsd:element name="double" type="xsd:double"/> </xsd:choice> </xsd:complexType> <!-- Restriction du type de base --> <xsd:complexType name="Float"> <xsd:complexContent> <xsd:restriction base="Number"> <xsd:choice> <!-- Suppression de l'lment integer --> <xsd:element name="float" type="xsd:float"/> <xsd:element name="double" type="xsd:double"/> </xsd:choice> </xsd:restriction> </xsd:complexContent> </xsd:complexType> ... </xsd:schema> Le document suivant est valide pour le schma prcdent. Il utilise une substitution de type [Section 5.10.2] avec l'attribut xsi:type pour changer le type de l'lment number en Float. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <numbers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <number> <integer>42</integer> </number> <number xsi:type="Float"> <!-- lment integer impossible --> <integer>42</integer> <float>3.14</float> </number> </numbers>
5.10. Substitutions
79
Schmas XML
Les schmas XML prvoient plusieurs mcanismes de substitution au niveau des types et des lments. Dans la substitution de type, un document peut changer explicitement le type associ un lment afin d'y placer un contenu diffrent de celui prvu par le schma. La substitution d'lments va encore plus loin. Un document peut remplacer un lment par un autre lment. Les substitutions ne sont pas toujours possibles. Une premire condition pour qu'elles puissent s'effectuer est que les types soient compatibles. Il faut que le type de substitution soit un type driv du type initial. Les substitutions sont donc troitement lies aux diffrentes faons d'obtenir des types drivs par extension ou restriction. Une seconde condition pour rendre possible les substitutions est que celles-ci doivent tre autorises par le schma. Les schmas possdent diffrents outils pour contrler les substitutions [Section 5.10.4].
5.10.1. Annihilation
L'annihilation est un mcanisme qui permet de mettre aucun contenu un lment alors que le type de l'lment prvoit que le contenu est normalement non vide. Cette notion correspond l'absence de valeur telle qu'elle peut apparatre dans les bases de donnes. Le schma doit d'abord autoriser le mcanisme en donnant la valeur true l'attribut nillable de l'lment xsd:element. La valeur par dfaut de cet attribut est false. Le document doit ensuite, explicitement, dclarer que l'lment n'a pas de valeur en donnant la valeur true l'attribut xsi:nil qui est dans l'espace de noms des instances de schmas. Le contenu de l'lment doit alors tre vide. Dans le schma suivant, l'lment item est dclar annihilable. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="list"> <xsd:complexType> <xsd:sequence> <xsd:element name="item" nillable="true" maxOccurs="unbounded" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Le document suivant est valide pour ce schma. L'lment item peut avoir un contenu vide si on lui ajoute un attribut xsi:nil avec la valeur true. <?xml version="1.0" encoding="iso-8859-1"?> <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- Contenu normal --> <item>123</item> <!-- Contenu annihil --> <item xsi:nil="true"></item> <!-- Contenu ncessairement vide --> <item xsi:nil="true"> </item> <item>789</item> </list>
80
Schmas XML
<?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.liafa.jussieu.fr/~carton/"> <xsd:element name="name" type="Name"/> ... <xsd:complexType name="Name"> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Fullname"> <xsd:complexContent> <xsd:extension base="Name"> <xsd:sequence> <xsd:element name="title" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:ID"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:schema> Le document suivant est valide pour ce schma. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <tns:names xmlns:tns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- lment name avec le type tns:Name --> <tns:name> <firstname>Bessiewallis</firstname> <lastname>Warfield</lastname> </tns:name> <!-- lment name avec le type tns:Fullname --> <tns:name id="id52" xsi:type="tns:Fullname"> <firstname>Elizabeth II Alexandra Mary</firstname> <lastname>Windsor</lastname> <title>Queen of England</title> </tns:name> </tns:names> L'attribut xsi:type peut aussi changer le type d'un lment en un autre type obtenu par restriction du type original. Dans l'exemple suivant, un type Byte est dclar par restriction du type prdfini xsd:nonNegativeInteger. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" xmlns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="value" type="xsd:integer"/> ... <xsd:simpleType name="Byte"> <xsd:restriction base="xsd:nonNegativeInteger"> <xsd:maxInclusive value="255"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>
81
Schmas XML
Le document suivant est valide pour ce schma. Il est possible de changer le type de l'lment value en xsd:nonNegativeInteger car ce type prdfini drive du type prdfini xsd:integer. Cet exemple illustre aussi l'utilisation indispensable des espaces de noms. Il est, en effet, ncessaire de dclarer trois espaces de noms : celui des lments du document, celui des schmas pour le type xsd:nonNegativeInteger et celui des instances de schmas pour l'attribut xsi:type. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <tns:values xmlns:tns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <tns:value>-1</tns:value> <tns:value xsi:type="xsd:nonNegativeInteger">256</tns:value> <tns:value xsi:type="tns:Byte">255</tns:value> </tns:values>
82
Schmas XML
<negative>-1</negative> </integers> Un lment donn est ncessairement le chef d'un unique groupe puisque chaque groupe est identifi par son chef. De mme, un mme lment ne peut appartenir qu' au plus un groupe puisque l'attribut substitutionGroup de xsd:element ne peut contenir qu'un seul nom d'lment. La version 1.1 des schmas autorise l'attribut substitutionGroup contenir plusieurs noms d'lments. Un lment peut ainsi appartenir plusieurs groupes de substitution. Les substitutions peuvent tre utilises en cascade. Un lment membre d'un groupe de substitution peut lui-mme tre chef d'un autre groupe de substitution. Les membres de ce dernier groupe peuvent bien sr remplacer leur chef de groupe mais aussi son chef de groupe. Dans le schma suivant, l'lment head est le chef d'un groupe comprenant l'lment subs. Cet lment subs est, son tour, chef d'un groupe de substitution comprenant l'lment subsubs. Cet lment subsubs peut dont remplacer l'lment subs mais aussi l'lment head. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- L'lment chef de groupe --> <xsd:element name="head" type="xsd:string"/> <!-- Un lment subs pouvant se substituer head --> <xsd:element name="subs" type="xsd:string" substitutionGroup="head"/> <!-- Un lment subsubs pouvant se substituer subs et head --> <xsd:element name="subsubs" type="xsd:string" substitutionGroup="subs"/> <xsd:element name="heads"> <xsd:complexType> <xsd:sequence> <xsd:element ref="head" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <heads> <head>lment head original</head> <subs>Substitution de head par subs</subs> <subsubs>Substitution de head par subsubs</subsubs> </heads> Les dfinitions circulaires de groupes de substitution sont interdites. Un chef de groupe ne peut pas tre membre d'un groupe dont le chef serait lui mme membre d'un de ses groupes. Les dclarations suivantes ne sont donc pas valides. <xsd:element name="head" type="xsd:string" substitutionGroup="subs"/> <xsd:element name="subs" type="xsd:string" substitutionGroup="head"/> Les groupes de substitution permettent, quelquefois, de compenser les lacunes de l'oprateur xsd:all [Section 5.6.4]. Il est, en effet, possible de simuler un oprateur xsd:choice [Section 5.6.3] avec un lment abstrait et un groupe de substitution. Dans le schma suivant, l'lment number est abstrait. Il doit ncessairement tre remplac, dans un document, par un lment de son groupe de substitution, c'est--dire par un lment integer ou par un lment double. Il y a donc le choix entre un lment integer ou un lment double. Le type de l'lment number est xsd:anyType pour que les types xsd:integer et xsd:double des lments integer et double puissent en driver. <?xml version="1.0" encoding="iso-8859-1"?>
83
Schmas XML
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="properties"> <xsd:complexType> <xsd:sequence> <xsd:element ref="property" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="property"> <xsd:complexType> <xsd:all> <xsd:element name="key" type="xsd:string"/> <xsd:element ref="number"/> <xsd:element name="condition" type="xsd:string" minOccurs="0"/> </xsd:all> </xsd:complexType> </xsd:element> <xsd:element name="number" type="xsd:anyType" abstract="true"/> <xsd:element name="integer" type="xsd:integer" substitutionGroup="number"/> <xsd:element name="double" type="xsd:double" substitutionGroup="number"/> </xsd:schema>
bloque l'utilisation du type dans les bloque la prsence de l'lment dans les documents documents bloque la substitution du type dans les bloque la substitution de type pour cet documents lment dans les documents bloque la drivation de types dans le schma bloque l'ajout d'lments dans le groupe de substitution dans le schma
84
Schmas XML
Le type VeryShortString est obtenu par restriction du type ShortString. Il ne peut pas donner une nouvelle valeur xsd:maxLength. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base : restriction du type xsd:string --> <xsd:simpleType name="ShortString"> <xsd:restriction base="xsd:string"> <!-- Facette fixe --> <xsd:maxLength value="32" fixed="true"/> </xsd:restriction> </xsd:simpleType> <!-- Restriction du type ShortString --> <xsd:simpleType name="VeryShortString"> <xsd:restriction base="ShortString"> <!-- Facette modifie --> <xsd:minLength value="2"/> <!-- Facette impossible modifier --> <xsd:maxLength value="16"/> </xsd:restriction> </xsd:simpleType> </xsd:schema> ... Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <strings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <string>Une chane assez courte</string> <string xsi:type="VeryShortString">Trs courte</string> </strings>
85
Schmas XML
</xsd:complexType> <!-- Type driv concret --> <xsd:complexType name="InternPrice"> <xsd:simpleContent> <xsd:restriction base="Price"> <xsd:attribute name="currency" type="xsd:string" use="required"/> </xsd:restriction> </xsd:simpleContent> </xsd:complexType> <!-- lment price de type abstrait --> <xsd:element name="price" type="Price"/> <!-- lment interprice de type concret substituable price --> <xsd:element name="internprice" type="InternPrice" substitutionGroup="price"/> <xsd:element name="prices"> <xsd:complexType> <xsd:sequence> <xsd:element ref="price" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Le document ci-dessous est valide pour le schma donn ci-dessus. L'lment price n'apparat pas avec le type Price qui est abstrait. Soit le type Price est remplac par le type driv InternPrice, soit l'lment price est remplac par l'lment internprice. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <prices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- lment de type Price non autoris --> <price>78.9</price> <!-- Substitution de type --> <price xsi:type="InternPrice" currency="euro">12.34</price> <!-- Substitution d'lment --> <internprice currency="dollar">45.56</internprice> </prices> Dans l'exemple suivant, on dfinit un type abstrait AbstractType sans contrainte. Ce type est alors quivalent au type xsd:anyType. On drive ensuite deux types par extension Derived1 et Derived2. Le premier type Derived1 dclare un attribut att de type xsd:string et un lment string comme unique contenu. Le second type Derived2 ne dclare aucun attribut mais il dclare un contenu constitu d'un lment string suivi d'un lment integer. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" xmlns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="value" type="Abstract"/> <xsd:element name="values"> <xsd:complexType> <xsd:sequence> <xsd:element ref="value" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:complexType name="Abstract" abstract="true"/> <xsd:complexType name="Derived1"> <xsd:complexContent> <xsd:extension base="Abstract">
86
Schmas XML
<xsd:sequence> <xsd:element name="string" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="att" type="xsd:string"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="Derived2"> <xsd:complexContent> <xsd:extension base="Abstract"> <xsd:sequence> <xsd:element name="string" type="xsd:string"/> <xsd:element name="integer" type="xsd:integer"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:schema> Le document suivant est valide pour ce schma. L'lment value apparat deux fois dans le document mais avec respectivement les types Derived1 et Derived2. Ces types sont dclars l'aide de l'attribut xsi:type. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <tns:values xmlns:tns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- lment value de type Abstract impossible --> <tns:value xsi:type="tns:Derived1" att="avec un attribut"> <string>Une chane</string> </tns:value> <tns:value xsi:type="tns:Derived2"> <string>Un entier</string> <integer>-1</integer> </tns:value> </tns:values>
87
Schmas XML
<xsd:length value="27"/> </xsd:restriction> </xsd:simpleType> ... Le document suivant est valide pour le schma prcdent. L'lment abstrait value n'apparat pas. Il est systmatiquement remplac par l'lment other. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <values xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- lment value impossible --> <value>Une chane d'une autre longueur</value> <!-- lment value impossible mme avec une substitution de type --> <value xsi:type="String27">Une chane de 27 caractres</value> <!-- Substitution d'lment --> <other>Une chane de mme longueur</other> </values>
88
Schmas XML
</xsd:complexContent> </xsd:complexType> <!-- Type obtenu par restriction du type de base --> <xsd:complexType name="Restriction"> <xsd:complexContent> <xsd:restriction base="Base"> <xsd:sequence> <xsd:element name="integer" type="xsd:nonNegativeInteger"/> </xsd:sequence> </xsd:restriction> </xsd:complexContent> </xsd:complexType> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <values xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <value> <integer>-1</integer> </value> <!-- Substitution autorise avec le mme type --> <sametype> <integer>-1</integer> </sametype> <!-- lment substitu d'un type driv impossible --> <subst att="Un attribut"> <integer>-1</integer> </subst> <!-- lment value de type Extension impossible --> <value xsi:type="Extension" att="Un attribut"> <integer>1</integer> </value> <!-- lment value de type Restriction impossible --> <value xsi:type="Restriction"> <integer>1</integer> </value> </values> L'attribut block bloque la substitution par un type dont une des tapes de drivation et pas seulement la premire tape est mentionne dans ses valeurs. Si, par exemple, l'attribut block d'une dfinition de type contient extension, seuls les types obtenus par restrictions successives de ce type peuvent le remplacer. Dans le schma suivant, le type List bloque sa substitution par un type obtenu par extension. Le type ShortList est obtenu par restriction du type List et le type AttrShortList est obtenu par extension du type ShortList. Le type ShortList peut se substituer au type List. Au contraire, le type AttrShortList ne peut pas se substituer au type List car il y a une drivation par extension entre le type List et le type AttrShortList. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base ne pouvant pas tre substitu par une extension --> <xsd:complexType name="List" block="extension"> <xsd:sequence> <xsd:element name="item" type="xsd:string" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <!-- Restriction du type de base --> <xsd:complexType name="ShortList">
89
Schmas XML
<xsd:complexContent> <xsd:restriction base="List"> <xsd:sequence> <!-- Nombre limit d'lments item --> <xsd:element name="item" type="xsd:string" maxOccurs="8"/> </xsd:sequence> </xsd:restriction> </xsd:complexContent> </xsd:complexType> <!-- Extension de la restriction du type de base --> <xsd:complexType name="AttrShortList"> <xsd:complexContent> <xsd:extension base="ShortList"> <!-- Ajout d'un attribut --> <xsd:attribute name="length" type="xsd:integer"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="list" type="List"/> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <!-- Type ShortList possible mais type AttrShortList impossible --> <list xsi:type="ShortList" xsi:type="AttrShortList" length="3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <item>Premier item</item> <item>Deuxime item</item> <item>Troisime item</item> </list>
90
Schmas XML
</xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <integers xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <integer>0</integer> <!-- Substitution par un lment de mme type --> <sametype>1</sametype> <!-- Substitution de type impossible --> <integer xsi:type="xsd:positiveInteger">1</integer> <!-- Substitution d'lment avec un type driv impossible --> <positive>1</positive> </integers> L'attribut block de l'lment xsd:element peut aussi contenir la valeur substitution. Cette valeur a un effet trs proche de l'attribut final avec la valeur #all. Elle empche les lments du groupe de substitution de se substituer dans les documents instance. Cela anihile l'intret d'avoir des lments dans le groupe de substitution puisque ceux-ci ne peuvent pas rellement se substituer leur chef de groupe. Dans le schma suivant, les lments sametype et positive appartiennent au groupe de substitution de l'lment integer. En rechanche, ils ne peuvent pas se substituer cet lment en raison de la valeur substitution de l'attribut block. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="integer" type="xsd:integer" block="substitution"/> <!-- lment avec le mme type --> <xsd:element name="sametype" type="xsd:integer" substitutionGroup="integer"/> <!-- lment avec un type obtenu par restriction --> <xsd:element name="positive" type="xsd:positiveInteger" substitutionGroup="integer"/> ... </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <integers xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <integer>0</integer> <!-- Substitution de type --> <integer xsi:type="xsd:positiveInteger">1</integer> <!-- Substitution d'lment avec le mme type impossible --> <sametype>1</sametype> <!-- Substitution d'lment avec un type driv impossible --> <positive>1</positive> </integers>
91
Schmas XML
valeur de cet attribut est soit la chane #all soit une liste de valeurs parmi les valeurs restriction, list et union. Il est donc impossible de bloquer les extensions d'un type simple. Pour un type complexe, la valeur de cet attribut est soit la chane #all soit une liste de valeurs parmi les valeurs extension, restriction. Les valeurs numres ou toutes pour #all bloquent les diffrentes faons de dfinir des nouveaux types. La valeur par dfaut de cet attribut est donne par la valeur de l'attribut finalDefault de l'lment xsd:schema. Le schma suivant n'est pas correct car les dfinitions des types Extension et Restriction sont impossibles en raison de la valeur #all de l'attribut final dans la dfinition du type Base. Si la valeur de cet attribut final est change en restriction, la dfinition du type Restriction reste incorrecte mais la dfinition du type Extension devient correcte. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> ... <!-- L'attribut final="#all" empche les restrictions et extensions --> <xsd:complexType name="Base" final="#all"> <xsd:sequence> <xsd:element name="integer" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> <!-- Extension du type Base impossible --> <xsd:complexType name="Extension"> <xsd:complexContent> <xsd:extension base="Base"> <xsd:attribute name="att" type="xsd:string"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <!-- Restriction du type Base impossible --> <xsd:complexType name="Restriction"> <xsd:complexContent> <xsd:restriction base="Base"> <xsd:sequence> <xsd:element name="integer" type="xsd:nonNegativeInteger"/> </xsd:sequence> </xsd:restriction> </xsd:complexContent> </xsd:complexType> </xsd:schema> Le bloquage impos par l'attribut final n'opre que sur la drivation directe de types. Dans le schma suivant, le type List bloque les extensions avec final="extension". Le type ShortList est driv par restriction du type List. Ce type peut tre tendu en un type AttrShortList. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Type de base bloquant les extensions --> <xsd:complexType name="List" final="extension"> <xsd:sequence> <xsd:element name="item" type="xsd:string" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <!-- Restriction du type de base --> <xsd:complexType name="ShortList"> <xsd:complexContent> <xsd:restriction base="List"> <xsd:sequence> <!-- Nombre limit d'lments item --> <xsd:element name="item" type="xsd:string" maxOccurs="8"/>
92
Schmas XML
</xsd:sequence> </xsd:restriction> </xsd:complexContent> </xsd:complexType> <!-- Extension de la restriction du type de base --> <xsd:complexType name="AttrShortList"> <xsd:complexContent> <xsd:extension base="ShortList"> <!-- Ajout d'un attribut --> <xsd:attribute name="length" type="xsd:integer"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="list" type="List"/> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <list length="3" xsi:type="AttrShortList" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <item>Premier item</item> <item>Deuxime item</item> <item>Troisime item</item> </list> La diffrence entre les attributs final et block est que final concerne la dfinition de types drivs alors que block concerne l'utilisation des types drivs dans les documents instance.
93
Schmas XML
<xsd:extension base="xsd:integer"> <xsd:attribute name="att" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> ... </xsd:schema> Le document suivant est valide pour le schma prcdent. L'lment attributed ne peut pas se substituter l'lment integer. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <integers> <integer>0</integer> <!-- Substitution lment --> <positive>1</positive> <!-- lment attributed impossible --> <attributed att="Un attribut">-1</attributed> </integers>
94
Schmas XML
</xsd:choice> </xsd:group> <xsd:complexType name="Person"> <xsd:sequence> <xsd:element name="surname" type="xsd:string" minOccurs="0"/> <xsd:group ref="Name"/> </xsd:sequence> </xsd:complexType> <xsd:element name="characters"> <xsd:complexType> <xsd:sequence> <xsd:element name="character" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:group ref="Name"/> <xsd:element name="creator" type="Person" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <characters> <character> <firstname>Gaston</firstname> <lastname>Lagaffe</lastname> <creator> <firstname>Andr</firstname> <lastname>Franquin</lastname> </creator> </character> <character> <name>Astrix</name> <creator> <surname>Al Uderzo</surname> <firstname>Albert</firstname> <lastname>Uderzo</lastname> </creator> <creator> <firstname>Ren</firstname> <lastname>Goscinny</lastname> </creator> </character> Un groupe est en fait un fragment de type qui peut tre utilis l'intrieur de la dfinition de n'importe quel type. En revanche, il ne peut pas servir comme type dans la dclaration d'un l'lment. l'inverse, un type peut servir dans la dclaration d'lments mais il ne peut pas tre directement inclus par un autre type. Les groupes sont en fait un mcanisme d'abrviation. Ils permettent d'accrotre la modularit des schmas en vitant de recopier plusieurs fois le mme fragment dans la dfinition de diffrents types.
Schmas XML
Les groupes d'attributs jouent, pour les attributs, un rle similaire aux groupes d'lments. Ils permettent de regrouper plusieurs dclarations d'attributs dans le but d'une rutilisation. L'lment xsd:attributeGroup permet de dfinir un groupe d'attributs dont le nom est donn par l'attribut name. L'lment xsd:attributeGroup doit tre enfant de l'lment racine xsd:schema du schma. Ceci signifie que la porte de la dfinition du groupe est le schma dans son intgralit. Le contenu de l'lment xsd:attributeGroup est constitu de dclarations d'attributs introduites par l'lment xsd:attribute. Dans l'exemple suivant, le groupe d'attributs LangType regroupe les dclaration des deux attributs lang et type. <xsd:attributeGroup name="LangType"> <xsd:attribute name="lang" type="xsd:language"/> <xsd:attribute name="type" type="xsd:string"/> </xsd:attributeGroup>
Un groupe d'attributs peut tre employ dans la dfinition d'un type ou la dfinition d'un autre groupe d'attributs. L'utilisation d'un groupe est quivalente l'insertion de son contenu. L'utilisation d'un groupe est introduite par un lment xsd:attributeGroup avec un attribut ref qui donne le nom du groupe insrer. Le groupe d'attributs LangType peut tre employ de la faon suivante dans la dfinition d'un type complexe nomm ou anonyme. Tout lment du type SomeType dfini ci-dessous pourra avoir les attributs lang et type dclars dans le groupe LangType. <xsd:complexType name="SomeType"> <!-- Contenu --> ... <xsd:attributeGroup ref="LangType"/> </xsd:complexType> Il est possible d'utiliser successivement plusieurs groupes d'attributs pour dclarer les attributs d'un type mais il faut une occurrence de xsd:attributeGroup pour chaque groupe utilis. <xsd:attributeGroup ref="AttrGroup1"/> <xsd:attributeGroup ref="AttrGroup2"/> Un groupe d'attributs peut aussi tre utilis dans la dfinition d'un autre groupe d'attributs. Le nouveau groupe dfini contient tous les attributs du ou des groupes rfrencs en plus des attributs qu'il dclare explicitement. Ce mcanisme est semblable l'hritage des classes dans les langages de programmation objet. <xsd:attributeGroup name="LangTypeClass"> <xsd:attributeGroup ref="LangType"/> <xsd:attribute name="class" type="xsd:string"/> </xsd:attributeGroup>
Le schma l'adresse http://www.w3.org/2001/xml.xsd [Section 5.14] dclare les quatre attributs particuliers [Section 2.7.4] xml:lang, xml:space, xml:base et xml:id. Il dfinit galement un groupe d'attributs xml:specialAttrs permettant de dclarer simultanment ces quatre attributs. Cet exemple montre que les noms des groupes d'lments et des groupes d'attributs sont des noms qualifis dans l'espace de noms cible du schma.
96
Schmas XML
des lments ou des attributs. La porte de ces contraintes peut tre n'importe quel contenu d'lment et non pas l'intgralit du document comme dans les DTD. Ces contraintes sont de deux types. Elles peuvent tre des contraintes d'unicit comme celle des attributs de type ID des DTD ou des contraintes d'existence comme celle des attributs de type IDREF et IDREFS des DTD. Les contraintes utilisent des expressions XPath [Chapitre 6] mais une connaissance superficielle de ce langage suffit pour les utiliser.
97
Schmas XML
revanche, deux lments person contenus dans des lments group diffrents peuvent avoir la mme valeur d'attribut id. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="groups"> <xsd:complexType> <xsd:sequence> <xsd:element ref="group" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <!-- Unicit des attributs num des lments group --> <xsd:unique name="group.num"> <xsd:selector xpath="group"/> <xsd:field xpath="@num"/> </xsd:unique> </xsd:element> <xsd:element name="group"> <xsd:complexType> <xsd:sequence> <xsd:element name="person" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="num" type="xsd:integer"/> </xsd:complexType> <!-- Unicit des attributs id des lments person --> <xsd:key name="person.id"> <xsd:selector xpath="person"/> <xsd:field xpath="@id"/> </xsd:key> </xsd:element> </xsd:schema> Le document suivant est valide pour le schma prcdent. Deux lments person contenus respectivement dans le premier et le deuxime lment group ont la mme valeur AC pour l'attribut id. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <groups> <group num="1"> <person id="AC"> <firstname>Albert</firstname> <lastname>Cohen</lastname> </person> <person id="VH"> <firstname>Victor</firstname> <lastname>Hugo</lastname> </person> </group> <group num="2"> <person id="AC"> <firstname>Anders</firstname> <lastname>Celsius</lastname>
98
Schmas XML
99
Schmas XML
<xsd:field xpath="@id"/> </xsd:key> <xsd:key name="person.names"> <xsd:selector xpath="person"/> <xsd:field xpath="firstname"/> <xsd:field xpath="lastname"/> </xsd:key>
100
Schmas XML
Dans l'exemple suivant, la contrainte d'unicit idchapter impose que la valeur d'un attribut id d'un lment chapter soit unique. La contrainte d'existence idref utilise cette contrainte idchapter pour imposer que la valeur d'un attribut idref de tout lment ref soir aussi la valeur d'un attribut id d'un lment chapter. Ceci signifie que tout lment ref rfrence, par son attribut idref, un chapitre qui existe bien dans le document. <!-- Unicit des attributs id des lments chapter --> <xsd:key name="idchapter"> <xsd:selector xpath="chapter"/> <xsd:field xpath="@id"/> </xsd:key> <!-- Existence des rfrences idref des lments ref --> <xsd:keyref name="idref" refer="idchapter"> <xsd:selector xpath=".//ref"/> <xsd:field xpath="@idref"/> </xsd:keyref> Dans l'exemple prcdent, la valeur d'un des attributs xpath est l'expression .//ref qui slectionne tous les descendants de nom ref de l'lment courant. Cette expression est en fait une abrviation [Section 6.7] de l'expression ./descendant-or-self::node()/ref.
101
Schmas XML
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="list"> <xsd:complexType> <xsd:sequence> <xsd:element name="orders" type="Orders"/> <xsd:element name="catalog" type="Catalog"/> </xsd:sequence> <xsd:attribute name="period" type="xsd:duration"/> </xsd:complexType> <!-- Unicit du couple (date,heure) --> <xsd:unique name="dummy"> <xsd:selector xpath="orders/order"/> <xsd:field xpath="@date"/> <xsd:field xpath="@time"/> </xsd:unique> <!-- Unicit du numro de srie --> <xsd:key name="serial"> <xsd:selector xpath="catalog/product"/> <xsd:field xpath="@serial"/> </xsd:key> <!-- Existence dans le catalogue de tout produit command --> <xsd:keyref name="unused" refer="serial"> <xsd:selector xpath="orders/order/product"/> <xsd:field xpath="@serial"/> </xsd:keyref> </xsd:element> <!-- Suite du schma --> ...
102
Schmas XML
l'lment name est dans l'espace de noms http://www.liafa.jussieu.fr/~carton/ alors que les lments firstname et lastname sont sans espace de noms. <?xml version="1.0" encoding="iso-8859-1"?> <!-- unqualified est la valeur par dfaut de elementFormDefault --> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" elementFormDefault="unqualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="name"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Un document valide pour ce schma est le suivant. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <tns:name xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <firstname>Gaston</firstname> <lastname>Lagaffe</lastname> </tns:name> Si la valeur de l'attribut elementFormDefault est qualified, tous les lments sont dans l'espace de noms cible. Dans le schma suivant, les trois lments name, firstname et lastname sont dans l'espace de noms http://www.liafa.jussieu.fr/~carton/. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="name"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Un document valide pour ce schma est le suivant. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <tns:name xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <tns:firstname>Gaston</tns:firstname> <tns:lastname>Lagaffe</tns:lastname> </tns:name>
Le comportement pour les attributs est identique mais il est gouvern par l'attribut attributeFormDefault de l'lment xsd:schema. La valeur par dfaut de cet attribut est aussi unqualified. Les lments et attributs dfinis globalement sont toujours dans l'espace de noms cible. Pour les lments et attributs locaux, il est possible de changer le comportement dict par elementFormDefault et attributeFormDefault en utilisant l'attribut form des lments xsd:element et xsd:attribute.
103
Schmas XML
Cet attribut peut prendre les valeurs qualified ou unqualified. Le schma suivant spcifie que l'lment firstname doit tre qualifi. Tous les autres lments locaux comme lastname n'ont pas tre qualifis car la valeur par dfaut de l'attribut elementFormDefault est unqualified. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="name"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string" form="qualified"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Un document valide pour ce schma est le suivant. <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <tns:name xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <tns:firstname>Gaston</tns:firstname> <lastname>Lagaffe</lastname> </tns:name>
104
Schmas XML
qui pourrait tre ajoute au schma prcdent. La dfinition de ce type est rcursive et la rfrence lui-mme utilise bien sr le nom qualifi. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" xmlns:tns="http://www.liafa.jussieu.fr/~carton/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- Dclaration des lments globaux name et tree --> <xsd:element name="name" type="xsd:string"/> <!-- Rfrence au type Tree par son nom qualifi --> <xsd:element name="tree" type="tns:Tree"/> <xsd:complexType name="Tree"> <xsd:sequence> <!-- Rfrence l'lment global name par son nom qualifi --> <xsd:element ref="tns:name"/> <!-- Rfrence rcursive au type Tree par son nom qualifi --> <!-- Le nom child de l'lment dclar n'est pas qualifi --> <xsd:element name="child" type="tns:Tree" minOccurs="0" maxOccurs="2"/> </xsd:sequence> </xsd:complexType> </xsd:schema> L'utilisation de minOccurs avec la valeur 0 pour l'lment child est indispensable pour terminer la rcursivit. Sinon, aucun document valide ne peut avoir d'lment de type Tree. Le document suivant est valide pour le schma prcdent. <?xml version="1.0" encoding="iso-8859-1"?> <tns:tree xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <tns:name>Racine</tns:name> <child> <tns:name>Fils Gauche</tns:name> <child><tns:name>Petit fils</tns:name></child> </child> <child><tns:name>Fils Droit</tns:name></child> </tns:tree> Il est souvent assez lourd de qualifier chacun des noms des objets dfinis dans le schma. Une alternative assez commode consiste rendre l'espace de noms par dfaut gal l'espace de noms cible comme dans l'exemple suivant. Ceci impose bien sr de ne pas utiliser l'espace de noms par dfaut pour les lments des schmas comme il pourrait tre tentant de le faire. Dans la pratique, on associe l'espace de noms par dfaut l'espace de noms cible et on dclare galement un prfixe pour cet espace de noms afin de pouvoir y faire rfrence de faon explicite. Dans l'exemple suivant, l'espace de noms cible http://www.liafa.jussieu.fr/~carton/ est dclar comme l'espace de noms par dfaut et il est galement associ au prfixe tns. <?xml version="1.0" encoding="iso-8859-1"?> <xsd:schema targetNamespace="http://www.liafa.jussieu.fr/~carton/" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.liafa.jussieu.fr/~carton/" xmlns:tns="http://www.liafa.jussieu.fr/~carton/"> <!-- Rfrence au type Name par son nom qualifi --> <xsd:element name="name" type="Name" /> <!-- Dfinition du type Name --> <xsd:complexType name="Name"> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence>
105
Schmas XML
</xsd:complexType> </xsd:schema>
106
Schmas XML
caractres '|', '?', '*', '+', '.', '\', '(', ')', '[', ']', '{', '}. Pour supprimer le caractre spcial d'un de ces caractres et l'inclure dans une expression, il faut le faire prcder du caractre d'chappement '\'. Quelques caractres d'espacement [Section 2.2.2] bnificient de notations spcifiques. La tabulation U+09, le saut de ligne U+0A et le retour chariot U+0D peuvent tre dsigns par '\t', '\n' et '\r'. Ces notations ne sont pas indispensables puisque ces trois caractres peuvent tre insrs dans un document XML avec la notation &#....
5.15.1. Oprateurs
Les principaux oprateurs des expressions rationnelles sont l'union dsigne par le caractre '|', la concatnation note par simple juxtaposition et les oprateurs de rptition '?', '*', '+'. Comme pour les expressions arithmtiques, on peut utiliser les parenthses '(' et ')' pour former des groupes. Une expression de la forme expr-1|expr-2 dsigne l'union des ensembles de chanes dsigns par expr-1 et expr-2. L'expression a|b dsigne, par exemple, l'ensemble contenant les deux chanes 'a' et 'b' (sans les apostrophes). Une expression de la forme expr-1expr-2 dsigne l'ensemble des chanes obtenue en concatnant (c'est--dire en mettant bout bout) une chane conforme l'expression expr-1 et une chane conforme l'expression expr-2. L'expression ab dsigne, par exemple, l'ensemble contenant l'unique chane ab. Il est, bien sr, possible de combiner ces oprateurs. L'expression aba|ba dsigne, par exemple, l'ensemble form des deux chanes aba et ba. L'expression a(a|b)bc dsigne l'ensemble contenant les deux chanes aabc et abbc.
5.15.2. Rptitions
Les oprateurs '?', '*', '+' permettent de rpter des groupes. Il utilisent une notation postfixe : ils se placent aprs leur oprande. S'ils sont placs aprs un caractre, ils s'appliquent uniquement celui-ci mais s'ils sont placs aprs un groupe entre parenthses, ils s'appliquent tout le groupe. Ils autorisent, respectivement, la rptition de leur oprande, zro ou une fois, un nombre quelconque de fois et un nombre positif de fois. Une expression de la forme expr? dsigne l'ensemble constitu de la chane vide et des chanes conformes l'expression expr. Une expression de la forme expr* dsigne l'ensemble constitu de toutes les chanes obtenues en concatnant plusieurs (ventuellement zro) chanes conformes l'expression expr. L'expression a? dsigne, par exemple, l'ensemble form de la chane vide et de la chane 'a'. Les expressions a* et (a|b)* dsignent, respectivement, les ensembles constitus des chanes formes uniquement de 'a' et les chanes formes de 'a' et de 'b'. Les accolades '{' et '}' permettent d'exprimer des rptitions dont le nombre est, soit un entier fix, soit dans un intervalle donn. Une expression de la forme expr{n}, o n est un entier, dsigne l'ensemble constitu de toutes les chanes obtenues en concatnant exactement n chanes conformes l'expression expr. Une expression de la forme expr{m,n}, o m et n sont des entiers, dsigne l'ensemble constitu de toutes les chanes obtenues en concatnant un nombre de chanes conformes l'expression expr compris, au sens large, entre m et n. L'entier n peut tre omis pour donner une expression de la forme expr{m,}. Le nombre de rptitions doit seulement tre suprieur m. L'expression (a|b){6} dsigne, par exemple, les chanes de longueur 6 formes de 'a' et de 'b'. L'expression (a|b){3,8} dsigne les chanes de longueur comprise entre 3 et 8 formes de 'a' et de 'b'.
107
Schmas XML
Lorsque le caractre le premier caractre aprs le crochet ouvrant est le caractre '^', l'expression dsigne le complmentaire de l'ensemble qui aurait t dcrit sans le caractre '^'. L'expression [^0-9] dsigne, par exemple, l'ensemble des caractres qui ne sont pas un chiffre. Pour inclure un caractre '^' dans l'ensemble, il faut le placer une autre place que juste aprs le crochet ouvrant. L'expression [0-9^] dsigne, par exemple, l'ensemble form des chiffres et du caractre '^'. Un ensemble de caractres peut tre dcrit comme la diffrence de deux ensembles entre crochet. La syntaxe prend la forme [...-[...]] o ... est remplac par une suite de caractres et d'intervalles comme dans les exemples prcdents. L'expression [a-z-[aeiouy]] dsigne, par exemple, l'ensemble des consonnes minuscules. Certains ensembles de caractres frquemment utiliss peuvent tre dcrits par le caractre d'chappement '\' suivi d'une lettre. Les diffrentes combinaisons possibles sont donnes ci-dessous. \s caractres d'espacement [Section 2.2.2], c'est--dire l'ensemble [ \t\n\r] \S caractres autres que les caractres d'espacement, c'est--dire l'ensemble [^ \t\n\r] \d chiffres, c'est--dire [0-9] \D caractres autres que les chiffres, c'est--dire [^0-9] \w caractres alphanumriques et le tiret '-', c'est--dire [-0-9a-zA-Z] \W caractres autres que les caractres alphanumriques et le tiret, c'est--dire [^-0-9a-zA-Z] \i premiers caractres des noms XML [Section 2.2.3], c'est--dire [:_a-zA-Z] \I caractres autres que les premiers caractres des noms XML, c'est--dire [^:_a-zA-Z] \c caractres des noms XML, c'est--dire [-.:_a-zA-Z] \C caractre autres que les caractres des noms XML, c'est--dire [^-.:_a-zA-Z] L'expression \s*\d+\s* dsigne, par exemple, une suite non vide de chiffres encadre, ventuellement, par des caractres d'espacement. L'expression \i\c* dsigne l'ensemble des noms XML. Il est aussi possible de dcrire un ensemble de caractres en utilisant une des catgories de caractres Unicode. La syntaxe prend la forme \p{cat} pour l'ensemble des caractres de la catgorie cat et \P{cat} pour son complmentaire. L'expression \p{Lu} dsigne, par exemple, toutes les lettres majuscules. Les principales catgories de caractres Unicode sont les suivantes.
108
Schmas XML
Catgorie L Lu Ll N P Z
Signification lettres lettres majuscules lettres minuscules chiffres caractre de ponctuation Sparateurs
109
Chapitre 6. XPath
XPath est un langage permettant de slectionner des parties d'un document XML. Il est utilis dans de nombreux dialectes XML. Dans cet ouvrage, il est dj apparu dans les contraintes de cohrence [Section 5.12] des schmas XML. Les schmatrons [Chapitre 7] du chapitre suivant sont essentiellement bass sur XPath. Le langage XSLT [Chapitre 8] fait galement un usage intensif de XPath pour dsigner les parties traiter. Le langage XPath n'est pas un langage autonome. C'est un langage d'expressions utilis au sein d'un autre langage hte. Il ressemble, dans cet aspect, aux expressions rationnelles, appeles aussi expressions rgulires qui est abrg en regex telles qu'elles sont utilises dans les langages de script tels que Perl ou Python. La syntaxe de XPath n'est pas une syntaxe XML car les expressions XPath apparaissent en gnral comme valeurs d'attributs de documents XML. C'est en particulier le cas pour les schmas, les schmatrons et XSLT. XPath tait au dpart un langage permettant essentiellement de dcrire des ensembles de nuds dans un document XML. La version 1.0 de XPath comprenait quelques fonctions pour la manipulation de nombres et de chanes de caractres. L'objectif tait alors de pouvoir comparer les contenus de nuds. La version 2.0 de XPath a considrablement enrichi le langage. Il est devenu un langage beaucoup plus complet capable, par exemple, de manipuler des listes de nuds et de valeurs atomiques. XPath est uniquement un langage d'expressions dont l'valuation donne des valeurs sans effet de bord. Il n'est pas possible dans XPath de mmoriser un rsultat. Il n'existe pas de variables propres XPath mais une expression XPath peut rfrencer des variables du langage hte. Les valeurs de ces variables sont alors utilises pour valuer l'expression. L'affectation de valeurs ces variables se fait uniquement au niveau du langage hte. Le langage XPath utilise aussi des variables propres particulires qui servent parcourir des listes. Ces variables s'apparentent aux variables du langage hte car elles ne sont jamais affectes explicitement. Leur porte est en outre toujours limite un oprateur d'itration comme for [Section 6.6.2]. Le cur de XPath est form des expressions de chemins permettant de dcrire des ensembles de nuds d'un document XML. Ces expressions ressemblent aux chemins Unix pour nommer des fichiers dans une arborescence.
110
XPath
element node Chaque lment du document est reprsent un nud de cette sorte. Le contenu texte de l'lment n'est pas contenu dans ce nud mais dans des nuds textuels. attribute node Chaque attribut est reprsent par un nud de cette sorte dont le parent est le nud de l'lment ayant cet attribut. La valeur de l'attribut est contenue dans le nud. comment node Chaque commentaire du document est reprsent par un nud de cette sorte qui contient le texte du commentaire. processing instruction node Chaque instruction de traitement est reprsente par un nud de cette sorte qui contient le texte de l'instruction. text node Ces nuds dits textuels encapsulent le contenu texte des lments. Chaque fragment de texte non intrrompu par un lment, une instruction de traitement ou un commentaire est contenu dans un tel nud. Le contenu textuel d'un lment est rparti dans plusieurs nuds de cette sorte lorsque l'lment contient aussi d'autres lments, des commentaires ou des instructions de traitement qui scindent le contenu textuel en plusieurs fragments. namespace node Les nuds de cette sorte reprsentaient en XPath 1.0 les espaces de noms dclars dans un lment. Il sont obsoltes et et ne doivent plus tre utiliss. Afin d'illustrer ces sortes de nuds, voici ci-dessous un document XML trs simple ainsi que son arbre. <?xml version="1.0" encoding="iso-8859-1"?> <!-- Time-stamp: "tree.xml 14 Feb 2008 09:29:00" --> <?xml-stylesheet href="tree.xsl" type="text/xsl"?> <list type="technical"> <item key="id001" lang="fr"> XML & Co </item> <item> <!-- Un commentaire inutile --> Du texte </item> et encore du texte la fin. </list> Dans la figure ci-dessous, chaque nud de l'arbre est reprsent par un rectangle contenant trois informations. La premire information est la sorte du nud, la deuxime est le nom ventuel du nud et la troisime est la valeur textuelle du nud.
111
XPath
Do c u me n t
XM . . . f i n . L
Co mme n t
Ti me . . . 0 0 "
PI x ml - s t y l e
hr e f . . . / xs l
El e me n t l i st
XM . . . f i n . L
At t r i b u t e t y pe
t e c hni c a l
El e me n t i t em
XM & Co L
El e me n t i t em
Du t e x t e
Te x t
e t . . . f i n.
At t r i b u t e key
i d0001
At t r i b u t e l ang
fr
Te x t
XM & Co L
Co mme n t
Un . . . u t i l e
Te x t
Du t e x t e
112
XPath
Pour un attribut, la valeur textuelle est la valeur de l'attribut. Pour une instruction de traitement, c'est le texte qui suit le nom de l'instruction. Pour un commentaire, c'est le texte du commentaire sans les dlimiteurs <!-et -->. La valeur textuelle d'un nud textuel est juste le texte qu'il contient. type Cette proprit n'existe que si le document a t un valid par un schma [Chapitre 5]. Il s'agit du type attribu l'lment ou l'attribut lors de la validation par le schma. Ce type peut tre un type prdfini ou un type dfini dans le schma. valeur type Cette valeur n'existe que si le document a t un valid par un schma [Chapitre 5]. Il s'agit de la valeur obtenue en convertissant la valeur textuelle dans le type du nud. Si le type d'un attribut est, par exemple, xsd:double et sa valeur textuelle est la chane 1.0e-3, sa valeur est le nombre flottant 0.001. Cette conversion n'est possible que si le type du nud est un type simple. Chaque nud a une valeur qui est utilise chaque fois qu'un nud apparat l o une valeur atomique est requise. Beaucoup de fonctions et d'oprateurs XPath prennent en paramtre des valeurs atomiques. Lorsqu'un nud est pass en paramtre de tels fonctions ou oprateurs, celui-ci est converti automatiquement en sa valeur. Ce processus se droule de la faon suivante. Si le nud a une valeur type (c'est--dire lorsque le document est trait avec un schma), la valeur est la valeur type et son type est celui de la valeur type. Sinon, la valeur est la valeur textuelle du nud et son type est xsd:untypedAtomic. Cette conversion d'un nud en valeur est appele atomisation. L'atomisation d'un nud peut donner une liste de valeurs atomiques ventuellement vide. C'est le cas lorsque le type du nud est un type de listes comme le type prdfini xsd:IDREFS ou les types construits avec l'oprateur xsd:list [Section 5.6.6]. Lorsqu'une liste contenant des nuds doit tre convertie en une liste de valeurs, chacun des nuds est atomis et sa valeur le remplace dans la liste. lorsque la valeur du nud comporte plusieurs valeurs atomiques, celles-ci s'insrent dans la liste la place du nud.
6.1.1.2. Fonctions
Il existe des fonctions XPath permettant de rcuprer les proprits d'un nud. Les fonctions sont dcrites avec leur type de retour et le type de leurs paramtres. Les types utiliss sont ceux du systme de typage [Section 6.1.4] de XPath. Lorsque le type du paramtre est node()?, la fonction prend en paramtre un nud ou rien. Dans ce dernier cas, le paramtre est implicitement le nud courant.
113
XPath
retourne les valeurs types des nuds de la liste list. node() root(node()? node) retourne la racine de l'arbre qui contient le nud node ou le nud courant si node est absent. node()* id(xsd:string s) la chane s doit tre une liste de noms XML spars par des espaces. La fonction retourne la liste des nuds dont la valeur de l'attribut de type ID [Section 3.7.2] ou xsd:ID [Section 5.5.1.4] est un des noms de la chane s. La valeur passe en paramtre est souvent la valeur d'un attribut de type IDREF ou IDREFS. Pour qu'un attribut soit de type ID, il doit tre dclar de ce type dans une DTD. Il est aussi possible d'utiliser l'attribut xml:id [Section 2.7.4.4] qui est de type xsd:ID. xsd:anyURI base-uri(node()? node) retourne l'URI de base [Section 2.7.4.3] du nud node ou du nud courant si node est absent. xsd:anyURI document-uri(node()? node) retourne l'URI de base [Section 2.7.4.3] du document contenant le nud node ou le nud courant si node est absent. xsd:anyURI resolve-uri(xsd:string? url, xsd:string? base) combine l'URI uri avec l'URI de base base et retourne le rsultat. Si l'URI base est omise et que le langage hte est XSLT, c'est l'URI de base de la feuille de style qui est utilise. Les espaces de noms [Chapitre 4] sont manipuls en XPath 1.0 travers l'axe namespace. Cet axe est obsolte en XPath 2.0. Il est remplac par des fonctions permettant d'accder aux espaces de noms. xsd:string* namespace-uri(node()? node) retourne l'URI qui dfinit l'espace de noms dans lequel se trouve le nud node ou le nud courant si node est absent. xsd:string* in-scope-prefixes(node() node) retourne la liste des prfixes associs un espace de noms dans le nud node. Si l'espace de noms par dfaut est dfini, la liste contient la chane vide. La liste contient toujours le prfixe xml associ l'espace de noms XML. xsd:string namespace-uri-for-prefix(xsd:string prefix, node() node) retourne l'URI qui dfinit l'espace de noms auquel est associ le prfixe prefix dans le nud node. for $i in in-scope-prefixes(.) return concat($i, '=', namespace-uri-forprefix($i, .)) donne une chane forme d'un bloc de la forme prefixe=uri pour chaque espace de noms dclar dans le nud courant.
114
XPath
L'ordre du document peut tre manipul explicitement par les oprateurs XPath '<<' et '>>' [Section 6.5.3]. Il intervient aussi de faon implicite dans l'valuation de certains oprateurs, comme par exemple '/', qui ordonnent les nuds de leur rsultat suivant cet ordre.
6.1.4. Typage
XPath possde un systme de typage assez rudimentaire qui permet de dcrire les types des paramtres et le type de retour des fonctions. Ce systme de typage est galement utilis par XSLT pour donner le type d'une variable [Section 8.9] lors de sa dclaration et pour les types de retour et des paramtres des fonctions d'extension
115
XPath
[Section 8.10]. Les types des valeurs influent aussi sur les coportement de certains oprateurs et en particulier des comparaisons [Section 6.5]. Ce systme est organis en une hirarchie dont la racine est le type item() (avec les parenthses). Tous les autres types drivent de ce type qui est le plus gnral. Toute valeur manipule par XPath est donc de ce type. Il y a ensuite des types pour les nuds et des types pour les valeurs atomiques. Pour les nuds, il y a d'abord un type gnrique node() ainsi que des types pour chacun des types de nuds [Section 6.1.1]. Ces types sont document-node(), element(), attribute(), text(), comment(), processinginstruction() et comment() (avec les parenthses). Les types pour les valeurs atomiques sont les types prdfinis [Section 5.5.1] des schmas comme xsd:integer. Toute valeur atomique extraite du document par atomisation est type. Lorsque le document est valid par un schma avant traitement par une feuille de style XSLT, les types des valeurs atomiques des contenus d'lments et des valeurs d'attributs sont donns par le schma. Lorsque le document n'est pas valid par un schma, toutes ces valeurs atomiques provenant du document sont considres du type xsd:untypedAtomic. Le systme de type possde trois oprateurs '?', '*' et '+', en notation postfixe, pour construire de nouveaux types. Ils s'appliquent aux types pour les nuds et les valeurs atomiques dcrits prcdemment. L'oprateur '?' dsigne un nouveau type autorisant l'absence de valeur. Ces types sont surtout utiliss pour dcrire les paramtres optionnels des fonctions. La fonction XPath name() [Section 6.1.1.1] a, par exemple, un paramtre de type node()?. Ceci signifie que son paramtre est soit un nud soit rien. L'oprateur '*' construit un nouveau type pour les listes. Le type xsd:integer* est, par exemple, le type des listes d'entiers ventuellement vides. L'oprateur '+' construit un nouveau type pour les listes non vides. Le type xsd:integer+ est, par exemple, le type des listes non vides d'entiers.
6.1.5. Contexte
L'valuation d'une expression XPath se fait dans un contexte qui est fourni par le langage hte. Le contexte se dcompose en le contexte statique et le contexte dynamique. Cette distinction prend du sens lorsque les programmes du langage hte sont susceptibles d'tre compil. Le contexte statique comprend tout ce qui peut tre dtermin par une analyse statique du programme hte. Tout ce qui dpend du document fait, au contraire, partie du contexte dynamique. Les expressions XPath sont beaucoup utilises dans les feuilles de style XSLT. Comme le langage XSLT est sans effet de bord, l'analyse statique des feuilles de styles XSLT est relativement facile et permet de dterminer beaucoup d'information.
116
XPath
Collations Toutes les collations [Section 2.2.5] en porte. URI de base URI de base [Section 2.7.4.3] de l'lment.
117
XPath
revanche, des appels dans des traitements diffrents peuvent conduire des rsultats diffrents. Cette fonction est souvent utilise pour produire une valeur destine un attribut de type ID ou xsd:ID comme xml:id [Section 2.7.4.4]. node() current() retourne le nud courant auquel s'applique la rgle dfinie par xsl:template [Section 8.5.1]. node()* current-group() retourne la liste des nuds du groupe courant lors de l'utilisation de xsl:for-each-group [Section 8.7.4]. xsd:string current-grouping-key() retourne la cl courante lors de l'utilisation de xsl:for-each-group [Section 8.7.4]. xsd:string regexp-group(xsd:integer n) retourne le fragment de texte entre une paire de parenthses de l'expression rationnelle lors de l'utilisation xsl:matching-substring [Section 8.14].
6.2.1.1. Axes
118
XPath
Chacun des axes donne une relation qui relie les nuds slectionns au nud courant. Les axes qu'il est possible d'utiliser dans les expressions XPath sont les suivants. self Le nud lui-mme (galit)
parent Parent
119
XPath
ancestor-or-self Anctre ou le nud lui-mme preceding-sibling Frre gauche (enfant du mme parent)
preceding gauche
120
XPath
following droite
namespace Espace de noms du nud L'axe namespace est un hritage de XPath 1.0 qui doit tre considr comme obsolte. Il est conseill d'utiliser les fonctions XPath pour accder aux espaces de noms d'un nud. Les axes self, parent, child, preceding-sibling et following-sibling permettent de slectionner le nud lui-mme et les nuds proches comme le montre la figure ci-dessous.
pa r e nt s el f
pr e c e di ng- s i bl i ng
f o l l o wi n g - s i b l i n g
c hi l d
An c e s t o r
Se l f Pr e c e d i n g Fo l l o wi n g
De s c e n d a n t
121
XPath
6.2.1.2. Types
Une fois donn un axe, le type permet de restreindre l'ensemble des nuds slectionns un des nuds d'une certaine forme. Les types possibles sont les suivants. * tous les lments ou tous les attributs suivant l'axe utilis ns:* tous les lments ou tous les attributs (suivant l'axe) dans l'espace de noms associ au prfixe ns *:local tous les lments ou tous les attributs (suivant l'axe) de nom local local name les nuds de nom name (lments ou attributs suivant l'axe utilis) node() tous les nuds text() tous les nuds textuels comment() tous les commentaires processing-instruction() ou processing-instruction(name) toutes les instructions de traitement ou les instructions de traitement de nom name Les types node(), text(), comment() et processing-instruction() se prsentent comme des pseudo fonctions sans paramtre. Les parenthses sont indispensables car les expressions text et text() s'valuent diffremment. L'expression text retourne les lments de nom text qui sont enfants du nud courant alors que l'expression text() retourne les nuds textuels qui sont enfants du nud courant. Il faut, galement, distinguer l'expression string qui s'value en une liste de nuds de nom string des expressions 'string' et "string" qui s'valuent en une chane de caractres. child::* ou * tous les lments qui sont enfants du nud courant attribute::* ou @* tous les attributs du nud courant attribute::id ou @id attribut id du nud courant child::node() ou node() tous les enfants du nud courant child::text ou text tous les lments de nom text qui sont enfants du nud courant child::text() ou text() tous les nuds textuels qui sont enfants du nud courant descendant::comment()
122
XPath
tous les commentaires qui sont descendants du nud courant, c'est--dire contenus dans le nud courant following::processing-instruction() toutes les instructions de traitement qui suivent le nud courant. child::processing-instruction('xml-stylesheet') toutes les instructions de traitement de nom xml-stylesheet qui sont enfants du nud courant.
123
XPath
Supposons, par exemple, que l'expression expr1 retourne la liste (n1, n2, n3) forme de trois nuds. L'expression expr2 est donc value trois fois. Elle est value une premire fois en prenant le nud courant gal n1, la position du contexte gale 1 et la taille du contexte gale 3. Elle est value une deuxime fois en prenant le nud courant gal n2, la position du contexte gale 2 et la taille du contexte gale 3. Elle est value une troisime et dernire fois en prenant le nud courant gal n3, la position du contexte gale 3 et la taille du contexte gale 3. Si ces trois valuations retournent respectivement les listes (n0, n2, n5), (n1) et (n0, n1, n2, n4, n6) et que l'ordre du document est n0, n1, n2, n4, n5, n6, le rsultat de l'valuation est la liste (n0, n1, n2, n4, n5, n6). self::node()/child::* ou ./* tous les lements qui sont enfants du nud courant child::*/child::* ou */* tous les lments qui sont des enfants des enfants du nud courant child::p/child::em ou p/em tous les lments em enfants d'un lment p enfant du nud courant child::*/attribute::* ou */@* tous les attributs des lments qui sont enfants du nud courant parent::*/parent::* ou ../.. le parent du parent du nud courant parent::*/child::* ou ../* tous lments qui sont frres du nud courant, y compris le nud courant child::*/parent::* ou */.. le nud courant s'il contient au moins un lment ou aucun nud sinon descendant::p/child::em ou .//p/em tous les lements em qui sont enfants d'un lment p descendant du nud courant descendant::*/descendant::* ou descendant::* tous les lments descendants du nud courant ancestor::*/descendant::* tous les lments du document descendant::*/ancestor::* tous les anctres et tous les descendants du nud courant ayant au moins un lment comme enfant si le nud courant a au moins un lment comme enfant et aucun nud sinon. descendant::p/following-sibling::em[position()=1] sibling::em[1] premier frre em d'un lment p descendant du nud courant. ou .//p/following-
L'oprateur '/' peut tre cascad et il est associatif gauche. Une expression de la forme expr1/expr2/ expr3 est implicitement parenthse (expr1/expr2)/expr3. Ce parenthsage est trs souvent inutile car l'oprateur '/' est associatif l'exception de quelques cas pathologiques. child::*/child::*/attribute::* ou */*/@* tous les attributs des lments qui sont des enfants des enfants du nud courant parent::*/child::*/descendant::text() tous les nuds textuels descendants d'un frre du nud courant L'oprateur '/' peut aussi tre employ dans des expressions de la forme /expr2 qui sont l'analogue des chemins absolus dans les systmes de fichiers. Une expression de la forme /expr2 est value de la faon suivante. L'expression expr2 est value en ayant, au pralable, fix le nud courant la racine de l'arbre contenant le nud courant, la position dans le contexte
124
XPath
1 et la taille du contexte 1. Une telle expression est donc quivalente une expression root(.)/expr2. La fonction root() retourne la racine de l'arbre contenant son paramtre. Le nud courant appartient trs souvent l'arbre d'un document XML. Dans ce cas, la racine de cet arbre est un nud de la sorte document node. Il est galement possible que le nud courant appartienne un fragment de document et que la racine de cet arbre soit un nud quelconque. Les expressions de la forme /expr2 se comportent comme des chemins absolus puiqu'elles s'valuent en partant d'une racine. Elles ne sont toutefois pas compltement absolues car la racine choisie dpend du nud courant. La racine choisie est celle de l'arbre contenant le nud courant. / le nud document node racine de l'arbre /child::* ou /* l'lment racine du document /child::book ou /book l'lment racine du document si son nom est book et aucun nud sinon /child::book/child:chapter ou /book/chapter les lments chapter enfant de l'lment racine du document si son nom est book et aucun nud sinon /descendant::section ou //section tous les lments section du document
125
XPath
true() and false() false true() or false() true not(false()) true Les valeurs des autres types peuvent tre converties explicitement en des valeurs boolennes par la fonction xsd:boolean(). Elles sont aussi converties implicitement ds qu'une valeur boolenne est requise. C'est le cas, par exemple, des filtres [Section 6.4.2] et de la structure de contrle if [Section 6.6.1] de XPath ou des structures de contrle xsl:if [Section 8.7.1] et xsl:when [Section 8.7.2] de XSLT. Les rgles qui s'appliquent alors sont les suivantes. Une liste vide est convertie en false. Une liste vide non vide dont le premier lment est un nud est convertie en true. Si la liste contient une seule valeur atomique, les rgles suivantes s'appliquent. Rappelons qu'une valeur atomique est considre comme une liste contenant cet objet et inversement. Un nombre est converti en true sauf s'il vaut 0 ou NaN. Une chane de caractres est convertie en true sauf si elle est vide. Les autres cas provoquent une erreur. xsd:boolean(()) donne false car la liste est vide xsd:boolean((/,0)) donne true car le premier objet de la liste est un nud xsd:boolean(0) donne false car l'entier est gal 0 xsd:boolean(7) donne true car l'entier est diffrent de 0 xsd:boolean('') donne false car la chane de caractres est vide xsd:boolean('string') donne true car la chane de caractres n'est pas vide
6.3.2. Nombres
Les seuls nombres existant en XPath 1.0 taient les nombres flottants. XPath 2.0 manipule les nombres des trois types xsd:integer, xsd:decimal et xsd:double des schmas XML [Section 5.5.1.1].
126
XPath
Oprateur div Cet oprateur calcule le quotient de la division de deux nombres entiers, dcimaux ou flottants. 3 div 2, 4.5 div 6.7 1.5, 0.671641791044776119 Oprateurs idiv et mod Ces oprateurs calculent respectivement le quotient et le reste de la division entire de deux entiers. 3 idiv 2, 3 mod 2 2, 1 number abs(number x) retourne la valeur absolue d'un nombre entier ou flottant. La valeur retourne est du mme type que la valeur passe en paramtre. abs(-1), abs(2.3) 1, 2.3 number floor(number x) retourne la valeur entire approche par valeur infrieure d'un nombre dcimal ou flottant. floor(1), floor(2.5), floor(2,7), floor(-2.5) 1, 2, 2, -3 number ceiling(number x) retourne la valeur entire approche par valeur suprieure d'un nombre dcimal ou flottant. ceiling(1), ceiling(2.5), ceiling(2.3), ceiling(-2.5) 1, 3, 3, -2 number round(number x) retourne la valeur entire approche la plus proche d'un nombre dcimal ou flottant. Si le paramtre est gal n+1/2 pour un entier n, la valeur retourne est l'entier n+1. round(1), round(2.4), round(2.5), round(-2.5) 1, 2, 3, -2 number round-half-to-even(number x, xsd:integer? precision) retourne le multiple de 10-precision le plus proche du nombre dcimal ou flottant x. La valeur par dfaut de precision est 0. Dans ce cas, la fonction retourne l'entier le plus proche de x. Si x est gale distance de deux multiples, c'est--dire si sa valeur est de la forme (n+1/2)10-precision, la fonction retourne le multiple pair. round-half-to-even(12.34,-1), round-half-to-even(12.34,1) 10, 12.3 round-half-to-even(2.5), round-half-to-even(3.5) 2, 4 xsd:anyAtomicType min(xsd:anyAtomicType* list, xsd:string? col) retourne le minimum d'une liste de valeurs qui sont comparables pour l'ordre <. Le paramtre optionnel col spcifie la collation utiliser pour comparer des chanes de caractres. min(1 to 6), min(('Hello', 'new', 'world')) 1, 'Hello' xsd:anyAtomicType max(xsd:anyAtomicType* list, xsd:string? col) retourne le maximum d'une liste de valeurs qui sont comparables pour l'ordre lt. Le paramtre optionnel col spcifie la collation utiliser pour comparer des chanes de caractres.
127
XPath
number sum(xsd:anyAtomicType* list) retourne la somme d'une liste de nombres. Les valeurs qui ne sont pas des nombres sont converties au pralable en flottants avec xsd:double. sum(1 to 6) 21 number avg(xsd:anyAtomicType* list) retourne la moyenne d'une liste de nombres. Les valeurs qui ne sont pas des nombres sont converties au pralable en flottants avec xsd:double. avg(1 to 6) 3.5
128
XPath
retourne la concatnation des chanes de caractres de la liste en insrant la chane sep entre elles. Contrairement la fonction concat, le nombre de paramtres de cette fonction est fix 2 mais le premier paramtre est une liste. string-join(('Hello', 'new', 'world'), ' ') 'Hello new world' xsd:integer compare(xsd:string s1, xsd:string s2, xsd:anyURI? col) retourne la comparaison des deux chanes de caractres s1 et s2 en utilisant la collation optionnelle identifie par l'URI col. La valeur de retour est -1, 0 ou 1 suivant que s1 est avant s2 pour l'ordre lexicographique, gale s2 ou aprs s2. Si col est absente, la collation par dfaut est utilise. Celle-ci est base sur les codes Unicode. compare('Hello', 'world') -1 compare('hello', 'World') 1 xsd:boolean starts-with(xsd:string s, xsd:string prefix) retourne true si la chane s commence par la chane prefix et false sinon. xsd:boolean ends-with(xsd:string s, xsd:string suffix) retourne true si la chane s se termine par la chane suffix et false sinon. xsd:boolean contains(xsd:string s, xsd:string factor) retourne true si la chane factor apparat comme sous-chane dans la chane s et false sinon. contains('Hello', 'lo') true xsd:boolean matches(xsd:string s, xsd:string regexp, xsd:string? flags) retourne true si une partie de la chane s est conforme l'expression rationnelle regexp [Section 5.15] et false sinon. La chane optionnelle flags prcise comment doit tre effectue l'opration. matches('Hello world', '\w+') true matches('Hello world', '^\w+$') false matches('Hello', '^\w+$') true xsd:string substring(xsd:string s, xsd:double start xsd:double length) retourne la sous-chane commenant la position start et de longueur length ou moins si la fin de la chane s est atteinte. Les positions dans la chane s1 sont numrotes partir de 1. Les paramtres start et length sont des flottants par compatibilit avec XPath 1.0. Ils sont convertis en entiers avec round(). substring('Hello world', 3, 5) 'llo w' substring('Hello world', 7, 10) 'world' xsd:string substring-before(xsd:string s1, xsd:string s2)
129
XPath
retourne la sous-chane de s1 avant la premire occurrence de la chane s2 dans s1. substring-before('Hello world', 'o') 'Hell' substring-before('Hello world', 'ol') '' xsd:string substring-after(xsd:string s1, xsd:string s2) retourne la sous-chane de s1 aprs la premire occurrence de la chane s2 dans s1. substring-after('Hello world', 'o') ' world' substring-after('Hello world', 'ol') '' xsd:string translate(xsd:string s, xsd:string from, xsd:string to) retourne la chane de obtenue en remplaant dans la chane s chaque caractre de la chane from par le caractre la mme position dans la chane to. Si la chane from est plus longue que la chane to, les caractres de from sans caractres en correspondance dans to sont supprims de la chane s. translate('Hello world', 'lo', 'ru') 'Herru wurrd' translate('01-44-27-45-19', '-', '') '0144274519' xsd:string replace(xsd:string xsd:string? flags) s, xsd:string regexp, xsd:string repl,
retourne la chane de obtenue en remplaant dans la chane s l'occurrence de l'expression rationnelle regexp [Section 5.15] par la chane repl. L'expression regexp peut dlimiter des blocs avec des paires de parenthses '(' et ')' qui peuvent ensuite tre utiliss dans la chane repl avec la syntaxe $1, $2, . replace('Hello world', 'o', 'u') 'Hellu wurld' replace('="\'\"=', '(["\\])', '\\$1') '=\"\\'\\\"=' replace('(code,1234)', '\(([^,]*),([^\)]*)\)', '($2,$1)') '(1234,code)' xsd:string* tokenize(xsd:string s, xsd:string regexp) retourne la liste des chanes obtenues en dcoupant la chane s chaque occurence de l'expression regexp [Section 5.15] qui ne peut pas contenir la chane vide. tokenize('Hello new world', '\s+') ('Hello', 'new', 'world') tokenize('Hello  world', '\s') ('Hello', '', 'world') xsd:string normalize-space(xsd:string s) supprime les caractres d'espacement [Section 2.2.2] en dbut et en fin de chane et remplace chaque suite de caractres d'espacement conscutifs par un seul espace.
130
XPath
normalize-space(' Hello &x0A; world ') 'Hello world' xsd:string lower-case(xsd:string s) retourne la chane s mise en minuscule. lower-case('Hello world') 'hello world' xsd:string upper-case(xsd:string s) retourne la chane s mise en majuscule. upper-case('Hello world') 'HELLO WORLD' xsd:string codepoints-to-string(xsd:integer* list) convertit une liste de points de code [Section 2.2] en une chane de caractres. codepoints-to-string((65, 8364, 48)) 'A0' xsd:integer* string-to-codepoints(xsd:string s) convertit une chane de caractres en une liste de points de code [Section 2.2]. string-to-codepoints('A€0') (65, 8364, 48) xsd:string normalize-unicode(xsd:string s, xsd:string? norm) retourne la normalisation [Section 2.2.6] de la chane s avec la normalisation spcifie par la chane norm. Cette dernire peut prendre les valeurs NFC, NFD, NFKC et NFKD si le processeur implmente chacune de ces normalisations. Si norm est absente, la normalisation C (NFC) par dfaut et toujours implmente est utilise. string-to-codepoints(normalize-unicode(codepoints-to-string((105, 776)))) (239)
131
XPath
6.3.4.1. Modificateurs
Les fonctions matches() et replace() prennent un dernier paramtre optionnel flag qui modifie leur comportement. Ce paramtre doit tre une chane de caractres pouvant contenir les caractres 'i', 'm' et 's' dans n'importe quel ordre. Chacun de ces caractres joue le rle d'un modificateur qui influence un des aspects du fonctionnement de ces fonctions. Le caractre 'i' indique que la chane est compare l'expression dans tenir compte de la casse des lettres. Ceci signifie que les lettres minuscules et majuscules ne sont plus distingues. matches('Hello world', 'hello') donne false. matches('Hello world', 'hello', 'i') donne true. Le caractre 'm' modifie la signification des ancres '^' et '$'. Il indique que la chane est compare l'expression en mode multi-ligne. Dans ce mode, la chane est vue comme plusieurs chanes obtenues en dcoupant chaque saut de ligne marqu par le caractre U+0A [Section 2.2.2]. Ceci signifie que le caractre '^' dsigne alors la chane vide place au dbut de la chane ou aprs un saut de ligne et que le caractre '$' dsigne alors la chane vide place la fin de la chane ou avant un saut de ligne. matches('Hello
world', '^Hello$') donne false. matches('Hello
world', '^Hello$', 'm') donne true. Le caractre 's' modifie la signification du caractre spcial '.'. Il dsigne normalement tout caractre autre qu'un saut de ligne. Avec le modificateur 's', il dsigne tout caractre, y compris le saut de ligne U+0A [Section 2.2.2]. matches('Hello
world', '^.*$') donne false. matches('Hello
world', '^.*$', 's') donne true.
6.4. Listes
La liste est la structure de donnes fondamentale de XPath. Il existe plusieurs oprateurs permettant de construire et de manipuler des listes. La restriction importante des listes XPath est qu'elles ne peuvent pas tre imbriques. Une liste XPath ne peut pas contenir d'autres listes. Elle peut uniquement contenir des nuds et des valeurs atomiques. Ainsi, l'expression ((1,2),(3,4,5)) ne donne pas une liste contenant deux listes de deux et trois entiers. Elle donne la liste de cinq entiers que donne galement l'expression (1,2,3,4,5).
6.4.1. Constructeurs
L'oprateur essentiel de construction de listes est ',' (virgule) qui permet de concatner, c'est--dire mettre bout bout, des listes. Il est aussi bien utilis pour crire des listes constantes comme (1,2,3,4,5) que pour concatner les rsultats d'autres expressions. Contrairement aux oprateurs de chemins [Section 6.2], l'oprateur ',' ne rordonne pas les lments des listes et ne supprime pas les doublons. Le rsultat de l'expression expr1,expr2 est la nouvelle liste forme des valeurs du rsultat de expr1 suivis des valeurs du rsultat l'expression expr2. Si une valeur apparat dans les deux rsultats, elle a plusieurs occurrences dans le rsultat final. Par exemple, le rsultat de l'expression (1,2),(1,3) est bien la liste (1,2,1,3) avec deux occurrences de l'entier 1.
132
XPath
Le fait qu'une valeur soit assimile la liste (de longueur 1) contenant cette valeur simplifie l'criture des expressions. Ainsi les deux expressions (1),(2) et 1,2 sont quivalentes. Cette identification entre une valeur et une liste ne cre pas d'ambigut car les listes XPath ne peuvent pas tre imbriques. Il n'y a pas de diffrence entre les deux expressions ((1),(2)) et (1,2). title, author donne la liste des enfants de nom title puis des enfants de nom author du nud courant. 1, 'Two', 3.14, true() donne la liste (1, 'Two', 3.14, true) constitue d'un entier, d'une chane de caractres, d'un nombre flottant et d'une valeur boolenne. (1, 2), 3, (4, (5)) donne la liste (1, 2, 3, 4, 5) sans imbrication. (1, 2), 2, 1, 2 donne la liste (1, 2, 2, 1, 2) avec rptitions. L'oprateur to permet de crer une liste contenant une suite d'entiers conscutifs. L'expression n1 to n2 donne la liste n1,n1+1,n1+2,,n2-1,n2 des entiers de n1 n2 compris. Cet oprateur est surtout utile avec l'oprateur for [Section 6.6.2] pour itrer sur une liste d'entiers. 1 to 5 donne la liste (1, 2, 3, 4, 5) 1, 2 to 4, 5 donne la liste (1, 2, 3, 4, 5)
6.4.2. Filtres
Un filtre permet de slectionner dans une liste les objets qui satisfont une condition. Un filtre se prsente comme une expression entre des crochets '[' et ']' place aprs la liste filtrer. Une expression de la forme expr1[expr2] est value de la faon suivante. L'expression expr1 est d'abord value pour donner une liste l d'objets. Pour chaque objet o de la liste l, l'expression expr2 est value en modifiant, au pralable, le focus [Section 6.1.5.2] de la manire suivante. L'objet courant est fix l'objet o, la position du contexte est fixe la position de l'objet o dans la liste l et la taille du contexte est fixe la taille de l. Le rsultat de cette valuation est ensuite converti en une valeur boolenne en utilisant les rgles de conversion [Section 6.3.1]. Le rsultat final de l'valuation de expr1[expr2] est la liste des objets de l pour lesquels expr2 s'est value en la valeur true. Les objets slectionns restent bien sr dans l'ordre de la liste l. La liste rsultat est en fait construite en supprimant de la liste l les objets pour lesquels expr2 s'value en false. Lors de l'valuation de l'expression suivante, l'objet courant qui est retourn par '.' prend les valeurs successives 1, 2, 3, 4 et 5. Seules les valeurs paires satisfont la condition et sont conserves. (1 to 5)[. mod 2 = 0] donne la liste (2,4) des entiers pairs de la liste Les filtres sont beaucoup utiliss dans les expression de chemin [Section 6.2.2] pour slectionner des nuds. Plusieurs conditions peuvent tre combines l'aide des oprateurs boolens and et or. Les filtres peuvent aussi tre enchans en les mettant l'un aprs l'autre. text[position() > 1 and position() < 4] donne les enfants text du nud courant aux positions 2 et 3 text[position() > 1][position() < 4] donne les enfants text du nud courant aux positions 2, 3 et 4
133
XPath
Le second exemple montre que les filtres peuvent tre enchans. Il ne donne pas le mme rsultat que le premier exemple car les positions retournes par la fonction position() du second filtre sont celles dans la liste obtenue aprs le premier filtre. Comme le premier enfant text a t supprim, il y a un dcalage d'une unit. Les expressions de chemins retournent des listes de nuds tris dans l'ordre du document et sans doublon. Au contraire, l'oprateur ',' ne supprime pas les doublons. p[@align or @type] donne la liste des enfants p du nud courant ayant un attribut align ou type. p[@align], p[@type] donne la liste des enfants p du nud courant ayant un attribut align suivis des enfants p ayant un attribut type. Si un nud p possde les deux attributs, il apparat deux fois dans la liste.
6.4.3. Fonctions
Il existe des fonctions XPath permettant de manipuler les listes. xsd:integer count(item()* l) retourne la longueur de la liste l, c'est--dire le nombre de nuds ou valeurs atomiques qui la composent. count('Hello world', 1, 2, 3) 4 xsd:boolean empty(item()* l) retourne true si la liste l est vide et false sinon. empty(1 to 5) false xsd:boolean exists(item()* l) retourne true si la liste l est non vide et false sinon. exists(1 to 5) true item()* distinct-values(item()* l) retourne une liste des valeurs distinctes de la liste l en supprimant les valeurs gales pour l'oprateur eq. distinct-values((1, 'Hello', 0, 1, 'World')) (1, 'Hello', 0, 'World') xsd:integer* index-of(item()* l, item() value) retourne la liste des positions de la valeur value dans la liste l. index-of((1, 'Hello', 0, 1, 'World'), 1) (1, 4) item()* subsequence(item()* l, xsd:double start xsd:double length) retourne la sous-liste commenant la position start et de longueur length ou moins si la fin de la liste l est atteinte. subsequence((1, 'Hello', 0, 1, 'World'), 2, 3) ('Hello', 0, 1)
134
XPath
item()* remove(item()* l, xsd:integer pos) retourne la liste obtenue en supprimant de la liste l la valeur la position pos. remove(1 to 5, 3) (1, 2, 4, 5) item()* insert-before(item()* l1, xsd:integer pos, item()* l2) retourne la liste obtenue en insrant la liste l2 dans la liste l1 la position pos. insert-before(1 to 5, 3, 1 to 3) (1, 2, 1, 2, 3, 3, 4, 5) item()* reverse(item()* l) retourne la liste obtenue en inversant l'ordre reverse(1 to 5) (5, 4, 3, 2, 1)
6.5. Comparaisons
Les comparaisons sont un aspect important mais dlicat de XPath. Elles jouent un rle important en XPath car elles permettent d'affiner la slection des nuds en prenant en compte leurs contenus. Il est, par exemple, possible de slectionner des lments d'un document dont la valeur d'un attribut satisfait une condition comme dans les expressions item[@type='free'] et list[@length < 5]. Les comparaisons sont aussi dlicates utiliser car leur smantique est source de piges conduisant aisment des programmes errons. Il existe deux types d'oprateurs pour effectuer des comparaisons entre valeurs. Les premiers oprateurs dits gnraux datent de la premire version de XPath. Ils permettent de comparer deux valeurs quelconques, y compris des listes, avec des rsultats parfois inattendus. Les seconds oprateurs ont t introduits avec la version 2.0 de XPath. Ils autorisent uniquement les comparaisons entres les valeurs atomiques de mme type. Ils sont plus restrictifs mais leur comportement est beaucoup plus prvisible. Il existe aussi l'oprateur is et les deux oprateurs << et >> permettant de tester l'galit et l'ordre de nuds dans le document.
135
XPath
des attibuts doivent tre convertis explicitement l'aide des fonctions de conversion lorsque le document est trait indpendamment d'un schma. Pour tester si la valeur d'un attribut pos vaut la valeur 1, il est ncessaire d'crire xsd:integer(@pos) eq 1 o la valeur de l'attribut pos est convertie en entier par la fonction xsd:integer. Les oprateurs gnraux de comparaison vitent ces conversions fastidieuses car ils effectuent eux-mmes des conversions implicites. La contraintes d'galit des types des valeurs n'est pas stricte. Il est possible de comparer une valeur d'un type avec une valeur d'un type obtenu par restriction [Section 5.9]. Il est galement possible de comparer des valeurs des diffrents types numriques xsd:integer, xsd:decimal, xsd:float et xsd:double.
Lorsque les deux valeurs sont de type xsd:untypedAtomic, celle-ci sont compares comme des chanes de caractres. Lorsqu'une seule des deux valeurs est de type xsd:untypedAtomic, celle-ci est convertie dans le type de l'autre valeur avant de les comparer. Quand le type de l'autre valeur est un type numrique, la valeur de type xsd:untypedAtomic est convertie en une valeur de type xsd:double plutt que dans le type de l'autre valeur. Ceci vite qu'une valeur dcimale comme 1.2 soit convertie en entier avant d'tre compare la valeur 1. Si les deux valeurs sont de types incompatibles, la comparaison choue et provoque une erreur. Pour illustrer ces comparaisons, on considre le petit document suivant. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <list> <item type="1">1</item> <item type="01">2</item> <item type="03">3</item> <item type="1.2">4</item> <!-- Erreur car 'str' ne peut tre convertie en nombre flottant --> <item type="str">5</item> </list> Les expressions suivantes sont values sur le document prcdent en supposant, chaque fois, que le nud courant est l'lment racine list du document. Pour chacune des expressions, le rsultat est une liste d'enfants
136
XPath
item de l'lment list. Il est dcrit en donnant les positions de ces lments item slectionns. Le rsultat item[1], item[2] de la premire expression signifie, par exemple, qu'elle slectionne le premier et le deuxime enfants item. item[@type=1] donne item[1], item[2] car la valeur de l'attribut type est convertie en nombre flottant avant d'tre compare 1. La valeur '01' est donc convertie en '1'. item[@type='1'] donne item[1] car la valeur de l'attribut type est convertie en chane de caractres avant d'tre compare '1'. item[@type=.] donne item[1] car la valeur de l'attribut type et le contenu de l'lment item sont convertis en chanes de caractres avant d'tre compars. item[@type=1.2] donne item[4] car la valeur de l'attribut type est convertie en nombre flottant avant d'tre compare 1.2. item[xsd:double(.)=xsd:double(@type)] donne item[1], item[3] car la valeur de l'attribut type et le contenu de l'lment item sont convertis en nombres flottants avant d'tre compars. Il faut faire attention au fait que les comparaisons peuvent chouer et provoquer des erreurs lorsque les types ne sont pas compatibles. Ce problme renforce l'intrt de la validation des documents avant de les traiter.
137
XPath
chaque logiciel peut les effectuer dans l'ordre qui lui convient. Lorsqu'une de ces comparaisons donne la valeur true et qu'une autre de ces comparaisons choue, la rsultat de la comparaison des deux listes est imprvisible. Il est gal true si une comparaison donnant true est effectue avant toute comparaison qui choue mais la comparaison globale choue dans le cas contraire. La smantique des comparaisons de listes permet d'crire simplement certains tests. Pour savoir si une valeur contenue, par exemple, dans une variable $n est gale une des valeurs de la liste (2, 3, 5, 7), il suffit d'crire $n = (2, 3, 5, 7).
138
XPath
<a> <xsl:choose> <xsl:when test="@xml:id"> <xsl:attribute name="id" select="@xml:id"/> </xsl:when> <xsl:otherwise> <xsl:attribute name="id" select="generate-id()"/> </xsl:otherwise> </xsl:choose> </a>
6.6.1. Conditionnelle
L'oprateur if permet d'effectuer un test. Sa syntaxe est la suivante. if (test) then expr1 else expr2 La smantique est celle de if dans tous les langages de programmation. L'expression test est value et le rsultat est converti en une valeur boolenne [Section 6.3.1]. Si cette valeur boolenne est true, l'expression expr1 est value et le rsultat est celui de l'expression globale. Sinon, l'expression expr2 est value et le rsultat est celui de l'expression globale. La partie else expr2 est obligatoire et ne peut pas tre omise. Lorsque cette seconde partie est inutile, on met simplement else (). if (contains($url, ':')) then substring-before($url, ':') else '' l'valuation de cette expression retourne le protocole d'une URL plac avant le caractre ':' si celle-ci en contient un. L'oprateur if est parfois remplac par un filtre [Section 6.4.2]. L'expression if (@xml:id) then @xml:id else generate-id() est en effet quivalente l'expression plus concise (@xml:id, generate-id()) [1].
6.6.2. Itration
L'oprateur for permet de parcourir des listes pour construire une nouvelle liste. Il ne s'agit pas d'une structure de contrle pour des itrations quelconques comme le for ou le while des langages C ou Java. Il s'apparente plus l'oprateur map des langages fonctionnels comme ML qui permet d'appliquer une fonction chacun des objets d'une liste. La syntaxe de l'oprateur for est la suivante o var est une variable et expr1 et expr2 sont deux expressions. La variable var peut uniquement apparatre dans l'expression expr2. for var in expr1 return expr2 L'valuation d'une telle expression est ralise de la faon suivante. L'expression expr1 est d'abord value pour donner une liste de valeurs. Pour chacune de ces valeurs, celle-ci est affecte la variable var et l'expression expr2 est value. Le rsultat global est la liste obtenue en concatnant les listes obtenues pour chacune des valuations de l'expression expr2. Le rsultat de l'expression expr2 est une liste qui peut donc contribuer plusieurs valeurs de la liste finale. Si, au contraire, ce rsultat est la liste vide, il n'y a aucune contribution la liste finale. La variable var introduite par l'oprateur for est une variable muette. Sa porte est rduite l'expression expr2 aprs le mot cl return. Aucune valeur ne peut lui tre affecte directement. for $i in 1 to 5 return $i * $i l'valuation de cette expression donne la liste (1,4,9,16,25) des cinq premiers carrs
139
XPath
for $i in 1 to 3 return (2 * $i, 2 * $i + 1) l'valuation de cette expression donne la liste (2,3,4,5,6,7) qui est la concatnation des trois listes (2,3), (4,5) et (6,7) for $i in 1 to 5 return if ($i mod 2) then () else $i * $i l'valuation de cette expression donne la liste (4,16) des carrs des deux nombres pairs 2 et 4 pour lesquels $i mod 2 donne 0 Il est possible d'imbriquer plusieurs oprateurs for. Il y a d'ailleurs une syntaxe tendue qui permet une criture concise de ces itrations imbriques. Cette syntaxe prend la forme suivante. for var-1 in expr-1, , var-N in expr-N return expr Cette expression est, en fait, quivalente l'expression suivante crite avec la premire syntaxe. for var-1 in expr-1 return for return for var-N in expr-N return expr
for $i in 0 to 2, $j in 0 to 2 return $i * 3 + $j l'valuation de cette expression donne la liste (0,1,2,3,4,5,6,7,8) qui est la concatnation des trois listes (0,1,2), (3,4,5) et (6,7,8)
140
XPath
' ' l'axe child:: peut tre omis. .. est l'abrviation de parent::node(). @ est l'abrviation de attribute::. // est l'abrviation de /descendant-or-self::node()/. [n] est l'abrviation de [position()=n] o n est un entier. En XPath 1.0, la formule '.' tait une abrviation pour self::node() et elle dsignait toujours un nud. En XPath 2.0, elle dsigne l'objet courant qui peut tre une valeur atomique ou un nud. Il faut remarquer que '//' n'est pas une abbrviation de descendant-or-self::. Les deux expressions //section[1] et descendant-or-self::section[1] donnent des rsultats diffrents. La premire expression donne la liste des lments section qui sont le premier enfant section de leur parent alors que la seconde donne le premier lment section du document.
6.8. Motifs
Les motifs XPath sont des expressions XPath simplifies permettant de slectionner de faon simple des nuds dans un document. Ils sont beaucoup utiliss par XSLT [Chapitre 8], d'abord pour spcifier des nuds auxquels s'applique une rgle [Section 8.5.1] mais aussi pour la numrotation [Section 8.6.11] et l'indexation [Section 8.12]. Ils rpondent une exigence d'efficacit. Le cur de XSLT est l'application de rgles des nuds du document source. Il est important de dterminer rapidement quelles sont les rgles susceptibles de s'appliquer un nud. Dans ce but, les motifs n'utilisent qu'un sous-ensemble trs limit de XPath. De surcrot, les motifs sont valus de faon particulire, sans utiliser le nud courant. Les seuls oprateurs utiliss dans les motifs sont les oprateurs '|', '/' et '//' et leur imbrication est trs restreinte. Un motif prend ncessairement la forme suivante expr-1 | expr-2 | ... | expr-N o les expressions expr-1, , expr-N ne contiennent que des oprateurs '/' et '//'. En outre, les seuls axes possibles dans les motifs sont les deux axes child::, attribute::. L'axe descendant-or-self:: est implicite dans l'utilisation de l'oprateur '//' mais c'est la seule faon de l'utiliser dans un motif. En revanche, les tests portant sur les types de nuds comme text() ou comment() et les filtres sont autoriss dans les motifs. L'valuation d'un motif XPath est ralise de faon diffrente d'une expression XPath classique. Celle-ci ne ncessite pas de nud courant. Un motif est toujours valu partir de la racine du document. De plus, un motif commence toujours implicitement par l'oprateur '//'. Le motif section est, en fait, valu comme l'expression //section. Il slectionne tous les lments section du document. Des exemples de motifs avec les nuds qu'ils slectionnent sont donns ci-dessous. / la racine du document *
141
XPath
tous les lments section tous les lments section chapter|section tous les lments chapter et section chapter/section tous les lments section enfants d'un lment chapter chapter//section tous les lments section descendants d'un lment chapter section[1] tous les lments section qui sont le premier enfant de leur parent section[@lang] tous les lments section ayant un attribut lang section[@lang='fr'] tous les lments section dont l'attribut lang a la valeur fr @* tous les attributs section/@lang tous les attributs lang des lments section text() tous les nuds textuels
142
XPath
dir [node] affiche les informations relatives au nud node. grep string affiche les occurrences de la chane string dans le contenu du nud courant. Une session d'exprimentation du mode interactif de xmllint avec le fichier de bibliographie bibliography.xml est prsente ci-dessous. bash $ xmllint --shell bibliography.xml / > grep XML /bibliography/book[1]/title : t-27 XML langage et applications /bibliography/book[2]/title : t-14 XML by Example /bibliography/book[5]/title : t-46 Modlisation et manipulation ... /bibliography/book[6]/title : t-25 XML Schema et XML Infoset /bibliography/book[7]/title : ta3 XML / > xpath bibliography/book[@lang='en'] Object is a Node Set : Set contains 2 nodes: 1 ELEMENT book ATTRIBUTE key TEXT content=Marchal00 ATTRIBUTE lang TEXT content=en 2 ELEMENT book ATTRIBUTE key TEXT content=Zeldman03 ATTRIBUTE lang TEXT content=en / > cd bibliography/book[3] book > xpath @lang Object is a Node Set : Set contains 1 nodes: 1 ATTRIBUTE lang TEXT content=fr book > cd .. bibliography >
Quantification existentielle some $i in satisfies E2 Quantification universelle every $i in satisfies E2 Test if (E1) else E3 then
143
XPath
Oprateur / [ ] and or not to eq ne lt le gt ge = != < <= > >= << is >> + * - div idiv
1 to 5 $x lt $y $x < $y
| union Oprations sur les listes de E1 | E2 intersection nuds except instance of cast as Changements de type castable as treat as
of
144
Chapitre 7. Schematron
7.1. Introduction
Schematron est un autre formalisme permettant de spcifier la structure d'un document XML. C'est donc au dpart une alternative aux schmas [Chapitre 5] mais il est plutt complmentaire des schmas. Ce formalisme n'est pas trs adapt pour dfinir l'imbrication des lments comme le font les schmas en donnant une grammaire. En revanche, il permet d'imposer des contraintes sur le document qu'il est difficile, voire impossible, d'exprimer avec les schmas. Il est frquent d'utiliser les deux formalismes conjointement. Un schma dfinit la structure globale du document et un schematron la complte en ajoutant des contraintes supplmentaires que doit satisfaire le document pour tre valide. Il existe d'ailleurs des mcanismes permettant d'inclure un schematron au sein d'un schma. Schematron est bas sur XPath [Chapitre 6]. Un schematron est constitu de rgles crites avec des expressions XPath qui expriment la prsence ou l'absence de motifs dans le document. Ce mcanisme rend schematron trs puissant puisqu'il est possible de mettre en relation des lments et des attributs qui sont loigns dans le document. Schematron reste cependant trs simple car le vocabulaire est restreint. L'criture d'un schematron requiert l'utilisation de seulement quelques lments.
145
Schematron
Le rsultat de la vrification du document ci-dessus avec le schematron donn prcdemment est donn la section suivante.
7.3. Fonctionnement
Le principe de fonctionnement de schematron est le suivant. Un document cible est valid avec un schematron en utilisant une application approprie. Cette validation produit un rapport qui retrace les diffrentes tapes de la validation. Ce rapport contient des messages destins l'utilisateur. Ces messages peuvent provenir d'ventuelles erreurs mais ils peuvent aussi tre positifs et confirmer que le document satisfait bien certaines contraintes. Ces diffrents messages sont produits par l'application de validation ou sont issus du schematron. Le schematron associe en effet des messages aux diffrentes contraintes qu'il contient. Ce rapport est souvent lui mme un document XML. La validation d'un document avec un schematron est souvent ralise en deux phases. Dans une premire phase, le schematron est transform en une version compile qui est indpendante du document. Dans une seconde phase, la version compile est utilise pour produire le rapport. La premire phase est parfois, elle-mme, scinde en plusieurs tapes afin de prendre en compte les inclusions et les blocs abstraits.
Co m p ila t e u r c o mp i l e r . x s l
Sc h e m a t ro n s c h e ma . s c h
Sc h e m a t ro n c o m p il s c h e ma . x s l
XSLT Pro c e s s o r
Do c u m e n t d o c u me n t . x ml
Ra p p o rt r e p o r t . x ml
XSLT Pro c e s s o r
146
Schematron
rapport peut tre un simple fichier texte mais il est souvent un document XML, en particulier lorsque la validation est ralise via XSLT. Le format SVRL est un dialecte XML conu spcialement pour les rapports de validation avec des schematrons. Il est en particulier utilis par l'implmentation standard de schematron disponible l'adresse http://www.schematron.com/. Le rapport SVRL obtenu par la validation du document XML avec le schematron donns ci-dessus est le suivant. <?xml version="1.0" standalone="yes"?> <svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron" title="Comparaison attribut/nombre d'enfants" schemaVersion="ISO19757-3"> <svrl:active-pattern/> <svrl:fired-rule context="list"/> <svrl:fired-rule context="list"/> <svrl:failed-assert test="@length = count(*)" location="/lists/list[2]"> <svrl:text>L'attribut length doit tre gal au nombre d'enfants.</svrl:text> </svrl:failed-assert> </svrl:schematron-output>
147
Schematron
7.5. Rgles
Chaque rgle est matrialise par un lment sch:rule qui contient un ou plusieurs tests. L'lment sch:rule possde un attribut context dont la valeur doit tre un motif XPath [Section 6.8]. Ce motif dtermine sur quels nuds s'applique la rgle. Les tests d'une rgle sont introduits par les lments sch:assert et sch:report. Ces deux lments prennent la mme forme. Ils possdent un attribut test dont la valeur est une expression XPath et ils contiennent du texte qui est ventuellement utilis pour construire le rapport. Ces deux lments se distinguent par leurs smantiques qui sont l'oppos l'une de l'autre. <sch:rule context="...">
148
Schematron
<sch:assert test="..."> ... </sch:assert> <sch:report test="..."> ... </sch:report> ... </sch:rule> Un test introduit par sch:assert est ralis de la faon suivante. L'expression XPath contenue dans l'attribut test est value en prenant le nud slectionn comme contexte et le rsultat de l'valuation est converti en une valeur boolenne. Si le rsultat est false, le texte contenu dans l'lment sch:assert est ajout au rapport. Sinon rien n'est ajout au rapport. Dans l'exemple ci-dessous, le message d'erreur est ajout au rapport si la condition n'est pas vrifie, c'est--dire si l'lment book n'a aucun des attributs id ou key. <sch:rule context="book"> <sch:assert test="@id|@key"> L'lment book doit avoir un attribut id ou key </sch:assert> </sch:rule> Un test introduit par sch:report est, au contraire, ralis de la faon suivante. L'expression XPath contenue dans l'attribut test est value en prenant le nud slectionn comme contexte et le rsultat de l'valuation est converti en une valeur boolenne. Si le rsultat est true, le texte contenu dans l'lment sch:report est ajout au rapport. Sinon rien n'est ajout au rapport. Dans l'exemple ci-dessous, le message d'erreur est ajout au rapport si la condition est vrifie, c'est--dire si l'lment book a simultanment les deux attributs id et key. <sch:rule context="book"> <sch:report test="count(@id|@key) > 1"> L'lment book doit avoir un seul des attributs id ou key </sch:report> </sch:rule> Chaque rgle peut bien sr contenir plusieurs lments sch:assert et sch:report comme dans l'exemple ci-dessous. L'ordre de ces diffrents lments est sans importance. <sch:rule context="tns:pattern[@is-a]"> <sch:assert test="key('patid', @is-a)"> L'attribut is-a doit rfrencer un bloc abstrait. </sch:assert> <sch:report test="@abstract = 'true'"> Un bloc avec un attribut is-a ne peut pas tre abstrait. </sch:report> <sch:report test="rule"> Un bloc avec un attribut is-a ne peut pas contenir de rgle. </sch:report> </sch:rule> Le texte contenu dans les lments sch:assert et sch:report peut aussi contenir des lments sch:name et sch:value-of qui permettent d'ajouter du contenu dynamique. Lors de la construction du rapport, ces lments sont valus et ils sont remplacs par le rsultat de l'valuation. L'lment sch:name s'value en le nom de l'lment sur lequel est appliqu la rgle. Il est particulirement utile dans les rgles abstraites [Section 7.6] et les blocs abstraits [Section 7.7] o le nom du contexte n'est pas fix. L'lment sch:value-of a un attribut select contenant une expression XPath. L'valuation de cette expression remplace l'lment sch:value-of dans le rapport. Un exemple d'utilisation de cet lment est donn la section suivante.
149
Schematron
150
Schematron
<!-- Rgle abstraite qui teste si le premier enfant est title --> <sch:rule abstract="true" id="has-title"> <sch:assert test="*[1][self::title]"> L'lment <sch:name/> doit avoir un enfant title qui doit tre le premier enfant. </sch:assert> </sch:rule> <!-- Utilisation de la rgle abstraite pour les lments book --> <sch:rule context="book"> <sch:extends rule="has-title"/> <sch:assert test="chapter"> Le livre soit contenir au moins un chapitre. </sch:assert> </sch:rule> <!-- Utilisation de la rgle abstraite pour les lments chapter --> <sch:rule context="chapter"> <sch:extends rule="has-title"/> <sch:assert test="para"> Le chapire soit contenir au moins un paragraphe. </sch:assert> </sch:rule> </sch:pattern> </sch:schema> Ce schematron permet de vrifier que le document suivant n'est pas correct. L'lment title n'est pas le premier enfant du second chapter et le troisime chapter n'a pas d'enfant title. <?xml version="1.0" encoding="utf-8" standalone="yes"?> <book> <title>Titre du livre</title> <chapter> <title>Premier chapitre</title> <para>Ceci est le premier chapitre ...</para> </chapter> <chapter> <para>Paragraphe avant le titre ...</para> <title>Titre mal plac</title> <para>Second paragraphe du second chapitre aprs le titre ...</para> </chapter> <chapter> <para>Chapitre sans titre</para> </chapter> </book>
151
Schematron
schematrons est l'analogue de l'lment xsl:with-param de XSLT. L'lment xsl:param de XSLT n'a pas d'quivalent dans les schematrons car les paramtres des blocs abstraits ne sont pas dclars. Le schematron suivant dfinit un bloc abstrait uniq qui contient deux rgles dpendant des paramtres elem et desc. La premire rgle vrifie que l'lment elem a au moins un descendant desc. La seconde vrifie au contraire qu'il n'a pas plus d'un descendant desc. Ces deux rgles conjugues vrifient donc que l'lment elem a exactement un seul descendant desc. Le bloc abstrait uniq est ensuite utilis par les deux blocs uniq-id et uniq-title. Le premier bloc donne les valeurs book et @id|@key aux deux paramtres elem et desc. Il vrifie donc que chaque lment book possde exactement un seul des deux attributs id et key. Le second bloc donne les valeurs book et title aux paramtres elem et desc. Il vrifie donc que chaque lment book possde exactement un seul enfant title. La vrification effectue par le premier bloc n'est pas faisable avec les DTD [Chapitre 3] et les schmas XML [Chapitre 5]. Les dclarations d'attributs de ces deux langages se font sur chacun des attributs de faon indpendante. Il n'est pas possible d'exprimer une contrainte qui met en relation deux attributs ou deux lments. <?xml version="1.0" encoding="utf-8"?> <sch:schema queryBinding="xslt" schemaVersion="ISO19757-3" xmlns:sch="http://purl.oclc.org/dsdl/schematron"> <sch:title>Utilisation de blocs abtraits</sch:title> <!-- Dclaration du bloc abstrait --> <sch:pattern abstract="true" id="uniq"> <!-- Les rgles utilisent les paramtres elem et desc --> <sch:rule context="$elem"> <sch:assert test="$desc"> L'lment <sch:name/> doit avoir un descendant $desc. </sch:assert> <sch:report test="count($desc) > 1"> L'lment <sch:name/> doit avoir un seul descendant $desc. </sch:report> </sch:rule> </sch:pattern> <!-- Utilisation du bloc abstrait --> <sch:pattern is-a="uniq" id="uniq-id"> <sch:param name="elem" value="book"/> <sch:param name="desc" value="@id|@key"/> </sch:pattern> <sch:pattern is-a="uniq" id="uniq-title"> <sch:param name="elem" value="book"/> <sch:param name="desc" value="title"/> </sch:pattern> </sch:schema> Le mcanisme des blocs abstraits est souvent implment comme les #define du langage C. Chaque bloc qui utilise un bloc abstrait est remplac par une copie de celui-ci o les paramtres sont substitus par leurs valeurs. Le schematron prcdent est en fait quivalent au schematron suivant. Le bloc abstrait uniq a disparu mais ses rgles apparaissent dupliques dans les deux blocs uniq-id et uniq-title. <?xml version="1.0" encoding="utf-8"?> <sch:schema queryBinding="xslt" schemaVersion="ISO19757-3" xmlns:sch="http://purl.oclc.org/dsdl/schematron"> <sch:title>Substitution des blocs abstraits</sch:title> <sch:pattern id="uniq-id"> <sch:rule context="book"> <sch:assert test="@id|@key"> L'lment <sch:name/> doit avoir un descendant @id|@key </sch:assert> <sch:report test="count(@id|@key) > 1">
152
Schematron
L'lment <sch:name/> doit avoir un seul descendant @id|@key </sch:report> </sch:rule> </sch:pattern> <sch:pattern id="uniq-title"> <sch:rule context="book"> <sch:assert test="title"> L'lment <sch:name/> doit avoir un descendant title </sch:assert> <sch:report test="count(title) > 1"> L'lment <sch:name/> doit avoir un seul descendant title </sch:report> </sch:rule> </sch:pattern> </sch:schema> L'exemple ci-dessous illustre la puissance des schematrons. Ce schematron exprime certaines contraintes que doivent satisfaire les schematrons pour tre valides. Ces contraintes portent sur les liens entre les lments pattern abstraits et ceux qui les utilisent. <?xml version="1.0" encoding="utf-8"?> <sch:schema queryBinding="xslt" schemaVersion="ISO19757-3" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <sch:title>Vrification des liens is-a des schematrons</sch:title> <sch:p>Ce schematron vrifie que, dans un schematron, tout bloc rfrenc par un autre bloc par l'attribut is-a est bien dclar abstrait par l'attribut abstract avec la valeur true.</sch:p> <!-- Dclaration de l'espace de noms cible : celui des schematrons --> <!-- Ne pas utiliser le prfixe sch car cela pose problme --> <sch:ns prefix="tns" uri="http://purl.oclc.org/dsdl/schematron"/> <!-- Cl pour retrouver les lments pattern par leur id --> <xsl:key name="patid" match="tns:pattern" use="@id"/> <sch:pattern> <sch:rule context="tns:pattern[@is-a]"> <sch:assert test="key('patid', @is-a)"> L'attribut is-a doit rfrencer un bloc abstrait. </sch:assert> <sch:report test="@abstract = 'true'"> Un bloc avec un attribut is-a ne peut pas tre abstrait. </sch:report> <sch:report test="rule"> Un bloc avec un attribut is-a ne peut pas contenir de rgle. </sch:report> </sch:rule> </sch:pattern> <sch:pattern> <sch:rule context="tns:pattern[@abstract = 'true']"> <sch:assert test="@id"> Un bloc abstrait doit avoir un attribut id. </sch:assert> <sch:report test="@is-a"> Un bloc abstrait ne peut pas avoir un attribut is-a. </sch:report>
153
Schematron
154
Chapitre 8. XSLT
Le langage XSL (pour XML Stylesheet Language) a t conu pour transformer des documents XML en d'autres formats comme PDF ou des pages HTML. Au cours de son dveloppement, le projet s'est avr plus complexe que prvu et il a t scind en deux units distinctes XSLT et XSL-FO. Le langage XSLT (pour XML Stylesheet Language Transformation) est un langage de transformation de documents XML. Le langage XSL-FO [Chapitre 9] (pour XML Stylesheet Language - Formatting Objets) est un langage de mise en page de document. Le processus de transformation d'un document XML en un document imprimable, au format PDF par exemple, est donc dcoup en deux phases. Dans la premire phase, le document XML est transform en un document XSL-FO l'aide de feuilles de style XSLT. Dans la seconde phase, le document FO obtenu la premire phase est converti par un processeur FO en un document imprimable. Mme si le langage XSlT puise son origine dans la transformation de documents XML en document XSL-FO, il est adapt la transformation d'un document de n'importe quel dialecte XML dans un document de n'importe quel autre dialecte XML. Il est souvent utilis pour produire des documents XSL-FO ou XHTML, il peut aussi produire des documents SVG [Chapitre 11]. Ce chapitre est consacr la partie XSLT de XSL. Le cours est essentiellement bas sur des exemples. Les diffrentes constructions du langage XSLT sont illustres pas des fragments de programmes extraits des exemples.
8.1. Principe
Le principe de fonctionnent de XSLT est le suivant. Une feuille de style XSLT contient des rgles qui dcrivent des transformations. Ces rgles sont appliques un document source XML pour obtenir un nouveau document XML rsultat. Cette transformation est ralise par un programme appel processeur XSLT. La feuille de style est aussi appele programme dans la mesure o il s'agit des instructions excuter par le processeur.
155
XSLT
Fe u ille d e s t yle s t yl e s he e t . xs l
Do c u m e n t s o u rc e s o u r c e . x ml
Do c u m e n t r s u lt a t r e s u l t . x ml
XSLT Pro c e s s o r
156
XSLT
157
XSLT
Chaque rgle est dclare par un lment xsl:template. Le contenu de cet lment est le fragment de document qui est produit par l'application de cette rgle. Ce contenu contient des lments de l'espace de noms XSLT et des lments d'autres espaces de noms. Ces derniers lments sont recopis l'identique pour former le fragment. Les lments de XSLT sont des instructions qui sont excutes par le processeur XSLT. Ces lments sont remplacs dans le fragment par le rsultat de leur excution. L'lment essentiel est l'lment xsl:apply-templates qui permet d'invoquer l'application d'autres rgles. Les fragments de document produits par ces applications de rgles remplacent l'lment xsl:apply-templates. L'endroit o se trouve l'lment xsl:apply-templates constitue donc le point d'ancrage pour l'insertion du ou des fragments produits par son excution. La forme globale d'une rgle est donc la suivante. <xsl:template match="..."> <!-- Fragment produit --> ... <!-- Application de rgles --> <xsl:apply-templates .... /> ... <!-- Application de rgles --> <xsl:apply-templates .... /> ... <xsl:template/> Chacune des rgles est dclare avec un lment xsl:template dont l'attribut match prcise sur quels nuds elle est susceptible d'tre applique. Le processus de transformation consiste appliquer des rgles sur des nuds actifs du documents source. Au dpart, seule la racine est active et la premire rgle est donc applique cette racine. L'application de chaque rgle produit un fragment de document qui va constituer une partie du document rsultat. Elle active d'autres nuds avec des lments xsl:apply-templates placs au sein du fragment de document. Des rgles sont alors appliques ces nouveaux nuds actifs. D'une part, elles produisent des fragments de documents qui s'insrent dans le document rsultat la place des lments xsl:apply-templates qui les ont provoques. D'autre part, elles activent ventuellement d'autres nuds pour continuer le processus. Ce dernier s'arrte lorsqu'il n'y a plus de nuds actifs. Le processus de transformation s'apparente donc un parcours de l'arbre du document source. Il y a cependant une diffrence importante. Dans un parcours classique d'un arbre comme les parcours en largeur ou en profondeur, le traitement d'un nud entrane le traitement de ses enfants. L'application d'une rgle XSLT active d'autres nuds mais ceux-ci ne sont pas ncessairement les enfants du nud sur lequel la rgle s'applique. Les nuds activs sont dtermins par l'attribut select des lments xsl:apply-templates. Chaque attribut select contient une expression XPath dont l'valuation donne la liste des nuds activs. La figure ci-dessous illustre la construction de l'arbre rsultat par l'application des rgles XSLT. Chacun des triangles marqus template reprsente un fragment de document produit par l'application d'une rgle. Tous ces triangles sont de mme taille sur la figure mme si les fragments ne sont pas identiques. Les flches marques apply-templates symbolisent l'application de nouvelles rgles par l'activation de nuds. L'arbre du document rsultat est, en quelque sorte, obtenu en contractant ces flches marques apply-templates et en insrant leur point de dpart le triangle sur lequel elles pointent. Les flches partant d'un mme triangle peuvent partir de points diffrents car un mme fragment de document peut contenir plusieurs lments xsl:applytemplates.
158
XSLT
t e mp l a t e a p p l y - t e mp l a t e s a p p l y - t e mp l a t e s
t e mp l a t e
t e mp l a t e
t e mp l a t e
a p p l y - t e mp l a t e s
t e mp l a t e
t e mp l a t e
t e mp l a t e
t e mp l a t e
8.4. Entte
Le programme ou feuille de style est entirement inclus dans un lment xsl:stylesheet ou de faon compltement quivalente un lment xsl:transform. L'attribut version prcise la version de XSLT utilise. Les valeurs possibles sont 1.0 ou 2.0. Un processeur XSLT 1.0 signale gnralement une erreur lorsque la feuille de style n'utilise pas cette version. Un processeur XSLT 2.0 passe dans un mode de compatibilit avec la version 1.0 lorsqu'il rencontre une feuille de style de XSLT 1.0. L'espace de noms des lments de XSLT doit tre dclar. Il est identifi par l'URI http://www.w3.org/1999/XSL/Transform. Le prfixe xsl est gnralement associ cet espace de noms. Dans tout ce chapitre, ce prfixe est utilis pour qualifier les lments XSLT. Il est aussi indispensable de dclarer les espaces de noms du document rsultat si celui-ci en utilise. Ces dclarations d'espaces de noms sont importantes car le contenu de chaque rgle contient un mlange d'lments XSLT et d'lments du document rsultat. Les processeurs XSLT ajoutent les dclarations ncessaires d'espaces de noms dans le document rsultat. Il arrive que certains espaces de noms soient dclars alors qu'ils ne sont pas indispensables. L'attribut excluderesult-prefixes de xsl:stylesheet permet d'indiquer que certains espaces de noms ne seront pas utiliss dans le document rsultat et que leurs dclarations doivent tre omises. Cet attribut contient une liste de prfixes spars par des espaces. Dans l'exemple suivant, les espaces de noms associs aux prfixes xsl (XSLT) et dbk (DocBook) ne sont pas dclars dans le document rsultat. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" exclude-result-prefixes="xsl dbk" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dbk="http://docbook.org/ns/docbook" xmlns="http://www.w3.org/1999/xhtml">
159
XSLT
... L'lment xsl:output doit tre un enfant de l'lment xsl:stylesheet. Il permet de contrler le format du document rsultat. Son attribut method qui peut prendre les valeurs xml, xhtml, html et text indique le type de document rsultat produit. Ses attributs encoding, doctype-public, doctype-system prcisent respectivement l'encodage du document, le FPI et l'URL de la DTD [Section 3.2.2]. Un exemple typique d'utilisation est le suivant. <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output method="xml" encoding="iso-8859-1" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" indent="yes"/>
160
XSLT
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <list> <sublist> <preserve> <p>a b c</p> <p> a b c </p> </preserve> <strip xml:space="preserve"> <p>a b c</p> <p> a b c </p> </strip> <strip> <p>a b c</p> <p> a b c </p> </strip> </sublist> <sublist xml:space="preserve"> <strip> <p>a b c</p> <p> a b c </p> </strip> <strip xml:space="default"> <p>a b c</p> <p> a b c </p> </strip> </sublist> </list> Si la feuille de style prcdente est applique au document prcdent, certains espaces sont supprims. Aucun des espaces contenus dans les lments p n'est supprim car ces lments ont un seul nud textuel comme enfant et ce nud textuel contient des caractres autres que des espaces. En revanche, des retours la ligne entre les balises <strip> et <p> ainsi que les espaces entre les balises </p> et <p> disparaissent car les nuds textuels qui les contiennent ne contiennent que des caractres d'espacement. <?xml version="1.0" encoding="iso-8859-1"?> <list> <sublist> <preserve> <p>a b c</p> <p> a b c </p> </preserve> <!-- La valeur "preserve" de l'attribut xml:space inhibe la suppression des espaces --> <strip xml:space="preserve"> <p>a b c</p> <p> a b c </p> </strip> <strip><p>a b c</p><p> a b c </p></strip> </sublist> <sublist xml:space="preserve"> <!-- La valeur "preserve" de l'attribut xml:space du parent inhibe la suppression des espaces --> <strip> <p>a b c</p> <p> a b c </p> </strip> <!-- La valeur "default" de l'attribut xml:space masque la valeur "preserve" de l'attribut du parent --> <strip xml:space="default"><p>a b c</p><p> a b c </p></strip> </sublist> </list>
161
XSLT
dfinition de rgle par un lment xsl:template prcise, par un motif XPath, les nuds sur lesquels elle s'applique. Chaque application de rgles par un lment xsl:apply-templates prcise les nuds actifs auxquels doit tre applique une rgle mais ne spcifie pas du tout la rgle appliquer. Le choix de la rgle appliquer chaque nud est fait par le processeur XSLT en fonction de priorits entre les rgles [Section 8.5.3]. Ces priorits sont dtermines partir des motifs XPath de chaque rgle. Ce principe de fonctionnement est le mode normal de fonctionnement de XSLT. Il est, cependant, utile l'occasion d'appliquer une rgle dtermine un nud. L'lment xsl:call-template permet l'appel explicite d'une rgle par son nom. Les dfinitions de rgles sont globales. Tous les lments xsl:template sont enfants de l'lment racine xsl:stylesheet et la porte des rgles est l'intgralit de la feuille de style. Au contraire, les lments xsl:apply-templates et xsl:call-template ne peuvent apparatre que dans le contenu d'un lment xsl:template.
162
XSLT
applique. Le rsultat de ces application de rgles remplace alors l'lment xsl:apply-templates dans le contenu de l'lment xsl:template pour former le rsultat de la rgle en cours d'application. L'expression XPath de l'attribut select slectionne, en gnral, plusieurs nuds. Sur chacun de ces nuds, est applique une seule rgle dpendant du nud. La rgle est choisie parmi les rgles o il y a concordance entre le motif XPath de l'attribut match et le nud. Lors de l'application la rgle choisie, chaque nud slectionn devient le nud courant du focus. Pour appliquer plusieurs rgles un mme nud, il faut plusieurs lments xsl:apply-templates. Il est, en particulier, possible d'avoir recours des modes [Section 8.11] pour appliquer des rgles diffrentes. La valeur par dfaut de l'attribut select est node() qui slectionne tous les enfants du nud courant, y compris les nuds textuels, les commentaires et les instructions de traitement. Pour slectionner uniquement les enfants qui sont des lments, il faut mettre la valeur '*'. Pour slectionner tous les attributs du nud courant, il faut mettre la valeur @* qui est l'abrviation de attribute::*. Il est, bien sr, possible de mettre toute expression XPath comme ancestor-or-self::p[@xml:lang][1]/@xml:lang. Une partie importante de la programmation XSLT rside dans les choix judicieux des valeurs des attributs select des lments xsl:apply-templates ainsi que des valeurs des attributs match des lments xsl:template. Dans la feuille de style suivante, la premire rgle qui s'applique la racine '/' cre la structure du document XHTML. Les enfants li de l'lment ul sont crs par les applications de rgles sur les lments book provoques par le premier lment xsl:apply-templates. Les contenus des lments li sont construits par les applications de rgles sur les enfants des lments book provoques par le second lment xsl:applytemplates. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:template match="/"> <html> <head><title>Bibliographie</title></head> <body> <h1>Bibliographie</h1> <ul><xsl:apply-templates select="bibliography/book"/></ul> </body> </html> </xsl:template> <xsl:template match="book"> <!-- Une entre (item) de la liste par livre --> <li><xsl:apply-templates select="*"/></li> </xsl:template> ... </xsl:stylesheet> Les nuds sur lesquels sont appliqus les rgles sont trs souvent des descendants et mme des enfants du nud courant mais ils peuvent galement tre trs loigns dans le document. Dans l'exemple suivant, les lments sont retourns par la fonction XPath id. Il faut remarquer que l'lment xsl:for-each change le focus et que l'expression XPath '.' ne dsigne plus le nud courant sur lequel s'applique la rgle. <xsl:template match="dbk:co"> <xsl:text>\includegraphics[scale=0.25]{images/callouts/</xsl:text> <xsl:number level="single" count="dbk:co" format="1"/> <xsl:text>.pdf}</xsl:text> </xsl:template> w<xsl:template match="dbk:callout"> <xsl:text>\item[</xsl:text> <!-- Parcours des lments rfrencs par l'attribut arearefs --> <xsl:for-each select="id(@arearefs)"> <xsl:apply-templates select="."/> </xsl:for-each>
163
XSLT
<xsl:text>]</xsl:text> <xsl:apply-templates/> </xsl:template> Les nuds slectionns par l'expression XPath de l'attribut select sont normalement traits dans l'ordre du document [Section 6.1.2]. L'lment xsl:apply-templates peut, nanmoins, contenir un ou plusieurs lments sort pour effectuer un tri [Section 8.8] des nuds slectionns.
8.5.3. Priorits
Lorsque plusieurs rgles peuvent s'appliquer un mme nud, le processeur XSLT choisit la plus approprie parmi celles-ci. Le choix de la rgle est d'abord dict par les priorits d'import [Section 8.15] entre les feuilles de style puis par les priorits entre les rgles. Le choix de la rgle appliquer s'effectue en deux tapes. La premire tape consiste ne conserver que les rgles de la feuille de style de priorit d'import maximale parmi les rgles applicables. Lorsqu'une feuille de style est importe par une autre feuille de style, elle a une priorit d'import infrieure celle qui l'importe. L'ordre des imports a galement une incidence sur les priorits d'import. La seconde tape consiste choisir, parmi les rgles restantes, celle qui a la priorit maximale. C'est une erreur s'il y en a plusieurs de priorit maximale. Le processeur XSLT peut signaler l'erreur ou continuer en choisissant une des rgles. La priorit d'une rgle est un nombre dcimal. Elle peut est fixe par un attribut priority de l'lment xsl:template. Sinon, elle prend une valeur par dfaut qui dpend de la forme du motif [Section 6.8] contenu dans l'attribut match. Les priorits par dfaut prennent des valeurs entre -0.5 et 0.5. Lorsque le motif est de la forme expr-1 | ... | expr-N, le processeur considre chacun des motifs expr-i de faon indpendante. Il fait comme si la rgle tait rpte pour chacun de ces motifs. L'axe n'a aucune incidence sur la priorit par dfaut. Celle-ci est dtermine par les rgles ci-dessous. -0.5 pour les motifs trs gnraux de la forme *, @*, node(), text(), comment() ainsi que le motif /, -0.25 pour les motifs de la forme *:name ou prefix:* comme *:p ou dbk:*, 0 pour les motifs de la forme name ou @name comme section ou @type, 0.5 pour tous les autres motifs comme chapter/section ou section[@type].
164
XSLT
<div style="text-align: right"> <xsl:next-match/> </div> </xsl:template> L'lment xsl:apply-imports permet d'appliquer au nud courant une rgle provenant d'une feuille de style importe [Section 8.15] par la feuille de style contenant la rgle en cours. La rgle applique est la rgle ayant une priorit maximale parmi les rgles provenant des feuilles de style importes. Cet lment est souvent utilis pour redfinir une rgle d'une feuille de style importe tout en utilisant la rgle redfinie. Dans l'exemple suivant, la feuille de style general.xsl contient une rgle pour les lments DocBook para. <!-- Feuille de style general.xsl --> <!-- Paragraphes --> <xsl:template match="dbk:para"> <p xsl:use-attribute-sets="para"><xsl:apply-templates/></p> </xsl:template> La feuille de style main.xsl importe la feuille de style general.xsl [Section 8.15]. Elle contient une nouvelle rgle pour les lments DocBook para. Cette rgle a une priorit d'import suprieure et elle est donc applique en priorit. Cette rgle fait appel la rgle contenue dans general.xsl par l'lment xsl:apply-imports. <!-- Feuille de style main.xsl --> <!-- Import de la feuille de style general.xsl --> <xsl:import href="general.xsl"/> <!-- Paragraphes aligns gauche --> <xsl:template match="dbk:para"> <div style="text-align: left"> <xsl:apply-imports/> </div> </xsl:template>
165
XSLT
<i><xsl:apply-templates/></i> <xsl:call-template name="comma"/> </xsl:template> <xsl:template match="url"> <!-- URL du livre en police fixe --> <tt><xsl:apply-templates/></tt> <xsl:call-template name="comma"/> </xsl:template> <xsl:template match="*"> <xsl:apply-templates/> <xsl:call-template name="comma"/> </xsl:template> <xsl:template name="comma"> <!-- Virgule si ce n'est pas le dernier --> <xsl:if test="position() != last()"> <xsl:text>, </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> Les deux lments xsl:apply-templates et xsl:call-template peuvent contenir des lments xsl:with-param pour spcifier les valeurs de paramtres [Section 8.9.2] que la rgle applique peut avoir dclars avec l'lment xsl:param.
166
XSLT
<html> <head> <title>Localized Hello World !</title> </head> <body> <h1><xsl:value-of select="text"/></h1> </body> </html> </xsl:template> Si la feuille de style ainsi modifie est applique au document suivant, on obtient un document XHTML o le contenu de l'lment h1 est maintenant Bonjour !. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <!-- lment text contenant le texte insr dans l'lment h1 --> <text>Bonjour !</text> Du contenu peut aussi tre construit par un lment xsl:apply-templates. Ce contenu est alors le rsultat de l'application de rgles aux lments slectionns par l'attribut select de xsl:apply-templates. On reprend le document bibliography.xml dj utilis au chapitre sur syntaxe [Chapitre 2]. La feuille de style suivante transforme le document bibliography.xml en un document XHTML qui prsente la bibliographie sous forme d'une liste avec une mise en forme minimaliste Cette feuille de style fonctionne de la manire suivante. La premire rgle est applique la racine du document source. Elle produit le squelette du document XHTML avec en particulier un lment ul pour contenir la liste des livres. Le contenu de cet lment ul est obtenu en appliquant une rgle chacun des lments book. La seconde rgle de la feuille de style est la rgle qui est applique aux lments book. Pour chacun de ces lments, elle produit un lment li qui s'insre dans le contenu de l'lment ul. Le contenu de l'lment li est, nouveau, produit en appliquant une rgle aux enfants de l'lment book. C'est la dernire rgle qui s'applique chacun de ces lments. Cette rgle se contente de rappeler rcursivement une rgle sur leurs enfants. La rgle par dfaut recopie alors les contenus textuels de ces lment. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <!-- Rgle pour la racine qui construit le squelette --> <xsl:template match="/"> <html> <head> <title>Bibliographie</title> </head> <body> <h1>Bibliographie</h1> <ul><xsl:apply-templates select="bibliography/book"/></ul> </body> </html> </xsl:template> <!-- Rgle pour les lments book --> <xsl:template match="book"> <!-- Une entre li de la liste par livre --> <li><xsl:apply-templates/></li> </xsl:template> <!-- Rgle pour les autres lments --> <xsl:template match="*"> <!-- Rcupration du texte par la rgle par dfaut --> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
167
XSLT
En appliquant la feuille de syle prcdente au document bibliography.xml, on obtient le document XHTML suivant dont l'indentation a t remanie pour une meilleure prsentation. <?xml version="1.0" encoding="UTF-8"?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Bibliographie</title> </head> <body> <h1>Bibliographie</h1> <ul> <li>XML langage et appplications Alain Michard 2001 Eyrolles 2-212-09206-7 http://www.editions-eyrolles/livres/michard/ </li> <li>Designing with web standards Jeffrey Zeldman 2003 New Riders 0-7357-1201-8 </li> ... </ul> </body> </html> Dans la feuille de style prcdente, plusieurs rgles sont susceptibles de s'appliquer aux lments book : la deuxime rgle dont la valeur de l'attribut match est book et la troisime dont la valeur de l'attribut match est '*'. Le processeur XSLT choisit la deuxime en raison des priorits attribues aux rgles en fonction du motif contenu dans l'attribut match. La prsentation de la bibliographie en XHTML obtenue avec le feuille de style prcdente est trs sommaire. Il est possible de l'amliorer en mettant, par exemple, le titre en italique et l'URL en fonte fixe. Il suffit, pour cela, d'ajouter deux rgles spcifiques pour les lments title et url. Les deux nouvelles rgles suivantes ont une priorit suprieure la dernire rgle de la feuille de style et elle est donc applique aux lments title et url. <!-- Rgle pour les lments title --> <xsl:template match="title"> <!-- Titre en italique --> <i><xsl:apply-templates/></i> </xsl:template> <!-- Rgle pour les lments url --> <xsl:template match="url"> <!-- URL en fonte fixe --> <tt><xsl:apply-templates/></tt> </xsl:template> Beaucoup de la programmation XSLT s'effectue en jouant sur les lments slectionns par les attributs match des lments xsl:apply-templates. La feuille de style suivante prsente la bibliographie en XHTML sous la forme de deux listes, une pour les livres en franais et une autre pour les livres en anglais. Le changement par rapport la feuille de style prcdente se situe dans la rgle applique la racine. Celle-ci contient maintenant deux lments xsl:apply-templates. Le premier active les livres en franais et le second les livres en anglais. <?xml version="1.0" encoding="iso-8859-1" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:template match="/"> <html> <head> <title>Bibliographie Franais/Anglais</title> </head> <body> <h1>Bibliographie en franais</h1>
168
XSLT
<!-- Traitement des livres avec l'attribut lang="fr" --> <ul><xsl:apply-templates select="bibliography/book[@lang='fr']"/></ul> <h1>Bibliographie en anglais</h1> <!-- Traitement des livres avec l'attribut lang="en" --> <ul><xsl:apply-templates select="bibliography/book[@lang='en']"/></ul> </body> </html> </xsl:template> <!-- Les autres rgles sont inchanges --> ... </xsl:stylesheet>
169
XSLT
170
XSLT
<!-- La valeur textuelle est retourne --> <xsl:value-of select="."/> </xsl:template> <!-- Rgle pour les intructions de traitement et les commentaires --> <!-- Suppression de ceux-ci car cette rgle ne retourne rien --> <xsl:template match="processing-instruction()|comment()"/> La rgle par dfaut des attributs est d'afficher leur valeur. La valeur des attributs n'apparaissent pas dans le rsultat ci-dessus car cette rgle par dfaut pour les attributs n'est pas invoque. En effet, la valeur par dfaut de l'attribut select de l'lment apply-templates est node() qui ne slectionne pas les attributs.
171
XSLT
La prsentation de la bibliographie en XHTML peut tre amliore par l'ajout de virgules ',' entre les proprits titre, auteur, de chacun des livres. L'lment xsl:text est alors ncessaire pour insrer les virgules. Il faut, en outre, grer l'absence de virgule la fin grce l'lment xsl:if [Section 8.7.1]. <!-- Rgle pour les autres lments --> <xsl:template match="*"> <xsl:apply-templates/> <!-- Virgule aprs ces lments --> <xsl:if test="position() != last()"> <xsl:text>, </xsl:text> </xsl:if> </xsl:template> Pour que le test position() != last() fonctionne correctement, il faut que la rgle applique aux lments book n'active pas les nuds textuels contenant des caractres d'espacements. Il faut, pour cela, remplacer la valeur par dfaut de l'attribut select par la valeur '*' qui ne slectionne que les enfants qui sont des lments et pas ceux de type text(). <!-- Rgle pour les lments book --> <xsl:template match="book"> <!-- Une entre li de la liste par livre --> <li><xsl:apply-templates select="*"/></li> </xsl:template>
172
XSLT
Quelques exemples d'utilisation de xsl:value-of. <xsl:value-of select="."/> <xsl:value-of select="generate-id()"/> <xsl:value-of select="key('idchapter', @idref)/title"/>
173
XSLT
groupes title et para. Le groupe title est utilis pour ajouter des attributs aux lments h1 et h2 construits par la feuille de style. Le groupe para est utilis pour ajouter des attributs aux lments p. Il faut remarquer que de nom l'attribut use-attribute-sets n'est pas qualifi lorsque celui-ci apparat dans un lment XSLT comme xsl:attribute-set alors qu'il est qualifi lorsque celui-ci apparat dans des lments hors de l'espace de noms XSLT comme h1 et p. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dbk="http://docbook.org/ns/docbook" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output ... /> <!-- Dfinition d'un groupe d'attribut text --> <xsl:attribute-set name="text"> <xsl:attribute name="align">left</xsl:attribute> </xsl:attribute-set> <!-- Dfinition d'un groupe d'attribut para pour les paragraphes --> <xsl:attribute-set name="para" use-attribute-sets="text"/> <!-- Dfinition d'un groupe d'attribut title pour les titres --> <xsl:attribute-set name="title" use-attribute-sets="text"> <xsl:attribute name="id" select="generate-id()"/> </xsl:attribute-set> <xsl:template match="/"> <xsl:comment>Generated by dbk2html.xsl</xsl:comment> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title><xsl:value-of select="dbk:book/dbk:title"/></title></head> <body><xsl:apply-templates/></body> </html> </xsl:template> <!-- lments non traits --> <xsl:template match="dbk:title|dbk:subtitle"/> <!-- Livre --> <xsl:template match="dbk:book"> <xsl:apply-templates/> </xsl:template> <!-- Chapitres --> <xsl:template match="dbk:chapter"> <h1 xsl:use-attribute-sets="title"><xsl:value-of select="dbk:title"/></h1> <xsl:apply-templates/> </xsl:template> <!-- Sections de niveau 1 --> <xsl:template match="dbk:sect1"> <h2 xsl:use-attribute-sets="title"><xsl:value-of select="dbk:title"/></h2> <xsl:apply-templates/> </xsl:template> <!-- Paragraphes --> <xsl:template match="dbk:para"> <p xsl:use-attribute-sets="para"><xsl:apply-templates/></p> </xsl:template> </xsl:stylesheet> Un document produit par cette feuille de style contient de multiples occurrences des mmes attributs avec les mmes valeurs. Il est prfrable d'utiliser CSS [Chapitre 10] qui permet de sparer le contenu de la prsentation et de rduire, du mme coup, la taille du fichier XHTML. Une feuille de style peut importer la feuille de style prcdente tout en redfinissant certains groupes d'attributs pour en modifier le comportement.
174
XSLT
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Import de la feuille de style prcdente --> <xsl:import href="dbk2html.xsl"/> <!-- Modification du groupe d'attributs text --> <xsl:attribute-set name="title"> <!-- Nouvelle valeur de l'attribut align --> <xsl:attribute name="align">center</xsl:attribute> </xsl:attribute-set> <!-- Modification du groupe d'attributa text --> <xsl:attribute-set name="para"> <!-- Ajout d'un d'attribut style --> <xsl:attribute name="style">font-family: serif</xsl:attribute> </xsl:attribute-set> </xsl:stylesheet>
175
XSLT
<xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> <!-- Rgle pour la racine et les lments autres que book --> <xsl:template match="/|*"> <xsl:copy> <!-- Copie explicite des attributs --> <xsl:copy-of select="@*"/> <!-- Copie explicite des enfants --> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- Rgle pour les lments book --> <xsl:template match="book"> <xsl:copy> <!-- Copie explicite des attributs autres que 'lang' --> <xsl:copy-of select="@*[name() != 'lang']"/> <!-- Ajout de l'lment lang --> <lang><xsl:value-of select="@lang"/></lang> <!-- Copie explicite des enfants --> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> En appliquant la feuille de style prcdente au document bibliography.xml, on obtient le document suivant. <?xml version="1.0" encoding="iso-8859-1"?> <bibliography> <book key="Michard01"> <lang>fr</lang> <title>XML langage et appplications</title> <author>Alain Michard</author> <year>2001</year> <publisher>Eyrolles</publisher> <isbn>2-212-09206-7</isbn> <url>http://www.editions-eyrolles/livres/michard/</url> </book> <book key="Zeldman03"> <lang>en</lang> <title>Designing with web standards</title> <author>Jeffrey Zeldman</author> <year>2003</year> <publisher>New Riders</publisher> <isbn>0-7357-1201-8</isbn> </book> <!-- Fichier tronqu --> ... </bibliography>
176
XSLT
<?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="xml" encoding="iso-8859-1" indent="yes"/> <xsl:template match="/"> <bibliography> <bibliodiv> <xsl:copy-of select="bibliography/book[@lang='fr']"/> </bibliodiv> <bibliodiv> <xsl:copy-of select="bibliography/book[@lang='en']"/> </bibliodiv> </bibliography> </xsl:template> </xsl:stylesheet>
8.6.11. Numrotation
Le rle de l'lment xsl:number est double. Sa premire fonction est de crer un entier ou une liste d'entiers pour numroter un lment. La seconde fonction est de formater cet entier ou cette liste. La seconde fonction est plutt adapte la numrotation. Pour formater un nombre de faon prcise, il est prfrable d'utiliser la fonction XPath format-number() [Section 8.6.12].
8.6.11.1. Formats
La fonction de formatage est relativement simple. L'attribut format de xsl:number contient une chane forme d'un prfixe, d'un indicateur de format et d'un suffixe. Le prfixe et le suffixe doivent tre forms de caractres non alphanumriques. Ils sont recopis sans changement. L'indicateur de format est remplac par l'entier. Le tableau suivant rcapitule les diffrents formats possibles. Le format par dfaut est 1. Format 1 01 a A i I Rsultat 1, 2, 3, , 9, 10, 11, 01, 02, 03, , 09, 10, 11, a, b, c, , z, aa, ab, A, B, C, , Z, AA, AB, i, ii, iii, iv, v, vi, vii, viii, ix, x, xi, I, II, III, IV, V, VI, VII, VIII, IX, X, XI,
177
XSLT
peut contenir plusieurs indicateurs de formats spars par des caractres non alphanumriques comme 1.1.1 ou [A-1-i].
2 2 .3 .2 21
Mo d e s in g le
Mo d e m u lt ip le
Mo d e a n y
178
XSLT
En appliquant la feuille de style au document prcdent, on obtient le document XML suivant. Chaque lment section contient en plus un numro calcul par xsl:number en mode single. <?xml version="1.0" encoding="iso-8859-1"?> <book> <chapter> <section>1 <section>1</section><section>2</section> </section> <section>2 <section>1</section><section>2</section> </section> </chapter> <chapter> <section>1 <section>1</section><section>2</section> </section> <section>2 <section>1</section><section>2</section> </section> </chapter> </book> Dans le mode multiple, l'lment xsl:number fournit une liste d'entiers qui est calcule de la faon suivante. Le nud de dpart est dtermin par l'attribut from qui contient un motif XPath. C'est l'anctre le plus proche du nud courant qui satisfait le motif de l'attribut from. Ensuite, on considre chacun des anctres entre le nud de dpart et le nud courant qui satisfait l'attribut count. Pour chacun de ces anctres, le nombre (plus une unit) de frres gauches qui satisfont le motif de count fournit un des entiers de la suite. Si l'lment xsl:number de la feuille de style prcdente est remplac par l'lment suivant, on obtient le document ci-dessous. Comme le format est A.1.i, chaque section contient un numro global form d'un numro de chapitre (A, B, ), d'un numro de section (1, 2, ) et d'un numro de sous-section (i, ii, ). Ces diffrents numros sont spars par les points '.' qui sont repris du format. <xsl:number level="multiple" count="chapter|section" format="A.1.i"/> <?xml version="1.0" encoding="iso-8859-1"?> <book> <chapter> <section>A.1 <section>A.1.i</section><section>A.1.ii</section> </section> <section>A.2 <section>A.2.i</section><section>A.2.ii</section> </section> </chapter> <chapter> <section>B.1 <section>B.1.i</section><section>B.1.ii</section> </section> <section>B.2 <section>B.2.i</section><section>B.2.ii</section> </section> </chapter> </book> Dans le mode any, le nud de dpart est gal au dernier nud avant le nud courant qui vrifie le motif donn par l'attribut from. Par dfaut le nud de dpart est la racine du document. Le numro est gal au nombre (augment d'une unit pour commencer avec 1) de nuds entre le nud de dpart et le nud courant qui satisfont le motif donn par l'attribut count.
179
XSLT
Si l'lment xsl:number de la feuille de style prcdente est remplac par l'lment suivant, on obtient le document ci-dessous. Chaque section contient son numro d'ordre dans le document car la valeur par dfaut de from est la racine du document. <xsl:number level="any" count="section" format="1"/> <?xml version="1.0" encoding="iso-8859-1"?> <book> <chapter> <section>1 <section>2</section><section>3</section> </section> <section>4 <section>5</section><section>6</section> </section> </chapter> <chapter> <section>7 <section>8</section><section>9</section> </section> <section>10 <section>11</section><section>12</section> </section> </chapter> </book> L'lment xsl:number suivant utilise l'attribut from pour limiter la numrotation des lments section aux contenus des lments chapter. En appliquant la feuille de style prcdente avec cet lment xsl:number, on obtient le document ci-dessous. Chaque section contient son numro d'ordre dans le chapitre. <xsl:number level="any" count="section" from="chapter" format="1"/> <?xml version="1.0" encoding="iso-8859-1"?> <book> <chapter> <section>1 <section>2</section><section>3</section> </section> <section>4 <section>5</section><section>6</section> </section> </chapter> <chapter> <section>1 <section>2</section><section>3</section> </section> <section>4 <section>5</section><section>6</section> </section> </chapter> </book>
180
XSLT
La fonction XPath format-number() permet de formater un nombre entier ou dcimal de faon plus prcise. Le premier paramtre est le nombre formater et le second est une chane de caractres qui dcrit le formatage effectuer. Cette fonction est inspire de la classe DecimalFormat de Java et elle s'apparente, par les formats utiliss, la fonction printf du langage C. Un troisime paramtre optionnel rfrence ventuellement un lment xsl:decimal-format pour changer la signification de certains caractres dans le format. Lorsqu'aucun lment xsl:decimal-format n'est rfrenc, le format est une chane de caractres forme des caractres '#', '0', '.', ',', '%', '' (de code hexadcimal x2030) et ';'. La signification de ces diffrents caractres est donne ci-dessous. La chane passe en second paramtre peut aussi contenir d'autres caractres qui sont recopis inchangs dans le rsultat. '#' position pour un chiffre '0' position pour un chiffre remplac ventuellement par 0 '.' position du point dcimal ',' position du sparateur de groupe (milliers, millions, ) ';' sparateur entre un format pour les nombres positifs et un format pour les nombres ngatifs. La chane de caractres passe en second paramtre format-number() peut contenir deux formats spars par un caractre ';' comme #000;-#00 par exemple. Le premier format #000 est alors utilis pour les nombres positifs et le second format -#00 pour les nombres ngatifs. Dans ce cas, le second format doit explicitement insrer le caractre '-' car c'est la valeur absolue du nombre qui est formate. En formatant les nombres 12 et -12 avec ce format #000;-#00, on obtient respectivement 012 et -12. La table ci-dessous donne quelques exemples de rsultats de la fonction format-number() avec des formats diffrents. Nombre\Format 1 123 1234 12.34 1.234 ## 1 123 1234 12 1 #### 1 123 1234 12 1 #,#00.## 01 123 1,234 12.34 01.23 ####.00 1.00 123.00 1234.00 12.34 1.23 0000.00 0001.00 0123.00 1234.00 0012.34 0001.23
181
XSLT
zero-digit caractre pour la position d'un chiffre remplac par '0' ('0' par dfaut) pattern-separator caractre pour sparer deux formats pour les nombres positifs et les nombres ngatifs (';' par dfaut) percent caractre pour formater les pourcentages ('%' par dfaut) per-mille caractre pour formater les millimes ('' par dfaut) Les lments xsl:decimal-format doivent tre enfants de l'lment racine xsl:stylesheet de la feuille de style et leur porte est globale. Ils peuvent tre rfrencs par la fonction format-number() dans n'importe quelle expression XPath de la feuille de style. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Format des nombres en englais --> <xsl:decimal-format name="en" decimal-separator="." grouping-separator=","/> <!-- Format des nombres en franais --> <xsl:decimal-format name="fr" decimal-separator="," grouping-separator="."/> ... <price xml:lang="en-GB" currency="pound"> <xsl:value-of select="format-number($price, '###,###,###.##', 'en')"/> </price> ... <price xml:lang="fr" currency="euro"> <xsl:value-of select="format-number($price, '###.###.###,##', 'fr')"/> </price> ...
XSLT
L'lment xsl:choose permet de raliser plusieurs tests conscutivement. Il contient des lments xsl:when et ventuellement un lment xsl:otherwise. Chacun des lments xsl:when possde un attribut test contenant une expression XPath servant de condition. Les conditions contenues dans les attributs test des lments xsl:when sont values puis converties en valeur boolenne [Section 6.3.1] dans l'ordre des lments xsl:when Le contenu du permier lment xsl:when dont la condition donne la valeur true est pris en compte et les contenus des autres xsl:when et d'un ventuel xsl:otherwise sont ignors. Si aucune condition ne donne la valeur true, le contenu de l'lment xsl:otherwise est pris en compte et les contenus de tous les lments xsl:when sont ignors. Le fragment de feuille de style retourne le contenu de l'enfant title de nud courant si cet enfant existe ou construit un titre avec un numro sinon. <xsl:choose> <xsl:when test="title"> <xsl:value-of select="title"/> </xsl:when> <xsl:otherwise> <xsl:text>Section </xsl:text> <xsl:number level="single" count="section"/> </xsl:otherwise> </xsl:choose>
183
XSLT
<xsl:for-each select="bibliography/book"> <xsl:sort select="author" order="ascending"/> <tr> <td><xsl:number value="position()" format="1"/></td> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="author"/></td> <td><xsl:value-of select="publisher"/></td> <td><xsl:value-of select="year"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> En appliquant la feuille de style prcdente au document bibliography.xml, on obtient le document suivant. <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Bibliographie en tableau</title> </head> <body> <h1>Bibliographie en tableau</h1> <table align="center" border="1" cellpadding="2" cellspacing="0"> <tr> <th>Numéro</th> <th>Titre</th> <th>Auteur</th> <th>Éditeur</th> <th>Année</th> </tr> <tr> <td>1</td> <td>XML langage et appplications</td> <td>Alain Michard</td> <td>Eyrolles</td> <td>2001</td> </tr> <!-- Fichier tronqu --> ... </table> </body> </html>
184
XSLT
L'attribut select de cet lment utilise la fonction current-group() qui retourne la liste des objets du groupe. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output method="xhtml" encoding="iso-8859-1" indent="yes"/> <xsl:template match="/"> <html> <head> <title>Bibliographie par anne</title> </head> <body> <h1>Bibliographie par anne</h1> <!-- Regroupement des livres par annes --> <xsl:for-each-group select="bibliography/book" group-by="year"> <!-- Tri des groupes par annes --> <xsl:sort select="current-grouping-key()"/> <!-- Titre avec l'anne --> <h2> <xsl:text>Anne </xsl:text> <xsl:value-of select="current-grouping-key()"/> </h2> <!-- Liste des livres de l'anne --> <ul> <!-- Traitement de chacun des lments du groupe --> <xsl:for-each select="current-group()"> <!-- Tri des lments du groupe par auteur puis publisher --> <xsl:sort select="author"/> <xsl:sort select="publisher"/> <xsl:apply-templates/> </xsl:for-each> </ul> </xsl:for-each-group> </body> </html> </xsl:template> <!-- Rgle pour les lments title --> <xsl:template match="title"> <i><xsl:apply-templates/></i> <xsl:call-template name="separator"/> </xsl:template> <!-- Rgle pour les autres lments --> <xsl:template match="*"> <xsl:apply-templates/> <xsl:call-template name="separator"/> </xsl:template> <!-- Virgule aprs les lments --> <xsl:template name="separator"> <xsl:if test="position() != last()"> <xsl:text>, </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> En appliquant la feuille de style prcdente au document bibliography.xml, on obtient le document suivant. <?xml version="1.0" encoding="iso-8859-1"?>
185
XSLT
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Bibliographie par anne</title> </head> <body> <h1>Bibliographie par anne</h1> <h2>Anne 2000</h2> <ul> <li><i>XML by Example</i>, Benot Marchal, 2000, Macmillan Computer Publishing, 0-7897-2242-9</li> ... </ul> <h2>Anne 2001</h2> ... </body> </html> La feuille de style suivante donne un exemple classique d'utilisation de l'lment xsl:for-each-group. Celle-ci effectue une transformation d'un document XHTML en un document DocBook. Pour simplifier, on se contente de sous-ensembles trs restreints de ces deux dialectes XML. On considre uniquement les lments html, body, h1, h2 et p de XHTML et des lments book, chapter, sect1, title et para de DocBook. Ces deux langages organisent un document de manires diffrentes. Dans un document XHTML, les chapitres et les sections sont uniquement dlimits par les titres h1 et h2. Au contraire, dans un document DocBook, les lments chapter et sect1 encapsulent les chapitres et les sections. Ces diffrences rendent plus difficile la transformation de XHTML vers DocBook. Pour trouver le contenu d'un chapitre, il est ncessaire de regrouper tous les lments placs entre deux lments h1 conscutifs. L'lment xsl:for-each-group permet justement de raliser facilement cette opration. L'espace de noms par dfaut de la feuille de style est celui de DocBook. Les noms des lments XHTML doivent ainsi tre qualifis par le prfixe html associ l'espace de noms de XHTML. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://docbook.org/ns/docbook" exclude-result-prefixes="xsl html"> <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> <xsl:template match="/"> <book> <xsl:apply-templates select="html:html/html:body"/> </book> </xsl:template> <xsl:template match="html:body"> <!-- Regroupement des lments avec l'lment h1 qui prcde --> <xsl:for-each-group select="*" group-starting-with="html:h1"> <chapter> <!-- Titre avec le contenu de l'lment h1 --> <title><xsl:value-of select="current-group()[1]"/></title> <!-- Traitement du groupe --> <!-- Regroupement des lments avec l'lment h2 qui prcde --> <xsl:for-each-group select="current-group()" group-starting-with="html:h2"> <xsl:choose> <xsl:when test="local-name(current-group()[1]) = 'h2'"> <sect1>
186
XSLT
<!-- Titre avec le contenu de l'lment h2 --> <title><xsl:value-of select="current-group()[1]"/></title> <xsl:apply-templates select="current-group()"/> </sect1> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </chapter> </xsl:for-each-group> </xsl:template> <!-- Supression des lments h1 et h2 --> <xsl:template match="html:h1|html:h2"/> <!-- Transformation des lments p en lments para --> <xsl:template match="html:p"> <para><xsl:apply-templates/></para> </xsl:template> </xsl:stylesheet> Le document suivant est le document XHTML sur lequel est appliqu la tranformation. Celui-ci reprsente le squelette typique d'un document XHTML avec des titres de niveaux 1 et 2 et des paragraphes. <?xml version="1.0" encoding="iso-8859-1" ?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <title>Fichier HTML exemple</title> </head> <body> <h1>Titre I</h1> <p>Paragraphe I.0.1</p> <h2>Titre I.1</h2> <p>Paragraphe I.1.1</p> <p>Paragraphe I.1.2</p> <h2>Titre I.2</h2> <p>Paragraphe I.2.1</p> <p>Paragraphe I.2.2</p> <h1>titre II</h1> <p>Paragraphe II.0.1</p> <h2>Titre II.1</h2> <p>Paragraphe II.1.1</p> <p>Paragraphe II.1.2</p> <h2>Titre II.2</h2> <p>Paragraphe II.2.1</p> <p>Paragraphe II.2.2</p> </body> </html> Le document suivant est le document DocBook obtenu par transformation par la feuille de style prddente du document XHTML prcdent. Les deux lments h1 du document XHTML donnent deux lments chapter dans le document DocBook. <?xml version="1.0" encoding="iso-8859-1"?> <book xmlns="http://docbook.org/ns/docbook"> <chapter> <title>Titre I</title> <para>Para I.0.1</para> <sect1>
187
XSLT
<title>Titre I.1</title> <para>Para I.1.1</para> <para>Para I.1.2</para> </sect1> <sect1> <title>Titre I.2</title> <para>Para I.2.1</para> <para>Para I.2.2</para> </sect1> </chapter> <chapter> <title>titre II</title> <para>Para II.0.1</para> <sect1> <title>Titre II.1</title> <para>Para II.1.1</para> <para>Para II.1.2</para> </sect1> <sect1> <title>Titre II.2</title> <para>Para II.2.1</para> <para>Para II.2.2</para> </sect1> </chapter> </book>
8.8. Tris
L'lment xsl:sort permet de trier des lments avant de les traiter. L'lment xsl:sort doit tre le premier fils des lments xsl:apply-templates, xsl:call-template, xsl:for-each ou xsl:foreach-group. Le tri s'applique tous les lments slectionns par l'attribut select de ces diffrents lments. Le fragment de feuille de style suivant permet par exemple de trier les lments book par auteur par ordre croissant. <xsl:apply-templates select="bibliography/book"> <xsl:sort select="author" order="ascending"/> </xsl:apply-templates>
L'attribut select de xsl:sort dtermine la cl du tri. L'attribut data-type qui peut prendre les valeurs number ou text spcifie comment les cls doivent tre interprtes. Il est possible d'avoir plusieurs cls de tri en mettant plusieurs lments xsl:sort comme dans l'exemple suivant. Les lments book sont d'abord tris par auteur puis par anne. <xsl:apply-templates select="bibliography/book"> <xsl:sort select="author" order="ascending"/> <xsl:sort select="year" order="descending"/> </xsl:apply-templates>
Le tri ralis par xsl:sort est bas sur les valeurs retournes par l'expression XPath contenue dans l'attribut select. Cette expression est souvent le nom d'un enfant ou d'un attribut mais elle peut aussi tre plus complexe. La feuille de style suivante rordonne les enfants des lments book. L'expression contenue dans l'attribut select de xsl:sort retourne un numro d'ordre en fonction du nom de l'lment. Ce numro est calcul avec la fonction index-of() et une liste de noms dans l'ordre souhait. Cette solution donne une expression concise. Elle a aussi l'avantage que l'ordre est donn par une liste qui peut tre fixe ou calcule. Cette liste peut, par exemple, tre la liste des noms des enfants du premier lment book.
188
XSLT
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> <!-- Liste des noms des enfants du premier lment book --> <xsl:variable name="orderlist" as="xsd:string*" select="/bibliography/book[1]/*/name()"/> ... <xsl:template match="book"> <xsl:copy> <!-- Copie des attributs --> <xsl:copy-of select="@*"/> <xsl:apply-templates> <!-- Tri des enfants dans l'ordre donn par la liste fixe --> <!-- Les noms absents de la liste sont placs la fin --> <xsl:sort select="(index-of(('title', 'author', 'publisher', 'year', 'isbn'), name()),10)[1]"/> <!-- Tri dans l'ordre des enfants du premier lment book --> <!-- <xsl:sort select="index-of($orderlist, name())"/> --> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
189
XSLT
l'lment xsl:variable et les paramtres par l'lment xsl:param. L'lment xsl:with-param permet d'instancier un paramtre lors de l'appel une rgle.
8.9.1. Variables
La valeur de la variable est fixe au moment de sa dclaration par l'lment xsl:variable et ne peut plus changer ensuite. Les variables ne sont donc pas vraiment variables. Il s'agit d'objets non mutables dans la terminologie des langages de programmation. La porte de la variable est l'lment XSLT qui la contient. Les variables dont la dclaration est enfant de l'lment xsl:stylesheet sont donc globales. L'attribut name dtermine le nom de la variable. La valeur est donne soit par une expression XPath dans l'attribut select soit directement dans le contenu de l'lment xsl:variable. Un attribut optionnel as peut spcifier le type de la variable. Les types possibles sont les types XPath [Section 6.1.4]. Dans l'exemple suivant, les deux variables squares et cubes sont dclares de type xsd:integer*. Chacune d'elles contient donc une liste ventuellement vide d'entiers. La valeur de la variable square est donne par l'lment xsl:sequence contenu dans l'lment xsl:variable. La valeur de la variable cubes est donne par l'expression XPath de l'attribut select. <xsl:variable name="squares" as="xsd:integer*"> <xsl:for-each select="1 to 5"> <xsl:sequence select=". * ."/> </xsl:for-each> </xsl:variable> <xsl:variable name="cubes" as="xsd:integer*" select="for $i in 1 to 5 return $i * $i * $i"/> Une variable dclare peut apparatre dans une expression XPath en tant prcde du caractre '$' comme dans l'exemple suivant. <xsl:value-of select="$squares"/> Une variable permet aussi de mmoriser un ou plusieurs nuds. Il est parfois ncessaire de mmoriser le nud courant dans une variable afin de pouvoir y accder dans une expression XPath qui modifie contexte dynamique [Section 6.1.5.2]. Le fragment de feuille de style mmorise le nud courant dans la variable current. Elle l'utilise ensuite pour slectionner les lments publisher dont l'attribut id est gal l'attribut by du nud courant. <xsl:variable name="current" select="."/> <xsl:xsl:copy-of select="//publisher[@id = $current/@by]"/> XSLT 2.0 a introduit une fonction current() qui retourne le nud courant. Il n'est plus ncessaire de le stocker dans une variable. L'exemple prcdent pourrait tre rcrit de la faon suivante. <xsl:xsl:copy-of select="//publisher[@id = current()/@by]"/> L'expression XPath //publisher[@id = $current/@by] n'est pas trs efficace car elle ncessite un parcours complet du document pour retrouver le bon lment publisher. Elle peut avantageusement tre remplace par un appel la fonction key(). Il faut au pralable crer avec xsl:key [Section 8.12] un index des lments publisher par leur attribut id. Cette approche est dveloppe dans l'exemple suivant. Une variable peut aussi tre utilise, dans un souci d'efficacit pour mmoriser un rsultat intermdiaire. Dans l'exemple suivant, le nud retourn par la fonction key() est mmoris dans la variable result puis utilis plusieurs reprises. <!-- Indexation des lments publisher par leur attribut id --> <xsl:key name="idpublisher" match="publisher" use="@id"/> ... <!-- Sauvegarde du noeud recherch --> <xsl:variable name="result" select="key('idpublisher', @by)"/>
190
XSLT
<publisher> <!-- Utilisation multiple du noeud --> <xsl:copy-of select="$result/@*[name() != 'id']"/> <xsl:copy-of select="$result/* | $result/text()"/> </publisher> L'lment xsl:variable permet galement de dclarer des variables locales lors de la dfinition de fonctions d'extension XPath [Section 8.10].
8.9.2. Paramtres
Il existe des paramtres XSLT qui s'apparentent aux paramtres des fonctions des langages classiques comme C ou Java. Ils servent transmettent des valeurs la feuille de style et aux rgles. Les paramtres sont dclars par l'lment xsl:param qui permet galement de donner une valeur par dfaut comme en C++. Cet lment peut tre enfant de l'lment racine xsl:stylesheet ou des lments xsl:template. Dans le premier cas, le paramtre est global et dans le second cas, il est local la rgle dclare par xsl:template. Comme avec l'lment xsl:variable, l'attribut name de l'lment xsl:param dtermine le nom du paramtre. La valeur par dfaut est optionnelle. Elle est donne soit par une expression XPath dans l'attribut select soit directement dans le contenu de l'lment xsl:param. Un attribut optionnel as peut spcifier le type du paramtre [Section 6.1.4]. Le fragment suivant dclare un paramtre bg-color avec une valeur par dfaut gale la chane de caractres white. <xsl:param name="bg-color" select="'white'"/> Les apostrophes ''' sont ncessaires autour de la chane white car la valeur de l'attribut select est une expression XPath. La mme dclaration peut galement prendre la forme suivante sans les apostrophes. <xsl:param name="bg-color">white<xsl:param/>
191
XSLT
body { background-color: <xsl:value-of select="$bg-color"/>; } </xsl:comment> </style> </head> <body><xsl:apply-templates/></body> </html> </xsl:template> ... </xsl:stylesheet> Pour changer la couleur de fond du document rsultat, il faut donner une autre valeur au paramtre bg-color comme dans l'exemple suivant. xsltproc --stringparam bg-color blue dbk2html.xsl dbk2html.xml
192
XSLT
</xsl:copy> </xsl:template> <!-- Retourne un attribut id --> <xsl:template name="get-id"> <!-- Paramtre avec le noeud courant comme valeur par dfaut --> <xsl:param name="node" as="node()" select="."/> <xsl:attribute name="id" select="($node/@id, $node/@xml:id, generate-id($node))[1]"/> </xsl:template> </xsl:stylesheet> L'lment xsl:param est galement utilis pour dclarer les paramtres des fonctions d'extension XPath [Section 8.10]. La rgle get-id de la feuille de style prcdente aurait aussi pu tre remplace par une fonction d'extension. Dans la feuille de style suivante, la fonction XPath get-id() calcule la valeur de l'attribut id partir des attributs id et xml:id du nud pass en paramtre. <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:fun="http://www.liafa.jussieur.fr/~carton"> <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> <!-- Dfinition de la fonction d'extension get-id --> <xsl:function name="fun:get-id" as="xsd:string"> <xsl:param name="node" as="node()"/> <xsl:sequence select="($node/@id, $node/@xml:id, generate-id($node))[1]"/> </xsl:function> <xsl:template match="/"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="*"> <xsl:copy> <!-- Ajout de l'attribut id --> <xsl:attribute name="id" select="fun:get-id(.)"/> <xsl:apply-templates select="*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
8.9.3. Rcursivit
XPath 2.0 a ajout des fonctions qui facilitent le traitement des chanes de caractres. Avec XSLT 1.0 et XPath 1.0, il est souvent ncessaire d'avoir recours des rgles rcursives pour certains traitements. Les deux rgles quote.string et quote.string.char donnes ci-dessous insrent un caractre '\' avant chaque caractre '\' ou '"' d'une chane. <!-- Insertion de '\' avant chaque caractre '"' et '\' du contenu --> <xsl:template match="text()"> <xsl:call-template name="quote.string"> <xsl:with-param name="string" select="."/> </xsl:call-template> </xsl:template> <!-- Insertion de '\' avant chaque caractre '"' et '\' du paramtre string --> <xsl:template name="quote.string"> <!-- Chane reue en paramtre --> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, '"')">
193
XSLT
<xsl:call-template name="quote.string.char"> <xsl:with-param name="string" select="$string"/> <xsl:with-param name="char" select="'"'"/> </xsl:call-template> </xsl:when> <xsl:when test="contains($string, '\')"> <xsl:call-template name="quote.string.char"> <xsl:with-param name="string" select="$string"/> <xsl:with-param name="char" select="'\'"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string"/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Fonction auxiliare pour quote.string --> <xsl:template name="quote.string.char"> <!-- Chane reue en paramtre --> <xsl:param name="string"/> <!-- Caractre reu en paramtre --> <xsl:param name="char"/> <xsl:variable name="prefix"> <xsl:call-template name="quote.string"> <xsl:with-param name="string" select="substring-before($string, $char)"/> </xsl:call-template> </xsl:variable> <xsl:variable name="suffix"> <xsl:call-template name="quote.string"> <xsl:with-param name="string" select="substring-after($string, $char)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="concat($prefix, '\', $char, $suffix)"/> </xsl:template> Ce traitement pourrait tre ralis de faon plus concise avec la fonction XPath 2.0 replace(). <!-- Insertion de '\' avant chaque caractre '"' et '\' du contenu --> <xsl:template match="text()"> <xsl:value-of select="replace(., '(["\\])', '\\$1')"> </xsl:template>
194
XSLT
<xsl:template match="/"> <xsl:apply-templates select="text"> <xsl:with-param name="tunnel" select="'tunnel'" tunnel="yes"/> <xsl:with-param name="lunnet" select="'lunnet'"/> </xsl:apply-templates> </xsl:template> <xsl:template match="text"> <xsl:apply-templates select="text()"/> </xsl:template> <xsl:template match="text()"> <!-- L'attribut tunnel="yes" est ncessaire --> <xsl:param name="tunnel" select="'default'" tunnel="yes"/> <xsl:param name="lunnet" select="'default'"/> <!-- Produit la valeur 'tunnel' fournie au dpart --> <xsl:value-of select="$tunnel"/> <!-- Produit la valeur 'default' dclare par dfaut --> <xsl:value-of select="$lunnet"/> </xsl:template> </xsl:stylesheet>
195
XSLT
Une fois dfinie, la fonction url:protocol peut tre utilise comme n'importe quelle autre fonction XPath. L'exemple suivant cre un nud texte contenant http. <xsl:value-of select="url:protocol('http://www.liafa.jussieu.fr/')"/> La fonction url:protocol peut tre utilise pour dfinir une nouvelle fonction url:address qui extrait la partie adresse internet d'une URL. Cette fonction utilise une variable locale protocol pour stocker le rsultat de la fonction url:protocol. <xsl:function name="url:address" as="xsd:string"> <xsl:param name="url" as="xsd:string"/> <xsl:variable name="protocol" as="xsd:string" select="url:protocol($url)"/> <xsl:sequence select=" if (($protocol eq 'file') or ($protocol eq '')) then '' else substring-before(substring-after($url, '://'), '/')"/> </xsl:function> L'expression XPath url:address('http://www.liafa.jussieu.fr/~carton/') s'value, par exemple, en la chane de caractres www.liafa.jussieu.fr. Les fonctions dfinies par xsl:function peuvent bien sr tre rcursives. La fonction rcursive suivante url:file extrait le nom du fichier d'un chemin d'accs. C'est la chane de caractres situe aprs la dernire occurrence du caractre '/'. <xsl:function name="url:file" as="xsd:string"> <xsl:param name="path" as="xsd:string"/> <xsl:sequence select=" if (contains($path, '/')) then url:file(substring-after($path, '/')) else $path"/> </xsl:function> L'expression XPath url:file('Enseignement/XML/index.html') s'value, par exemple, en la chane de caractres index.html. Une fonction XPath est identifie par son nom qualifi et son arit (nombre de paramtres). Il est ainsi possible d'avoir deux fonctions de mme nom pouvu qu'elles soient d'arits diffrentes. Ceci permet de simuler des paramtres avec des valeurs par dfaut en donnant plusieurs dfinitions d'une fonction avec des nombres de paramtres diffrents. Dans l'exemple suivant, la fonction fun:join-path est dfinie une premire fois avec trois paramtres. La seconde dfinition avec seulement deux paramtres permet d'omettre le troisime paramtre qui devient ainsi optionnel. <!-- Dfinition d'une fonction join-path avec 3 paramtres --> <xsl:function name="fun:join-path" as="xsd:string"> <xsl:param name="path1" as="xsd:string"/> <xsl:param name="path2" as="xsd:string"/> <xsl:param name="sep" as="xsd:string"/> <xsl:sequence select="concat($path1, $sep, $path2)"/> </xsl:function> <!-- Dfinition d'une fonction join-path avec 2 paramtres --> <xsl:function name="fun:join-path" as="xsd:string"> <xsl:param name="path1" as="xsd:string"/> <xsl:param name="path2" as="xsd:string"/> <xsl:sequence select="concat($path1, '/' , $path2)"/> </xsl:function> ... <!-- Appel de la fonction 3 paramtres --> <xsl:value-of select="fun:join-path('Directory', 'index.html', '/')"/> <!-- Appel de la fonction 2 paramtres -->
196
XSLT
8.11. Modes
Il est frquent qu'une feuille de style traite plusieurs fois les mmes nuds du document d'entre pour en extraire divers fragments. Ces diffrents traitements peuvent tre distingus par des modes. Chaque rgle de la feuille de style dclare pour quel mode elle s'applique avec l'attribut mode de l'lment xsl:template. En parallle, chaque application de rgles avec xsl:apply-templates spcifie un mode avec un attribut mode. Chaque mode est identifi par un identificateur. Il existe en outre les valeurs particulires #default, #all et #current qui peuvent apparatre dans les valeurs des attributs mode. La valeur de l'attribut mode de l'lment xsl:template est soit la valeur #all soit une liste de modes, y compris #default, spars par des espaces. La valeur #current n'a pas de sens dans ce contexte et ne peut pas apparatre. La valeur par dfaut est bien sr #default. <!-- Rgle applicable avec le mode #default --> <xsl:template match="..."> ... <!-- Rgle applicable avec le mode test --> <xsl:template match="..." mode="test"> ... <!-- Rgle applicable avec les modes #default foo et bar --> <xsl:template match="..." mode="#default foo bar"> ... <!-- Rgle applicable avec tous les modes --> <xsl:template match="..." mode="#all"> ... La valeur de l'attribut mode de l'lment xsl:apply-templates est soit #default soit #current soit le nom d'un seul mode. La valeur #all n'a pas de sens dans ce contexte et ne peut pas apparatre. La valeur #current permet appliquer des rgles avec le mme mode que celui de la rgle en cours. La valeur par dfaut est encore #default. <!-- Application avec le mode #default --> <xsl:apply-templates select="..."/> ... <!-- Application avec le mode test --> <xsl:apply-templates select="..." mode="test"/> ... <!-- Application avec le mode dj en cours --> <xsl:apply-templates select="..." mode="#current"/> ... Dans l'exemple suivant, le nud text est trait d'abord dans le mode par dfaut #default puis dans le mode test. Dans chacun de ces traitements, ses fils textuels sont traits d'abord dans le mode par dfaut puis dans son propre mode de traitement. Les fils textuels sont donc, au final, traits trois fois dans le mode par dfaut et une fois dans le mode test. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="iso-8859-1"/> <xsl:template match="/"> <xsl:apply-templates select="text"/> <xsl:apply-templates select="text" mode="test"/> </xsl:template> <xsl:template match="text" mode="#default test"> <xsl:apply-templates select="text()"/>
197
XSLT
<xsl:apply-templates select="text()" mode="#current"/> </xsl:template> <xsl:template match="text()"> <xsl:text>Mode #default: </xsl:text> <xsl:value-of select="."/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="text()" mode="test"> <xsl:text>Mode test: </xsl:text> <xsl:value-of select="."/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> L'exemple suivant illustre une utilisation classique des modes. Le document est trait une premire fois en mode toc pour en extraire une table des matires et une seconde fois pour crer le corps du document proprement dit. <!-- Rgle pour la racine --> <xsl:template match="/"> <html> <head> <title><xsl:value-of select="book/title"/></title> </head> <body> <!-- Fabrication de la table des matires --> <xsl:apply-templates mode="toc"/> <!-- Fabrication du corps du document --> <xsl:apply-templates/> </body> </html> </xsl:template> ... <!-- Rgles pour la table des matires --> <xsl:template match="book" mode="toc"> <h1>Table des matires</h1> <ul><xsl:apply-templates mode="toc"/></ul> </xsl:template>
8.12. Indexation
La fonction id() [Section 6.1.1.2] permet de retrouver des nuds dans un document partir de leur attribut de type ID [Section 3.7.2]. Elle prend en paramtre une liste de noms spars par des espaces. Elle retourne une liste contenant les lments dont la valeur de l'attribut de type ID est un des noms passs en paramtre. Cette fonction est typiquement utilise pour traiter des attributs de type IDREF ou IDREFS. Ces attributs servent rfrencer des lments du document en donnant une (pour IDREF) ou plusieurs (pour IDREFS) valeurs d'attibuts de type ID. La fonction id() permet justement de retrouver ces lments rfrencs. L'exemple suivant illustre l'utilisation classique de la fonction id(). On suppose avoir un document contenant une bibliographie o les diteurs ont t placs dans une section spare du document. Chaque lment book contient un lment published ayant un attribut by de type IDREF pour identifier l'lment publisher correspondant dans la liste des dideurs. La feuille de style suivante permet de revenir une bibliographie o chaque lment book contient directement l'lment publisher correspondant. L'lment retourn par la fonction id() est stock dans une variable [Section 8.9] pour l'utiliser plusieurs reprises. <?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="xml" encoding="iso-8859-1" indent="yes"/> <!-- Rgle pour la racine -->
198
XSLT
<xsl:template match="/"> <bibliography> <xsl:apply-templates select="bibliography/books/book"/> </bibliography> </xsl:template> <!-- Rgles pour les livres --> <xsl:template match="book"> <book> <!-- Copie des attributs --> <xsl:copy-of select="@*"/> <!-- Copie des lments autres que published --> <xsl:copy-of select="*[name() != 'published']"/> <!-- Remplacement des lments published --> <xsl:apply-templates select="published"/> </book> </xsl:template> <!-- Rgle pour remplacer published par le publisher rfrenc --> <xsl:template match="published"> <!-- Elment publisher rfrenc par l'lment published --> <xsl:variable name="pubnode" select="id(@by)"/> <publisher> <!-- Recopie des attributs autres que id --> <!-- L'attribut id ne doit pas tre recopi car sinon, on peut obtenir plusieurs lments publisher avec la mme valeur de cet attribut --> <xsl:copy-of select="$pubnode/@*[name() != 'id']"/> <xsl:copy-of select="$pubnode/* | $pubnode/text()"/> </publisher> </xsl:template> </xsl:stylesheet>
Lorsque la fonction id() retourne plusieurs nuds, il est possible de les traiter un par un en utilisant un lment xsl:for-each comme dans l'exemple suivant. <xsl:for-each select="id(@arearefs)"> <xsl:apply-templates select="."/> </xsl:for-each>
Afin de pouvoir accder efficacement des nuds d'un document XML, il est possible de crer des index. L'lment xsl:key cre un index. L'lment xsl:key doit tre un enfant de l'lment racine xsl:stylesheet. L'attribut name de xsl:key fixe le nom de l'index pour son utilisation. L'attribut match contient un motif [Section 6.8] qui dtermine les nuds indexs. L'attribut use contient une expression XPath qui spcifie la cl d'indexation, c'est--dire la valeur qui identifie les nuds et permet de les retrouver. Pour chaque nud slectionn par le motif, cette expression est value en prenant le nud slectionn comme nud courant. Pour indexer des lments en fonction de la valeur de leur attribut type, on utilise l'expression @type comme valeur de l'attribut use. La valeur de l'attribut use peut tre une expression plus complexe qui slectionne des enfants et des attributs. Dans l'exemple suivant, tous les lments chapter du document sont indxs en fonction de leur attribut id. <xsl:key name="idchapter" match="chapter" use="@id"/>
La fonction key() de XPath permet de retrouver un nud en utilisant un index cr par xsl:key. Le premier paramtre est le nom de l'index et le second est la valeur de la cl. Dans l'exemple suivant, on utilise l'index cr l'exemple prcdent. La valeur de l'attribut @idref d'un lment contenu dans la variable $node sert pour retrouver l'lment dont c'est la valeur de l'attribut id. Le nom idchapter de l'index est un nom XML et il doit tre plac entre apostrophes ou guillemets.
199
XSLT
<xsl:value-of select="key('idchapter', $node/@idref)/title"/> L'utilisation des index peut tre contourne par des expressions XPath approprie. L'expression ci-dessus avec la fonction key est quivalente l'expression XPath ci-dessous qui utilise l'oprateur '//' [Section 6.7]. <xsl:value-of select="//chapter[@id = $node/@idref]/title"/> L'inconvnient de cette dernire expression est d'imposer un parcours complet du document pour chacune de ses valuations. Si l'expression est value de nombreuses reprises, ceci peut conduire des problmes d'efficacit. Lors de la prsentation des attributs de type ID et IDREF [Section 3.7.2], il a t observ que la bibliographie bibliography.xml doit tre organise de faon diffrente si les lments publisher contiennent des informations autres que le nom de l'diteur. Afin d'viter de dupliquer ces informations dans chaque livre, il est prfrable de regrouper les lments publisher dans une section part. Chaque lment publisher contenu dans un lment book est alors remplac par un lment published avec un attribut by de type IDREF pour rfrencer l'lment publisher dplac. La feuille de style suivante remplace les lments publisher par des lments published et les regroupe dans une liste en fin de document. Elle suppose que chaque lment publisher contient, au moins, un enfant name avec le nom de l'diteur. Elle supprime galement les doublons en vitant que deux lments publisher avec le mme nom, c'est--dire le mme contenu de l'lment name, apparaissent dans la liste. Cette suppression des doublons est ralise par une indexation des lments publisher sur le contenu de name. Pour chaque lment publisher, l'indexation permet de retrouver efficacement tous les lments publisher avec un contenu identique de name. Seul le premier de ces lments publisher est ajout la liste des diteurs dans le document rsultat. Pour savoir si un lment publisher est le premier de ces lments avec le mme nom, celui-ci est compar avec le premier de la liste retourne par la fonction key() avec l'oprateur is [Section 6.5.3]. La copie de cet lment publisher est ralise par un lment xsl:copy [Section 8.6.9] ainsi que par lement xsl:copyof [Section 8.6.10] pour ses attributs et ses enfants. <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> <!-- Indexation des lments publisher par leur nom --> <xsl:key name="pubname" match="publisher" use="name"/> <xsl:template match="/"> <bibliography> <books> <!-- Livres --> <xsl:apply-templates select="bibliography/book"/> </books> <publishers> <!-- diteurs --> <xsl:apply-templates select="bibliography/book/publisher"/> </publishers> </bibliography> </xsl:template> <!-- Rgles pour les livres --> <xsl:template match="book"> <book> <!-- Copie des attributs et des enfants autres que publisher --> <xsl:copy-of select="@* | *[name() != 'publisher']"/> <!-- Transformation de l'lment publisher en lment published --> <xsl:if test="publisher"> <published id="{generate-id(key('pubname', publisher/name)[1])}"/> </xsl:if> </book> </xsl:template> <!-- Copie d'un lment publisher en ajoutant un attribut id -->
200
XSLT
<xsl:template match="publisher"> <!-- Test si l'lment publisher est le premier avec le mme nom --> <xsl:if test=". is key('pubname', name)[1]"> <xsl:copy> <!-- Ajout de l'attribut id --> <xsl:attribute name="id"> <xsl:value-of select="generate-id()"/> </xsl:attribute> <!-- Copie des attributs et des enfants --> <xsl:copy-of select="@* | *"/> </xsl:copy> </xsl:if> </xsl:template> </xsl:stylesheet>
201
XSLT
</xsl:template> </xsl:stylesheet> L'ajout d'un lment xsl:sort comme fils de l'lment <xsl:apply-templates select="document(@href)/cities/city"/> permet de trier les lments l'intrieur d'un des documents rfrencs. Pour trier les lments globalement, il faut supprimer les deux itrations imbriques et les remplacer par une seule itration comme dans l'exemple suivant. <xsl:apply-templates select="document(files/file/@href)/cities/city"> <xsl:sort select="."/> </xsl:apply-templates> Dans l'expression XPath document(files/file/@href)/cities/city, on utilise le fait que la fonction document() prend en paramtre une liste de noms de fichiers et qu'elle retourne l'ensemble des contenus des fichiers.
202
XSLT
</names> On obtient le document suivant o les noms sont mieux structurs. <?xml version="1.0" encoding="iso-8859-1"?> <names> <name><firstname>Gaston</firstname><lastname>Lagaffe</lastname></name> <name><firstname>Achille</firstname><lastname>Talon</lastname></name> <name>Astrix</name> </names>
203
XSLT
finalement, les feuilles F et G (cf. Figure). L'ordre des feuilles par priorit d'import croissante est D, E, B, F, G, C, A. Cet ordre correspond un parcours suffixe de l'arbre des imports.
A
im p o rt s
B D E F
C G
204
Chapitre 9. XSL-FO
XSL-FO est un dialecte de XML permettant de dcrire le rendu de documents. Un document XSF-FO contient le contenu mme du document ainsi que toutes les indications de rendu. Il s'apparente donc un mlange de HTML et CSS [Chapitre 10] avec une syntaxe XML mais il est plus destin l'impression qu'au rendu sur cran. Le langage XSL-FO est trs verbeux et donc peu adapt l'criture directe de documents. Il est plutt conu pour des documents produits par des feuilles de style XSLT [Chapitre 8].
205
10.2. Rgles
Une feuille de style est forme de rgles qui ont la forme suivante. Les espaces et les retours la ligne jouent uniquement un rle de sparateurs. L'indentation de la feuille de style est donc libre. selector { property1: value1; property2: value2; ... propertyN: valueN; } Le slecteur selector dtermine quels sont les lments auxquels s'applique la rgle. Les proprits property1, property2, , propertyN de tous ces lments prendront les valeurs respectives value1, value2, , valueN. Chaque valeur est spare du nom de la proprit par le caractre ':'. Le caractre ';' spare les couples proprit/valeur de la rgle. Il n'est donc pas indispensable aprs le dernier couple de la rgle. Des commentaires peuvent tre mis dans les feuilles de styles en dehors ou dans les rgles en utilisant une syntaxe identique celle du langage C. Ils commencent par les deux caractres '/*' et se terminent par les deux caractres '*/'. L'exemple ci-dessous est la feuille de style utilise pour la prsentation de cet ouvrage au format HTML. /* Fond blanc */ body { background-color: white; } /* Equations et figures centres */ p.equation, p.figure { text-align: center; } /* Zone de code : fond jaune clair, bordure noire et marges */ pre { background-color: #ffffcc; border: 1px solid black; margin: 10px; padding: 5px; }
206
CSS
10.2.1. Mdia
Les rgles d'une feuille de style peuvent dpendre du mdia utilis pour rendre le document. Par mdia, on entend le support physique servant matrialiser le document. Il peut s'agir d'un cran d'ordinateur, d'un projecteur, de papier. La syntaxe est la suivante. @media medium { /* Rgles pour le mdia */ ... } Les principales valeurs possibles pour medium sont screen pour un cran d'ordinateur, print pour du papier et projection pour un projecteur.
10.2.2. Slecteurs
Un slecteur prend la forme gnrale suivante. Il est constitu par une suite de slecteurs spars par des virgules. Il slectionne alors tous les lments slectionns par chacun des slecteurs individuels. selector1, selector1, ..., selectorN La forme la plus simple d'un slecteur est le nom name d'un lment comme h1, p ou encore pre. Tous les lments de nom name sont alors slectionns. Dans l'exemple suivant, le fond de l'lment body, c'est--dire de tout le document, est blanc. body { background-color: white; } Tous les lments dont l'attribut class contient la chane classname peuvent tre slectionns par le slecteur .classname o le la valeur de l'attribut est prcde d'un point '.'. L'attribut class d'un lment peut contenir plusieurs chanes spares par des espaces comme dans l'exemple suivant. Un slecteur de forme .classname slectionne un lment si la chane classname est une des chanes de la valeur de l'attribut class. <p class="numbered equation"> ... </p> Cette forme de slecteur peut tre combine avec le nom name d'un lment pour former un slecteur name.classname qui slectionne tous les lments de nom name dont l'attribut class contient la chane classname. Dans l'exemple suivant, tous les lments p de classe equation ou figure auront leur texte centr. p.equation, p.figure { text-align: center; } L'lment unique dont l'attribut id a la valeur name peut tre slectionn par le slecteur #name o la valeur de l'attribut est prcde d'un dise '#'. Dans l'exemple suivant, le contenu de l'lment h1 dont l'attribut id vaut title sera de couleur rouge. h1#title { color: red } Le slecteur '*' slectionne tous les lments. Dans l'exemple suivant, tous les lments (c'est--dire le texte) seront de couleur bleue l'exception des lments p qui seront de couleur grise. * { color: blue }
207
CSS
p { color: gray } Certaines parties d'un document qui ne correspondent pas un lment peuvent tre slectionnes par des pseudolments. La premire ligne et le premier caractre du contenu d'un lment name peuvent tre dsigns par name:first-line et name:first-letter. p:first-line { text-indent: 15pt; } Le pseudo-lment :first-child permet en outre de slectionner le premier enfant d'un lment. Dans l'exemple suivant, la rgle s'applique uniquement la premire entre d'une liste. li:first-child { color: blue; } Les pseudo-lments :before et :after et la proprit content permettent d'ajouter du contenu avant et aprs un lment. li:before { content: "[" counter(c) "]"; counter-increment: c; } Les pseudo-classes :link, :visited, :hover et :active s'appliquent l'lment a et permettent de slectionner les liens, les liens dj traverss, les liens sous le curseur et les liens activs. a:link a:visited a:hover a:active { { { { color: color: color: color: blue; } magenta; } red; } red; }
La pseudo-classe :focus permet de slectionner l'entre d'un formulaire qui a le focus. Un slecteur peut aussi prendre en compte la prsence d'attributs et leurs valeurs. Un ou plusieurs prdicats portant sur les attributs sont ajouts un slecteur lmentaire. Chacun des prdicats est ajout aprs le slecteur entre crochet '[' et ']'. Les diffrents prdicats possibles sont les suivants. [att] L'lment est slectionn s'il a un attribut att quelque soit sa valeur. [att=value] L'lment est slectionn s'il a un attribut att dont la valeur est exactement la chane value. [att~=value] L'lment est slectionn s'il a un attribut att dont la valeur est une suite de chanes spares par des espaces dont l'une est exactement la chane value. Le slecteur .classname est donc une abrviation de [class~="classname"]. [att|=value] L'lment est slectionn s'il a un attribut att dont la valeur est une suite de chanes de caractres spares par des tirets '-' dont la premire chane est gale la chane value. Dans l'exemple suivant, la rgle s'applique aux lments p dont l'attribut lang commence par en- comme enGB ou en-US mais pas fr. La proprit quote dfinit quels caractres doivent entourer les citations.
208
CSS
p[lang|="en"] { quotes: '"' '"' "'" "'"; } Il est possible de mettre plusieurs prdicats portant sur les attributs comme dans l'exemple suivant. Le slecteur suivant slectionne les lments p ayant un attribut lang de valeur fr et un attribut type de valeur center. p[lang="fr"][type="center"] { ... } Il est possible de composer des slecteurs avec les trois oprateurs ' ' (espace), '>' et '+' pour former des nouveaux slecteurs. Le slecteur selector1 selector2 slectionne tous les lments slectionns par selector2 qui sont en outre descendants dans l'arbre du document (c'est--dire inclus) d'un lment slectionn par selector1. Dans l'exemple suivant, seuls les lments em contenus directement ou non dans un lment p auront leur texte en gras. p em { font-weight: bold; } Cet oprateur peut aussi combiner plusieurs slecteurs. Dans l'exemple suivant, sont slectionns les lments de classe sc contenus dans un lment em lui mme contenu dans un lment p. Il y a bien un espace entre em et .sc. Le slecteur p em.sc est bien sr diffrent. p em .sc { font-variant: small-caps; } Le slecteur selector1 > selector2 slectionne tous les lments slectionns par selector2 qui sont en outre enfant (c'est--dire directement inclus) d'un lment slectionn par selector1. Le slecteur selector1 + selector2 slectionne tous les lments slectionns par selector2 qui sont en outre frre droit (c'est--dire qui suivent directement) d'un lment slectionn par selector1.
10.2.3. Proprits
Les proprits qui peuvent tre modifies par une rgle dpendent des lments slectionns. Pour chaque lment de XHTML, il y a une liste des proprits qui peuvent tre modifies.
10.2.4. Valeurs
Les valeurs possibles dpendent de la proprit. Certaines proprits acceptent comme display uniquement un nombre dtermin de valeurs. D'autres encore prennent une couleur, un entier, un pourcentage, un nombre dcimal ou une dimension avec une unit. Pour les dimensions, il est ncessaire de faire suivre le nombre d'une unit parmi les units suivantes. Symbole px pt pc em ex Unit pixel point = 1/72 in pica = 12 pt largeur du M dans la police hauteur du x dans la police
209
CSS
Symbole in mm cm
10.3.2. Cascade
Plusieurs rgles peuvent s'appliquer un mme lment. Il y a souvent plusieurs feuilles de style pour le mme document : une feuille de style par dfaut pour l'application, une autre fournie par l'auteur du document et ventuellement une feuille donne par l'utilisateur. De plus, une mme feuille peut contenir plusieurs rgles qui slectionnent le mme lment. La priorit d'une rgle est d'abord dtermine par sa provenance. La feuille de style de l'auteur a priorit sur celle de l'utilisateur qui a elle-mme priorit sur celle de l'application. Pour les rgles provenant de la mme feuille de style, on applique l'algorithme suivant pour dterminer leur priorit. On calcule une spcificit de chaque slecteur qui est un triplet (a,b,c) d'entiers. L'entier a est le nombre d'occurrences de prdicats sur l'attribut id de forme #ident. L'entier b est le nombre de prdicats sur les autres attributs y compris les attributs class de forme classname. Le nombre c est finalement le nombre de noms d'lments apparaissant dans le slecteur. Les spcificits (a,b,c) et (a',b',c') des slecteurs des deux rgles sont alors compares par ordre lexicographique. Ceci signifie qu'on compare d'abord a et a', puis b et b' si a est gal a', puis finalement c et c' si (a,b) est gal (a',b'). Pour des rgles dont les slecteurs ont mme spcificit, c'est l'ordre d'apparition dans la feuille de style qui dtermine la priorit. La dernire rgle apparue a une priorit suprieure.
210
CSS
To p TM TB TP LM Le ft LB LP Co n t e n t Ma rg in Bo rd e r Pa d d in g RP RB RM Rig h t
BP BB BM Bo t t o m
211
CSS
bibliography { display: block; border: 1px solid black; margin: 30px; padding: 20px; } /* Mode liste sans marque */ book { display: list-item; list-style: none; } /* Calcul de la marque */ book:before { content: "[" counter(c) "]"; counter-increment: c; } /* Titre en italique */ title { font-style: italic; } /* Virgule aprs chaque champ */ title:after, author:after, year:after, publisher:after { content: ", "; } /* Fonte sans-serif pour l'url */ url { font-family: sans-serif; } /* Virgule avant l'URL si elle est prsente */ url:before { content: ", "; }
212
CSS
213
CSS
10.7.2. Fond
Proprit background background-attachement background-color background-image background-position background-repeat Valeur combinaison des proprits background-* scroll ou fixed couleur image pourcentage, dimension ou (top, center ou bottom) et (left, right ou center) no-repeat, repeat-x, repeat-y ou repeat
padding padding-top padding-right dimension ou pourcentage padding-bottom padding-left border-style border-width border-color none, dotted, dashed, solid, groove, ridge, inset ou outset medium, thin, thick ou une dimension couleur double,
margin margin-top margin-right margin- auto, dimension ou pourcentage bottom margin-left position top right bottom left float clear overflow visibility static, relative, absolute ou fixed auto, dimension ou pourcentage none, left ou right none, left, right ou both visible, hidden, scroll ou auto visible ou hidden
10.7.4. Listes
Proprit list-style list-style-image list-style-position list-style-type Valeur Combinaison des trois proprits list-style-* image outside ou inside none, disc, circle, square, decimal, upperRoman, lower-Roman, upper-alpha ou loweralpha
214
e llo , S VG ! H
Figure 11.1. Rendu du document ci-dessous
<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg version="1.0" width="200" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <path id="textpath" d="M 15,80 C 35,65 40,65 50,65 C 60,65 80,75 95,75 C 110,75 135,60 150,60 C 165,60 170,60 185,65" style="fill:none;stroke:black;" /> </defs> <text style="font-family:Verdana; font-size:28; font-weight:bold; fill:red"> <textPath xlink:href="#textpath"> Hello, SVG! </textPath> </text> <use xlink:href="#textpath" y="10"/> </svg>
Rendu
215
SVG
Rendu
x,y wid t h h e ig h t
x3 ,y3
x4 ,y4 x2 ,y2
x3 ,y3
x4 ,y4 x2 ,y2
11.2.2. Chemins
lment Point de dpart <path d="M x1 y1"/>
x1 ,y1
Rendu
x1 ,y1
x1 ,y2
216
SVG
Rendu
x2 ,y2 x1 ,y1
c x,c y x2 ,y2
x1 ,y1
Courbe de Bzier quadratique avec partage de point de contrle <path d="M x1 y1 Q cx cy x2 y2 T x3 y3"/>
c x1 ,c y1 x3 ,y3 x2 ,y2
x1 ,y1
Courbe de Bzier cubique <path d="M x1 y1 C cx1 cy1 cx2 cy2 x2 y2"/>
c x1 ,c y1 x2 ,y2
x1 ,y1
c x2 ,c y2
Courbe de Bzier cubique avec partage de point de contrle <path d="M x1 y1 C cx1 cy1 cx2 cy2 x2 y2 S cx3 cy3 x3 y3"/>
x1 ,y1
Pour une introduction aux courbes de Bezier, on peut se rferer cette partie [Section 11.5].
11.2.3. Remplissage
lment Rgle evenodd <path d="..." fill="evenodd"/> Rendu (PNG)
217
SVG
Rendu (PNG)
11.3. Transformations
L'lment g permet de grouper plusieurs lments graphiques. Il est ainsi possible d'associer simlutanment plusieurs lments des rgles de style communes. L'lment g permet aussi d'appliquer des transformations affines sur les lments graphiques. L'attribut transform de l'lment g contient une suite de transformations appliques successivments. Les transformations possibles sont les suivantes. Transformation translate(dx,dy) scale(x) ou scale(x,y) rotate(a) ou scale(a,cx,cy) skewX(x) et skewY(y) Action Translation (dplacement) Dilatation Rotation Inclinaisons
218
SVG
P2
P2
P3
P2
P1
P4
P1
P3
P1
P4
219
SVG
Si dans la construction prcdente, les milieux sont remplacs par les barycentres avec les poids t et 1-t, on obtient le point de la courbe de coordonnes x(t), y(t). P3 H P2 L4 = R1 L3 R3 L2 R2
P1 = L1
P4 = R4
11.5.2. B-splines
Les courbes B-splines sont aussi des courbes de degr 3. Elles sont donc aussi dtermines par quatre points de contrle. Contrairement une courbe de Bzier, une B-spline ne passe par aucun de ses points de contrle. Par contre, les B-splines sont adaptes pour tre mises bout bout afin de former une courbe ayant de multiples points de contrle. Soient n+3 points P1,,Pn+3. Ils dterminent n B-spline s1,,sn de la manire suivante. Chaque B-spline si est dtermine par les points de contrle Pi, Pi+1, Pi+2 et Pi+3. Si les coordonnes des points de contrle sont (x1, y1), , (xn+3, yn+3), l'quation de la spline si est la suivante. xi(t) = 1/6[ (1-t)3xi + (3t3-6t2+4)xi+1 + (-3t3+3t2+3t+1)xi+2 + t3xi+3] pour 0 t 1 yi(t) = 1/6[ (1-t)3yi + (3t3-6t2+4)yi+1 + (-3t3+3t2+3t+1)yi+2 + t3yi+3] pour 0 t 1 partir des quations dfinissant les splines si, on vrifie facilement les formules suivantes qui montrent que la courbe obtenue en mettant bout bout les courbes si est de classe C2, c'est--dire deux fois drivable. si(1) = si+1(0) = 1/6(Pi+1 + 4Pi+2 + Pi+3) s'i(1) = s'i+1(0) = 1/2(Pi+3 - Pi+1) s''i(1) = s''i+1(0) = Pi+3 - 2Pi+2 + Pi+1
11.5.3. Conversions
Puisque seules les courbes de Bzier sont prsentes en SVG, il est ncessaire de savoir passer d'une B-Spline une courbe de Bzier. La B-spline de points de contrle P1, P2, P3 et P4 est en fait la courbe de Bzier dont les points de contrle P'1, P'2, P'3 et P'4 sont calculs de la manire suivante. Si les coordonnes des points P1, P2, P3 et P4 sont (x1, y1), (x2, y2), (x3, y3) et (x4, y4), les coordonnes (x'1, y'1), (x'2, y'2), (x'3, y'3) et (x'4, y'4) des points P'1, P'2, P'3 et P'4 sont donnes par les formules suivantes pour les premires coordonnes et des formules similaires pour la seconde. x'1 = 1/6(x1 + 4x2 + x3)
220
SVG
x'2 = 1/6(4x2 + 2x3) x'3 = 1/6(2x2 + 4x3) x'4 = 1/6(x2 + 4x3 + x4) Les formules suivantes permettent la transformation inverse x1 = 6x'1 - 7x'2 + 2x'3 x2 = 2x'2 - x'3 x3 = -x'2 + 2x'3 x4 = 2x'2 - 7x'3 + 6x'4
221
12.1. SAX
12.1.1. Principe
Ap p lic a t io n
Do c u m e n t s o u rc e s o u r c e . x ml
Eve n t Ha n d le r Pa rs e r
222
Programmation XML
* @version 1.0 */ class TrivialSAXHandler extends DefaultHandler { public void setDocumentLocator(Locator locator) { System.out.println("Location : " + "publicId=" + locator.getPublicId() + " systemId=" + locator.getSystemId()); } public void startDocument() { System.out.println("Debut du document"); } public void endDocument() { System.out.println("Fin du document"); } public void startElement(String namespace, String localname, String qualname, Attributes atts) { System.out.println("Balise ouvrante : " + "namespace=" + namespace + " localname=" + localname + " qualname=" + qualname); } public void endElement(String namespace, String localname, String qualname) { System.out.println("Balise fermante : " + "namespace=" + namespace + " localname=" + localname + " qualname=" + qualname); } public void characters(char[] ch, int start, int length) { System.out.print("Caractres : "); for(int i = start; i < start+length; i++) System.out.print(ch[i]); System.out.println(); } } Lecture TrivialSAXRead.java d'un fichier XML // IO import import // SAX import import
/** * Lecture triviale d'un document XML avec SAX * @author O. Carton * @version 1.0 */ class TrivialSAXRead { public static void main(String [] args) throws Exception { // Cration de la fabrique de parsers
223
Programmation XML
SAXParserFactory parserFactory = SAXParserFactory.newInstance(); // Cration du parser SAXParser parser = parserFactory.newSAXParser(); // Lecture de chaque fichier pass en paramtre for(int i = 0; i < args.length; i++) { // Flux d'entre InputStream is = new FileInputStream(args[i]); parser.parse(is, new TrivialSAXHandler()); } } }
12.2. DOM
12.2.1. Principe
Ap p lic a t io n
Do c u m e n t s o u rc e s o u r c e . x ml
Do c u m e n t t re e
Bu ild e r
224
Programmation XML
Du texte </item> et encore du texte. </table> La figure ci-dessous reprsente sous forme d'arbre le document XML prsent ci-dessus.
Do c u m e n t
At t rib u t e Ele m e n t
Co m m e n t Te xt
Te xt
225
Programmation XML
Do c u m e n t Typ e
Ele m e n t
At t r CDATASe c t io n No d e Ch a ra c t e rDa t a Te xt Co m m e n t En t it y
En t it yRe fe re n c e
Pro c e s s in g In s t ru c t io n
No t a t io n
No d e Lis t
/** * Lecture triviale d'un document XML avec DOM * @author O. Carton * @version 1.0 */ class TrivialDOMRead { public static void main(String [] args) throws Exception { // Cration de la fabrique de constructeur de documents DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // Cration du constructeur de documents DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
226
Programmation XML
// Lecture de chaque fichier pass en paramtre for(int i = 0; i < args.length; i++) { // Flux d'entre InputStream is = new FileInputStream(args[i]); // Construction du document Document doc = documentBuilder.parse(is); // Exploitation du document ... System.out.println(doc); } } }
12.3. Comparaison
La grande diffrence entre les API, SAX et DOM est que la premire ne charge pas le document en mmoire alors que la seconde construit en mmoire une reprsentation arborescente du document. La premire est donc particulirement adapte aux (trs) gros documents. Par contre, elle offre des facilits de traitement plus rduites. Le fonctionnement par vnements rend difficiles des traitements non linaires du document. Au contraire, l'API DOM rend plus faciles des parcours de l'arbre.
12.4. AJAX
Cette page [http://developer.apple.com/internet/webcontent/xmlhttpreq.html] donne un petit historique de l'objet XMLHttpRequest. <?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" xml:lang="fr" lang="fr"> <head> <title> Chargement dynamique </title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="Author" content="Olivier Carton" /> <script type="text/javascript"> // Dans la premire version de Google Suggest, la fonction // s'appelait sendRPCDone. Elle s'appelle maintenant // window.google.ac.Suggest_apply window.google = new Object(); window.google.ac = new Object(); window.google.ac.Suggest_apply = sendRPCDone; var XMLHttpRequestObject = false; // Cration du gestionnaire de connexion if (window.XMLHttpRequest) { XMLHttpRequestObject = new XMLHttpRequest(); } else { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } // Fonction de chargement des donnes function getData(url) { if (XMLHttpRequestObject) { // Mise en place de la requte XMLHttpRequestObject.open("GET", url);
227
Programmation XML
// Mise en place du handler XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { // valuation du rsultat eval(XMLHttpRequestObject.responseText); } } // Envoi de la requte XMLHttpRequestObject.send(null); } } // Fonction appele chaque entre de caractre function getSuggest(keyEvent) { var keyEvent = (keyEvent) ? keyEvent : window.event; var input = (keyEvent.target) ? keyEvent.target : keyEvent.srcElement; // Utilisation du wrapper google.php var url = "google.php?qu="; if (keyEvent.type == 'keyup') { if (input.value) { getData(url + input.value); } else { var target = document.getElementById("target"); target.innerHTML = "<div></div>"; } } } // Fonction appele par la requte function sendRPCDone(unused, term, results, unusedArray) { // Entte de la table de prsentation des rsultats var data = "<table align='left' border='1' " + "cellpadding='2' cellspacing='0'>"; if (results.length != 0) { for (var i = 1; i < results.length-1; i = i + 2) { data += "<tr><td><a href='http://www.google.com/search?q=" + results[i] + "'>" + results[i] + "</a></td>" + "<td>" + results[i+1] + "</td></tr>"; } } data += "</table>"; var target = document.getElementById("target"); target.innerHTML = data; } </script> </head> <body> <h2>Google Live Search</h2> <!-- Zone de saisie --> <!-- La fonction getSuggest est appele chaque touche relache --> <p><input type="text" onkeyup="JavaScript:getSuggest(event)" /></p> <!-- Div recevant le rsultat --> <p><div id="target"></div></p> </body>
228
Programmation XML
</html>
229
Annexe A. Acronymes
AJAX [ ] Asynchronous JavaScript and XML API [ ] Application Programming Interface BMP [ ] Basic Multilingual Plane [Section 2.2] BOM [ ] Byte Order Mark [Section 2.2.4] CSS [ ] Cascading Style Sheet [Chapitre 10] DOM [ ] Document Object Model DTD [ ] Document Type Definition [Chapitre 3] FPI Formal Public Identifier [Section 3.2.2] Infoset XML Information Set ISBN [ ] International Standard Book Number NCName No Colon Name (Nom local) [Chapitre 4] PCDATA Parsed characters DATA PNG [ ] Portable Network Graphics PDF Portable Document Format PSVI Post-Schema Validation Infoset QName Qualified Name [Chapitre 4] RDF [ ] Resource Description Framework RSS [ ] Really Simple Syndication SAML [ ] Security Assertion Markup Language SAX [ ] Simple API for XML
230
Acronymes
SGML [ ] Standard Generalized Markup Language [Chapitre 1] SMIL [ ] Synchronized Multimedia Integration Language SOAP [ ] Simple Object Access Protocol SVG [ ] Scalable Vector Graphics [Chapitre 11] SVRL [http://www.schematron.com/validators.html] Schematron Validation Report Language [Section 7.3] UBL [ ] Universal Business Language UCS [ ] Universal Character Set [Section 2.2] URI [ ] Uniform Resource Identifier [Section 2.3] URL [ ] Uniform Resource Locator [Section 2.3] URN [ ] Uniform Resource Name [Section 2.3] UTF [ ] Universal Transformation Format [Section 2.2.4] WSDL [ ] Web Services Description Language XML [ ] eXtensible Markup Language XSD [ ] XML Schema Definition [Chapitre 5] XSL [ ] eXtensible Style Language [Chapitre 8] XSL-FO [ ] XSL Formating Object [Chapitre 9]
231
Bibliographie
XML
A. Michard. XML langage et applications. Eyrolles. Paris. 2001. 2-212-09206-7. B. Marchal. XML by Example. Macmillan Couputer Publishing. 2000. M. Morrison. XML. CampusPress. 2005. F. Role. Modlisation et manipulation de documents XML. Lavoisier. 2005.
XPath
M. Kay. XPath 2.0 Programmer's Reference. Wiley Publishing, Inc.. Indianapolis. 2004.
Schmas XML
V. Lamareille. XML Schema et XML Infoset. Cpadus. 2006. J.-J. Thomasson. Schmas XML. Eyrolles. 2003. 2-212-11195-9.
XSLT et XSL-FO
P. Drix. XSLT fondamental. Eyrolles. 2002. D. Tidwell. XSLT. O'Reilly. 2001. M. Kay. XSLT 2.0 Programmer's Reference. Wiley Publishing Inc.. 2004. M. Kay. XSLT 2.0 and XPath 2.0. Wiley Publishing, Inc.. Indianapolis. 2008. 978-0-470-19274-0.
CSS
C. Aubry. CSS 1 et CSS 2.1. Editions ENI. 2006.
SVG
J. Eisenberg. SVG Essentials. O'Reilly. 2002. 2-596-00223-8.
232
Index
Symboles
##any, 66 ##local, 66 ##other, 66 ##targetNamespace, 66 #all, 197 #current, 197 #default, 197 #FIXED, 38, 69 #IMPLIED, 27, 37, 38, 69 #PCDATA, 23, 26, 34, 37, 60 #REQUIRED, 28, 37, 38, 69 ' ', 141, 172, 172, 209 '!=', 123, 136, 172 '"', 15, 19, 27, 29, 29, 31, 38, 38, 128 '#', 181, 207 '$', 74, 130, 131, 132 '%', 31, 181 '&', 18, 19, 29, 29, 171 ''', 15, 19, 27, 29, 29, 31, 38, 38, 128, 191, 191 '(' et ')', 32, 36, 107, 130 '()', 139 '*', 32, 74, 100, 106, 116, 122, 126, 141, 160, 163, 172, 190, 207 '*/', 206 '+', 26, 32, 106, 116, 126, 209 ',', 32, 60, 115, 132, 134, 134, 180, 181 '-', 8, 20, 26, 107, 108, 126, 181, 208 '-->', 21, 213 '.', 8, 74, 107, 117, 132, 133, 137, 141, 162, 163, 173, 181, 190, 201, 207 '..', 141 '/', 13, 100, 115, 123, 141, 141, 162 '/*', 206 '//', 13, 26, 100, 123, 141, 141, 190, 200 '/>', 17 '0', 181 ':', 8, 12, 13, 26, 42, 206 '::', 118 ';', 29, 31, 181, 206 '<!', 25, 28 '<!--', 21, 213 '<', 11, 16, 17, 18, 19, 123, 123, 136, 171 '</', 16 '<<', 114, 138 '<=', 136, 150 '<?', 22 '<?xml', 15, 22, 27 '=', 19, 123, 136, 208 '>', 16, 17, 18, 19, 28, 29, 123, 136, 171, 209 '>=', 136, 150 '>>', 114, 138 '?', 11, 32, 106, 116 '?>', 22
'@', 100, 141 '@*', 142, 163 'i', 132 'm', 132 's', 132 'U+', 7 '[' et ']', 26, 107, 133, 141, 208 '\', 106, 108 '\c', 108 '\C', 108 '\d', 108 '\D', 108 '\i', 108 '\I', 108 '\s', 108, 130 '\S', 108 '\w', 108 '\W', 108 ']]>', 18 '^', 74, 108, 131, 132 '_', 8 '{' et '}', 107, 138, 171, 206 '{{' et '}}', 171 '|', 32, 36, 61, 100, 106, 125, 141 '|=', 208 '~=', 208 '', 11 '', 11 '', 181 '', 9 '##', 9
A
absolute, 211 abstract, 83, 84, 85, 87, 150, 151 analyse lexicale, 8, 18, 22, 56, 75 ancestor-or-self::, 120, 173 ancestor::, 120 anctre, 18 and, 125, 133, 150 ANY, 35 arbre du document, 110 as, 190, 191, 192, 195 atomisation, 113, 116 ATTLIST, 35 attribut, 18 dclaration, 35, 67 interdit, 69 obligatoire, 38, 69 optionnel, 38, 69 particulier, 19 attribute(), 116 attribute::, 119, 122 attributeFormDefault, 49, 103 axe, 118, 118, 141
233
Index
B
balise, 16 base, 70, 72 block, 49, 84, 88, 90, 211 blockDefault, 49, 88, 90
C
C++, 47, 53, 70, 85, 191 caractres codage des, 9 d'chappement, 106 d'espacement, 8, 20, 33, 56, 75, 106, 130, 160 des identificateurs, 8, 74 spciaux, 8, 18, 19, 22, 171 CDATA, 18, 36 child::, 119, 122, 122 collapse, 75 collation, 11, 117 comment(), 116, 116, 122, 122 commentaire, 21, 28, 50, 111, 148, 175, 206, 213 contenu d'un lment, 16 dterministe, 34 mixte, 34, 59 pur, 32, 58 context, 148 contexte, 116, 190 dynamique, 117 statique, 116 corps du document, 15, 16
ELEMENT, 32, 60 element(), 116 elementFormDefault, 49, 102 else, 139 EMPTY, 35, 37, 37 encoding, 15, 160 enfant, 18, 112 entte, 15, 22, 27, 31 entit, 29 gnrale, 29 paramtre, 27, 31 prdfinie, 29, 171 ENTITIES, 36 ENTITY, 29, 31, 36 eq, 135, 196 espace de noms, 12, 41, 66, 70, 102, 116, 147, 159, 166, 169 cible, 66, 96, 102, 106 par dfaut, 43 Euro, 10, 30, 30, 131 every, 117, 140 except, 123, 125 exclude-result-prefixes, 159, 186 expression rationnelle, 32, 106, 129, 130, 130, 131, 202 XPath, 110
F
facette, 73 fixe, 84 false, 54, 125 filtre, 123, 133 final, 49, 84, 91, 91, 93 finalDefault, 49, 92 fixed, 51, 69, 84, 211 focus, 117, 123, 133, 162, 163, 165, 183 following-sibling::, 120 following::, 121, 123 for, 117, 139, 190 form, 49 FPI, 26, 27, 29, 29, 31, 160 frre, 18
D
decimal-separator, 182 default, 20, 51, 69 descendant, 18 descendant-or-self::, 120 descendant::, 119, 122 display, 211 div, 127 DocBook, 5, 22, 41, 45, 46, 164, 173, 186, 203 DOCTYPE, 16, 25, 25, 26, 27, 27, 27 doctype-public, 160 doctype-system, 160 document-node(), 116 DTD, 25, 47, 160 Dublin Core, 41, 46
G
ge, 135 gros-boutiste, 11 group-starting-with, 186 groupe d'attributs, 94, 106, 173 d'lments, 94 de substitution, 82 grouping-separator, 180, 182 grouping-size, 180 gt, 135
E
lment, 16, 16 abstrait, 83, 87 bloqu, 90 dclaration, 32, 51 final, 93 global, 52 local, 52 racine, 16, 18, 21, 25 vide, 17, 35, 60
H
html:style, 191
234
Index
I
ID, 8, 21, 36, 96, 114, 117 id, 31, 37 identificateur, 8 idiv, 127 IDREF, 36, 37, 96, 114 IDREFS, 36, 37, 114 if, 126, 139, 195, 196, 196, 196 in, 139, 140, 140 inline, 211 instruction de traitement, 22, 111, 175 intersect, 125 is, 138, 200 is-a, 151 ISBN, 12 ISO 10646, 7 ISO 3166, 20, 55 ISO 639, 20, 26, 55 ISO 9070, 26 ISO-8859-1, 10, 15 ISO-8859-15, 10 item(), 116 itemType, 64
ne, 135 nillable, 80 NMTOKEN, 8, 36 NMTOKENS, 36 node(), 113, 116, 122, 123, 124, 163, 163, 171 nom local, 42 qualifi, 8, 42, 174 XML, 8, 16, 19, 22, 29, 37, 108 none, 211 normalisation des caractres d'espacement, 130 des fins de lignes, 8 Unicode, 12, 131 NOTATION, 36 nud, 18, 110 courant, 113, 117, 118, 118, 141, 162, 165
O
objet courant, 117, 123, 133, 183 OpenDocument, 5 optional, 69 or, 125, 133, 134, 196 ordre du document, 114, 123, 125, 135, 138
J
Java, 47, 53, 70, 85, 138, 139, 181, 191 jeton, 8, 36
P
paramtre, 191 parent, 18, 112 parent::, 119 parse, 23 Perl, 106 petit-boutiste, 11 point de code, 6, 7, 131 position, 211 preceding-sibling::, 120 preceding::, 120 preserve, 20, 75 priorit, 164, 203 d'import, 164, 203 priority, 164 processContents, 65, 70 processing-instruction(), 116, 122, 123, 123 prohibited, 69, 69 prologue, 15, 15 PUBLIC, 26, 27, 29, 31
L
Latin-1, 10 Latin-15, 10 le, 135 ligature, 11 link, 212 list-item, 211 lt, 135
M
marque d'ordre des octets, 11 match, 158, 162, 164, 168 MathML, 4, 42 maxOccurs, 61, 63, 63, 64, 65 memberTypes, 63 minOccurs, 61, 63, 64, 65, 105 mixed, 59 ML, 139 mod, 127, 133, 173 mode, 162, 197, 197 motif XPath, 141, 148, 162, 177, 199
Q
QNAME, 42 qualified, 49
N
name, 52, 58, 67, 67, 94, 96, 150, 165, 173, 173, 190, 191, 192, 195, 199 namespace, 66, 70, 106 namespace::, 121 NCNAME, 42
R
racine, 110, 114, 124 ref, 52, 60, 68, 94, 96, 104 regexp, 202 relative, 211 replace, 75
235
Index
S
SAML, 4 satisfies, 140, 140 sch:active, 154 sch:assert, 145, 148, 148, 149, 150 sch:extends, 150 sch:let, 150 sch:name, 149, 150, 152, 152 sch:ns, 147, 153 sch:p, 148 sch:param, 151 sch:pattern, 148, 150 sch:phase, 154 sch:report, 148, 148, 149, 149 sch:rule, 145, 148, 148, 149, 149, 149, 150 sch:schema, 145, 147, 150 sch:title, 145, 148 sch:value-of, 149, 154 schma, 47 schemaLocation, 106 section littrale, 18, 34 select, 149, 162, 172, 173, 175, 176, 183, 184, 188, 188, 190, 191, 192, 202 self::, 119, 141, 150 separator, 172 SMIL, 4 some, 117, 140 standalone, 15, 33 starts-with, 129 static, 211 style, 212, 213 substitution d'lment, 82, 85, 87 d'espaces de noms, 169 de type, 79, 80, 88, 90 substitutionGroup, 82, 87, 88, 90, 91, 93 SVG, 4 SVRL, 146 SYSTEM, 27, 27, 27, 29, 31, 31
U
U+, 6 UBL, 4 UCS-2, 9 UCS-4, 9 Unicode, 7 union, 125 unqualified, 49, 102 URI, 12, 26 de base, 13, 20, 117 rsolution, 13 URL, 12, 27, 27, 29, 29, 31, 160 URN, 12, 26 US-ASCII, 9, 15 use, 60, 69, 69 use-attribute-sets, 173 UTF-16, 9, 15 UTF-32, 9 UTF-8, 10, 15
V
version, 15, 16, 159
W
WSDL, 4
X
xi:include, 23 XInclude, 23, 45 XLink, 3, 36, 45 xml-stylesheet, 9, 22, 111, 212 xml:base, 9, 20, 23, 55, 106 xml:id, 9, 21, 32, 38, 106, 114, 117 xml:lang, 20, 31, 55, 106, 182 xml:space, 8, 20, 106, 160 xml:specialAttrs, 96, 106 xmllint, 23, 30, 40, 48, 142 xmlns, 42 XPath, 4 xpath:abs(), 127 xpath:avg(), 128 xpath:base-uri(), 21, 114 xpath:ceiling(), 127 xpath:codepoints-to-string(), 131 xpath:compare(), 129 xpath:concat(), 128, 173, 193, 196 xpath:contains(), 30, 129, 139, 193, 195, 196 xpath:count(), 123, 134, 147, 152 xpath:current(), 118, 162, 190 xpath:current-group(), 118, 184, 186 xpath:current-grouping-key(), 118, 184 xpath:data(), 113
T
targetNamespace, 49, 102 text(), 116, 122, 122, 124, 142, 172, 190, 193, 197 then, 139 to, 133, 190 true, 54, 125 type, 51, 67, 67, 104 abstrait, 85 anonyme, 51 bloqu, 88 complexe, 58, 71, 71, 75, 77 de document, 16 de nud, 110
236
Index
xpath:distinct-values(), 134 xpath:document(), 201 xpath:document-uri(), 114 xpath:empty(), 134 xpath:ends-with(), 129 xpath:exists(), 134 xpath:false(), 125 xpath:floor(), 127 xpath:format-number(), 117, 181 xpath:generate-id(), 117, 138, 192, 200 xpath:id(), 37, 114, 163, 198 xpath:in-scope-prefixes(), 114 xpath:index-of(), 134, 188 xpath:insert-before(), 135 xpath:key(), 19, 149, 153, 173, 190, 199, 200 xpath:last(), 117, 123, 172 xpath:local-name(), 113, 186 xpath:lower-case(), 131 xpath:matches(), 106, 129, 131 xpath:max(), 127 xpath:min(), 127 xpath:name(), 113, 116, 123, 175, 178, 188, 190, 200 xpath:namespace-uri(), 114 xpath:namespace-uri-for-prefix(), 114 xpath:node-name(), 113 xpath:normalize-space(), 130 xpath:normalize-unicode(), 12, 131 xpath:not(), 125 xpath:number(), 117 xpath:position(), 117, 123, 124, 133, 172, 173, 183 xpath:regexp-group(), 118, 202 xpath:remove(), 135 xpath:replace(), 106, 130, 131, 194, 202 xpath:resolve-uri(), 114 xpath:reverse(), 135 xpath:root(), 114 xpath:round(), 127 xpath:round-half-to-even(), 127 xpath:string(), 113 xpath:string-join(), 128 xpath:string-length(), 128 xpath:string-to-codepoints(), 131 xpath:subsequence(), 134 xpath:substring(), 129, 150 xpath:substring-after(), 130, 193, 196, 196 xpath:substring-before(), 129, 139, 193, 195, 196 xpath:sum(), 128 xpath:tokenize(), 106, 130, 131 xpath:translate(), 130 xpath:true(), 125 xpath:upper-case(), 131 XPointer, 3 XQuery, 4 xsd:all, 58, 62, 83, 94 xsd:annotation, 50 xsd:any, 65 xsd:anyAtomicType, 115 xsd:anyAttribute, 70
xsd:anySimpleType, 115 xsd:anyType, 53, 83, 115 xsd:anyURI, 20, 55, 115 xsd:appInfo, 51 xsd:attribute, 50, 60, 67, 96 xsd:attributeGroup, 94, 95, 106 xsd:base64Binary, 55 xsd:boolean, 54, 115 xsd:boolean(), 117, 126, 126 xsd:byte, 54 xsd:choice, 58, 60, 61, 83, 94 xsd:complexContent, 59, 63, 70, 73, 89 xsd:complexType, 50, 51, 53, 58, 59, 63, 70, 73, 85, 88, 91 xsd:date, 56, 69, 73, 115 xsd:dateTime, 56, 115 xsd:dayTimeDuration, 56, 115 xsd:decimal, 55, 71, 75, 115, 126 xsd:documentation, 51 xsd:double, 55, 75, 115, 126 xsd:double(), 137 xsd:duration, 56, 115 xsd:element, 50, 51, 51, 51, 59, 60, 80, 82, 87, 90, 93, 100 xsd:ENTITIES, 58 xsd:ENTITY, 58 xsd:enumeration, 63, 67, 73, 74 xsd:extension, 68, 69, 70, 71, 71, 75, 81, 86, 88, 89, 92, 92, 93 xsd:field, 97, 100 xsd:float, 55, 75, 115 xsd:fractionDigits, 75 xsd:gDay, 57 xsd:gMonth, 56 xsd:gMonthDay, 57 xsd:group, 94 xsd:gYear, 56 xsd:gYearMonth, 56 xsd:hexBinary, 55 xsd:ID, 21, 21, 58, 114, 117 xsd:IDREF, 58, 60 xsd:IDREFS, 58, 113 xsd:import, 106 xsd:include, 106 xsd:int, 54 xsd:integer, 52, 54, 73, 115, 116, 126 xsd:integer(), 135 xsd:key, 97, 101 xsd:keyref, 100 xsd:language, 20, 55, 68, 73 xsd:length, 64, 74, 87 xsd:list, 64, 74, 74, 113 xsd:long, 54 xsd:maxExclusive, 73, 74 xsd:maxInclusive, 58, 73, 74 xsd:maxLength, 74, 84 xsd:maxLenth, 75 xsd:minExclusive, 73, 73, 74
237
Index
xsd:minInclusive, 73, 74, 84 xsd:minLength, 74, 84 xsd:Name, 55 xsd:NCName, 55 xsd:negativeInteger, 54 xsd:NMTOKEN, 56, 58, 70 xsd:NMTOKENS, 58 xsd:nonNegativeInteger, 54, 58, 63, 88 xsd:nonPositiveInteger, 54 xsd:normalizedString, 55, 75 xsd:NOTATION, 58 xsd:pattern, 73, 74 xsd:positiveInteger, 54, 91, 93 xsd:QName, 55 xsd:restriction, 58, 63, 64, 67, 72, 75, 75, 81, 85, 85, 87, 88, 89, 92, 92 xsd:schema, 49, 50, 68, 88, 90, 92, 94, 96, 102 xsd:selector, 97, 100 xsd:sequence, 52, 58, 59, 60, 94 xsd:short, 54 xsd:simpleContent, 59, 68, 70, 71, 71, 73 xsd:simpleType, 50, 51, 53, 58, 73, 75, 91 xsd:string, 52, 55, 67, 74, 75, 115 xsd:time, 56, 115 xsd:token, 55, 75 xsd:totalDigits, 75 xsd:union, 63, 74 xsd:unique, 97 xsd:unsignedByte, 54 xsd:unsignedInt, 54 xsd:unsignedLong, 54 xsd:unsignedShort, 54 xsd:untyped, 115 xsd:untypedAtomic, 113, 115, 116, 136 xsd:whiteSpace, 75 xsd:yearMonthDuration, 56, 115 xsi:nil, 80 xsi:noNamespaceSchemaLocation, 44, 50 xsi:schemaLocation, 50 xsi:type, 80, 82, 85, 87, 90 xsl:analyze-string, 106, 202 xsl:apply-imports, 164, 203 xsl:apply-templates, 151, 158, 158, 161, 162, 167, 175, 183, 188, 192, 197 xsl:attribute, 139, 171, 173, 173, 174, 192, 200 xsl:attribute-set, 173 xsl:call-template, 151, 165, 185, 188, 192 xsl:choose, 139, 182, 182, 186 xsl:comment, 174, 175, 191 xsl:copy, 160, 175, 178, 188, 200 xsl:copy-of, 175, 176, 188, 190, 198, 200 xsl:decimal-format, 117, 181 xsl:element, 173, 175 xsl:for-each, 162, 163, 182, 183, 188, 190, 199 xsl:for-each-group, 118, 118, 182, 184, 188 xsl:function, 193, 195 xsl:if, 19, 172, 173, 178, 182, 200 xsl:import, 164, 165, 174, 203
xsl:include, 203 xsl:key, 153, 190, 199 xsl:matching-substring, 118, 202 xsl:namespace-alias, 169 xsl:next-match, 164 xsl:non-matching-substring, 202 xsl:number, 163, 177, 180, 183, 183 xsl:otherwise, 183 xsl:output, 160, 160, 176, 185 xsl:param, 151, 166, 189, 191, 195, 203 xsl:perform-sort, 189 xsl:preserve-space, 160 xsl:processing-instruction, 175 xsl:sequence, 115, 175, 189, 190, 193, 196, 196, 196 xsl:sort, 164, 183, 185, 188, 202 xsl:strip-space, 160 xsl:stylesheet, 159, 169, 190, 191, 191, 195, 199, 203 xsl:template, 118, 158, 158, 161, 162, 164, 166, 191, 197, 203 xsl:text, 163, 171, 183 xsl:transform, 159 xsl:value-of, 19, 166, 172, 174, 182, 183, 185, 189, 191, 196, 196, 197, 200 xsl:variable, 188, 189, 189, 190, 193, 196, 198 xsl:when, 30, 183 xsl:with-param, 151, 166, 189, 192 xsltproc, 191 XUL, 4
238