360 likes | 514 Views
PARTIE 2 Transformation des documents XML Le langage XSLT. Données de mise en forme. Processeur. Question de style. Intérêt de séparer le fond et la forme d’un document (rappel) : Pour se focaliser soit sur les données, soit sur leur présentation
E N D
PARTIE 2 Transformation des documents XML Le langage XSLT
Données de mise en forme Processeur Question de style • Intérêt de séparer le fond et la forme d’un document (rappel) : • Pour se focaliser soit sur les données, soit sur leur présentation • L’ingénierie des connaissances et la publication sont deux métiers différents • Pour restructurer et présenter les données de différentes manières • En fonction du type de terminal (écran de PC, écran de Palm, imprimante) • En fonction du type de sortie (textuelle, graphique, sonore, mixte) • En fonction de la charte graphique (sobre, colorée, délirante)
2 1 Exemple complet (1) • Transformations successives à partir d’un document XML : • Première transformation (structurelle) à l’aide d’une feuille XSL • Permet d’obtenir (dans notre cas) un document HTML « ultra-sobre » • Seconde transformation (de surface) à l’aide d’une feuille de style CSS • Permet d’appliquer un style (polices, couleurs, etc.) au document HTML
Exemple complet (2) • Voilà notre document XML de départ : <?xml version="1.0"?> <?xml:stylesheet type="text/xsl" href="waffles.xsl"?> <breakfast> <food> <name>Belgian Waffles</name> <price>$5.95</price> <description>Two of our famous Belgian Waffles ... </description> <calories>650</calories> </food> <food> <name>Strawberry Belgian Waffles</name> <price>$7.95</price> <description>Light Belgian Waffles covered with ... </description> <calories>900</calories> </food> </breakfast>
Exemple complet (3) • Voilà la feuille de XSL opérant la première transformation : <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <HTML> <HEAD> <LINK rel="StyleSheet" href="waffles.css" type="text/css" media="screen"/> </HEAD> <BODY> <xsl:apply-templates/> </BODY> </HTML> </xsl:template> <xsl:template match="food"> <DIV class="title"> <SPAN class="name"><xsl:value-of select="name"/></SPAN> (<xsl:value-of select="price"/>) </DIV> <DIV class="description"> <xsl:value-of select="description"/> <SPAN class="calories"> (<xsl:value-of select="calories"/>calories per serving) </SPAN> </DIV> </xsl:template> </xsl:stylesheet>
XSL (XML Stylesheet Language) • Plus que des feuilles de style : un langage de transformation • La mise en forme n’est qu’un aspect de la transformation : • Créer des graphiques à partir des valeurs contenues dans un document XML • Générer automatiquement des sommaires et des tables des matières, etc. • Modifier un document à partir de critères d’extraction, de tri, etc. • Les recommandations XSL sont organisées en plusieurs parties : • XSLT : XML Style Language Transformation • Puissant mécanisme de transformation des documents XML • Langage Xpath : un formalisme de parcours d'arborescence et de pattern-matching • XSLFO : XML Style Language Formatting Objects • Né de la fusion entre XSLT et CSS2 (Cascading Style Sheets) • Dédié à la mise en page complexe de documents « papier » • FOP (Apache) concerne la génération de documents PDF via XSLFO • XSL est fondé sur le modèle XML • XSL possède sa propre DTD • Beaucoup d'outils logiciels (éditeurs, parseurs, etc.) implémentent la recommandation et sont donc utilisables avec XSL
xsl:stylesheet • Une feuille de style XSLT est un avant tout un document XML • Tous les éléments standards XSLT sont dans l’espace de nommage http://www.w3.org/1999/XSL/Transform • Le préfixe associé aux éléments standards XSLT est « xsl » • Le numéro de version est un attribut obligatoire. La version 1.0 est largement utilisée, la recommandation pour la version la plus récente, 2.0, a été publiée le 23 janvier 2007.
xsl:template • L’attribut « match » contient un motif qui va permettre de sélectionner des nœuds dans l’arborescence XML • Ce motif utilise la syntaxe XPath des « chemins de localisation » • Si un nœud correspond au motif, le contenu du modèle est instancié et inséré dans le document résultant • Le modèle est généralement un fragment d'arbre « bien formé » qui peut comprendre d'autre éléments XSL. Ceux-ci seront interprétés et, selon l'élément, auront un effet sur l'exécution ou généreront un sous-fragement de l'arbre de sortie • Une template peut aussi être appelé explicitement par un nom
Syntaxe XPath abrégée (1) • Les chemins de localisation les plus simples sont : • Le symbole « / » : • Sélectionne le « nœud document ». C’est un chemin de localisation absolu car il est relatif au document que l’on est en train de traiter • Un nom unique d’élément : • Sélectionne les sous-éléments ayant le nom spécifié. Les éléments sélectionnés dépendent du nœud courant (context node) : c’est un chemin de localisation relatif • Un nom préfixé du symbole @ : • Sélectionne l’attribut du même nom de l’élément courant (ex : @make) • Les sélecteurs « comment() » et « text() » : • Sélectionnent respectivement les éventuels nœuds commentaires et nœuds textuels enfants du nœud courant
Syntaxe XPath abrégée (2) • Les sélectionneurs d'expression régulières (jokers) permettent de mieux spécifier la sélection : • Le symbole « * » : • Correspond à tout les nœuds éléments quelque soit leur nom. Il ne sélectionne pas les attributs, les nœuds de texte et les commentaires • L'expression « @* » : • Correspond à tout les nœuds attributs quelque soit leur nom • Le sélecteur « node() » : • Correspond à tous les nœuds (éléments, attributs, textes, etc.) • Sélection multiple avec le connecteur « | » : • Permet de sélectionner plus d’un type d’élément ou d’attribut : • Exemple : « * | @* » sélectionne les éléments et les attributs
Syntaxe XPath abrégée (3) • Les chemins de localisation composés : • La barre oblique « / » permet de combiner différentes étapes de localisation pour construire un chemin de localisation composé • Chaque étape de localisation est relative à celle qui la précède • Si l’expression commence par « / » le chemin de localisation est absolu • Si l’expression se termine par « text() » un contenu textuel est sélectionné • La double barre « // » permet de sélectionner des nœuds parmi tous les descendants du nœud contextuel • Exemple : « //@* » sélectionne tous les attributs du document. • Les sélecteurs « .. » et « . » : • Sélectionnent respectivement l’élément parent et le nœud courant
Syntaxe XPath abrégée (4) • Utilisation de prédicats pour restreindre une sélection : • Les prédicats contiennent des expressions booléennes qui seront testées pour chaque nœud de la liste de nœuds contextuels (sélectionnés par la première partie d'une expression XPath) • Les prédicats sont placés entre crochets : [@make = "Peugeot"] • Opérateurs booléens : [@make = "Peugeot" or @make = "BMW"] • On peut combiner les prédicats : [@make="Peugeot"][year > 2000] • XPath n’est pas dispensé des règles de XML concernant la forme des documents ; ainsi le symbole < sera remplacé par l’entité < • Le prédicat peut ne pas être explicitement un booléen, une évaluation « à la C » est effectuée : • Les nombres sont vrais s’ils correspondent à la position du nœud courant • Les chaînes de caractères sont vraies si elles ne sont pas vides • Les noms sont vrais si un fils du nœud courant a ce même nom
Syntaxe XPath abrégée (5) • Exemples de sélections d’éléments avec le langage XPath : • Lignée de noms : /cars/car /cars/car/year //year Contrainte de présence d’un sous-élément (fils) : /cars/car[country]/year • Contrainte sur la valeur d’un élément : /cars/car[year=2000] /cars/car[year!=2000] /cars/car[year=2000]/year • Contrainte sur la valeur d’un attribut : /cars/car[@make="Peugeot"] • Position dans la fratrie : /cars/car[1] /cars/car[last()] /cars/car[last() – 1] • À tester : /* • À tester : //* • À tester : //@*
xsl:apply-templates • Cet élément impose au processeur de chercher et d’appliquer un modèle pour chaque nœud identifié par l’attribut « select » • L’attribut « select » contient une expression XPath retournant un ensemble de nœuds et chaque nœud sera traité par le processeur • Remarque : il est possible d’effectuer un tri préalable sur l’ensemble de nœuds en utilisant l’élément <xsl:sort> expliqué ultérieurement L’attribut « select » est facultatif. Il prend comme valeur par défaut la collection de modèles qui s’appliquent aux fils du nœud courant.Lorsqu'il est absent, le processeur appliquera donc les modèles des enfants (descendants directs) du nœud contexte
xsl:value-of • Cet élément calcule la valeur textuelle de l’expression XPath et l’insère dans le document résultant • Si cette expression est un chemin de localisation : • Vers un nœud texte : insertion du texte • Vers un nœud élément : insertion du contenu textuel sans l'arbre de sortie • Vers un nœud attribut : insertion de la valeur de l’attribut • Si cet expression est une expression générale : • Insertion du résultat de l’évaluation de l’expression
Expressions XPath générales (1) • Arithmétique : • Les nombres sont au format IEEE754 (correspond au type Java double) • XPath fournit cinq opérateurs arithmétiques + , – , * , div , mod et six opérateurs de comparaison = , != , < , > , >= , <= • Chaînes de caractères : • Séquences de caractères Unicode (entre guillemets ou apostrophes) • Les opérateurs = , != , < , > , >= , <= sont utilisables sur les chaînes (attention aux chaînes qui représentent des nombres) • Booléens : • Souvent créés par des comparaisons et utilisés comme prédicats dans un chemin de localisation, dans un <xsl:if> ou dans un <xsl:when> • Pas de représentation littérale : les fonctions true() et false() remplissent ce besoin
Expressions XPath générales (2) • XPath 1.0 définit 27 fonctions utilisables dans les expressions • Les autres formalismes qui utilisent XPath (comme XSLT ou XPointer) étendent cette liste avec des fonctions qui leur sont spécifiques • Chaque fonction XPath retourne l’un des quatre types suivants : • Booléen, nombre, chaîne de caractères, liste de nœuds ordonnés • XPath est faiblement typé : si on passe un argument du mauvais type, il sera généralement converti vers le type approprié • Quelques fonctions sur les chaînes de caractères : • number string-length(string s): taille de la chaîne s • string concat(string s1, string s2, … ) : concaténation des n chaînes • boolean start-with(string s1, string s2) : vrai si s1 commence par s2 • boolean contains(string s1, string s2) : vrai si s1 contient s2 • etc.
Expressions XPath générales (3) • Quelques fonctions sur les nombres : • number round(number x) entier le plus proche de x • number floor(number x) plus grand entier <= x • number ceiling(number x) plus petit entier >= x • etc. • Quelques fonctions sur les nœuds et listes de nœuds : • number position() position du nœud courant • string local-name() nom du nœud courant • string name() nom préfixé (par l'espace ds noms) du nœud courant • number last() taille de la liste de nœuds courante • number count(node-set nodes) taille de la liste de nœuds
Les modèles implicites (1) • La feuille XSLT la plus simple qu’on puisse imaginer : • Résultat de la transformation (obtenu avec MSXML) : • Comment cela est-ce possible ? • Toutes les balises ont été supprimées • Les éléments textuels ont été recopiés dans leur ordre d’arrivée <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/> simple.xsl <?xml version="1.0" encoding="UTF-16"?> 520i2000232.860Germany307 1.4 HDi2000105.700806 2.0 16v2001170.100
Les modèles implicites (2) • Des modèles implicites sont intégrés aux processeurs : • La spécification XSLT 1.0 préconise que dans les moteurs XSLT les modèles suivants soient implicites (built-in templates rules) : • Assurer la récursivité à partir des éléments non prévus : • Si le nœud courant est le « nœud document » ou n’importe quel autre élément, alors aller visiter ses éléments fils • Réaliser l’affichage des contenus textuels : • Si le nœud courant est un « nœud textuel », alors l’afficher dans l’arbre résultant • Il est possible d’écraser de tels modèles en les redéfinissant • Les modèles intégrés sont placés au début de la feuille de style • En cas de modèles concurrents, le processeur doit appliquer le dernier <xsl:template match="/ | *"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"> <xsl:value-of select="."/> </xsl:template>
Fonctionnement du processeur • Algorithme (simplifié) de la transformation récursive : • Un pointeur « nœud courant » est positionné au « nœud document » • Le processeur cherche à faire correspondre un modèle • Si une correspondance est trouvée, le processeur applique le modèle • Si le processeur rencontre la balise <xsl:apply-templates/> il va appliquer cet algorithme (à partir de l’étape 2) à tous les fils du nœud courant • Si le processeur rencontre la balise <xsl:apply-templates select="xxx"/> il va appliquer cet algorithme (à partir de l’étape 2) à tous les éléments xxx • Si le processeur rencontre la balise <xsl:value-of select="."/> il va écrire dans l’arbre résultant la valeur textuelle du nœud courant • Si le processeur rencontre la balise <xsl:value-of select="xxx"/> il va écrire dans l’arbre résultant la valeur textuelle du nœud identifié par xxx • Si le processeur rencontre la balise <xsl:copy-of select="xxx"/> il va dupliquer dans l’arbre résultant le fragment de l’arbre identifié par xxx • Etc. etc.
xsl:element • Le nom de l’élément est donné par la valeur de l’attribut « name » • Revient à écrire littéralement les balises <nom> … </nom> dans la feuille de style mais la solution <xsl:element name="nom"> est plus jolie ! • Le contenu de l’élément est déterminé en instanciant le modèle • Des attributs peuvent être ajoutés via des enfants <xsl:attribute>
xsl:attribute • Peut être utilisé à l’intérieur d’un élément <xsl:element> • Peut être utilisé après un élément littéral (une balise littérale) • Dans tous les cas, cet élément doit précéder tous les éléments littéraux et les autres instructions insérant du contenu dans l’arbre résultant
xsl:attribute (suite) • Document source XML et feuille de style XSLT : • Résultat de la transformation (obtenu avec MSXML) : <lien protocol="mailto">Jerome.Lehuen@lium.univ-lemans.fr</lien> ... <xsl:template match="lien"> <xsl:element name="A"> <xsl:attribute name="href"> <xsl:value-of select="@protocol"/>:<xsl:value-of select="."/> </xsl:attribute> <xsl:value-of select="."/> </xsl:element> </xsl:template> ... <A href="mailto:Jerome.Lehuen@lium.univ-lemans.fr"> Jerome.Lehuen@lium.univ-lemans.fr </A>
xsl:text • Le contenu de l’élément <xsl:text> doit toujours être bien formé : tout les caractères < ou & doivent être écrits < et & • Cependant, quand le document est sérialisé, ces appels sont remplacés par les caractères représentés
xsl:if • Si l’expression est un chemin de localisation, elle sera considérée comme vraie s’il existe au moins un nœud sélectionné par l’expression
xsl:choose • Cet élément doit contenir au moins un élément <xsl:when> dont la syntaxe est identique à celle de l’élément <xsl:if> • L’élément optionnel <xsl:otherwise> contient le modèle par défaut • S’il n’y a pas d’élément <xsl:otherwise> et qu’aucune condition de test des éléments <xsl:when> n’est vraie, cet élément de produit rien
xsl:sort • Pour effectuer un tri à plusieurs clés, utiliser plusieurs <xsl:sort>
xsl:for-each • C’est une solution alternative à <xsl:templates> pour sélectionner un ensemble de nœud et appliquer un modèle • L’utilisation de <xsl:template> est plus souple car plus déclaratif
xsl:call-template • Le nœud courant est le même dans les modèles appelé et appelant • Les modèles peuvent être appelés récursivement : • Un élément <xsl:template> peut contenir un élément <xsl:call-template> le réinstanciant • On dispose alors d’un véritable langage de programmation fonctionnel
xsl:with-param • Cet élément peut aussi contenir un modèle qui sera instancié et passé comme valeur du paramètre • Dans ce cas, il ne doit pas y avoir d’attribut « select » • Pour passer plusieurs paramètres, utiliser plusieurs <xsl:with-param> • Les paramètres seront récupérés via des éléments <xsl:param>
xsl:param • L’élément <xsl:param> peut aussi être un élément top-level • En position top-level, cet élément fournit une valeur par défaut si le paramètre du même nom n’est pas indiqué quand un modèle est appelé
Fonctions utilisateur (1) • Appeler une fonction Javascript dans une transformation : • Code spécifique à Microsoft Internet Explorer : <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://mycompany.com/mynamespace"> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ function date() { return new Date().getDate(); } ]]> </msxsl:script> <xsl:template match="date"> Nous sommes le <xsl:value-of select="user:date()"/> </xsl:template> </xsl:stylesheet>
Fonctions utilisateur (2) • Code spécifique à Sablotron (transformation « server-side ») : • L’interprète PHP doit être compilé avec l’option --javascript <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="http://www.exslt.org/functions" xmlns:user="http://mycompany.com/mynamespace" extension-element-prefixes="func" exclude-result-prefixes="user"> <func:script implements-prefix="user" language="javascript"> <![CDATA[ function antispam(str) { return str.replace(/@/g, " @ "); } ]]> </func:script> <xsl:template match="email"> <xsl:value-of select="user:antispam(string(.))"/> </xsl:template> </xsl:stylesheet>
Transformation des documents (1) • Processeur « Instant Saxon » de Michael Kay : • http://users.iclway.co.uk/mhkay/saxon/ • Ligne de commande : saxon –o sortie.out source.xml style.xsl • Processeur « MSXML » de Microsoft : • http://msdn.microsoft.com/xml/ • Ligne de commande : msxsl source.xml style.xsl –o sortie.out • Processeur « XT » de James Clark : • http://www.jclark.com/xml/xt.html • Ligne de commande : java com.jclark.xsl.sax.Driver source.xmlstyle.xsl > sortie.out • Processeur « Xalan » du projet Apache XML : • http://xml.apache.org/xalan-j/ • Ligne de commande : java org.apache.xalan.xslt.Process –in source.xml –xsl style.xsl –out sortie.out