TP - transformations XSLT d’un répertoire
Il est temps de réellement mettre en pratique vos connaissances sur les transformations XSLT dans un TP.
Le sujet
L’énoncé
Dans ce TP, le travail demandé consiste à transformer un document XML comportant un répertoire téléphonique en un document HTML dont le rendu final doit être le suivant :
Comme vous pouvez le constater sur la capture d’écran ci-dessus, il vous faudra également styliser le document HTML à l’aide d’un peu de CSS en respectant les règles suivantes :
- Le nom et le prénom d’une personne sont des titres de catégorie 1.
- L’adresse d’une personne doit être écrite en italique.
- Les entêtes des listes des numéros de téléphone et des adresses e-mails sont des titres de catégorie 2.
- Les listes sont des vraies listes HTML.
- La couleur de fond est bleue pour un homme et rose pour une femme.
- Les numéros de téléphone et les adresses e-mails apparaissent uniquement si la personne en possède.
Le document XML
Le document XML à transformer est le suivant :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<repertoire>
<!-- John DOE -->
<personne sexe="masculin">
<nom>DOE</nom>
<prenom>John</prenom>
<adresse>
<numero>7</numero>
<voie type="impasse">impasse du chemin</voie>
<codePostal>75015</codePostal>
<ville>PARIS</ville>
<pays>FRANCE</pays>
</adresse>
<telephones>
<telephone type="fixe">01 02 03 04 05</telephone>
<telephone type="portable">06 07 08 09 10</telephone>
</telephones>
<emails>
<email type="personnel">john.doe@wanadoo.fr</email>
<email type="professionnel">john.doe@societe.com</email>
</emails>
</personne>
<!-- Marie POPPINS -->
<personne sexe="feminin">
<nom>POPPINS</nom>
<prenom>Marie</prenom>
<adresse>
<numero>28</numero>
<voie type="avenue">avenue de la république</voie>
<codePostal>13005</codePostal>
<ville>MARSEILLE</ville>
<pays>FRANCE</pays>
</adresse>
<telephones>
<telephone type="professionnel">04 05 06 07 08</telephone>
</telephones>
<emails>
<email type="professionnel">contact@poppins.fr</email>
</emails>
</personne>
<!-- Batte MAN -->
<personne sexe="masculin">
<nom>MAN</nom>
<prenom>Batte</prenom>
<adresse>
<numero>24</numero>
<voie type="avenue">impasse des héros</voie>
<codePostal>11004</codePostal>
<ville>GOTHAM CITY</ville>
<pays>USA</pays>
</adresse>
<telephones>
<telephone type="professionnel">01 03 05 07 09</telephone>
</telephones>
</personne>
</repertoire>
Une solution
Comme à chaque fois, je vous fais part de ma solution !
La transformation XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="html"
encoding="UTF-8"
doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"
indent="yes"
/>
<xsl:template match="/">
<html>
<head>
<title>Mon répertoire téléphonique</title>
<link type="text/css" rel="stylesheet" href="style.css"/>
</head>
<body>
<table>
<xsl:for-each select="repertoire/personne">
<xsl:choose>
<xsl:when test="@sexe = 'masculin'">
<xsl:call-template name="homme">
<xsl:with-param name="personne" select="." />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="femme">
<xsl:with-param name="personne" select="." />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="homme">
<xsl:param name="personne" />
<tr>
<td class="homme">
<xsl:call-template name="afficherPersonne">
<xsl:with-param name="personne" select="$personne" />
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template name="femme">
<xsl:param name="personne" />
<tr>
<td class="femme">
<xsl:call-template name="afficherPersonne">
<xsl:with-param name="personne" select="$personne" />
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template name="afficherPersonne">
<xsl:param name="personne" />
<h1>
<xsl:value-of select="$personne/nom" />
 
