original in en Egon Willighagen
en to fr Iznogood
Egon a rejoint l'équipe Hollandaise de LF en 1999 et il est devenu le deuxième éditeur au début de cette année. Il est étudiant en chimie à l'Université de Nijmegen. Il joue au basket et aime la randonnée.
Les Transformations XSL (XSLT) sont à la base d'une recommandation W3C et peuvent donc être considérées comme un standard. XSLT est une partie de XSL qui est le langage des pages au format XML. Son propos est, comme son nom l'indique, de formater ou de mettre en page un document XML. Le formatage de l'objet joue un grand rôle pour XSL dans la manière de présenter l'information, mais dans ce processus, la transformation de la donnée est souvent indispensable. Et c'est là que le module XSLT intervient.
Contrairement à XSL lui-même, XSLT est déjà recommandé et stable. Les processeurs XSLT sont déjà développés dans plusieurs langages de programmation. Les plus matures sont écrits en C (XT, écrit par James Clark) et en Java (Xalan, d'abord développé par Lotus Inc. et maintenant par la Fondation Apache). Mais en Perl, deux projets sont actuellement en cours: XML::XSLT et XML::Sabotron. Le premier est le plus ancien et il est complètement écrit en Perl alors que le second est une interface pour un processeur C++ XSLT.
La version courante est 0.21 et peut être téléchargée depuis CPAN. Récemment, le projet est devenu SourceForge et un arbre CVS est disponible. Cet article est néanmoins basé sur la 0.21. Le module Perl est developpé par Geert Josten, un étudiant chimiste à l'Université de Nijmegen, mais actuellement plusieurs autres personnes contribuent à son développement. Avec la mise en place de l'arbre CVS, une accélération de XML::XSLT est espérée. Ce qui est nécessaire pour accélérer l'implémentation du travail de W3C sur XSLT.
Le code Perl ci-dessous montre comment le module est utilisé:
#!/usr/bin/perl use XML::XSLT; my $xmlfile = "example.xml"; my $xslfile = "example.xsl"; my $parser = XML::XSLT->new ($xslfile, "FILE"); $parser->transform_document ($xmlfile, "FILE"); $parser->print_result();
Dans cet exemple, il est montré comment un fichier XML (example.xml) est transformé en un fichier XSLT (example.xsl). Mais la mise en page peut être aussi basée sur une arborescence DOM:
#!/usr/bin/perl use XML::XSLT; use XML::DOM; my $domparser = new XML::DOM::Parser; my $doc = $domparser->parsefile ("file.xml"); my $parser = XML::XSLT->new ($doc, "DOM");
ou une chaine:
#!/usr/bin/perl use XML::XSLT; my $xsl_string = qq{ <?xml version="1.0"?> <xsl:stylesheet> <xsl:template match="/"> <html> <xsl:apply-templates/> </body> </xsl:template> </xsl:stylesheet> }; my $parser = XML::XSLT->new ($xsl_string, "STRING");
Ces types d'arbres sont aussi disponibles pour la procédure transform_document() donnée dans le premier exemple.
Ici vous avez un script qui convertit un fichier XML basé sur une mise en page XSLT. Il demande deux arguments dans la ligne de commande, à savoir les noms de fichiers des pages XSLT et du fichier XML. Notez que ce script utilise le mécanisme de "FILE".
Maintenant que nous savons comment un processus XSLT peut être utilisé en Perl pour convertir des documents XML, nous pouvons aborder le standard XSLT.
La Transformation XSL a été conçue pour faciliter la publication de données stockées en XML. Alors que le Formatage XSL est utilisé pour la mise en page et la présentation, XSLT est utilisé pour les transformations de base des données XML, telles que le tri, la sélection d'information et le mélange d'informations de différentes sources. Mais, en réalité, il est évident que XSLT tout seul peut faire de la mise en page et de la présentation.
XML::XSLT ne couvre pas encore toutes les commandes XSLT, mais toutes les commandes utilisées dans cet article sont supportées.
La documentation XSLT définit comment un document XML peut être transformé. Ceci se réalise en définissant un modèle pour chaque élément. Ci-dessous, vous avez plusieurs exemples de documents XSLT qui s'appliquent tous à un document XML contenant une feuille Gnumeric ( application tableur pour GNOME). (Donc, maintenant vous savez que le format de stockage des documents Gnumeric est celui des documents XML. Normalement ils sont compressés au format gzip: essayez de décompresser un fichier *.gnumeric.)
Si vous regardez la feuille, vous verrez que parmi des données pures, le formatage est aussi stocké. Par exemple, la mise en page, la largeur et la hauteur de cellules. Nous allons créer plusieurs feuilles XSLT pour faire des travaux spécifiques comme:
Nous allons introduire les bases de XSLT en écrivant une feuille XSLT pour générer un sommaire très simple (verysimple.xsl):
<?xml version="1.0"?> <xsl:stylesheet version="1.0" \ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"/> <xsl:template match="Item"> <xsl:value-of select="./name"/> : <xsl:value-of select="./val-string"/> </xsl:template> </xsl:stylesheet>
Le premier modèle inclut tous les éléments dans le document XML. Le second modèle inclut tous les CDATA dans le document XML. Enfin le dernier modèle, réalise ce que nous souhaitons: chaque Item du Sommaire du document Gnumeric est donné par la valeur CDATA des éléments-fils name et val-string. Contrôlez ceci! Comparez l'affichage et regardez si c'est ce que vous attendiez d'un document basé sur XML.
Mais le premier modèle n'inclut-il pas les Items? Pourquoi cela s'applique-t-il au troisième modèle et non au premier? C'est parce que les derniers écrasent les premiers. Les modèles sont de cette manière triés du général vers le spécifique.
Notez que XML::XSLT affiche beaucoup d'espaces qui proviennent de la feuille XSLT. Je ne crois pas qu'il existe dans cette version une manière de s'en débarasser. Mais comme notre sortie sera faite en XHTML, nous ne nous en occupons pas pour le moment. L'exemple suivant a la même fonctionnalité mais rajoute les éléments pour le XHTML afin que nous puissons le visualiser avec un navigateur (simple.xsl):
<?xml version="1.0"?> <xsl:stylesheet version="1.0" \ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"/> <xsl:template match="Item"> <b><xsl:value-of select="./name"/></b>: <i>< xsl:value-of select="./val-string"/> </i><br /> </xsl:template> <xsl:template match="/"> <html> <head> <title>Summary Gnumeric File</title> </head> <body bgcolor="white"> <xsl:apply-templates/> </body> </html> </xsl:template> </xsl:stylesheet>
Il y a maintenant un modèle additionnel pour l'élément racine (/)(root). Ceci permet au code XHTML d'être sur toutes les autres sorties; la sortie que nous avions dans le premier exemple est maintenant placée dans body. Pourquoi? Quand XML::XSLT démarre le processus, il cherche un modèle qui inclut la racine. Il affiche alors le code XHTML jusqu'à l'ouverture de l'élément body. Il applique alors les modèles à tous les éléments fils. Quand tout est fini, il continue encore avec le modèle racine et imprime les marqueurs de fin de body et de html.
Il existe aussi d'autres codes additionnels XHTML dans le modèle Objet. Notez que vous pouvez intercaler des commandes XSLT avec des données en sortie. Un processeur XSLT comprend tout élément n'ayant pas le marqueur xsl en sortie.
Jusqu'ici les exemples n'ont donné que des modèles nouveaux ou modifiés. Les feuilles de styles complètes sont toutes liées. Pour finaliser notre premier exemple, nous allons ajouter un en-tête et nous verrons un autre exemple de la commande apply-templates (finalsimple.xsl):
<xsl:template match="Summary"> <h2>Summary</h2> <ul> <xsl:apply-templates/> </ul> </xsl:template>
La commande xsl:for-each donne quelques contrôles additionnels sur le traitement d'un document XML, spécialement avec l'association de xsl:sort mais cette commande n'est pas encore implémentée dans XML::XSLT.
Pour ajouter des informations dans les feuilles de Gnumeric Workbook, nous utiliserons xsl:for-each (foreach.xsl):
<xsl:template match="Sheets"> <xsl:for-each select="Sheet"> <h2><xsl:value-of select="Name"/></h2> <ul> Rows: <xsl:value-of select="MaxRow"/><br /> Cols: <xsl:value-of select="MaxCol"/><br /> </ul> </xsl:for-each> </xsl:template>
Mais le document XML utilisé n'a qu'une feuille de calcul. Vous voudriez sûrement l'utiliser sur un fichier Gnumeric avec plusieurs feuilles de calcul.
Comme mentionné plus tôt, nous ne pouvons pas trier des éléments avec XML::XSLT en ce moment. Et c'est vraiment dommage, car les données dans les fichiers Gnumeric ne sont pas triées. Si nous pouvions le faire, nous serions capable de générer une table XHTML qui donne le contenu exact de la feuille de calcul. Mais ce n'est pas possible actuellement. Néanmoins, nous pouvons faire une liste de toutes les informations dans une certaine ligne ou colonne. Ceci est expliqué dans le prochain exemple.
pour lister toutes les données de la troisième colonne (qui contient le salaire d'un riche étudiant en Hollande), nous pouvons utiliser la commande xsl:if (if.xsl):
<xsl:template match="Sheets"> <xsl:for-each select="Sheet"> <h2><xsl:value-of select="Name"/></h2> <ul> Rows: <xsl:value-of select="MaxRow"/><br /> Cols: <xsl:value-of select="MaxCol"/><br /> <xsl:apply-templates select="Cells"/><br /> </ul> </xsl:for-each> </xsl:template> <xsl:template match="Cells"> Content of Col 3: <xsl:for-each select="Cell"> <xsl:if test="@Col='3'"> <xsl:value-of select="Content"/><xsl:text>, </xsl:text> </xsl:if> </xsl:for-each> </xsl:template>
Puisque le modèle des Sheets ne s'en est pas chargé, nous devons appliquer des modèles aux éléments fils des Cells. En utilisant l'attribut de sélection avec la commande xsl:apply-templates, nous forçons l'application du modèle aux seuls éléments de Cells.
Le modèle des Cells prend en charge tous les éléments fils Cell (vérifiez ceci avec le code source du fichier XML!), mais n'affiche les valeurs que si l'attribut Col a la valeur "3". Notez que le signe at se réfère à des attributs alors que l'omission du signe se réfère à l'élément.
Maintenant que les modèles deviennent plus complexes, il est nécessaire de noter quel est l'élément courant. A l'intérieur d'un document, il n'y a pas de sujet particulier, mais dans un modèle, un sujet particulier est appliqué. Par exemple, lorsque l'on applique le modèle Cells, le processeur s'occupe en particulier d'une instance de cet élément. Ici, un élément Cell. Lorsqu'on sélectionne une information, ce sujet particulier est appliqué: select="." dans le modèle Cells se réfère à un élément des Cells. Le select="Cell" dans la commande xsl:for-each sélectionnera tous les éléments de Cell, mais une fois dans la boucle, le sujet particulier sera celui de l'un des éléments des Cell. Notez que test="@Col" renvoie à un attribut d'une Cell et pas de toutes les Cells. A l'intérieur de la boucle, un seul peut servir de référence aux éléments de Cells avec select="../@name", excepté pour les Cells qui n'ont pas d'attributs.
La commande xsl:text s'assure que tous les textes sont affichés. Normalement, l'espace dans la séquence ", " sera considéré comme un espace vide, ce qui n'a pas grande importance. En utilisant xsl:text, on peut être sûr que tout le texte est affiché.
Il y a beaucoup d'autres choses à faire avec les modules XSLT et XML::XSLT. Ce court article est juste une introduction au module. Il a probablement provoqué plus de questions que de réponses mais ce n'est pas plus mal. Posez ces questions sur la page de commentaires ou postez-les sur la liste de diffusion du site web XML::XSLT.
CDATA
CDATA correspond à des données caractère et peut avoir toute séquence de caractères ne contenant pas "]]>". Voir XML Recommendation.
DOM
Document Object Model. Une interface qui peut être utilisée pour accèder à des documents, des documents XML par exemple. Voir le site web DOM.
Gnumeric
Un tableur pour Gnome.