Comprenez XPath
Transformez un document XML en HTML.
Cette page (et le reste du site) est entièrement générée avec XSLT !
Il n'y a pas d'opérateurs ensemblistes dans XPath, en revanche, on peut facilement les obtenir. A quelle opération ensembliste correspond chacune des expressions suivantes ?
$node-set1 | $node-set2
$node-set1[count(. | $node-set2) != count($node-set2)]
$node-set1[count(. | $node-set2) != count($node-set2)] | $node-set2[count(. | $node-set1)
!= count($node-set1)]
Que retournent à partir de ce document :
//a/item[2] = //b/item
?
//a/item[2] != //b/item
?
Comment obtenir {a} - {b}
?
Utilisez ce testeur XPath
//a/item[not(. = //b/item)]
<data> <a> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item>5</item> </a> <b> <item>2</item> <item>3</item> <item>4</item> <item>6</item> <item>7</item> </b> </data>
Ecrire une requête XPath qui fasse un "select distinct" sur les catégories dans ce document :
Utilisez ce testeur XPath
//category[not(. = preceding::category)]
<dataset> <node> <category>C1</category> </node> <node> <category>C2</category> </node> <node> <category>C1</category> </node> <node> <category>C3</category> </node> <node> <category>C1</category> </node> <node> <category>C2</category> </node> <node> <category>C1</category> </node> <node> <category>C3</category> </node> </dataset>
On dispose du document XML :
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE zoo SYSTEM "zoo.dtd" [ <!ENTITY % notations SYSTEM "notations.ent"> %notations; <!ENTITY flipper.jpg SYSTEM "flipper.jpg" NDATA jpg> <!ENTITY oum.jpg SYSTEM "oum.jpg" NDATA jpg> <!ENTITY ecco.jpg SYSTEM "ecco.jpg" NDATA jpg> ]> <!-- Un petit Zoo avec quelques animaux --> <zoo> <info>Ouvert tous les jours de 8h00 à 19h00</info> <info><img src="nourrir.gif" />Il est <b>interdit</b> de nourrir les animaux€.</info> <aquarium> <mammifères-marins> <dauphins> <dauphin id="jhgtr13" photo="flipper.jpg" date-naissance="1997-4-1"> <nom>Flipper</nom> <sexe>M</sexe> <taille unité="cm">215</taille> <poids unité="kg">105</poids> </dauphin> <dauphin id="lkjh45" photo="ecco.jpg" date-naissance="2003-10-23"> <nom>Ecco</nom> <sexe>F</sexe> <taille unité="cm">202</taille> <poids unité="kg">98</poids> </dauphin> <dauphin id="kjlhy90" photo="oum.jpg" date-naissance="1996-12-25"> <nom>Oum</nom> <sexe>F</sexe> <!-- c'est mon préféré --> <taille unité="cm">295</taille> <poids unité="kg" status="mesure approximative">190<!-- il faut refaire la pesée --></poids> </dauphin> </dauphins> </mammifères-marins> <poissons> <sélaciens> <danger>Il est <b>interdit</b> de nager avec les requins.</danger> <requin id="plojk09" espèce="marteau" date-naissance="1998-6-5"> <nom>Oussama</nom> <sexe>M</sexe> <taille unité="cm">455</taille> <poids unité="kg">540</poids> <commentaire>A tendance a se jeter contre les murs <![CDATA[<<< marteau & cinglé !!! >>>]]> <!-- Il faudra bien le faire piquer un jour --> </commentaire> </requin> <requin id="vgyuh43" espèce="requin bleu" nom-savant="carcharias glaucus" date-naissance="2004-1-13"> <nom>Saddam</nom> <sexe>M</sexe> <taille unité="cm">355</taille> <poids unité="kg" status="">425</poids> </requin> </sélaciens> </poissons> </aquarium> </zoo>
et de sa DTD :
<?xml version="1.0" encoding="ISO-8859-1" ?> <!ENTITY nourrir.gif SYSTEM "nourrir.gif" NDATA gif> <!ENTITY % block "p | info | danger | attention"> <!ENTITY % inline "b | i | em | strong | stabilo | img"> <!ENTITY % attractions "aquarium?, vivarium?, enclos?, volière?"> <!ENTITY % animal "nom, sexe, taille, poids, commentaire?"> <!ENTITY % animal-attr " id ID #REQUIRED espèce CDATA #IMPLIED nom-savant CDATA #IMPLIED photo ENTITY #IMPLIED date-naissance CDATA #REQUIRED "> <!ENTITY % u-attr " unité CDATA #REQUIRED status CDATA #IMPLIED "> <!ELEMENT p (#PCDATA | %inline;)*> <!ELEMENT info (#PCDATA | %inline;)*> <!ELEMENT danger (#PCDATA | %inline;)*> <!ELEMENT attention (#PCDATA | %inline;)*> <!ELEMENT b (#PCDATA | %inline;)*> <!ELEMENT i (#PCDATA | %inline;)*> <!ELEMENT em (#PCDATA | %inline;)*> <!ELEMENT strong (#PCDATA | %inline;)*> <!ELEMENT stabilo (#PCDATA | %inline;)*> <!ELEMENT img EMPTY> <!ATTLIST img src ENTITY #REQUIRED> <!ELEMENT zoo ((%block;)*, %attractions;)> <!ELEMENT aquarium (mammifères-marins?, poissons?)> <!ELEMENT mammifères-marins (dauphins?, baleines?, orques?)> <!ELEMENT poissons (sélaciens?)> <!ELEMENT vivarium (serpents?, arachnéens?)> <!ELEMENT serpents (boas?)> <!ELEMENT arachnéens (mygales?)> <!ELEMENT enclos (primates?, fauves?)> <!ELEMENT primates (gorilles?, orangs-outans?)> <!ELEMENT fauves (tigres?, lions?)> <!ELEMENT volière (oiseaux-terrestres?, oiseaux-aquatiques?, rapaces?)> <!ELEMENT oiseaux-terrestres (autruches?)> <!ELEMENT oiseaux-aquatiques (pingouins?, manchots?)> <!ELEMENT rapaces (aigles?)*> <!ELEMENT dauphins (%block; | dauphin)+> <!ELEMENT dauphin (%animal;)> <!ATTLIST dauphin %animal-attr;> <!ELEMENT baleines (%block; | baleine)+> <!ELEMENT baleine (%animal;)> <!ATTLIST baleine %animal-attr;> <!ELEMENT orques (%block; | orque)+> <!ELEMENT orque (%animal;)> <!ATTLIST orque %animal-attr;> <!ELEMENT sélaciens (%block; | requin)+> <!ELEMENT requin (%animal;)> <!ATTLIST requin %animal-attr;> <!ELEMENT boas (%block; | boa)+> <!ELEMENT boa (%animal;)> <!ATTLIST boa %animal-attr;> <!ELEMENT mygales (%block; | mygale)+> <!ELEMENT mygale (%animal;)> <!ATTLIST mygale %animal-attr;> <!ELEMENT gorilles (%block; | gorille)+> <!ELEMENT gorille (%animal;)> <!ATTLIST gorille %animal-attr;> <!ELEMENT orangs-outans (%block; | orang-outan)+> <!ELEMENT orang-outan (%animal;)> <!ATTLIST orang-outan %animal-attr;> <!ELEMENT tigres (%block; | tigre)+> <!ELEMENT tigre (%animal;)> <!ATTLIST tigre %animal-attr;> <!ELEMENT lions (%block; | lion)+> <!ELEMENT lion (%animal;)> <!ATTLIST lion %animal-attr;> <!ELEMENT autruches (%block; | autruche)+> <!ELEMENT autruche (%animal;)> <!ATTLIST autruche %animal-attr;> <!ELEMENT pingoins (%block; | pingoin)+> <!ELEMENT pingoin (%animal;)> <!ATTLIST pingoin %animal-attr;> <!ELEMENT manchots (%block; | manchot)+> <!ELEMENT manchot (%animal;)> <!ATTLIST manchot %animal-attr;> <!ELEMENT aigles (%block; | aigle)+> <!ELEMENT aigle (%animal;)> <!ATTLIST aigle %animal-attr;> <!ELEMENT nom (#PCDATA)> <!ELEMENT sexe (#PCDATA)> <!ELEMENT taille (#PCDATA)> <!ATTLIST taille %u-attr;> <!ELEMENT poids (#PCDATA)> <!ATTLIST poids %u-attr;> <!ELEMENT commentaire (#PCDATA | %block;)*>
qui utilise une entité :
<?xml version="1.0" encoding="ISO-8859-1" ?> <!NOTATION jpg SYSTEM "images/jpeg"> <!NOTATION gif SYSTEM "images/gif">
Le document XML décrit les animaux d'un Zoo. L'objectif est de faire une feuille de style XSLT qui transforme le document source XML en une version publiée en (X)HTML. Tout se passe côté client (dans un prochain tépé, tout se passera côté serveur Web).
Créez une feuille de style minimaliste qui affiche le corps HTML avec un titre grâce à une règle qui réagit sur la racine du source XML.
Modifiez le source XML pour lui assigner cette feuille de style.
Il suffit d'ajouter dans le document XML source juste après la
déclaration <?xml?>
l'instruction de traitement
suivante qui sera interprêtée par le navigateur :
<?xml-stylesheet type="text/xsl" href="zoo.xsl"?>
Chargez le document dans le navigateur.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link href="zoo.css" rel="stylesheet" type="text/css"/> </head> <body> <h1>Bienvenue au Zoo</h1> </body> </html> </xsl:template> </xsl:stylesheet>
Ajoutez des règles à votre feuille de style pour qu'elle transforme le contenu en (X)HTML en utilisant ces ressources.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link href="zoo.css" rel="stylesheet" type="text/css"/> </head> <body> <h1>Bienvenue au Zoo</h1> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="info|attention|danger"> <xsl:choose> <xsl:when test="parent::dauphins or parent::sélaciens"> <tr> <td colspan="6"><xsl:call-template name="avertissement"/></td> </tr> </xsl:when> <xsl:otherwise> <xsl:call-template name="avertissement"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="avertissement"> <table class="{name()}" align="center"> <tr> <td><img src="{name()}.gif" /></td> <td><xsl:apply-templates /></td> </tr> </table> </xsl:template> <xsl:template match="b"><b><xsl:apply-templates /></b></xsl:template> <xsl:template match="i"><i><xsl:apply-templates /></i></xsl:template> <xsl:template match="em"><em><xsl:apply-templates /></em></xsl:template> <xsl:template match="strong"><strong><xsl:apply-templates /></strong></xsl:template> <xsl:template match="dauphins|sélaciens"> <h2><xsl:value-of select="name()" /></h2> <table border="1"> <tr> <th>Nom</th> <th>Date naissance</th> <th>Type</th> <th>Taille</th> <th>Poids</th> <th>Sexe</th> </tr> <xsl:apply-templates/> </table> </xsl:template> <xsl:template match="dauphin|requin"> <tr> <td><xsl:value-of select="nom" /></td> <td><xsl:value-of select="@date-naissance" /></td> <td><xsl:value-of select="@espèce" /><br /><i><xsl:value-of select="@nom-savant" /></i></td> <td><xsl:value-of select="taille" /> <xsl:value-of select="taille/@unité" /></td> <td><xsl:value-of select="poids" /> <xsl:value-of select="poids/@unité" /></td> <td><xsl:value-of select="sexe" /></td> <xsl:if test="@photo"> <td><img src="{@photo}" alt="{nom}" /></td> </xsl:if> </tr> </xsl:template> </xsl:stylesheet>
Un navigateur peut afficher le résultat HTML d'une transformation XSLT. Le problème est que le code HTML produit n'est pas visible (il est gardé jalousement par le navigateur qui se contente de le consommer pour formatter l'affichage).
Une solution alternative :
xsltproc stylesheet.xsl input.xml
java TestXSLT stylesheet.xsl input.xml
et qui affiche le résultat sur la sortie standard.
Un document XML associé à sa feuille de style XSLT avec la PI appropriée est supposée être mis en forme dans le navigateur. Tout cela fonctionne bien avec un document hébergé sur un serveur Web, mais peut ne pas fonctionner pour un fichier local.
Les navigateurs embarquent une règle, la "same origin policy" (SOP) qui leur interdit d'exécuter un script sur des données ne provenant pas du même site Web. Cette règle est précieuse car par exemple elle empêche à un pirate d'accéder à vos coordonnées bancaires ! Elle concerne non seulement les scripts Javascript, mais les scripts XSLT également.
Malheureusement, certains navigateurs Web trop zélés considèrent qu'il ne faut pas faire confiance à un script chargé depuis un fichier local. C'est pourquoi ceux-là n'affichent rien.
Pour ces exercices il faut alors soit utiliser un autre navigateur, soit utiliser un outil en ligne de commande pour procéder à la transformation.
On veut séparer ce qui est documentaire (les éléments <img>
,
<b>
, <info>
, <danger>
,
<commentaire>
, etc)
de ce qui est structure de données (les autres éléments).
Déclarez et utilisez dans le document XML source 2 espaces de nommage pour identifier ces 2 familles. Vous n'utiliserez pas de préfixe pour les éléments de structures de données, vous en utiliserez un pour les éléments documentaires. Utilisez un URN et un URL pour les 2 URIs d'espace de nom.
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE zoo SYSTEM "zoo.dtd" [ <!ENTITY % notations SYSTEM "notations.ent"> %notations; <!ENTITY flipper.jpg SYSTEM "flipper.jpg" NDATA jpg> <!ENTITY oum.jpg SYSTEM "oum.jpg" NDATA jpg> <!ENTITY ecco.jpg SYSTEM "ecco.jpg" NDATA jpg> ]> <!-- Un petit Zoo avec quelques animaux --> <zoo xmlns="urn:unice:master-2004-2005" xmlns:doc="http://www.unice.fr/master/2004-2005"> <doc:info>Ouvert tous les jours de 8h00 à 19h00</doc:info> <doc:attention>Il est <doc:b>interdit</doc:b> de nourrir les animaux.</doc:attention> <aquarium> <mammifères-marins> <dauphins> <dauphin id="jhgtr13" photo="flipper.jpg" date-naissance="1997-4-1"> <nom>Flipper</nom> <sexe>M</sexe> <taille unité="cm">215</taille> <poids unité="kg">105</poids> </dauphin> <dauphin id="lkjh45" photo="ecco.jpg" date-naissance="2003-10-23"> <nom>Ecco</nom> <sexe>F</sexe> <taille unité="cm">202</taille> <poids unité="kg">98</poids> </dauphin> <dauphin id="kjlhy90" photo="oum.jpg" date-naissance="1996-12-25"> <nom>Oum</nom> <sexe>F</sexe> <!-- c'est mon préféré --> <taille unité="cm">295</taille> <poids unité="kg" status="mesure approximative">190<!-- il faut refaire la pesée --></poids> </dauphin> </dauphins> </mammifères-marins> <poissons> <sélaciens> <doc:danger>Il est <doc:b>interdit</doc:b> de nager avec les requins.</doc:danger> <requin id="plojk09" espèce="marteau" date-naissance="1998-6-5"> <nom>Oussama</nom> <sexe>M</sexe> <taille unité="cm">455</taille> <poids unité="kg">540</poids> <doc:commentaire>A tendance a se jeter contre les murs <![CDATA[<<< marteau & cinglé !!! >>>]]> <!-- Il faudra bien le faire piquer un jour --> </doc:commentaire> </requin> <requin id="vgyuh43" espèce="requin bleu" nom-savant="carcharias glaucus" date-naissance="2004-1-13"> <nom>Saddam</nom> <sexe>M</sexe> <taille unité="cm">355</taille> <poids unité="kg" status="">425</poids> </requin> </sélaciens> </poissons> </aquarium> </zoo>
Que fait le parseur XML lorsqu'il rencontre votre URL d'espace de nom ?
Rechargez le document dans le navigateur.
Que constatez-vous ? Pourquoi ?
L'affichage n'est plus celui souhaité.
En ajoutant des déclarations <zoo xmlns="...">
, tous les éléments
sont associés à cet espace de nommage; or la feuille de style ne traite que des éléments
sans espace de nommage, donc peu de chose devraient être affichées : la règle qui
correspond à la racine, puis les règles par défaut qui peuvent s'appliquer (affichage
du texte brut).
Pour que la feuille de style XSLT réagisse sur les éléments qui appartiennent à un espace de nommage, il faut faire une déclaration en utilisant un préfixe (c'est une contrainte de XPath). Le fait qu'il y ait ou non un préfixe dans le document source n'a pas d'importance, seul importe le fait que les éléments sont dans un espace de noms, et que les règles XSLT correspondent à ces espaces de noms.
Corrigez votre feuille de style pour qu'elle fonctionne à nouveau.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:zoo="urn:unice:master-2004-2005" xmlns:doc="http://www.unice.fr/master/2004-2005" exclude-result-prefixes="zoo doc"> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link href="zoo.css" rel="stylesheet" type="text/css"/> </head> <body> <h1>Bienvenue au Zoo</h1> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="doc:info|doc:attention|doc:danger"> <xsl:choose> <xsl:when test="parent::zoo:dauphins or parent::zoo:sélaciens"> <tr> <td colspan="6"><xsl:call-template name="doc:avertissement"/></td> </tr> </xsl:when> <xsl:otherwise> <xsl:call-template name="doc:avertissement"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="doc:avertissement"> <table class="{local-name()}" align="center"> <tr> <td><img src="{local-name()}.gif" /></td> <td><xsl:apply-templates /></td> </tr> </table> </xsl:template> <xsl:template match="doc:b"><b><xsl:apply-templates /></b></xsl:template> <xsl:template match="doc:i"><i><xsl:apply-templates /></i></xsl:template> <xsl:template match="doc:em"><em><xsl:apply-templates /></em></xsl:template> <xsl:template match="doc:strong"><strong><xsl:apply-templates /></strong></xsl:template> <xsl:template match="zoo:dauphins|zoo:sélaciens"> <h2><xsl:value-of select="local-name()" /></h2> <table border="1"> <tr> <th>Nom</th> <th>Date naissance</th> <th>Type</th> <th>Taille</th> <th>Poids</th> <th>Sexe</th> </tr> <xsl:apply-templates/> </table> </xsl:template> <xsl:template match="zoo:dauphin|zoo:requin"> <tr> <td><xsl:value-of select="zoo:nom" /></td> <td><xsl:value-of select="@date-naissance" /></td> <td><xsl:value-of select="@espèce" /><br /><i><xsl:value-of select="@nom-savant" /></i></td> <td><xsl:value-of select="zoo:taille" /> <xsl:value-of select="zoo:taille/@unité" /></td> <td><xsl:value-of select="zoo:poids" /> <xsl:value-of select="zoo:poids/@unité" /></td> <td><xsl:value-of select="zoo:sexe" /></td> <xsl:if test="@photo"> <td><img src="{@photo}" alt="{zoo:nom}" /></td> </xsl:if> </tr> </xsl:template> </xsl:stylesheet>
Que remarquez-vous des patterns qui correspondent aux attributs ?
xmlns="..."
), mais les attributs sans préfixes n'appartiennent jamais
à un espace de nommmage; donc on peut (on doit) les adresser sans préfixe dans XSLT.
On veut que les mois des dates apparaissent en clair, c'est à dire sous la forme "15 mars 2004" au lieu de "2004-03-15". On utilise cette librairie qui fait ça très bien.
Est-ce que cette feuille de style peut-être distribuée sur la planète sans problème ? Pourquoi ?
On ne peut raisonnablement pas distribuer cette feuille de style sur internet.
La feuille de style déclare l'espace de nommage suivant :
xmlns:date="*** Processing dates ***"
.
Bien que valide (le parseur ne vérifie pas la consistance de l'URI de l'espace
de nom), on ne peut pas dire qu'il s'agisse d'un identificateur universel :
quelqu'un pourrait avoir la même (mauvaise) idée ; il y a donc, potentiellement,
un risque de collision de noms.
Utilisez des URIs à la place.
Faites les adaptations nécessaires à votre feuille de style pour que les dates apparaissent en clair.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:zoo="urn:unice:master-2004-2005" xmlns:doc="http://www.unice.fr/master/2004-2005" xmlns:date="*** Processing dates ***" exclude-result-prefixes="zoo doc date"> <xsl:import href="dates.xsl"/> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link href="zoo.css" rel="stylesheet" type="text/css"/> </head> <body> <h1>Bienvenue au Zoo</h1> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="doc:info|doc:attention|doc:danger"> <xsl:choose> <xsl:when test="parent::zoo:dauphins or parent::zoo:sélaciens"> <tr> <td colspan="6"><xsl:call-template name="doc:avertissement"/></td> </tr> </xsl:when> <xsl:otherwise> <xsl:call-template name="doc:avertissement"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="doc:avertissement"> <table class="{local-name()}" align="center"> <tr> <td><img src="{local-name()}.gif" /></td> <td><xsl:apply-templates /></td> </tr> </table> </xsl:template> <xsl:template match="doc:b"><b><xsl:apply-templates /></b></xsl:template> <xsl:template match="doc:i"><i><xsl:apply-templates /></i></xsl:template> <xsl:template match="doc:em"><em><xsl:apply-templates /></em></xsl:template> <xsl:template match="doc:strong"><strong><xsl:apply-templates /></strong></xsl:template> <xsl:template match="zoo:dauphins|zoo:sélaciens"> <h2><xsl:value-of select="local-name()" /></h2> <table border="1"> <tr> <th>Nom</th> <th>Date naissance</th> <th>Type</th> <th>Taille</th> <th>Poids</th> <th>Sexe</th> </tr> <xsl:apply-templates/> </table> </xsl:template> <xsl:template match="zoo:dauphin|zoo:requin"> <tr> <td><xsl:value-of select="zoo:nom" /></td> <td> <xsl:call-template name="date:format"> <xsl:with-param name="date" select="@date-naissance"/> </xsl:call-template> </td> <td><xsl:value-of select="@espèce" /><br /><i><xsl:value-of select="@nom-savant" /></i></td> <td><xsl:value-of select="zoo:taille" /> <xsl:value-of select="zoo:taille/@unité" /></td> <td><xsl:value-of select="zoo:poids" /> <xsl:value-of select="zoo:poids/@unité" /></td> <td><xsl:value-of select="zoo:sexe" /></td> <xsl:if test="@photo"> <td><img src="{@photo}" alt="{zoo:nom}" /></td> </xsl:if> </tr> </xsl:template> </xsl:stylesheet>
Créez une table des matières des animaux du zoo, dont chaque item pointe vers les fiches descriptives complètes. Vous utiliserez des règles avec un mode nommé.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:zoo="urn:unice:master-2004-2005" xmlns:doc="http://www.unice.fr/master/2004-2005" xmlns:date="*** Processing dates ***" exclude-result-prefixes="zoo doc date"> <xsl:import href="dates.xsl"/> <xsl:output method="html"/> <xsl:param name="liste-par-nom" select="false()" /> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link href="zoo.css" rel="stylesheet" type="text/css"/> </head> <body> <h1>Bienvenue au Zoo</h1> <xsl:choose> <xsl:when test="$liste-par-nom"> <ul> <xsl:apply-templates mode="toc" select="//zoo:nom"> <xsl:sort select="."/> </xsl:apply-templates> </ul> </xsl:when> <xsl:otherwise> <ul> <xsl:apply-templates mode="toc" select="//zoo:nom"> <xsl:sort select="../@date-naissance"/> </xsl:apply-templates> </ul> </xsl:otherwise> </xsl:choose> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="zoo:nom" mode="toc"> <li><a href="#{generate-id()}"><xsl:value-of select="."/></a></li> </xsl:template> <xsl:template match="doc:info|doc:attention|doc:danger"> <xsl:choose> <xsl:when test="parent::zoo:dauphins or parent::zoo:sélaciens"> <tr> <td colspan="6"><xsl:call-template name="doc:avertissement"/></td> </tr> </xsl:when> <xsl:otherwise> <xsl:call-template name="doc:avertissement"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="doc:avertissement"> <table class="{local-name()}" align="center"> <tr> <td><img src="{local-name()}.gif" /></td> <td><xsl:apply-templates /></td> </tr> </table> </xsl:template> <xsl:template match="doc:b"><b><xsl:apply-templates /></b></xsl:template> <xsl:template match="doc:i"><i><xsl:apply-templates /></i></xsl:template> <xsl:template match="doc:em"><em><xsl:apply-templates /></em></xsl:template> <xsl:template match="doc:strong"><strong><xsl:apply-templates /></strong></xsl:template> <xsl:template match="zoo:dauphins|zoo:sélaciens"> <h2><xsl:value-of select="local-name()" /></h2> <table border="1"> <tr> <th>Nom</th> <th>Date naissance</th> <th>Type</th> <th>Taille</th> <th>Poids</th> <th>Sexe</th> </tr> <xsl:apply-templates/> </table> </xsl:template> <xsl:template match="zoo:dauphin|zoo:requin"> <tr> <td><a name="{generate-id(zoo:nom)}"><xsl:value-of select="zoo:nom" /></a></td> <td> <xsl:call-template name="date:format"> <xsl:with-param name="date" select="@date-naissance"/> </xsl:call-template> </td> <td><xsl:value-of select="@espèce" /><br /><i><xsl:value-of select="@nom-savant" /></i></td> <td><xsl:value-of select="zoo:taille" /> <xsl:value-of select="zoo:taille/@unité" /></td> <td><xsl:value-of select="zoo:poids" /> <xsl:value-of select="zoo:poids/@unité" /></td> <td><xsl:value-of select="zoo:sexe" /></td> <xsl:if test="@photo"> <td><img src="{@photo}" alt="{zoo:nom}" /></td> </xsl:if> </tr> </xsl:template> </xsl:stylesheet>
Triez votre table des matières par ordre alphabétique sur le nom des animaux. Faites une autre règle pour trier votre table des matières par date de naissance croissante. Déclarez un paramètre à votre feuille de style pour pouvoir choisir le type de tri. Comment peut-on passer un paramètre à la feuille de style côté client ?
Il n'y a pas de moyen trivial de faire de passage de paramètres à la feuille de style côté client. Il faut faire appel à Javascript pour instancier le processeurs XSLT. Le problème est qu'on perd toute compatibilité : selon le navigateur, les objets ne s'invoquent pas de la même manière.
Le salut réside dans les transformations opérées côté serveur, beaucoup plus souples et neutres vis à vis du client.
Pour faire une présentation soignée, le mieux est d'utiliser un framework CSS. Si vous n'en connaissez pas téléchargez Bootstrap.
Adaptez votre feuille de style XSLT pour qu'elle utilise ce framework, et faites les changements nécessaires pour utiliser ses composants. Utilisez aussi des composants dynamiques avec Javascript.
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:zoo="urn:org.inria.ns.tp:tp-web-rest:zoo" xmlns:doc="http://org.inria.ns.tp/tp-web-rest/doc" xmlns:date="urn:org.inria.ns.tp:tp-web-rest:dates" exclude-result-prefixes="zoo doc date"> <xsl:import href="dates.xsl"/> <xsl:output method="html" doctype-public=" "/> <xsl:param name="liste-par-nom" select="true()" /> <xsl:template match="/"> <html> <head> <title>Zoo</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"/> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css"/> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"/> <style> body { padding-top: 60px; } h2:first-letter { text-transform: uppercase; } </style> </head> <body> <header class="navbar navbar-default navbar-inverse navbar-fixed-top" role="banner"> <div class="navbar-header navbar-brand">Bienvenue au Zoo</div> </header> <div class="container"> <div class="well sidebar-nav"> <ul class="nav nav-pills nav-stacked"> <xsl:choose> <xsl:when test="$liste-par-nom"> <xsl:apply-templates mode="toc" select="//zoo:nom"> <xsl:sort select="."/> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates mode="toc" select="//zoo:nom"> <xsl:sort select="../@date-naissance"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </ul> </div> <xsl:apply-templates/> </div> </body> </html> </xsl:template> <xsl:template match="zoo:nom" mode="toc"> <li><a href="#{generate-id()}"><xsl:value-of select="."/></a></li> </xsl:template> <xsl:template match="zoo:aquarium/*/*/doc:info | zoo:aquarium/*/*/doc:attention | zoo:aquarium/*/*/doc:danger"> <tr> <td colspan="6"><xsl:apply-templates select="." mode="apply"/></td> </tr> </xsl:template> <xsl:template match="doc:info | doc:attention | doc:danger"> <xsl:apply-templates select="." mode="apply"/> </xsl:template> <xsl:template match="doc:info" mode="apply"> <div class="alert alert-info"> <p class="lead"> <span class="glyphicon glyphicon-info-sign"/> <xsl:text> </xsl:text> <xsl:apply-templates /> </p> </div> </xsl:template> <xsl:template match="doc:attention" mode="apply"> <div class="alert alert-warning"> <p class="lead"> <span class="glyphicon glyphicon-warning-sign"/> <xsl:text> </xsl:text> <xsl:apply-templates /> </p> </div> </xsl:template> <xsl:template match="doc:danger" mode="apply"> <div class="alert alert-danger"> <p class="lead"> <span class="glyphicon glyphicon-cutlery"/> <xsl:text> </xsl:text> <xsl:apply-templates /> </p> </div> </xsl:template> <xsl:template match="doc:b"><b><xsl:apply-templates /></b></xsl:template> <xsl:template match="doc:i"><i><xsl:apply-templates /></i></xsl:template> <xsl:template match="doc:em"><em><xsl:apply-templates /></em></xsl:template> <xsl:template match="doc:strong"><strong><xsl:apply-templates /></strong></xsl:template> <xsl:template match="zoo:dauphins|zoo:sélaciens"> <h2><xsl:value-of select="local-name()"/></h2> <table class="table table-bordered"> <tr> <th>Nom</th> <th>Date naissance</th> <th>Type</th> <th>Taille</th> <th>Poids</th> <th>Sexe</th> <xsl:if test="*/@photo"> <th>Photo</th> </xsl:if> </tr> <xsl:apply-templates/> </table> </xsl:template> <xsl:template match="zoo:dauphin|zoo:requin"> <tr> <td><a name="{generate-id(zoo:nom)}"><xsl:value-of select="zoo:nom" /></a></td> <td> <xsl:call-template name="date:format"> <xsl:with-param name="date" select="@date-naissance"/> </xsl:call-template> </td> <td><xsl:value-of select="@espèce" /><br /><i><xsl:value-of select="@nom-savant" /></i></td> <td><xsl:value-of select="zoo:taille" /> <xsl:value-of select="zoo:taille/@unité" /></td> <td><xsl:value-of select="zoo:poids" /> <xsl:value-of select="zoo:poids/@unité" /></td> <td><xsl:value-of select="zoo:sexe" /></td> <xsl:if test="@photo"> <td><img src="img/{@photo}" alt="{zoo:nom}" class="img-circle"/></td> </xsl:if> </tr> </xsl:template> </xsl:stylesheet>