Copyright © 2020-2023 Yves MARCOUX; dernière modification de cette page: 2023-03-13.
Yves MARCOUX - EBSI - Université de Montréal
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>
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 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
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.