Déboguer · Publié le

Une variable XSLT vide : les trois causes qu'on ne voit pas

Une variable qui vaut la chaîne vide ne provoque aucune erreur et se propage jusqu'à la sortie. Trois causes, toutes silencieuses.

XSLT n'a pas de valeur « indéfinie ». Une expression qui ne sélectionne rien rend une séquence vide, et une séquence vide convertie en chaîne donne la chaîne vide. La transformation continue, la sortie est fausse, et rien n'est signalé.

Trois causes couvrent l'essentiel :

  1. le contexte a bougé — le chemin est juste, mais il part d'un autre nœud que celui qu'on croit ;
  2. l'espace de noms manque au chemin, alors que le document en déclare un ;
  3. la variable contient un fragment, pas le nœud qu'on cherche — la conséquence de <xsl:variable> avec contenu plutôt qu'avec select.

Distinguer les trois en une exécution

Avant d'ouvrir la feuille, posez la question au processeur. count() sépare deux problèmes que la chaîne vide confond :

XSLT
<xsl:message>
  contexte : <xsl:value-of select="name(.)"/>
  trouvés  : <xsl:value-of select="count($total)"/>
  longueur : <xsl:value-of select="string-length($total)"/>
</xsl:message>
Ce que rend le messageCe que ça veut dire
trouvés : 0rien n'a été sélectionné — cause 1 ou 2
trouvés : 1, longueur : 0le nœud existe et il est vide : le problème est dans les données
trouvés : 12une séquence, là où vous attendiez une valeur — cause 3

🔴 C'est la distinction la plus rentable de cet article. « Rien de sélectionné » et « sélectionné mais vide » ont la même apparence dans la sortie et aucune cause commune : la première est une erreur de feuille, la seconde une erreur de données.

1. Le contexte a bougé

Le piège classique est un chemin relatif écrit hors de l'endroit où il est évalué :

XSLT
<xsl:for-each select="facture/ligne">
  <xsl:variable name="taux" select="facture/taux"/>
</xsl:for-each>

À l'intérieur du for-each, le nœud courant est une ligne. facture/taux cherche donc un facture enfant de la ligne — il n'y en a pas. Le chemin est correct en soi, il part du mauvais endroit.

⚠️ Le cas le plus discret est la variable à contenu : dans un <xsl:variable> qui a un corps, le contexte reste celui de l'extérieur, alors que l'écriture donne l'impression d'être « dedans ».

Les remèdes sont connus : ancrer sur la racine avec /, ou capturer le nœud courant dans une variable avant d'entrer dans la boucle.

2. L'espace de noms manque

Un chemin sans préfixe désigne des éléments sans espace de noms. Si le document en déclare un par défaut, aucun nœud ne correspond — sans le moindre message.

C'est la même cause que celle qui vide une transformation entière, et elle est détaillée dans les cinq causes silencieuses d'un XSLT vide. ⚠️ La différence ici est l'échelle : quand seul un chemin sur vingt est concerné, la sortie n'est pas vide, elle est partiellement fausse — et personne ne la relit.

3. La variable contient un fragment, pas un nœud

C'est la cause la moins connue, et elle vient d'une différence d'écriture d'une seule ligne :

XSLT
<!-- avec select : $a est le nœud ligne -->
<xsl:variable name="a" select="ligne"/>

<!-- avec contenu : $b est un nœud document qui CONTIENT une copie de ligne -->
<xsl:variable name="b"><xsl:copy-of select="ligne"/></xsl:variable>

$a/montant fonctionne. $b/montant ne rend rien : il faut écrire $b/ligne/montant, parce que $b est un nœud document et que ligne en est l'enfant.

⚠️ Le piège est que $b s'affiche correctement avec xsl:value-of — l'atomisation donne le texte attendu. La variable paraît bonne partout sauf là où on navigue dedans.

Ce que cet article ne couvre pas

  • un paramètre non transmis : xsl:param retombe sur sa valeur par défaut, souvent vide, et l'appelant ne signale rien ;
  • une clé déclarée sur un document et interrogée sur un autre — key() rend alors la séquence vide sans erreur ;
  • les paramètres tunnel, qui traversent les modèles intermédiaires et se perdent au premier xsl:call-template qui oublie tunnel="yes" ;
  • le cas où la donnée est simplement absente de la source, qui n'est pas un défaut de feuille.

🔴 Et une limite du diagnostic lui-même : xsl:message demande de modifier la feuille et de relancer. Sur une transformation longue, ou déclenchée par une chaîne qu'on ne pilote pas, ce n'est pas toujours possible.

Lire la valeur là où elle est affectée

Les trois causes se tranchent en regardant la variable au moment de l'affectation, pas là où elle est utilisée — c'est aussi ce qui explique pourquoi les traces d'erreur pointent souvent la mauvaise ligne, décrit dans lire une trace d'erreur Saxon sans la deviner.

Suspendre l'exécution sur la déclaration et inspecter le contexte répond aux trois questions d'un coup, sans toucher à la feuille : c'est ce que montre le chapitre déboguer du manuel.

Sur le même sujet

Recevoir les nouveaux articles

Un message quand un article paraît. Rien d'autre : ni promotion, ni relance, ni lettre d'information.

Votre adresse ne sert qu'à cela et n'est transmise à personne. Un lien de désinscription accompagne chaque message. Confidentialité

Tous les articles