Les 5 causes silencieuses d'un XSLT qui ne produit rien
La transformation se termine sans erreur et le fichier de sortie est vide. Cinq causes expliquent la quasi-totalité des cas, et aucune ne provoque de message.
Saxon rend 0, aucun message n'apparaît, et le fichier de sortie est vide — ou ne contient que la
déclaration XML. Cinq causes expliquent la quasi-totalité de ces cas :
- le document source déclare un espace de noms que la feuille ignore ;
- le
matchdésigne un élément qui n'existe pas sous ce nom ; xsl:apply-templatesest appelé sansselect, et la descente s'arrête ;- le modèle par défaut s'applique et recopie le texte sans les balises ;
- la sortie part ailleurs, écrite par
xsl:result-document.
Aucune ne produit d'erreur. C'est précisément ce qui les rend longues à trouver : un XSLT qui échoue vous le dit, un XSLT qui ne s'applique à rien se termine normalement.
Les cinq se distinguent en regardant ce qui sort, avant de relire la feuille.
| Ce que vous observez | Cause probable |
|---|---|
| fichier vide, ou déclaration XML seule | espace de noms, ou match sans correspondance |
| du texte nu, sans une seule balise | modèle par défaut |
| une partie de l'arbre seulement | apply-templates sans select |
| le fichier attendu reste vide, un autre est créé | xsl:result-document |
1. L'espace de noms que la feuille ignore
C'est la première par fréquence, et de loin. Le document source déclare un espace de noms par défaut :
<facture xmlns="http://exemple.org/facturation">
<lignes>
<ligne reference="A-100">Clavier</ligne>
</lignes>
</facture>
Et la feuille l'écrit sans préfixe :
<xsl:template match="facture">
<xsl:apply-templates select="lignes/ligne"/>
</xsl:template>
facture sans préfixe désigne l'élément facture sans espace de noms. Ce n'est pas le même
nœud. Le modèle ne s'applique jamais, et rien ne le signale.
La correction déclare l'espace de noms et l'utilise :
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://exemple.org/facturation">
<xsl:template match="f:facture">
<xsl:apply-templates select="f:lignes/f:ligne"/>
</xsl:template>
</xsl:stylesheet>
⚠️ Le piège tient à une asymétrie du langage. Un élément sans préfixe dans un chemin XPath
n'hérite pas de xmlns par défaut de la feuille — les attributs, eux, n'ont jamais d'espace de
noms implicite. Deux règles différentes, la même syntaxe.
En XSLT 2.0 et au-delà, xpath-default-namespace sur xsl:stylesheet évite les préfixes partout.
C'est confortable, mais cela rend le problème invisible le jour où le source change d'espace de
noms : le chemin continue de se lire, il ne trouve simplement plus rien.
2. Un match qui ne désigne rien
Une faute de casse suffit. XML est sensible à la casse, <Ligne> et <ligne> sont deux éléments
distincts, et un modèle qui vise le mauvais ne s'applique pas.
Le symptôme est identique à celui du cas précédent — sortie vide, aucun message —, ce qui explique qu'on cherche souvent l'espace de noms alors que le nom est simplement mal orthographié.
La façon la plus rapide de trancher entre 1 et 2 est de demander au processeur ce qu'il voit, plutôt que de relire :
<xsl:template match="/">
<xsl:message>racine : <xsl:value-of select="name(*)"/></xsl:message>
<xsl:message>espace : <xsl:value-of select="namespace-uri(*)"/></xsl:message>
</xsl:template>
Un namespace-uri non vide alors que votre feuille n'en déclare aucun : c'est le cas 1. Un nom qui
ne correspond pas à ce que vous attendiez : c'est le cas 2.
3. apply-templates sans select
Sans select, xsl:apply-templates traite les enfants du nœud courant, et rien de plus. Si la
donnée utile se trouve deux niveaux plus bas et qu'aucun modèle ne prend le relais, la descente
s'arrête au premier palier.
Le symptôme diffère des deux précédents : la sortie n'est pas vide, elle est partielle. C'est la distinction la plus utile de cet article — un fichier vide et un fichier incomplet n'ont pas les mêmes causes.
4. Le modèle par défaut
XSLT applique des règles implicites quand aucun modèle ne correspond. Celle qui compte ici : pour un nœud texte, le contenu est recopié tel quel.
C'est la cause du symptôme le plus déroutant — du texte sans une seule balise, comme si la feuille avait été ignorée. Elle ne l'a pas été : ses modèles ne se sont pas appliqués, et les règles par défaut ont pris la suite.
Pour l'écarter, désactivez la recopie et rendez le silence visible :
<xsl:template match="text()"/>
Si la sortie devient vide, vous lisiez bien du texte recopié par défaut, et le vrai problème est l'un des trois précédents.
5. La sortie écrite ailleurs
xsl:result-document écrit dans un fichier distinct. Si la feuille l'emploie et que vous regardez
la sortie principale, vous regardez un fichier que rien n'a rempli.
Il est fréquent que ce result-document soit dans une branche jamais atteinte : la sortie
principale est vide et aucun fichier secondaire n'apparaît. On conclut alors à tort que rien ne
s'est exécuté. C'est un cas assez particulier pour mériter son propre traitement — voir
ce que Saxon exige des feuilles à sorties multiples.
Les limites de cette liste
Ces cinq causes couvrent la grande majorité des sorties vides, pas leur totalité. Restent au moins :
une exception avalée par le programme appelant, une redirection de la sortie standard, un
xsl:strip-space trop large, et les feuilles pilotées par des paramètres non transmis — pour
celles-là, une variable vide a ses propres causes.
⚠️ Et un cas qu'aucune relecture ne rattrape : une transformation correcte dont la sortie est vide parce que la source l'est. Vérifiez la taille du fichier d'entrée avant de suspecter la feuille.
Voir ce qui s'applique, plutôt que le déduire
Les cinq cas ont un point commun : le premier réflexe utile n'est pas de relire la feuille, c'est
de savoir quel modèle s'applique réellement. Les xsl:message ci-dessus le montrent, au prix
d'une modification de la feuille et d'une deuxième exécution.
Un débogueur pas à pas répond à la même question sans y toucher : on suspend l'exécution à la racine, et on lit le nœud courant. C'est ce que décrit le chapitre déboguer du manuel, et poser un point d'arrêt dans une feuille de style montre la manipulation complète.