[BONUS] DOCTYPE HTML5 avec XSLT
Génération du DOCTYPE HTML5 avec XSLT
[Exercice BONUS]
Le but de cet exercice est de comprendre les différentes manières de générer le DOCTYPE HTML5 avec XSLT.
Rappel : le DOCTYPE valide en HTML5 est le suivant :
On dispose des fichiers xml et xsl suivants :
movies.xml
<movies>
<movie>
<title>Aliens</title>
<year>1986</year>
<rank>8.2</rank>
</movie>
<movie>
<title>Apollo 13</title>
<year>1995</year>
<rank>7.5</rank>
</movie>
<movie>
<title>Pi</title>
<year>1998</year>
<rank>7.1</rank>
</movie>
</movies>
movies.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="html"
doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"
encoding="utf-8"
indent="yes" />
<xsl:template match="/">
<html lang="en">
<head>
<title>List of Movies.</title>
<link rel="stylesheet" href="movies.css" />
</head>
<body>
<table class="movies">
<thead>
<tr>
<th>Title</th>
<th>Year</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="movies/movie">
<xsl:sort select="rank"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="rank"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Exemples repris et adaptés depuis : https://efxa.org/2013/06/03/how-to-transform-an-xml-document-into-html5-using-xslt/
Ouvrir ces fichiers dans Oxygen. Tester la génération du fichier HTML4 en sortie.
On remarque que les attributs doctype-public et doctype-system permettent de générer le DOCTYPE HTML4 voulu.
Question
Tester la modification des attributs doctype-public et doctype-system, leur suppression, pour essayer d'obtenir le DOCTYPE HTML5. Que se passe-t-il ?
<xsl:output
method="html"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"
encoding="utf-8"
indent="yes" />
<xsl:output
method="html"
doctype-public=""
encoding="utf-8"
indent="yes" />
Si les deux attributs sont omis (valeur vide ou non déclarés), alors le DOCTYPE n'est pas généré.
L'instruction XSLT 1.0 <xsl:text disable-output-escaping='yes'></xsl:text>
permet de générer du texte en sortie.
L'attribut disable-output-escaping='yes' permet de reconvertir les caractères HTML échappés en sortie (&
en "&" par exemple).
Rappel : les chevrons "<" et ">" correspondent respectivement aux codes suivants, <
et >
.
Question
Générer le DOCTYPE à l'aide de l'instruction donnée.
<xsl:text disable-output-escaping='yes'><!DOCTYPE html>
</xsl:text>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="html"
encoding="utf-8"
indent="yes" />
<xsl:template match="/">
<xsl:text disable-output-escaping='yes'><!DOCTYPE html>
</xsl:text>
<html lang="en">
<head>
<title>List of Movies.</title>
<link rel="stylesheet" href="movies.css" />
</head>
<body>
<table class="movies">
<thead>
<tr>
<th>Title</th>
<th>Year</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="movies/movie">
<xsl:sort select="rank"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="rank"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Le statut de DOE (disable-output-escaping) et la "DOCTYPE legacy string"
La solution ci-dessus utilise la fonctionnalité DOE (disable-output-escaping), mais celle-ci :
n'est qu'une fonctionnalité optionnelle d'un moteur XSLT 1.0 ;
est dépréciée en XSLT 2.0.
Les spécifications de HTML5 fournissent une alternative à l'aide de la "DOCTYPE legacy string" : <!DOCTYPE html SYSTEM "about:legacy-compat">
.
Question
Modifier le code xsl pour générer un DOCTYPE HTML5 à l'aide de la "DOCTYPE legacy string".
Utiliser l'attribut doctype-system dans l'instruction XSLT <xsl:output/>
.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="html"
encoding="utf-8"
doctype-system="about:legacy-compat"
indent="yes" />
<xsl:template match="/">
<html lang="en">
<head>
<title>List of Movies.</title>
<link rel="stylesheet" href="movies.css" />
</head>
<body>
<table class="movies">
<thead>
<tr>
<th>Title</th>
<th>Year</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="movies/movie">
<xsl:sort select="rank"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="rank"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
[BONUS] L'instruction <xsl:character-map>
La solution précédente ne doit être utilisé que si le moteur XSLT n'est pas capable de générer le DOCTYPE HTML5 standard (en version courte).
Source : spécification HTML5 du W3C.
Nous allons nous intéresser à une solution utilisant une instruction valide en XSLT 2.0, <xsl:character-map>
.
On placera cette instruction avant l'instruction <xsl:output>
.
La syntaxe de l'instruction :
<xsl:character-map name="name">
<xsl:output-character character="x" string="remplacement de x"/>
</xsl:character-map>
L'instruction <xsl:output-character>
utilisée à l'intérieur de <xsl:character-map>
prend un unique character et le remplace en sortie par la chaîne string spécifiée.
On utilisera l'attribut use-character-maps="charactermapname"
dans l'instruction <xsl:output>
pour activer les substitutions lors de la transformation xsl.
Question
Utiliser l'instruction <xsl:character-map>
pour générer le DOCTYPE HTML5.
Tout code d'une entité HTML (& par exemple) présent dans la valeur de string de la balise <xsl:output-character>
sera correctement retraduit en son caractère UNICODE en sortie ("&").
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:character-map name="doctype">
<xsl:output-character character="<" string="<"/>
<xsl:output-character character=">" string=">"/>
</xsl:character-map>
<xsl:output
method="html"
encoding="utf-8"
indent="yes"
use-character-maps="doctype"/>
<xsl:template match="/">
<xsl:text><!DOCTYPE html></xsl:text>
<html lang="en">
<head>
<title>List of Movies.</title>
<link rel="stylesheet" href="movies.css" />
</head>
<body>
<table class="movies">
<thead>
<tr>
<th>Title</th>
<th>Year</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="movies/movie">
<xsl:sort select="rank"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="rank"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>