« Tutoriel XSLT débutant » : différence entre les versions
mAucun résumé des modifications |
mAucun résumé des modifications |
||
Ligne 337 : | Ligne 337 : | ||
XPath est nettement plus puissant que les sélecteurs CSS. Avec XPath vous pouvez par exemple dire "Identifiez le 4ème mot du 2ème paragraph qui suit un titre qui commence par le mot ’début’". | XPath est nettement plus puissant que les sélecteurs CSS. Avec XPath vous pouvez par exemple dire "Identifiez le 4ème mot du 2ème paragraph qui suit un titre qui commence par le mot ’début’". | ||
==Récapitulatif de chemins simples de localisations XPATH== | ==Récapitulatif de chemins simples de localisations XPATH== | ||
Voir aussi: [http://tecfa.unige.ch/guides/tie/html/xml-xpath/xml-path.html http://tecfa.unige.ch/guides/tie/html/xml-path/xml-xpath.html ] | |||
{| border="1" | {| border="1" | ||
! rowspan="1" colspan="1" | | ! rowspan="1" colspan="1" | Elément syntaxique | ||
Elément | ! rowspan="1" colspan="1" | (Type de chemin) | ||
! rowspan="1" colspan="1" | | ! rowspan="1" colspan="1" | Exemple d’un chemin | ||
(Type de chemin) | ! rowspan="1" colspan="1" | Exemple d’un match réussi par rapport au chemin indiqué à gauche | ||
! rowspan="1" colspan="1" | | |||
Exemple d’un chemin | |||
! rowspan="1" colspan="1" | | |||
Exemple d’un match réussi par rapport au chemin indiqué à gauche | |||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | balise | ||
balise | | rowspan="1" colspan="1" | nom d’élément | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | project | ||
nom d’élément | | rowspan="1" colspan="1" | <nowiki> <project> ...... </project> </nowiki> | ||
| rowspan="1" colspan="1" | | |||
project | |||
| rowspan="1" colspan="1" | | |||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | / | ||
/ | | rowspan="1" colspan="1" | sépare enfants directs | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | project/title | ||
sépare enfants directs | | rowspan="1" colspan="1" | <nowiki><project> <title> ... </title></nowiki> | ||
| rowspan="1" colspan="1" | | |||
project/title | |||
| rowspan="1" colspan="1" | | |||
<project> <title> ... </title> | |||
|- | |- | ||
| rowspan="1" colspan="2" | | | rowspan="1" colspan="2" | | ||
| rowspan="1" colspan="1" |/ | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |(correspond à l’élément racine) | ||
/ | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |// | ||
(correspond à l’élément racine) | | rowspan="1" colspan="1" |descendant | ||
| rowspan="1" colspan="1" |project//title | |||
| rowspan="1" colspan="1" |<nowiki><project><problem> <title>....</title></nowiki> | |||
|- | |||
| rowspan="1" colspan="2" | | |||
| rowspan="1" colspan="1" |//title | |||
| rowspan="1" colspan="1" |<nowiki><racine>... <title>..</title> (n’mporte où) </nowiki> | |||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | <nowiki>*</nowiki>| | ||
| rowspan="1" colspan="1" | "wildcard" | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | <nowiki>*/title</nowiki> | ||
| rowspan="1" colspan="1" | <nowiki><bla> <title>..</title> et <bli> <title>...</title></nowiki> | |||
| rowspan="1" colspan="1" | | |||
| rowspan="1" colspan="1" | | |||
< | |||
|- | |- | ||
| rowspan="1" colspan="1" | <nowiki>|</nowiki> | |||
| rowspan="1" colspan="1" |opérateur "ou" | |||
| rowspan="1" colspan="1" |title|head | |||
| rowspan="1" colspan="1" |<nowiki><title>...</title> ou <head> ...</head>|-</nowiki> | |||
| rowspan="1" colspan="2" | | | rowspan="1" colspan="2" | | ||
| rowspan="1" colspan="1" |<nowiki>*|/|@*</nowiki> | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |(tous les éléments: les enfants, la racine et les attributs de la racine) | ||
// | |||
| rowspan="1" colspan="1" | | |||
|- | |- | ||
| rowspan="1" colspan="1" |. | |||
| rowspan="1" colspan="1" |élément courant | |||
| rowspan="1" colspan="1" |. | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |../ | ||
| rowspan="1" colspan="1" |élément supérieur | |||
| rowspan="1" colspan="1" |../problem | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |<nowiki><project></nowiki> | ||
| rowspan="1" colspan="1" | | |||
| rowspan="1" colspan="1" | | |||
<nowiki> | |||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |@ | ||
| rowspan="1" colspan="1" |nom d’attribut | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |@id | ||
| rowspan="1" colspan="1" |<nowiki><xyz id="test">...</xyz></nowiki> | |||
| rowspan="1" colspan="1" | | |||
| rowspan="1" colspan="1" | | |||
|- | |- | ||
| rowspan="1" colspan="2" | | | rowspan="1" colspan="2" | | ||
| rowspan="1" colspan="1" |project/@id | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |<nowiki><project id="test" ...> ... </project></nowiki> | ||
project/@id | |||
| rowspan="1" colspan="1" | | |||
|- | |- | ||
| rowspan="1" colspan="2" | | |||
| rowspan="1" colspan="1" |@attr=’type’ | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
| rowspan="1" colspan="1" |list[@type=’ol’] | |||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" |<nowiki> <list type="ol"> ...... </list></nowiki> | ||
|} | |} | ||
==Extraction d’une valeur== | ==Extraction d’une valeur== | ||
===xsl:value-of=== | ===xsl:value-of=== | ||
Ligne 478 : | Ligne 419 : | ||
* Sélectionne le résultat d’un XPath et le copie vers le document "sortie" | * Sélectionne le résultat d’un XPath et le copie vers le document "sortie" | ||
* Autrement dit: on extrait le contenu d’sous-élément, la valeur d’un attribut, etc. | * Autrement dit: on extrait le contenu d’sous-élément, la valeur d’un attribut, etc. | ||
'''Exemple:''' | '''Exemple:''' | ||
Ligne 485 : | Ligne 424 : | ||
* La règle suivante se déclenche dès qu’une balise <projet> est trouvée | * La règle suivante se déclenche dès qu’une balise <projet> est trouvée | ||
* Elle insère dans le document de sortie le contenu de l’élément <title> qui se trouve à l’intérieur d’un sous-élément <problem> | * Elle insère dans le document de sortie le contenu de l’élément <title> qui se trouve à l’intérieur d’un sous-élément <problem> | ||
<source lang="xml"> | |||
<xsl:template match="project"> | <xsl:template match="project"> | ||
<P> | <P> | ||
Ligne 490 : | Ligne 430 : | ||
</P> | </P> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
'''Syntaxe spéciale pour insérer la valeur d’un objet dans le string d’un attribut à générer:''' | '''Syntaxe spéciale pour insérer la valeur d’un objet dans le string d’un attribut à générer:''' | ||
<source lang="xml"> | |||
{....} | {....} | ||
<xsl:template match="contact-info"> | <xsl:template match="contact-info"> | ||
.... | .... | ||
<a href="mailto:{@email} "> | |||
<xsl:value-of select="@email"/></a> | |||
... | ... | ||
</source> | |||
{@email} insère la valeur de l’attribut email de l’élément courrant, par exemple: | {@email} insère la valeur de l’attribut email de l’élément courrant, par exemple: | ||
<contact-info email="test@test"> | <contact-info email="test@test"> | ||
===xsl:copy=== | ===xsl:copy=== | ||
Ligne 512 : | Ligne 451 : | ||
* Sert à copier "tel quel" un élément source vers le document produit | * Sert à copier "tel quel" un élément source vers le document produit | ||
* Copie les balises et le contenu ! | * Copie les balises et le contenu ! | ||
'''Scénarios d’usage''' | '''Scénarios d’usage''' | ||
* Utile pour reproduire l’original (ici un tag <p>...</p>) | * Utile pour reproduire l’original (ici un tag <p>...</p>) | ||
<source lang="xml"> | |||
<xsl:template match="p"> | <xsl:template match="p"> | ||
<xsl:copy> <xsl:apply-templates/> </xsl:copy> | <xsl:copy> <xsl:apply-templates/> </xsl:copy> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
* Utile pour récupérer tout ce qui n’a pas été défini, mais attention si le tag ne correspond pas à un tag HTML il faut regarder le source HTML produit et agir .... | * Utile pour récupérer tout ce qui n’a pas été défini, mais attention si le tag ne correspond pas à un tag HTML il faut regarder le source HTML produit et agir .... | ||
<source lang="xml"> | |||
<xsl:template match="*"> | <xsl:template match="*"> | ||
<xsl:copy>Garbage: <i> <xsl:apply-templates/> </i> </xsl:copy> | <xsl:copy>Garbage: <i> <xsl:apply-templates/> </i> </xsl:copy> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
Le fragment suivant copie tous les éléments non traités par les autres templates: | |||
* utile si vous utilisez des balises XHTML que vous ne désirez pas traiter ou encore si XSLT sert juste à "enrichir" votre code XML (genre table de matières) | |||
<source lang="xml"> | |||
<xsl:template match="*|@*"> | <xsl:template match="*|@*"> | ||
<xsl:copy> | <xsl:copy> | ||
Ligne 536 : | Ligne 477 : | ||
</xsl:copy> | </xsl:copy> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
== Exemples == | |||
=Exemples= | |||
==Utilisation de apply-templates et XPath== | ==Utilisation de apply-templates et XPath== | ||
Avant d’utiliser des constructions avancées comme "if" ou "for-each", réfléchissez bien si c’est vraiment nécessaire. Dans la plupart des cas il suffit de définir des règles avec "xsl:apply-templates" et le reste "s’organise" tout seul. | |||
===Simple XML vers HTML avec XSLT=== | ===Simple XML vers HTML avec XSLT=== | ||
* http://tecfa.unige.ch/guides/xml/examples/xsl-simple/ (fouiller le répertoire !) | * http://tecfa.unige.ch/guides/xml/examples/xsl-simple/ (fouiller le répertoire !) | ||
===Un texte en XML=== | ===Un texte en XML=== | ||
<source lang="xml"> | |||
<arbre> | <arbre> | ||
<para>Simples Templates et XPath</para> | <para>Simples Templates et XPath</para> | ||
Ligne 569 : | Ligne 505 : | ||
</uncle> | </uncle> | ||
</arbre> | </arbre> | ||
</source> | |||
===La feuille de style XSLT=== | ===La feuille de style XSLT=== | ||
Ici on veut produire un simple HTML à partir du XML, avec les consignes suivantes: | |||
* On aimerait que les enfants de <aunt> et <uncle> soient affichés différemment | |||
* Le prermier enfant de <uncle> doit être affiché spécialement aussi | |||
* Si voulez savoir comment ce code s’exécute, consultez le fichier *-trace.xml | * Si voulez savoir comment ce code s’exécute, consultez le fichier *-trace.xml | ||
<source lang="xml"> | |||
<xsl:template match="arbre"> | <xsl:template match="arbre"> | ||
<html><title>XSL Example</title><body> | <html><title>XSL Example</title><body> | ||
Ligne 605 : | Ligne 542 : | ||
<p style="color:blue"><xsl:apply-templates /></p> | <p style="color:blue"><xsl:apply-templates /></p> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
===Le résultat en HTML=== | ===Le résultat en HTML=== | ||
<source lang="xml"> | |||
<!DOCTYPE html | <!DOCTYPE html | ||
Ligne 629 : | Ligne 567 : | ||
</body> | </body> | ||
</html> | </html> | ||
</source> | |||
==Gestion de liens== | ==Gestion de liens== | ||
Ligne 635 : | Ligne 573 : | ||
Le formalisme XML en soi ne comprend pas les liens !! | Le formalisme XML en soi ne comprend pas les liens !! | ||
Il existe un langage XLink que vous pouvez utiliser (et qui fait partie des standards SVG). Sinon, vous inventez un élément ou encore un attribut pour ce type d’information et vous traduisez en <a href ...> | |||
===Traduction vers <a href="...">...</a>=== | ===Traduction vers <a href="...">...</a>=== | ||
Ligne 645 : | Ligne 581 : | ||
c.f. le code source de ces fichiers ! | c.f. le code source de ces fichiers ! | ||
===Extraits du fichier XML=== | ===Extraits du fichier XML=== | ||
Ligne 652 : | Ligne 586 : | ||
* On peut inventer une balise comme "url" pour l’URL et une autre balise comme "name" pour indiquer le nom du lien. | * On peut inventer une balise comme "url" pour l’URL et une autre balise comme "name" pour indiquer le nom du lien. | ||
<source lang="xml"> | |||
<address> | <address> | ||
<name>TECFA</name> | <name>TECFA</name> | ||
<url>http://tecfa.unige.ch</url> | <url>http://tecfa.unige.ch</url> | ||
</address> | </address> | ||
<address2> | <address2> | ||
Ligne 662 : | Ligne 596 : | ||
<url>http://tecfa.unige.ch</url> | <url>http://tecfa.unige.ch</url> | ||
</address2> | </address2> | ||
</source> | |||
Alternativement, on aurait pu mettre des informations dans un attribut | |||
<source lang="xml"> | |||
<address4 url="http://tecfa.unige.ch">TECFA</address4> | <address4 url="http://tecfa.unige.ch">TECFA</address4> | ||
<address5 url="http://tecfa.unige.ch">TECFA</address5> | <address5 url="http://tecfa.unige.ch">TECFA</address5> | ||
</source> | |||
===Extraits du fichier XSLT=== | ===Extraits du fichier XSLT=== | ||
Ligne 672 : | Ligne 609 : | ||
Pour address et address2 on crée des règles | Pour address et address2 on crée des règles | ||
<source lang="xml"> | |||
<xsl:template match="address"> | <xsl:template match="address"> | ||
<a href="{url} | <a href="{url} | ||
Ligne 677 : | Ligne 615 : | ||
"/> </a> | "/> </a> | ||
</xsl:template> | </xsl:template> | ||
<xsl:template match="address2"> | <xsl:template match="address2"> | ||
<xsl:apply-templates select="url"/> | <xsl:apply-templates select="url"/> | ||
</xsl:template> | </xsl:template> | ||
<xsl:template match="url"> | <xsl:template match="url"> | ||
<a href="{.}"> <xsl:value-of select="../name"/> </a> | <a href="{.}"> <xsl:value-of select="../name"/> </a> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
address3 et address2 sont traitées directement depuis l’élément mère | address3 et address2 sont traitées directement depuis l’élément mère | ||
<source lang="xml"> | |||
<a href="{address3/url}"><xsl:value-of select="address3/name"/></a> | <a href="{address3/url}"><xsl:value-of select="address3/name"/></a> | ||
<a href="{address4/@url}"><xsl:value-of select="address4"/></a> | <a href="{address4/@url}"><xsl:value-of select="address4"/></a> | ||
<xsl:template match="address5"> | <xsl:template match="address5"> | ||
<a href="{@url}"> <xsl:value-of select="."/> </a> | <a href="{@url}"> <xsl:value-of select="."/> </a> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
==Images== | ==Images== | ||
Il y n’a aucune magie spéciale pour gérer les images ! Simplement: | |||
* Examinez votre XML | |||
* Trouvez un moyen pour traduire en HTML (ou autre chose) | |||
===Insertion d’images=== | ===Insertion d’images=== | ||
'''Fichier XML''' | '''Fichier XML''' | ||
<source lang="xml"> | |||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
<?xml-stylesheet href="images.xsl" type="text/xsl"?> | <?xml-stylesheet href="images.xsl" type="text/xsl"?> | ||
Ligne 733 : | Ligne 663 : | ||
<comment>Written by DKS.</comment> | <comment>Written by DKS.</comment> | ||
</page> | </page> | ||
</source> | |||
'''XSLT stylesheet''' | '''XSLT stylesheet''' | ||
Ligne 741 : | Ligne 669 : | ||
* Une règle pour la balise "list" | * Une règle pour la balise "list" | ||
<source lang="xml"> | |||
<xsl:template match="list"> | <xsl:template match="list"> | ||
Apply templates for "image" elements: | Apply templates for "image" elements: | ||
<xsl:apply-templates select="image"/> | |||
</source> | |||
This will only insert the first "image2" element contents it finds: | |||
<p> <img src="{image2}"/> </p> | |||
And another template for a tag image3 element (with an attribute) | |||
<source lang="xml"> | |||
<xsl:apply-templates select="image3"/> | |||
</xsl:template> | |||
</source> | |||
Une règle pour la balise "image" | |||
<source lang="xml"> | |||
<xsl:template match="image"> | |||
<p> <img src="{.}"/> </p> | |||
</xsl:template> | |||
</source> | |||
Une règle pour la balise "image3" | |||
<source lang="xml"> | |||
<xsl:template match="image3"> | |||
<p> <img src="{@source}"/> | |||
<xsl:value-of select="."/> | |||
</p> | |||
</xsl:template> | |||
</source> | |||
==Fabrication de références (liens)== | ==Fabrication de références (liens)== | ||
===Table de matières pour éléments qui ont un identificateur=== | ===Table de matières pour éléments qui ont un identificateur=== | ||
* [http://tecfa.unige.ch/guides/xml/examples/recit/ | * [http://tecfa.unige.ch/guides/xml/examples/recit/ http://tecfa.unige.ch/guides/xml/examples/recit/] | ||
On utilise ici un attribut "mode" dans la définition des templates et apply-templates | |||
* Cela nous permet d’écrire plusieurs règles pour un même noeud | * Cela nous permet d’écrire plusieurs règles pour un même noeud | ||
* Ici par exemple, on utilise mode="toc" pour fabriquer une table des matières | * Ici par exemple, on utilise mode="toc" pour fabriquer une table des matières | ||
'''Fragment XSLT (fait d’abord la table des matières, ensuite le reste)''' | '''Fragment XSLT (fait d’abord la table des matières, ensuite le reste)''' | ||
<source lang="xml"> | |||
<xsl:template match="/"> | <xsl:template match="/"> | ||
<html> | <html> | ||
Ligne 800 : | Ligne 727 : | ||
</html> | </html> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
'''Fragments XSLT pour gérér la balise "EPISODE": 2 règles dont une avec un mode''' | '''Fragments XSLT pour gérér la balise "EPISODE": 2 règles dont une avec un mode''' | ||
<source lang="xml"> | |||
<xsl:template match="EPISODE" mode="toc" | <xsl:template match="EPISODE" mode="toc"> | ||
<a href="#{@id}"> | <a href="#{@id}"> | ||
<xsl:value-of select="SousBut"/></a> - | <xsl:value-of select="SousBut"/></a> - | ||
Ligne 811 : | Ligne 738 : | ||
</xsl:template> | </xsl:template> | ||
<xsl:template match="/RECIT/FIL/EPISODE"> | <xsl:template match="/RECIT/FIL/EPISODE"> | ||
<a name="{@id}" | <a name="{@id}"> <hr /> </a> | ||
<xsl:apply-templates/> | <xsl:apply-templates/> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
===Tables de matières pour éléments sans ID=== | ===Tables de matières pour éléments sans ID=== | ||
Plus difficile car il faut "fabriquer" des attributs "name" et "href" pour le HTML | |||
** la solution adopté ici est moche (on aurait pu compter les éléments) | ** la solution adopté ici est moche (on aurait pu compter les éléments) | ||
* il s’agit des jours d’un atelier webmaster qu’on peut consulter ici: | * il s’agit des jours d’un atelier webmaster qu’on peut consulter ici: | ||
Ligne 827 : | Ligne 753 : | ||
** programme.xsl - produit le résultat (voir le fichier programme.html) | ** programme.xsl - produit le résultat (voir le fichier programme.html) | ||
** matos.xsl, resume.xsl, animateurs.xsl créent des extraits variés du programme. | ** matos.xsl, resume.xsl, animateurs.xsl créent des extraits variés du programme. | ||
'''Fragments XSLT''' | '''Fragments XSLT''' | ||
<source lang="xml"> | |||
<!-- Code qui fabrique la table des matières (jours) en HTML --> | <!-- Code qui fabrique la table des matières (jours) en HTML --> | ||
Programme: <xsl:apply-templates select="//day" mode="toc" | Programme: <xsl:apply-templates select="//day" mode="toc"/> | ||
<xsl:template match="day" mode="toc"> | <xsl:template match="day" mode="toc"> | ||
Ligne 846 : | Ligne 766 : | ||
<!-- Code pour insérer des attributs "name" dans le HTML --> | <!-- Code pour insérer des attributs "name" dans le HTML --> | ||
<xsl:template match="day"> | <xsl:template match="day"> | ||
<a name="{@name}{@dayno}{@month}" | <a name="{@name}{@dayno}{@month}" > | ||
<xsl:value-of select="@name"/></a> - | |||
<xsl:value-of select="@dayno"/>/<xsl:value-of select="@month"/>/ | |||
<xsl:value-of select="@year"/> | <xsl:value-of select="@year"/> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
'''Fragment XML (élément à extraire)''' | '''Fragment XML (élément à extraire)''' | ||
Faire une table des matières avec les jours de l’Atelier (avec liens) | |||
<day name="lundi" year="2003" month="6" dayno="16"> | <day name="lundi" year="2003" month="6" dayno="16"> | ||
'''Résultat HTML''' | '''Résultat HTML''' | ||
Au début du fichier on a un menu qui affiche les jours (liens vers le bas) | |||
Programme: <a href="#lundi166">lundi</a> - <a href="#mardi176">mardi</a> - .... | Programme: <a href="#lundi166">lundi</a> - <a href="#mardi176">mardi</a> - .... | ||
...... | ...... | ||
Ligne 874 : | Ligne 790 : | ||
<a name="lundi166">lundi</a> - 16/6/2003 | <a name="lundi166">lundi</a> - 16/6/2003 | ||
'''Note:'''Dans ce répertoire il y a aussi un fichier programme-fo.xsl qui génère du code xsl-fo utilisé pour générer la version PDF du programme. | |||
'''Note:''' | |||
===Tables de matières pour éléments sans ID=== | ===Tables de matières pour éléments sans ID=== | ||
Ligne 888 : | Ligne 798 : | ||
* http://tecfa.unige.ch/guides/xml/examples/xsl-toc/ | * http://tecfa.unige.ch/guides/xml/examples/xsl-toc/ | ||
== Déclarations et style == | |||
Veillez à ce que le fichier produit corresponde aux normes, c.à.d qu’il contienne les déclarations nécessaires pour chaque type de document. | |||
===xsl:output=== | ===xsl:output=== | ||
Ligne 904 : | Ligne 806 : | ||
permet de définir le type de sortie qui sera produit et de générer des entêtes. Voici la syntaxe (simplifiée) pour XSL V 1.0 (1999) | permet de définir le type de sortie qui sera produit et de générer des entêtes. Voici la syntaxe (simplifiée) pour XSL V 1.0 (1999) | ||
<source lang="xml"> | |||
<xsl:output<br /> method = "xml" | "html" | "text"<br /> version = nmtoken<br /> encoding = string<br /> omit-xml-declaration = "yes" | "no"<br /> standalone = "yes" | "no"<br />doctype-public = string<br /> doctype-system = string<br /> indent = "yes" | "no"<br />media-type = string /> | <xsl:output<br /> method = "xml" | "html" | "text"<br /> version = nmtoken<br /> encoding = string<br /> omit-xml-declaration = "yes" | "no"<br /> standalone = "yes" | "no"<br />doctype-public = string<br /> doctype-system = string<br /> indent = "yes" | "no"<br />media-type = string /> | ||
</source> | |||
* A mettre au début du fichier (après xsl:stylesheet) | * A mettre au début du fichier (après xsl:stylesheet) | ||
* Ci-dessous qqs. exemples | * Ci-dessous qqs. exemples | ||
===Output en HTML 4.01 transitionnel=== | ===Output en HTML 4.01 transitionnel=== | ||
<xsl:output method="html" | <source lang="xml"> | ||
<xsl:output method="html" | |||
encoding="ISO-8859-1" | |||
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/> | |||
</source> | |||
===Output en XHTML "façon light"=== | ===Output en XHTML "façon light"=== | ||
<source lang="xml"> | |||
<xsl:output | <xsl:output | ||
method="html" | method="html" | ||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" | |||
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" | doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
indent="yes" | indent="yes" | ||
encoding="iso-8859-1" | encoding="iso-8859-1" | ||
/> | /> | ||
</source> | |||
===Output en XHTML "pur" (page XML) et transitionnel=== | ===Output en XHTML "pur" (page XML) et transitionnel=== | ||
<source lang="xml"> | |||
<xsl:stylesheet version="1.0" | <xsl:stylesheet version="1.0" | ||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | ||
xmlns="http://www.w3.org/1999/xhtml"> | xmlns="http://www.w3.org/1999/xhtml"> | ||
<xsl:output | <xsl:output | ||
method="xml" | method="xml" | ||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" | doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" | ||
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" | doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
indent="yes" | indent="yes" | ||
encoding="iso-8859-1" | encoding="iso-8859-1" | ||
/> | /> | ||
</source> | |||
===Output en XHTML "pur" et strict=== | ===Output en XHTML "pur" et strict=== | ||
<source lang="xml"> | |||
<xsl:stylesheet version="1.0" | <xsl:stylesheet version="1.0" | ||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | ||
xmlns="http://www.w3.org/1999/xhtml"> | xmlns="http://www.w3.org/1999/xhtml"> | ||
<xsl:output | <xsl:output | ||
method="xml" | method="xml" | ||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" | doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" | ||
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" | doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" | ||
indent="yes" | indent="yes" | ||
encoding="iso-8859-1" | encoding="iso-8859-1" | ||
/> | /> | ||
</source> | |||
===Output en SVG=== | ===Output en SVG=== | ||
<source lang="xml"> | |||
<xsl:output | <xsl:output | ||
method="xml" | method="xml" | ||
indent="yes" | indent="yes" | ||
standalone="no" | standalone="no" | ||
doctype-public="-//W3C//DTD SVG 1.0//EN" | doctype-public="-//W3C//DTD SVG 1.0//EN" | ||
doctype-system="http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd" | doctype-system="http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd" | ||
media-type="image/svg" | media-type="image/svg" | ||
/> | /> | ||
</source> | |||
===Output en VRML=== | ===Output en VRML=== | ||
<source lang="xml"> | |||
<xsl:output method="text" | <xsl:output method="text" | ||
encoding="UTF-8" | encoding="UTF-8" | ||
media-type="model/vrml"/> | media-type="model/vrml"/> | ||
.... | .... | ||
Ligne 1 009 : | Ligne 887 : | ||
...... | ...... | ||
</source> | |||
== CSS pour le résultat de la transformation == | |||
Lorsque vous produisez du HTML ou du XHTML, évitez de produire du HTML "vieille école" (balises "font", etc.). Il est simple d’associer une feuille de style CSS ! Vous "faites" comme à la main. Donc il faut insérer la balise "link" à l’endroit ou le <head> est généré. | |||
<source lang="xml"> | |||
<xsl:template match="racine"> | <xsl:template match="racine"> | ||
<html> | <html> | ||
Ligne 1 027 : | Ligne 905 : | ||
</title> | </title> | ||
</head> | </head> | ||
</source> | |||
==Générer plusieurs fichiers HTML à partir d’un seul XML== | ==Générer plusieurs fichiers HTML à partir d’un seul XML== | ||
Marche uniquement lorsqu’on traite le fichier XML en "batch" | |||
===Programme de l’Atelier WebMaster 2004=== | ===Programme de l’Atelier WebMaster 2004=== | ||
Ligne 1 040 : | Ligne 916 : | ||
* [http://tecfa.unige.ch/tecfa/teaching/formcont/webmaster2004/programme/programme.xsl programme.xsl] (montre comment faire) | * [http://tecfa.unige.ch/tecfa/teaching/formcont/webmaster2004/programme/programme.xsl programme.xsl] (montre comment faire) | ||
<source lang="xml"> | |||
<!-- au début du fichier --> | <!-- au début du fichier --> | ||
<xsl:output name="daypage" method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/> | <xsl:output name="daypage" method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/> | ||
Ligne 1 064 : | Ligne 941 : | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
Quelques astuces: | Quelques astuces: | ||
Si vous devez générer plusieurs pages pour un élément du même nom, il faut générer des noms de fichiers uniques: | |||
<source lang="xml"> | |||
<xsl:template match="day"> | <xsl:template match="day"> | ||
<xsl:result-document href="{@name}{@dayno}{@month}.html" format="daypage"> | <xsl:result-document href="{@name}{@dayno}{@month}.html" format="daypage"> | ||
</source> | |||
Dans l’exemple présent, on désire avoir une page / jour du programme. Chaque jour se distingue par une date spéciale (attributs dayno et month) | |||
Pour faire une table de matière (que vous pouvez inclure partout): | |||
* Voici la règle qui génère la table: | |||
<source lang="xml"> | |||
<xsl:template match="day" mode="toc"> | <xsl:template match="day" mode="toc"> | ||
<a href="{@name}{@dayno}{@month}.html"><xsl:value-of select="@name"/></a> - | <a href="{@name}{@dayno}{@month}.html"><xsl:value-of select="@name"/></a> - | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
Voici comment l’inclure: | |||
<b>Programme</b>: <a href="programme.html"> Top</a> - <xsl:apply-templates select="//day" mode="toc"/> | |||
== XSLT en "batch" et debugage == | |||
'''Avec un fichier de commande''' | '''Avec un fichier de commande''' | ||
Il existe plusieurs processeurs XSLT populaires qu’on peut utiliser pour produire un fichier de sortie à partir d’un xml + xslt. On conseille Saxon (ci-dessous) | |||
* Il faut passer par un processeur XSLT pour "debuger" une feuille de style XSLT client-side | * Il faut passer par un processeur XSLT pour "debuger" une feuille de style XSLT client-side | ||
* "View source" dans un navigateur ne montre pas le HTML ! | |||
* Donc maîtriser une "procédure manuelle" est intéressant !! | |||
* Alternativement, il existe des outils de debugage pour certains éditeurs | |||
Certains outils nécessitent l’installation d’un environnement Java. | |||
* il faut installer un runtime ou dévelopment kit Java pour utiliser les processeurs Xalan ou Saxon. | |||
* Un engin Runtime ("JRE") suffit: | |||
* Versions JRE 5 ou mieux ! | |||
* http://java.sun.com/products/ | * http://java.sun.com/products/ | ||
'''Avec un éditeur XML''' | '''Avec un éditeur XML''' | ||
La plupart des éditeurs XML ont un processeur XSLT intégré (les versions commerciales ont des fonctions de debugage). | |||
== Server-side avec PHP == | == Server-side avec PHP == | ||
Ligne 1 108 : | Ligne 991 : | ||
===XSLT avec PHP 5=== | ===XSLT avec PHP 5=== | ||
Le support XSLT est standard dans PHP 5. L’exemple ci-dessous applique une feuille de style travaux.xsl au fichier travaux.xml | |||
* http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.php | * http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.php | ||
* [http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.php http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.phps] | * [http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.php http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.phps] | ||
Ligne 1 132 : | Ligne 1 014 : | ||
</source> | </source> | ||
Donc pour utiliser ce "service", il suffit de copier le fichier php-xslt.php et changer les 2 noms de fichiers (travaux.xml et travaux.xsl) au début <br /> (enfin depuis le web il faut prendre php-xslt.text et le renommer en xxx.php) | |||
== Client-side XML+XSLT avec Firefox 1.0+ ou IE6+ == | |||
XSLT fonctionne sans problème avec les navigateurs IE, Mozilla/Firefox et Opera. | |||
===Un simple exemple=== | ===Un simple exemple=== | ||
Ligne 1 153 : | Ligne 1 031 : | ||
<xsl:output method="html"/> | <xsl:output method="html"/> | ||
* Voir les fichiers pour les détails. Si aucun contenu n’est affiché ou s’il est mal affiché, faites "Menu->View->Source" | * Voir les fichiers pour les détails. Si aucun contenu n’est affiché ou s’il est mal affiché, faites "Menu->View->Source" | ||
Notes: | |||
* http://www.mozilla.org/releases/ (Mozilla downloads) | |||
* Evitez de travailler avec IE 5.5. La version "normale" n’est pas conforme au standard XSLT. Installez soit IE 6.x ou 7.x soit MSXML3+,pour IE 5.5. | |||
* Il faut s’assurer que le serveur Web indique le bon mime type pour xml et xsl (text/xml). Ceci est fait à Tecfa, mais pas forcément chez votre fournisseur.... | |||
== Executive summary == | |||
# Créer une feuille XSLT xxx.xsl | |||
# Copier/coller le code ci-dessous: | |||
<source lang="xml"> | |||
<?xml version="1.0" encoding="ISO-8859-1" ?> | |||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | ||
</xsl:stylesheet> | </xsl:stylesheet> | ||
</source> | |||
# | # Ecrire une règle qui gère la racine. Cette règle doit produire l'entête, racine, head et body du HTML. | ||
<source lang="xml"> | |||
<xsl:template match="page"> | <xsl:template match="page"> | ||
<html> | <html> | ||
<head> <title> <xsl:value-of select="title"/> | <head> <title> <xsl:value-of select="title"/> | ||
Ligne 1 185 : | Ligne 1 056 : | ||
<body bgcolor="#ffffff"> | <body bgcolor="#ffffff"> | ||
<xsl:apply-templates/> | <xsl:apply-templates/> | ||
</body> | </body> | ||
</html> | </html> | ||
</xsl:template> | </xsl:template> | ||
</source> | |||
# Write rules for each (!!) of your XML elements, | # Write rules for each (!!) of your XML elements, | ||
Ligne 1 194 : | Ligne 1 065 : | ||
#* make sure to place a <xsl:apply-templates> inside each rule (usually between some HTML) ... unless you wish to censor contents. | #* make sure to place a <xsl:apply-templates> inside each rule (usually between some HTML) ... unless you wish to censor contents. | ||
# Associate this stylesheet with your XML file using: | # Associate this stylesheet with your XML file using: | ||
<?xml-stylesheet href="xxx.xsl" type="text/xsl"?> | |||
== Liens == | == Liens == | ||
* http://tecfa.unige.ch/guides/tie/html/xml-xslt/xml-xslt.html | * http://tecfa.unige.ch/guides/tie/html/xml-xslt/xml-xslt.html | ||
* http://tecfa.unige.ch/guides/tie/pdf/files/xml-xslt.pdf | * http://tecfa.unige.ch/guides/tie/pdf/files/xml-xslt.pdf | ||
[[Category: XML]] | [[Category: XML]] |
Version du 24 septembre 2009 à 22:06
Cet article est en construction: un auteur est en train de le modifier.
En principe, le ou les auteurs en question devraient bientôt présenter une meilleure version.
Introduction
Objectifs:
- Avoir une idée de XSLT 1.0
- Savoir écrire des simples feuilles de transformations XML vers (X)HTML
XSLT est un langage de transformations d’arbres (fichiers) XML. XSLT est écrit en XML.
XSLT permet la génération d’autres contenus à partir d’un fichier XML, par exemple:
- du HTML (bien formé)
- du XML plus compliqué (tables de matière + règles de formattage XSL/FO)
- des extraits en XML ou HTML ....
- du SVG, X3D ou toutes sortes d’autres formats à partir de XML
Utilisation (mécanisme de base):
- Définir des règles qui disent comment transformer un "noeud" (element, tag) et ses sous-éléments
- Organiser l’application de ces règles
Les feuilles de style XSLT
- Une feuille de style XSLT est un document séparé qui contient des règles de transformation XSLT
- On peut associer une feuille de style XSL(T) à un (ou plusieurs) documents XML
- Marche soit en "batch" (dans un éditeur ou en ligne de commande), soit avec un traitement "server-side", soit avec la plupart des clients Web modernes (Mozilla, IE6, etc.)
Documentation
- La spécification de XSLT 1.0 est formalisée (W3C Recommendation 16/11/99)
- http://www.w3.org/TR/xslt
- A Tecfa: voir la page XML/XSL dans la toolbox
Compléments à XSLT:
- Xpath (langage pour indiquer un chemin dans un arbre): http://www.w3.org/TR/xpath
- XSL/FO (mise en page): http://www.w3.org/TR/xsl/
- XQuery (langage d’interrogation, bases de données XML): , http://www.w3.org/TR/xquery/
Structure et utilisation d'un fichiers XSLT
Définition d’un fichier XSLT
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
....
</xsl:stylesheet>
- Normalement les fichiers XSLT ont l’extension *.xsl
- Il faut définir un namespace pour distinguer les balises XSL du langage cible. Dans l'exemple ci-dessus:
- xmlns:xsl="URL" définit un "namespace" pour les balises XSL
Donc dans nos exemples toutes les balises XSL commencent par "xsl:". Le fait que toutes les balises XSL commencent par xsl: empêche toute confusion
Association d’un fichier XSLT à un fichier XML
Lorsqu'on utilise XSLT "client-side", c.a.d dans un navigateur, il faut aussi le fichier XSLT au fichier XML avec l'instruction suivante:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="project.xsl" type="text/xsl"?>
<votre_xml>
......
</votre_xml>
Note: Il existe d’autres méthodes pour utiliser un fichier XSLT avec un fichier XML. Par exemple, dans un traitement "batch" on utilise une instruction comme "saxon -o fichier.html fichier.xml fichier.xsl" pour dire "utilise tel fichier ".xsl" pour tel fichier ".xml" pour produire tel fichier ".html".
Principe de fonctionnement de XSLT
XSLT est un véritable langage de programmation
Utilisation simple de XSLT
La transformation du document source (XML) se fait selon des règles (facteurs conditionnels)
- Une feuille de style XSL contient un jeu de règles qui déclarent comment traduire des éléments XML (selon leur contexte).
- On peut imaginer qu’on veuille traduire un commentaire défini par une balise XML <commentaire> en une construction html "
- " comme ci-dessous:
L’expression XML suivante:
<commentaire> xxxx </commentaire>
pourrait donner:
- Commentaire
- xxxx
- Le but d’une feuille de style XML serait de définir une transformation pour chaque balise XML
Une simple règle de traduction (appelée "template" en XSLT):
Traduction d’une balise "title" en "h1" centrée
Source XML à traduire:
<title>Hello friend</title>
La règle XSLT:
Un simple exemple XSLT
Sensibilisation XML + XSLT
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.dtd (DTD)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.xml.text (src XML)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page-html.xsl (style)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.xml (XML)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.html (résultat)
Le fichier XML (sans feuille de style):
<?xml version="1.0"?> <page> <title>Hello Cocoon friend</title> <content>Here is some content :) </content> <comment>Written by DKS/Tecfa, adapted from S.M./the Cocoon samples </comment> </page>
Le "document" XHTML résultant que l’on désire obtenir:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><title>Hello Cocoon friend</title></head><body bgcolor="#ffffff">
Hello Cocoon friend
Here is some content :)
Written by DKS/Tecfa, adapted from S.M./the Cocoon samples
</body></html>
Le fichier XSL:
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="page">
.....
<html> <head> <title> <xsl:value-of select="title"/> </title> </head> <body bgcolor="#ffffff"> <xsl:apply-templates/>
</body> </html> </xsl:template>
<xsl:template match="title">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="content">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="comment">
<xsl:apply-templates/>
</xsl:template> </xsl:stylesheet>
XSL de base
Opérations de base:
- Définir pour chaque balise une règle qui traduit la balise et son contenu
- Organiser l’application de ces règles, c.a.d. indiquer comment traiter le contenu.
- Note: Rappelez-vous que XSL est du XML (donc il faut respecter les principes de validité et de bien formé (pas de balises croisés par exemple !)
Rappel définition d’une règle ("template") avec xsl:template
Exemples xsl:template match="xxx"
Une règle applicable à toutes les balises "project":
<xsl:template match="project"> ......
</xsl:template>
Anatomie d’une simple feuille de style
Application de templates aux sous-éléments
<xsl:apply-templates />
- Ici on définit une simple règle pour la racine qui se déclenche (normalement) en premier):
<xsl:template match="/"> <html> <body> <xsl:apply-templates/>
</body> </html> </xsl:template>
- Un simple apply-templates (sans attributs) examine tous les noeuds enfants dans l’ordre. Si une règle qui correspond à un noeud est détectée, elle sera appliquée
<page> <title>Hello Cocoon friend</title> <content>Here is some content :) </content> <comment>Written by DKS/Tecfa, adapted from S.M./the Cocoon samples </comment> </page>
- Pour le XML ci-dessus, les 2 règles pour "title" et "content" se déclencheraient!
<xsl:template match="title">
<xsl:apply-templates/>
</xsl:template> <xsl:template match="content" >
<xsl:apply-templates/>
</xsl:template>
L’attribut "select" de apply-templates
- permet de spécifier un élément défini par un XPath (au lieu de tous les enfants),
- Autrement dit, on donne l’ordre explicite de chercher et d’appliquer toutes les règles à disposition pour un seul type d’élément identifé par un XPath
- Dans l’exemple ci-dessous la règle déclenchée pour un élément <page> lance seulement la règle qui s’applique au sous-élément <title>
<xsl:template match="page"> <xsl:apply-templates select ="title"/> </xsl:template>
Cette règle pourrait s’appliquer au texte XML suivant:
<page> <title>Hello Cocoon friend</title> <content> Here is some content. Olé !
</content> <comment> Written by DKS/Tecfa, adapted from S.M./the Cocoon samples
</comment> </page>
Déroulement de l’exécution des règles
En simplifiant .....
- Le "moteur" XSLT cherche d’abord à exécuter la première règle qu’il trouve pour l’élément racine.
- Cette règle normalement fait appel à d’autres règles
- soit implicitement : <xsl:apply-templates/>
- soit en faisant appel à des règles précises: <xsl:apply-templates select="regle"/>
- Chacune des sous-règles qui peuvent s’appliquer sera exécutée dans l’ordre et ainsi de suite
- Le processeur ne trouve que les règles qui s’appliquent aux enfants du contexte actuel !!!
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page-wrong.xml
<page> <title>Hello Cocoon friend</title> <content
>
Here is some content. Olé !
</content
> <comment > Written by DKS/Tecfa, adapted from S.M./the Cocoon samples </comment > </page>
La règle suivante ne marche pas, car comment n’est pas un enfant de content
<xsl:template match="content"> <xsl:apply-templates select ="comment"/> </xsl:template>
La règle suivante marche:
<xsl:template match="content"> <xsl:apply-templates select ="p> </xsl:template>
XPATH et extraction de valeurs
- Pour mieux comprendre le fonctionnement des "templates" et pour aborder l’instruction <xsl:value-of .... /> (qui permet d’extraire des informations d’un document source),
il faut avoir des notions du langage "XPath"... - XPath permet d’identifier un ou plusieurs fragments d’un document XML (cela rappelle les sélecteurs de CSS)
Exemple d’un simple XPATH:
<xsl:template match="page "> <xsl:apply-templates select ="title "/> </xsl:template>
"page" et "title sont des expressions XPath définissant un chemin de localisation
"
<xsl:template match="content"> <xsl:apply-templates select ="page/comment "/>
</xsl:template> "/page/comment" est une expression XPath un peu plus compliquée
XPath est nettement plus puissant que les sélecteurs CSS. Avec XPath vous pouvez par exemple dire "Identifiez le 4ème mot du 2ème paragraph qui suit un titre qui commence par le mot ’début’".
Récapitulatif de chemins simples de localisations XPATH
Voir aussi: http://tecfa.unige.ch/guides/tie/html/xml-path/xml-xpath.html
Elément syntaxique | (Type de chemin) | Exemple d’un chemin | Exemple d’un match réussi par rapport au chemin indiqué à gauche | ||||
---|---|---|---|---|---|---|---|
balise | nom d’élément | project | <project> ...... </project> | ||||
/ | sépare enfants directs | project/title | <project> <title> ... </title> | ||||
/ | (correspond à l’élément racine) | ||||||
// | descendant | project//title | <project><problem> <title>....</title> | ||||
//title | <racine>... <title>..</title> (n’mporte où) | ||||||
*| | "wildcard" | */title | <bla> <title>..</title> et <bli> <title>...</title> | ||||
| | opérateur "ou" | title|head | <title>...</title> ou <head> ...</head>|- | *|/|@* | (tous les éléments: les enfants, la racine et les attributs de la racine) | ||
. | élément courant | . | |||||
../ | élément supérieur | ../problem | <project> | ||||
@ | nom d’attribut | @id | <xyz id="test">...</xyz> | ||||
project/@id | <project id="test" ...> ... </project> | ||||||
@attr=’type’ | |||||||
list[@type=’ol’] | <list type="ol"> ...... </list> |
Extraction d’une valeur
xsl:value-of
- Sélectionne le résultat d’un XPath et le copie vers le document "sortie"
- Autrement dit: on extrait le contenu d’sous-élément, la valeur d’un attribut, etc.
Exemple:
- La règle suivante se déclenche dès qu’une balise <projet> est trouvée
- Elle insère dans le document de sortie le contenu de l’élément <title> qui se trouve à l’intérieur d’un sous-élément <problem>
<xsl:template match="project">
<P>
<xsl:value-of select="problem/title"/>
</P>
</xsl:template>
Syntaxe spéciale pour insérer la valeur d’un objet dans le string d’un attribut à générer:
{....}
<xsl:template match="contact-info">
....
<a href="mailto:{@email} ">
<xsl:value-of select="@email"/></a>
...
{@email} insère la valeur de l’attribut email de l’élément courrant, par exemple:
<contact-info email="test@test">
xsl:copy
- Sert à copier "tel quel" un élément source vers le document produit
- Copie les balises et le contenu !
Scénarios d’usage
- Utile pour reproduire l’original (ici un tag
...
)
<xsl:template match="p">
<xsl:copy> <xsl:apply-templates/> </xsl:copy>
</xsl:template>
- Utile pour récupérer tout ce qui n’a pas été défini, mais attention si le tag ne correspond pas à un tag HTML il faut regarder le source HTML produit et agir ....
<xsl:template match="*">
<xsl:copy>Garbage: <i> <xsl:apply-templates/> </i> </xsl:copy>
</xsl:template>
Le fragment suivant copie tous les éléments non traités par les autres templates:
- utile si vous utilisez des balises XHTML que vous ne désirez pas traiter ou encore si XSLT sert juste à "enrichir" votre code XML (genre table de matières)
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
Exemples
Utilisation de apply-templates et XPath
Avant d’utiliser des constructions avancées comme "if" ou "for-each", réfléchissez bien si c’est vraiment nécessaire. Dans la plupart des cas il suffit de définir des règles avec "xsl:apply-templates" et le reste "s’organise" tout seul.
Simple XML vers HTML avec XSLT
- http://tecfa.unige.ch/guides/xml/examples/xsl-simple/ (fouiller le répertoire !)
Un texte en XML
<arbre>
<para>Simples Templates et XPath</para>
<aunt>
<name>Auntie</name>
<child>Je suis un enfant de aunt</child>
</aunt>
<uncle>
<name>Uncle Ben</name>
<child>Je suis le premier enfant de uncle</child>
<child>Je suis le 2eme enfant de uncle</child>
<child>Je suis le 3eme enfant de uncle</child>
</uncle>
</arbre>
La feuille de style XSLT
Ici on veut produire un simple HTML à partir du XML, avec les consignes suivantes:
- On aimerait que les enfants de <aunt> et <uncle> soient affichés différemment
- Le prermier enfant de <uncle> doit être affiché spécialement aussi
- Si voulez savoir comment ce code s’exécute, consultez le fichier *-trace.xml
<xsl:template match="arbre">
<html><title>XSL Example</title><body>
<xsl:apply-templates />
</body> </html>
</xsl:template>
<xsl:template match="uncle|aunt">
<hr /> <xsl:apply-templates />
</xsl:template>
<xsl:template match="name">
<xsl:apply-templates /> :
</xsl:template>
<xsl:template match="uncle/child[position()=1]">
<p> <strong><xsl:apply-templates /></strong> </p>
</xsl:template>
<xsl:template match="uncle/child[position()>1]">
<p> <xsl:apply-templates /></p>
</xsl:template>
<xsl:template match="aunt/child">
<p style="color:blue"><xsl:apply-templates /></p>
</xsl:template>
Le résultat en HTML
<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<title>XSL Example</title>
<body>
Simples Templates et XPath
<hr>
Auntie :
<p style="color:blue">Je suis un enfant de aunt</p>
<hr>
Uncle Ben :
<p><strong>Je suis le premier enfant de uncle</strong></p>
<p>Je suis le 2eme enfant de uncle</p>
<p>Je suis le 3eme enfant de uncle</p>
</body>
</html>
Gestion de liens
Le formalisme XML en soi ne comprend pas les liens !!
Il existe un langage XLink que vous pouvez utiliser (et qui fait partie des standards SVG). Sinon, vous inventez un élément ou encore un attribut pour ce type d’information et vous traduisez en <a href ...>
Traduction vers <a href="...">...</a>
- http://tecfa.unige.ch/guides/xml/examples/xsl-links-to-url/links.xml
- http://tecfa.unige.ch/guides/xml/examples/xsl-links-to-url/links.xsl
c.f. le code source de ces fichiers !
Extraits du fichier XML
- On peut inventer une balise comme "url" pour l’URL et une autre balise comme "name" pour indiquer le nom du lien.
<address>
<name>TECFA</name>
<url>http://tecfa.unige.ch</url>
</address>
<address2>
<name>TECFA</name>
<url>http://tecfa.unige.ch</url>
</address2>
Alternativement, on aurait pu mettre des informations dans un attribut
<address4 url="http://tecfa.unige.ch">TECFA</address4>
<address5 url="http://tecfa.unige.ch">TECFA</address5>
Extraits du fichier XSLT
Pour address et address2 on crée des règles
<xsl:template match="address">
<a href="{url}
"> <xsl:value-of select="name
"/> </a>
</xsl:template>
<xsl:template match="address2">
<xsl:apply-templates select="url"/>
</xsl:template>
<xsl:template match="url">
<a href="{.}"> <xsl:value-of select="../name"/> </a>
</xsl:template>
address3 et address2 sont traitées directement depuis l’élément mère
<a href="{address3/url}"><xsl:value-of select="address3/name"/></a>
<a href="{address4/@url}"><xsl:value-of select="address4"/></a>
<xsl:template match="address5">
<a href="{@url}"> <xsl:value-of select="."/> </a>
</xsl:template>
Images
Il y n’a aucune magie spéciale pour gérer les images ! Simplement:
- Examinez votre XML
- Trouvez un moyen pour traduire en HTML (ou autre chose)
Insertion d’images
Fichier XML
<?xml version="1.0"?>
<?xml-stylesheet href="images.xsl" type="text/xsl"?>
<page>
<title>Hello Here are my images</title>
<list>
<image>
dolores_001.jpg</image>
<image>dolores_002.jpg</image>
<image>dolores_002.jpg</image>
<image2>scrolls.jpg </image2>
<image2>scrolls.jpg </image2>
<image3
source="dolores_002.jpg">Recipe image</image3>
</list>
<comment>Written by DKS.</comment>
</page>
XSLT stylesheet
- Une règle pour la balise "list"
<xsl:template match="list">
Apply templates for "image" elements:
<xsl:apply-templates select="image"/>
This will only insert the first "image2" element contents it finds:
<img src="{image2}"/>
And another template for a tag image3 element (with an attribute)
<xsl:apply-templates select="image3"/>
</xsl:template>
Une règle pour la balise "image"
<xsl:template match="image">
<p> <img src="{.}"/> </p>
</xsl:template>
Une règle pour la balise "image3"
<xsl:template match="image3">
<p> <img src="{@source}"/>
<xsl:value-of select="."/>
</p>
</xsl:template>
Fabrication de références (liens)
Table de matières pour éléments qui ont un identificateur
On utilise ici un attribut "mode" dans la définition des templates et apply-templates
- Cela nous permet d’écrire plusieurs règles pour un même noeud
- Ici par exemple, on utilise mode="toc" pour fabriquer une table des matières
Fragment XSLT (fait d’abord la table des matières, ensuite le reste)
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1><xsl:value-of select="/RECIT/Titre"/></h1>
<p> Highlights de l'histoire:
<xsl:apply-templates select="//EPISODE" mode="toc"/> </p>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
Fragments XSLT pour gérér la balise "EPISODE": 2 règles dont une avec un mode
<xsl:template match="EPISODE" mode="toc">
<a href="#{@id}">
<xsl:value-of select="SousBut"/></a> -
</xsl:template>
<xsl:template match="/RECIT/FIL/EPISODE">
<a name="{@id}"> <hr /> </a>
<xsl:apply-templates/>
</xsl:template>
Tables de matières pour éléments sans ID
Plus difficile car il faut "fabriquer" des attributs "name" et "href" pour le HTML
- la solution adopté ici est moche (on aurait pu compter les éléments)
- il s’agit des jours d’un atelier webmaster qu’on peut consulter ici:
- http://tecfa.unige.ch/tecfa/teaching/formcont/webmaster2003/programme/
- Pour comprendre cet exemple il faut fouiller dans les fichiers suivants:
- programme.xml - contient tout le "programme" de l’Atelier
- programme.xsl - produit le résultat (voir le fichier programme.html)
- matos.xsl, resume.xsl, animateurs.xsl créent des extraits variés du programme.
Fragments XSLT
<!-- Code qui fabrique la table des matières (jours) en HTML -->
Programme: <xsl:apply-templates select="//day" mode="toc"/>
<xsl:template match="day" mode="toc">
<a href="#{@name}{@dayno}{@month}"
><xsl:value-of select="@name"/></a> -
</xsl:template>
<!-- Code pour insérer des attributs "name" dans le HTML -->
<xsl:template match="day">
<a name="{@name}{@dayno}{@month}" >
<xsl:value-of select="@name"/></a> -
<xsl:value-of select="@dayno"/>/<xsl:value-of select="@month"/>/
<xsl:value-of select="@year"/>
</xsl:template>
Fragment XML (élément à extraire)
Faire une table des matières avec les jours de l’Atelier (avec liens)
<day name="lundi" year="2003" month="6" dayno="16">
Résultat HTML
Au début du fichier on a un menu qui affiche les jours (liens vers le bas)
Programme: <a href="#lundi166">lundi</a> - <a href="#mardi176">mardi</a> - .... ......
- Dans le fichier on insère les attributs "name"
<a name="lundi166">lundi</a> - 16/6/2003
Note:Dans ce répertoire il y a aussi un fichier programme-fo.xsl qui génère du code xsl-fo utilisé pour générer la version PDF du programme.
Tables de matières pour éléments sans ID
- Table des matières pour une "page travaux STAF" (portfolio étudiant)
- On liste les travaux
- http://tecfa.unige.ch/guides/xml/examples/xsl-toc/
Déclarations et style
Veillez à ce que le fichier produit corresponde aux normes, c.à.d qu’il contienne les déclarations nécessaires pour chaque type de document.
xsl:output
permet de définir le type de sortie qui sera produit et de générer des entêtes. Voici la syntaxe (simplifiée) pour XSL V 1.0 (1999)
<xsl:output<br /> method = "xml" | "html" | "text"<br /> version = nmtoken<br /> encoding = string<br /> omit-xml-declaration = "yes" | "no"<br /> standalone = "yes" | "no"<br />doctype-public = string<br /> doctype-system = string<br /> indent = "yes" | "no"<br />media-type = string />
- A mettre au début du fichier (après xsl:stylesheet)
- Ci-dessous qqs. exemples
Output en HTML 4.01 transitionnel
<xsl:output method="html"
encoding="ISO-8859-1"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
Output en XHTML "façon light"
<xsl:output
method="html"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
indent="yes"
encoding="iso-8859-1"
/>
Output en XHTML "pur" (page XML) et transitionnel
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
indent="yes"
encoding="iso-8859-1"
/>
Output en XHTML "pur" et strict
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
indent="yes"
encoding="iso-8859-1"
/>
Output en SVG
<xsl:output
method="xml"
indent="yes"
standalone="no"
doctype-public="-//W3C//DTD SVG 1.0//EN"
doctype-system="http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"
media-type="image/svg"
/>
Output en VRML
<xsl:output method="text"
encoding="UTF-8"
media-type="model/vrml"/>
....
<xsl:template match="/">#VRML V2.0 utf8
......
CSS pour le résultat de la transformation
Lorsque vous produisez du HTML ou du XHTML, évitez de produire du HTML "vieille école" (balises "font", etc.). Il est simple d’associer une feuille de style CSS ! Vous "faites" comme à la main. Donc il faut insérer la balise "link" à l’endroit ou le <head> est généré.
<xsl:template match="racine">
<html>
<head>
<link href="programme.css" type="text/css" rel="stylesheet"/>
<title>
bla bla
</title>
</head>
Générer plusieurs fichiers HTML à partir d’un seul XML
Marche uniquement lorsqu’on traite le fichier XML en "batch"
Programme de l’Atelier WebMaster 2004
- http://tecfa.unige.ch/tecfa/teaching/formcont/webmaster2004/programme/
- programme.xsl (montre comment faire)
<!-- au début du fichier -->
<xsl:output name="daypage" method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
.....
<!-- une règle qui génère une page -->
<xsl:template match="software">
<xsl:result-document href="software.html" format="daypage">
<html> <head>
<title> <xsl:value-of select="/course/course-title"/> </title> </head>
<body bgcolor="white">
[<a name="top" href="../welcome.html">Home</a>] -&gt; [<a name="top" href="programme.html">Programme</a>] -&gt; [Logiciels]
<ul>
......
<xsl:apply-templates select="soft"/>
</ul>
</body>
</html>
</xsl:result-document>
</xsl:template>
Quelques astuces:
Si vous devez générer plusieurs pages pour un élément du même nom, il faut générer des noms de fichiers uniques:
<xsl:template match="day">
<xsl:result-document href="{@name}{@dayno}{@month}.html" format="daypage">
Dans l’exemple présent, on désire avoir une page / jour du programme. Chaque jour se distingue par une date spéciale (attributs dayno et month)
Pour faire une table de matière (que vous pouvez inclure partout):
- Voici la règle qui génère la table:
<xsl:template match="day" mode="toc">
<a href="{@name}{@dayno}{@month}.html"><xsl:value-of select="@name"/></a> -
</xsl:template>
Voici comment l’inclure:
Programme: <a href="programme.html"> Top</a> - <xsl:apply-templates select="//day" mode="toc"/>
XSLT en "batch" et debugage
Avec un fichier de commande
Il existe plusieurs processeurs XSLT populaires qu’on peut utiliser pour produire un fichier de sortie à partir d’un xml + xslt. On conseille Saxon (ci-dessous)
- Il faut passer par un processeur XSLT pour "debuger" une feuille de style XSLT client-side
- "View source" dans un navigateur ne montre pas le HTML !
- Donc maîtriser une "procédure manuelle" est intéressant !!
- Alternativement, il existe des outils de debugage pour certains éditeurs
Certains outils nécessitent l’installation d’un environnement Java.
- il faut installer un runtime ou dévelopment kit Java pour utiliser les processeurs Xalan ou Saxon.
- Un engin Runtime ("JRE") suffit:
- Versions JRE 5 ou mieux !
- http://java.sun.com/products/
Avec un éditeur XML
La plupart des éditeurs XML ont un processeur XSLT intégré (les versions commerciales ont des fonctions de debugage).
Server-side avec PHP
XSLT avec PHP 5
Le support XSLT est standard dans PHP 5. L’exemple ci-dessous applique une feuille de style travaux.xsl au fichier travaux.xml
- http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.php
- http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.phps
- http://tecfa.unige.ch/guides/php/examples/xslt/php-xslt.text
$xml_file = ’travaux.xml’;
$xsl_file = ’travaux.xsl’;
// load the xml file (and test first if it exists)
$dom_object = new DomDocument();
if (!file_exists($xml_file)) exit(’Failed to open $xml_file’);
$dom_object->load($xml_file);
// create dom object for the XSL stylesheet and configure the transformer
$xsl_obj = new DomDocument();
if (!file_exists($xsl_file)) exit(’Failed to open $xsl_file’);
$xsl_obj->load($xsl_file);
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl_obj); // attach the xsl rules
$html_fragment = $proc->transformToXML($dom_object);
print ($html_fragment);
Donc pour utiliser ce "service", il suffit de copier le fichier php-xslt.php et changer les 2 noms de fichiers (travaux.xml et travaux.xsl) au début
(enfin depuis le web il faut prendre php-xslt.text et le renommer en xxx.php)
Client-side XML+XSLT avec Firefox 1.0+ ou IE6+
XSLT fonctionne sans problème avec les navigateurs IE, Mozilla/Firefox et Opera.
Un simple exemple
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.dtd (DTD)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.xml.text (src XML)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page-html.xsl (style)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.xml (XML)
- http://tecfa.unige.ch/guides/xml/examples/simple/hello-page.html (résultat)
- Il faut ajouter au moins la déclaration suivante (méthode de sérialisation)
<xsl:output method="html"/>
- Voir les fichiers pour les détails. Si aucun contenu n’est affiché ou s’il est mal affiché, faites "Menu->View->Source"
Notes:
- http://www.mozilla.org/releases/ (Mozilla downloads)
- Evitez de travailler avec IE 5.5. La version "normale" n’est pas conforme au standard XSLT. Installez soit IE 6.x ou 7.x soit MSXML3+,pour IE 5.5.
- Il faut s’assurer que le serveur Web indique le bon mime type pour xml et xsl (text/xml). Ceci est fait à Tecfa, mais pas forcément chez votre fournisseur....
Executive summary
- Créer une feuille XSLT xxx.xsl
- Copier/coller le code ci-dessous:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>
- Ecrire une règle qui gère la racine. Cette règle doit produire l'entête, racine, head et body du HTML.
<xsl:template match="page">
<html>
<head> <title> <xsl:value-of select="title"/>
</title> </head>
<body bgcolor="#ffffff">
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
- Write rules for each (!!) of your XML elements,
- for each insert some HTML, sometimes some text, or sometimes nothing
- make sure to place a <xsl:apply-templates> inside each rule (usually between some HTML) ... unless you wish to censor contents.
- Associate this stylesheet with your XML file using:
<?xml-stylesheet href="xxx.xsl" type="text/xsl"?>