Copyright © 2020-2023 Yves MARCOUX; dernière modification de cette page: 2023-03-13.

INU3011 Documents structurés

Stylage des éléments vides en XSLT

Yves MARCOUX - EBSI - Université de Montréal


Contexte

Supposons que vous avez défini un élément comme suit :

<!ELEMENT saveur (vinaigre | ketchup | gomme-baloune | autre-préciser)>

où chacun des éléments vinaigre, ketchup et gomme-baloune est défini EMPTY, autre-préciser étant pour sa part défini (#PCDATA).

Avec par exemple :

<saveur><vinaigre/></saveur>

<saveur><gomme-baloune/></saveur>

ou :

<saveur><autre-préciser>bacon</autre-préciser></saveur>

dans un document, on voudrait une feuille XSLT qui produise comme affichage final quelque chose comme :

Saveur : vinaigre

Saveur : gomme baloune

et :

Saveur : bacon

c’est-à-dire, en HTML, respectivement :

<p><strong>Saveur : </strong>vinaigre</p>

<p><strong>Saveur : </strong>gomme baloune</p>

et :

<p><strong>Saveur : </strong>bacon</p>


Solution

La première série d’exemples de 240-Ex-XSLT-pas-a-pas (XSLT-ex-pas-a-pas-1) présente une façon générale de styler des éléments vides.

Cette solution générale serait applicable ici. Cependant, puisque les éléments vides ne sont utilisés qu’à un seul endroit dans le présent modèle (ils ne surviennent que comme enfants de saveur), une solution plus simple existe : définir un gabarit pour chacun des éléments vides, produisant exactement l’extrant voulu pour chacun.

Ainsi, on peut par exemple définir :

<xsl:template match="vinaigre">vinaigre</xsl:template>

ou encore :

<xsl:template match="gomme-baloune">gomme baloune</xsl:template>

Bien sûr, autre-préciser doit être traité différemment :

<xsl:template match="autre-préciser"><xsl:value-of select="."/></xsl:template>

On n’a alors qu’à définir ainsi le gabarit pour saveur :

<xsl:template match="saveur">
  <p><strong>Saveur : </strong><xsl:apply-templates /></p>
</xsl:template>


Une voie plus rapide, mais limitée

Une solution plus rapide consiste à définir un seul gabarit, applicable à tous les éléments vides qui peuvent être enfants de saveur :

<xsl:template match="saveur/*"><xsl:value-of select="name(.)"/></xsl:template>

Les gabarits pour saveur et autre-préciser demeurent inchangés.

La fonction XPath name() (déjà mentionnée dans le cours) retourne ici le nom d’élément du nœud courant (.). Les éléments vides seront donc remplacés dans l’extrant par leur nom d’élément. C’est exactement ce que l’on veut, sauf pour « gomme-baloune », que l’on préférerait inscrit sans trait d’union. C’est la limite de cette solution.

Notez que maintenant, deux gabarits sont a priori applicables à autre-préciser, puisque cet élément est aussi enfant de saveur. Pour nous assurer que c’est le gabarit voulu qui traite cet élément, ajoutons-y un attribut priority avec une valeur supérieure à 1, par exemple 2 :

<xsl:template match="autre-préciser" priority="2">
  <xsl:value-of select="."/>
</xsl:template>

Avec les documents :

<saveur><ketchup/></saveur>

<saveur><autre-préciser>bacon</autre-préciser></saveur>

et :

<saveur><gomme-baloune/></saveur>

on obtient respectivement :

Saveur : ketchup

Saveur : bacon

et :

Saveur : gomme-baloune


La solution finale

Pour corriger le « problème » avec « gomme-baloune », il suffit de réintroduire le gabarit originel pour cet élément :

<xsl:template match="gomme-baloune">gomme baloune</xsl:template>

auquel on ajoutera aussi l’attribut priority="2", puisque le gabarit pour les enfants de saveur (celui avec match="saveur/*") est aussi applicable aux éléments gomme-baloune :

<xsl:template match="gomme-baloune" priority="2"
  >gomme baloune</xsl:template>

Ainsi, tous les éléments vides seront rendus exactement tel que souhaité, avec seulement deux gabarits pour les éléments vides, plutôt que trois.

Cette solution finale est présentée – avec un peu d’enrobage – dans le dossier d’exemples 245-Ex-XSLT-elements-vides.