XSLT et Saxon · Publié le

Sorties multiples : ce que Saxon exige vraiment

xsl:result-document échoue sur « no base output URI » alors que la feuille est correcte. L'exigence porte sur la façon dont la transformation est lancée, pas sur la feuille.

Error: no base output URI supplied

La feuille de style est correcte, et c'est ce qui rend le message déroutant : il ne désigne rien dans le fichier qu'on vient d'écrire.

xsl:result-document reçoit un href relatif. Relatif à quoi ? À l'URI de base de sortie, que Saxon déduit normalement de la destination principale de la transformation. Quand on n'en a pas donné — sortie vers un flux en mémoire, vers la console, vers un Writer fourni par l'appelant — il n'y a aucun point d'ancrage, et Saxon refuse plutôt que d'écrire dans un répertoire courant qu'il n'a pas choisi.

🔴 L'exigence porte donc sur l'appel, jamais sur la feuille. Tant qu'on cherche la faute dans le XSLT, on ne la trouve pas.

XSLT
<xsl:result-document href="lignes/{@id}.xml" method="xml">
  <xsl:apply-templates/>
</xsl:result-document>

Les trois façons de fournir l'ancrage

1. Donner une sortie principale, même si la transformation n'écrit rien dedans. C'est la voie la plus courte en ligne de commande :

Shell
java -jar saxon.jar -s:facture.xml -xsl:eclater.xsl -o:sortie/index.xml

Les fichiers partent alors dans sortie/lignes/. ⚠️ Le fichier principal est créé même vide — un index.xml de zéro octet à côté des vrais résultats n'est pas un bogue, c'est l'ancre.

2. Fournir l'URI explicitement. Depuis l'API s9api, setBaseOutputURI sur le transformeur règle la question sans imposer de sortie principale. C'est la bonne réponse quand le résultat principal n'a aucun sens — un éclatement pur, où tout part en fichiers annexes.

3. N'employer que des URI absolues dans href. Cela marche partout et fige les chemins : la feuille cesse d'être déplaçable, et un chemin absolu écrit sous Windows ne se rejoue pas ailleurs. À réserver aux cas où la destination est réellement fixe.

Ce qui casse ensuite

⚠️ Deux xsl:result-document visant la même URI dans une même transformation sont une erreur (XTDE1490), pas un écrasement silencieux. Le message ne nomme pas les deux instructions fautives, et c'est ce qui rend le défaut long à situer : quand l'URI est calculée — {@id} — il faut d'abord prouver que deux nœuds portent le même identifiant.

⚠️ Chaque document produit a ses propres attributs de sérialisation. Un xsl:output global ne s'applique pas automatiquement aux résultats secondaires : encodage, indentation et méthode se redéclarent sur xsl:result-document, ou se rattachent par son attribut format. Un fichier annexe qui ressort dans un encodage inattendu vient presque toujours de là — le mécanisme est détaillé dans choisir l'encodage de sortie d'un XSLT.

⚠️ L'écriture est immédiate, la transformation ne l'est pas. Une transformation qui échoue à mi-course laisse les fichiers déjà écrits sur le disque. Il n'y a pas de transaction : après un échec, le répertoire de sortie contient un résultat partiel qui ressemble à un résultat.

Quand aucun fichier n'est écrit du tout

Le symptôme est différent, et la cause aussi : si Saxon ne se plaint de rien et qu'il ne sort rien, l'instruction n'a jamais été atteinte. Le xsl:result-document est dans un modèle qui ne s'applique pas, ou dans une branche jamais prise. C'est le même diagnostic que les cinq causes silencieuses d'un XSLT vide, et il se tranche en un passage : un point d'arrêt sur le modèle qui contient l'instruction dit en une exécution si elle est atteinte.

Ce que cet article ne couvre pas

  • le mode flux (streaming), où les contraintes sur xsl:result-document sont bien plus strictes et méritent leur propre traitement ;
  • la validation des documents produits, qui est un sujet de schéma et non de sortie ;
  • les collections en entrée — écrire n fichiers depuis un document est le cas traité ici, en lire n est l'autre moitié du problème.

Le chapitre transformer et exporter du manuel décrit ce que l'application exige des feuilles produisant plusieurs fichiers, et où se règle la destination.

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