3.1 Rappel: 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.
-
"Lay back and let the rules do the work ...."
Exemple 3-1: Simple XML vers HTML avec XSLT
A. 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>
B. La feuille de style XSLT
-
Ici on veut produire un simple HTML à partir du XML
-
On aimerait que les enfants de <aunt> et <uncle> soient affichés différemment
-
Le premier 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>
C. Les 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>
D. Rappel du principe
-
au lieu de programmer des boucles, des if/else, appels de fonction etc. comme on le verra dans la suite, on définit plutôt des règles qui se déclenchent en fonction de la position d'un élément (ou encore de leurs attributs, contenus, etc.)
3.2 Les règles implicites
-
Les règles implicites sont souvent source de confusion ! Lisez cette section si dans votre arbre de sortie apparaît du texte que vous n'avez pas voulu inclure ....
Le "problème"
-
Citation de la spécification:
-
"Il existe une règle modèle [template] interne permettant à un traitement récursif de continuer même en cas de non-concordance de motif par une règle modèle explicite de la feuille de styles. Cette règle modèle s'applique aussi bien aux noeuds d'éléments qu'au noeud racine. Ce qui suit montre ce qui équivaut à cette règle interne" :
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
-
Il existe aussi un template interne pour les noeuds textuels et les noeuds d'attributs qui sert à en recopier le texte :
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
-
En clair cela veut dire que si vous ne spécifiez pas explicitement une règle pour les tous les éléments de votre arbre XML, XSLT va appliquer deux règles prédéfinies et qui vont copier le contenu des éléments sans règle.
-
Autrement dit, si vous ne voulez pas que le texte de ces éléments et attributs apparaisse, il faut agir ... !!
Solution
-
Soit redéfinir ces 2 règles,
<xsl:template match="*|/" />
<xsl:template match="text()|@*" />
-
notez la balise auto-fermante "/>".
-
il s'agit vraiment de règles qui ne produisent rien ....
-
Soit définir une règle pour chaque élément qui ne produit rien:
<xsl:template match="element_qui_ne_sert_a_rien" />
-
Cette 2ème solution est préférable, car souvent on utilise la règle implicite pour juste insérer le texte d'un noeud.
-
Au lieu d'écrire:
<xsl:template match="title">
<p><xsl:value-of select="." /></p>
</xsl:template>
<xsl:template match="title">
<p><xsl:apply-templates></p>
</xsl:template>