Faire un joli tableau HTML d'un XML via XSL
Bonjour,
je reviens vers ce forum malgré que mon dernier post n'est pas interessé grand monde voir personne ^^
l'idée est donc de transformer un XML récuperé sur le web en un joli tableau présentant les informations de maniere ordonnée.
Aujourd'hui je parviens à obtenir le résultat attendu avec le XSL que j'ai fait
Me reste un gros problème, la génération HTML peut être tres (voir trop) longue avec un XML de taille importante et je ne sais pas comment optimiser mon code ...
voici un exemple de XML
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="park.xsl" ?>
<park id="50">
<x>40</x> <!-- Largeur du park, nombre de colonne -->
<y>50</y> <!-- Hauteur du park, nombre de ligne -->
<!-- on doit générer un tableau sus cette forme
1 2 3 ... 40 (=x)
50 X
49 O
...
1
(=y)
-->
<!-- Le fichier XML en entrée est trié sur les Positions x (colonnes) à partir de 1, et y (lignes) à partir de 1
Il faudra donc retrié le xml sur y descendant (à partir de 50) et x ascendant -->
<nom>Parking numero 50</nom>
<pos x="1" y="1"> <!-- x=Position colonne, y=Position ligne -->
<vehicule id="1238">
<marque>peugeot</marque>
<type>407</type>
<chevaux>7</chevaux>
</vehicule>
</pos>
<pos x="4" y="10" bloque="O"/>
<pos x="5" y="23" bloque="O"/>
<pos x="6" y="31" bloque="O"/>
<pos x="15" y="1">
<vehicule id="1234">
<marque>peugeot</marque>
<type>305</type>
<chevaux>5</chevaux>
</vehicule>
</pos>
<pos x="18" y="10" bloque="O"/>
<pos x="23" y="5" bloque="O"/>
<pos x="25" y="33">
<vehicule id="4321">
<marque>renault</marque>
<type>clio</type>
<chevaux>4</chevaux>
</vehicule>
</pos>
<pos x="38" y="1">
<vehicule id="1235">
<marque>peugeot</marque>
<type>106</type>
<chevaux>4</chevaux>
</vehicule>
</pos>
</park> |
Voici le XSL que j'ai fait pour afficher les infos sous la forme attendue
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
</head>
<body>
<xsl:for-each select="park">
<xsl:sort select="pos/@y" data-type="number" order="descending"/>
<xsl:sort select="pos/@x" data-type="number" order="ascending"/>
<tr>
<td valign="top"><font face="arial"><xsl:value-of select="concat(@id,' ',nom)" /></font></td>
</tr>
<table border="1">
<tr valign="bottom">
<td align="right"><font face="arial"></font></td>
<!-- PREMIERE BOUCLE: Fixer les numeros (1 à x) en 1ere ligne -->
<xsl:call-template name="ligne1">
<xsl:with-param name="compteur" select="1" />
<xsl:with-param name="finboucle" select="x" />
</xsl:call-template>
</tr>
<!-- DEUXIEME BOUCLE: pour i=1 a Nombre de ligne (y) -->
<xsl:call-template name="lignes">
<xsl:with-param name="compteur" select="y" />
<xsl:with-param name="finboucle" select="1" />
</xsl:call-template>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
<!-- Première ligne, Numérotation -->
<xsl:template name="ligne1">
<xsl:param name="compteur" />
<xsl:param name="finboucle" />
<xsl:choose>
<xsl:when test="$compteur <= $finboucle">
<td align="right"><font face="arial"><xsl:value-of select="$compteur" /></font></td>
<xsl:call-template name="ligne1">
<xsl:with-param name="compteur" select="$compteur + 1" />
<xsl:with-param name="finboucle" select="$finboucle" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Boucle sur le nombre de ligne -->
<xsl:template name="lignes">
<xsl:param name="compteur" />
<xsl:param name="finboucle" />
<xsl:choose>
<xsl:when test="$compteur >= $finboucle">
<tr valign="bottom">
<!-- Numerotation de la ligne -->
<td align="right"><font face="arial"><xsl:value-of select="$compteur" /></font></td>
<!-- Génération de la ligne courante -->
<xsl:for-each select="pos[@y=$compteur]">
<xsl:variable name="PosX"><xsl:value-of select="@x" /></xsl:variable>
<xsl:variable name="xPrec"><xsl:value-of select="number(/park/pos[@y = $compteur and @x < $PosX][last()]/@x)" /></xsl:variable>
<!-- Faire le complement colonne a gauche -->
<xsl:choose>
<xsl:when test="$xPrec = 'NaN'">
<xsl:call-template name="lignevide">
<xsl:with-param name="compteur" select="1" />
<xsl:with-param name="finboucle" select="number(@x) - 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="lignevide">
<xsl:with-param name="compteur" select="number($xPrec) + 1" />
<xsl:with-param name="finboucle" select="number(@x) - 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<!-- on traite la colonne en cours -->
<xsl:choose>
<xsl:when test="@bloque = 'O'">
<!-- PLACE INOCCUPABLE -->
<td align="center"><font face="arial" color="#000000">X</font></td>
</xsl:when>
<xsl:otherwise>
<!-- PLACE OCCUPEE -->
<xsl:variable name="Infos">Id:<xsl:value-of select="vehicule/@id" /> (<xsl:value-of select="vehicule/marque" /> - <xsl:value-of select="vehicule/type" /> - <xsl:value-of select="vehicule/chevaux" /> - <xsl:value-of select="@x" />/<xsl:value-of select="@y" />)</xsl:variable>
<xsl:variable name="Lien">window.open('../infopark.php?id=<xsl:value-of select="vehicule/@id"/>','vehicule_Stat','height=350, width=390, scrollbars=1, status=0, toolbar=0, menubar=0');</xsl:variable>
<td valign="center">
<xsl:attribute name="title"><xsl:value-of select="$Infos" /></xsl:attribute>
<xsl:attribute name="onclick"><xsl:value-of select="$Lien"/></xsl:attribute>
<font face="arial" color="#FF0000">O</font>
</td>
</xsl:otherwise>
</xsl:choose>
<!-- Faire le complement colonne a droite -->
<xsl:variable name="xSuite"><xsl:value-of select="number(/park/pos[@y = $compteur and @x > $PosX]/@x)" /></xsl:variable>
<xsl:choose>
<xsl:when test="$xSuite = 'NaN'">
<xsl:call-template name="lignevide">
<xsl:with-param name="compteur" select="number(@x) + 1" />
<xsl:with-param name="finboucle" select="/park/x" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</tr>
<xsl:call-template name="lignes">
<xsl:with-param name="compteur" select="$compteur - 1" />
<xsl:with-param name="finboucle" select="$finboucle" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Génération ligne vide -->
<xsl:template name="lignevide">
<xsl:param name="compteur" />
<xsl:param name="finboucle" />
<xsl:choose>
<xsl:when test="$compteur <= $finboucle">
<td align="right"><font face="arial"> </font></td>
<xsl:call-template name="lignevide">
<xsl:with-param name="compteur" select="$compteur + 1" />
<xsl:with-param name="finboucle" select="$finboucle" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet> |
ce qui me pose le plus de souci, c'est la génération des colonnes complément à gauche et à droite, car j'ai besoin de connaitre pour ces traitements, les valeurs des enregistrements precedents et suivants
voici le code xsl utilisé pour repondre à ce besoin :
Code:
<xsl:variable name="xPrec"><xsl:value-of select="number(/park/pos[@y = $compteur and @x < $PosX][last()]/@x)" /></xsl:variable>
Ca me retourne la valeur de l'attribut x précédent, mais ca prend beaucoup de ressource, et ca se ressent sur un gros xml
de meme pour la valeur suivante cette instruction est hyper gourmande:
Code:
<xsl:variable name="xSuite"><xsl:value-of select="number(/park/pos[@y = $compteur and @x > $PosX]/@x)" /></xsl:variable>
Comment optimiser tout ca ?
voici le resultat attendu (sachant qu'il y a toujours au moins une information par ligne dans un XML normal):
http://freddyp2.free.fr/XML/park.xml