J'avais besoin d'utiliser XSL pour générer une sortie simple en texte brut à partir de XML. Comme je n'ai trouvé aucun bon exemple concis en ligne, j'ai décidé de poster ma solution ici. Tout lien renvoyant à un meilleur exemple serait bien entendu apprécié:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="script/command" xml:space="preserve">at -f <xsl:value-of select="username"/> <xsl:value-of select="startTime/@hours"/>:<xsl:value-of select="startTime/@minutes"/> <xsl:value-of select="startDate"/><xsl:text>
</xsl:text></xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Quelques choses importantes qui m'ont aidé ici:
La sortie résultante et souhaitée pour ce xslt était:
à -f alluser 23:58 17.4.2010
sur -f ggroup67 7:58 28.4.2010
sur -f ggroup70 15:58 18.4.2010
sur -f alluser 23:58 18.4.2010
sur -f ggroup61 7:58 22.9.2010
sur -f ggroup60 23:58 21.9.2010
sur -f alluser 3:58 22.9.2010
Comme je l'ai dit, toute suggestion sur la façon de le faire de manière plus élégante serait appréciée.
SUIVI 2011-05-08:
Voici le type de xml que je traite:
<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="script.xsd">
<command>
<username>alluser</username>
<startTime minutes="58" hours="23"/>
<startDate>17.4.2010</startDate>
</command>
</script>
script/command
Et éliminer le xsl:for-each
concat()
peut être utilisé pour raccourcir l'expression et vous éviter d'insérer explicitement autant d'éléments <xsl:text>
et <xsl:value-of>
.

Pour le retour chariot, plutôt que de compter sur la préservation du saut de ligne entre votre élément <xsl:text>
Est un peu plus sûre, car le formatage du code ne gâchera pas votre sauts de ligne. De plus, pour moi, cela se lit comme un saut de ligne explicite et est plus facile à comprendre l'intention.<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="script/command">
<xsl:value-of select="concat('at -f '
,username
,' '
,startTime/@hours
,':'
,startTime/@minutes
,' '
,startDate
,'
')"/>
</xsl:template>
</xsl:stylesheet>
Juste pour le plaisir: cela peut être fait de manière très générale et compacte:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:apply-templates select="node()|@*"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="username">
at -f <xsl:apply-templates select="*|@*"/>
</xsl:template>
</xsl:stylesheet>
lorsqu'il est appliqué sur ce document XML:
<script>
<command>
<username>John</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Kate</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Peter</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
</command>
</script>
le résultat voulu et correct est produit:
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
Note: Cette approche générique est mieux applicable si toutes les données à produire sont contenues dans des nœuds de texte - pas dans des attributs.