Link Search Menu Expand Document

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 :

resultat

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" />
      &#160;
      <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" />
      &#160;
      <xsl:value-of select="$adresse/voie" />
      <br/>
      <xsl:value-of select="$adresse/codePostal" />
      &#160;
      <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&eacute;pertoire t&eacute;l&eacute;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&eacute;ros de t&eacute;l&eacute;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&eacute;publique<br>
           13005 MARSEILLE<br>
           FRANCE
         </p>
         <h2>Num&eacute;ros de t&eacute;l&eacute;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&eacute;ros<br>
           11004 GOTHAM CITY<br>
           USA
         </p>
         <h2>Num&eacute;ros de t&eacute;l&eacute;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 !