<xsl:value-of select="$personne/prenom" />
</h1>
<xsl:call-template name="afficherAdresse">
<xsl:with-param name="adresse" select="$personne/adresse" />
</xsl:call-template>
<xsl:if test="count($personne/telephones) != 0">
<xsl:call-template name="afficherTelephones">
<xsl:with-param name="telephones" select="$personne/telephones" />
</xsl:call-template>
</xsl:if>
<xsl:if test="count($personne/emails) != 0">
<xsl:call-template name="afficherEmails">
<xsl:with-param name="emails" select="$personne/emails" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="afficherAdresse">
<xsl:param name="adresse" />
<p class="adresse" >
<xsl:value-of select="$adresse/numero" />
 
<xsl:value-of select="$adresse/voie" />
<br/>
<xsl:value-of select="$adresse/codePostal" />
 
<xsl:value-of select="$adresse/ville" />
<br/>
<xsl:value-of select="$adresse/pays" />
</p>
</xsl:template>
<xsl:template name="afficherTelephones">
<xsl:param name="telephones" />
<h2>Numéros de téléphones :</h2>
<ul>
<xsl:for-each select="$telephones/telephone">
<xsl:call-template name="afficherTelephone">
<xsl:with-param name="telephone" select="." />
</xsl:call-template>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template name="afficherTelephone">
<xsl:param name="telephone" />
<li>
<xsl:value-of select="$telephone/@type" /> : <xsl:value-of select="$telephone" />
</li>
</xsl:template>
<xsl:template name="afficherEmails">
<xsl:param name="emails" />
<h2>Adresses Emails :</h2>
<ul>
<xsl:for-each select="$emails/email">
<xsl:call-template name="afficherEmail">
<xsl:with-param name="email" select="." />
</xsl:call-template>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template name="afficherEmail">
<xsl:param name="email" />
<li>
<xsl:value-of select="$email/@type" /> : <xsl:value-of select="$email" />
</li>
</xsl:template>
</xsl:stylesheet>
Comme vous pouvez le constater, la transformation que j’ai choisie est basée sur la capture de l’élément racine du document XML puis sur l’appel de différents templates par la fonction <xsl:call-template />
auxquels je fais passer les paramètres nécessaires au rendu HTML. Il ne s’agit bien évidemment pas de LA solution unique et un résultat identique peut être atteint en choisissant d’utiliser la fonction <xsl:apply-templates />
.
Le document HTML
Le document HTML produit est le suivant :
<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Mon répertoire téléphonique</title>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<table>
<tr>
<td class="homme">
<h1>DOE John</h1>
<p class="adresse">
7 impasse du chemin<br>
75015 PARIS<br>
FRANCE
</p>
<h2>Numéros de téléphones :</h2>
<ul>
<li>fixe : 01 02 03 04 05</li>
<li>portable : 06 07 08 09 10</li>
</ul>
<h2>Adresses Emails :</h2>
<ul>
<li>personnel : john.doe@wanadoo.fr</li>
<li>professionnel : john.doe@societe.com</li>
</ul>
</td>
</tr>
<tr>
<td class="femme">
<h1>POPPINS Marie</h1>
<p class="adresse">
28 avenue de la république<br>
13005 MARSEILLE<br>
FRANCE
</p>
<h2>Numéros de téléphones :</h2>
<ul>
<li>professionnel : 04 05 06 07 08</li>
</ul>
<h2>Adresses Emails :</h2>
<ul>
<li>professionnel : contact@poppins.fr</li>
</ul>
</td>
</tr>
<tr>
<td class="homme">
<h1>MAN Batte</h1>
<p class="adresse">
24 impasse des héros<br>
11004 GOTHAM CITY<br>
USA
</p>
<h2>Numéros de téléphones :</h2>
<ul>
<li>professionnel : 01 03 05 07 09</li>
</ul>
</td>
</tr>
</table>
</body>
</html>
Le document CSS
Voyons maintenant le document CSS associé. Comme vous pouvez le constater, il est très basique :
table {
width: 100%;
}
td {
padding: 10px;
}
.homme {
background-color: blue;
}
.femme {
background-color: pink;
}
.adresse {
font-style: italic;
}
Ce cours vous plait ?
Retrouvez ce cours en livre physique sur Amazon !