Avec une transformation XSLT on souhaite afficher les données par groupes de M dans un tableau à C colonnes.
M et C étant des paramètres donnés.
Exemple N=11, M=3, C=3 | *************************
* fic1 * fic4 * fic7 *
* fic2 * fic5 * fic8 *
* fic3 * fic6 * fic9 *
*************************
* fic10 * * *
* fic11 * * *
* * * *
************************* |
C'est ici un tableau HTML est généré, mais on peut facilement le changer en autre chose.
De plus, une seconde solution existe, voir plus bas.
Le XML | <fichiers>
<fichier nom="fic1"/>
<fichier nom="fic2"/>
<fichier nom="fic3"/>
<fichier nom="fic4"/>
<fichier nom="fic5"/>
<fichier nom="fic6"/>
<fichier nom="fic7"/>
<fichier nom="fic8"/>
<fichier nom="fic9"/>
<fichier nom="fic10"/>
<fichier nom="fic11"/>
</fichiers> |
Le XSLT | <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="M" select="3"/>
<xsl:variable name="C" select="3"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<xsl:for-each select="//fichier[position() mod ($M * $C) = 1]">
<tr>
<xsl:for-each select=".|following-sibling::fichier[position() mod $M = 0 and position() < $M * $C]">
<td>
<xsl:for-each select=".|following-sibling::fichier[position() < $M]">
<xsl:value-of select="@nom"/><br/>
</xsl:for-each>
</td>
</xsl:for-each>
<xsl:if test="position() = last()">
<xsl:call-template name="cellules_vides">
<xsl:with-param name="nb" select="$C - ceiling(count(.|following-sibling::fichier) div $M)"/>
</xsl:call-template>
</xsl:if>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="cellules_vides">
<xsl:param name="nb"/>
<xsl:if test="$nb >= 1">
<td/>
<xsl:call-template name="cellules_vides">
<xsl:with-param name="nb" select="$nb - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet> |
Le Résultat | <html>
<body>
<table border="1">
<tr>
<td>
fic1
fic2
fic3
</td>
<td>
fic4
fic5
fic6
</td>
<td>
fic7
fic8
fic9
</td>
</tr>
<tr>
<td>
fic10
fic11
</td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html> |
La seconde solution est plus concise, moyennant une bidouille afin de garder une feuille XSLT bien formée.
De plus elle ne gère pas les cellules vides et ne fonctionne pas dans le cas d'une transformation côté client :
Le XSLT | <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="M" select="3"/>
<xsl:variable name="C" select="3"/>
<xsl:template match="/">
<html>
<body>
<table>
<xsl:apply-templates select="//fichier"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="fichier">
<xsl:if test="position() mod ($M * $C)=1">
<xsl:text disable-output-escaping="yes"><tr></xsl:text>
</xsl:if>
<xsl:if test="position() mod $M=1">
<xsl:text disable-output-escaping="yes"><td></xsl:text>
</xsl:if>
<xsl:value-of select="concat(@nom,';')"/>
<xsl:if test="position() mod $M=0 or position()=last()">
<xsl:text disable-output-escaping="yes"></td></xsl:text>
</xsl:if>
<xsl:if test="position() mod ($M * $C)=0 or position()=last()">
<xsl:text disable-output-escaping="yes"></tr></xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet> |
|