[XSLT] Boucles et tableaux...

Résolu/Fermé
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 - 11 janv. 2007 à 12:25
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 - 18 nov. 2011 à 15:36
Bonjour,

J'ai, d'un côté, un document XML qui comporte un nombre indéterminé de balises <element nom="" valeur="">.

Je voudrais, via une feuille de style XSLT, afficher les données de ces <element> dans un tableau de N colonnes, N étant prédéfini (3 ou 4, par exemple).
Je n'arrive pas à comprendre comment on peut faire quelque chose comme ça...

Pour le moment, j'affiche tout sur une seule ligne :
<div style="width:100%; overflow:auto; overflow-y:hidden;">
	<table border="0" class="form" style="margin-bottom:20px;">
		<tr>
			<!--on affiche tous les <element> en question-->
			<xsl:apply-templates select="child::node()" />
		</tr>
	</table>
</div>
<!--Et le template qui va bien :-->
<xsl:template match="/sectionClient/element">
	<td>
		<b><xsl:value-of select="@Nom" /> : </b>
		<xsl:value-of select="@Valeur" />
		<xsl:if test="@Nom='Adresse IP fixe'">
			<small>
			(<a href="telnet://{@Valeur}" target="_BLANK">telnet</a>) 
			(<a href="http://{@Valeur}" target="_BLANK">http</a>)
			</small>
		</xsl:if>
	</td>
</xsl:template>
Voilà... Tout s'affiche sur une ligne, et je ne sais pas comment couper la ligne de façon régulière, tous les 3 ou 4 éléments...

Merci de votre aide !

Xavier

3 réponses

Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
11 janv. 2007 à 18:39
Bon, pour ceux que ça intéresse, j'ai fini par résoudre mon problème !

Voilà un exemple de document xml, et le code XSL correspondant.
D'abord l'XML
<sectionSite>
	<groupeSite Groupe="Radius" Ordre="5">
		<elementSite Nom="Login" Valeur="xxx"/>
		<elementSite Nom="Adresse IP fixe" Valeur="xxx"/>
		<elementSite Nom="ISDN ok" Valeur="Oui"/>
		<elementSite Nom="Liaison ADSL" Valeur="Non"/>
	</groupeSite>
	<groupeSite Groupe="Radius" Ordre="5">
		<elementSite Nom="Login" Valeur="xxx"/>
		<elementSite Nom="Adresse IP fixe" Valeur="xxx"/>
		<elementSite Nom="ISDN ok" Valeur="Oui"/>
		<elementSite Nom="Liaison ADSL" Valeur="Non"/>
	</groupeSite>
	<groupeSite Groupe="Collecte / Préselection" Ordre="6">
		<elementSite Nom="Numéro 9T" Valeur="xxx"/>
		<elementSite Nom="Service actif 9T" Valeur="Oui"/>
		<elementSite Nom="Statut collecte 9T" Valeur="ACTIVATION_OK"/>
		<elementSite Nom="Préselection active 9T" Valeur="Non"/>
	</groupeSite>
	<groupeSite Groupe="Collecte / Préselection" Ordre="6">
		<elementSite Nom="Numéro Colt" Valeur="xxx"/>
		<elementSite Nom="Service actif Colt" Valeur="Oui"/>
		<elementSite Nom="Statut collecte Colt" Valeur="ACTIVATION_OK"/>
		<elementSite Nom="Préselection active Colt" Valeur="Non"/>
		<elementSite Nom="Statut préselection Colt" Valeur="DEMANDE_A"/>
	</groupeSite>
	<groupeSite Groupe="Equipement" Ordre="7">
		<elementSite Nom="Nom" Valeur="xxx"/>
		<elementSite Nom="Numéro" Valeur="xxx"/>
		<elementSite Nom="IP" Valeur="xxx"/>
		<elementSite Nom="Nature" Valeur="Telephone"/>
		<elementSite Nom="Marque" Valeur="LG"/>
		<elementSite Nom="Modèle" Valeur="6830"/>
		<elementSite Nom="Description" Valeur="telephone IP"/>
	</groupeSite>
	<groupeSite Groupe="Equipement" Ordre="7">
		<elementSite Nom="Nom" Valeur="xxx"/>
		<elementSite Nom="Numéro" Valeur="xxx"/>
		<elementSite Nom="IP" Valeur="xxx"/>
		<elementSite Nom="Nature" Valeur="Telephone"/>
		<elementSite Nom="Marque" Valeur="LG"/>
		<elementSite Nom="Modèle" Valeur="6830"/>
		<elementSite Nom="Description" Valeur="telephone IP"/>
	</groupeSite>
Puis le XSL
<xsl:template match="/sectionSite">
	<xsl:if test="count(child::node()[@Groupe='Radius']) > 0">
		<table border="0" class="form" style="margin-bottom:20px;">
			<xsl:apply-templates select="child::node()[@Groupe='Radius']" mode="premiers_3col"/>
		</table>
	</xsl:if>
	<xsl:if test="count(child::node()[@Groupe='Collecte / Préselection']) > 0">
		<table border="0" class="form" style="margin-bottom:20px;">
			<xsl:apply-templates select="child::node()[@Groupe='Collecte / Préselection']" mode="premiers_3col"/>
		</table>
	</xsl:if>
	<xsl:if test="count(child::node()[@Groupe='Equipement']) > 0">
		<table border="0" class="form" style="margin-bottom:20px;">
			<xsl:apply-templates select="child::node()[@Groupe='Equipement']" mode="premiers_4col"/>
		</table>
	</xsl:if>
</xsl:template>
<xsl:template match="/sectionSite/groupeSite" mode="premiers_3col">
	<xsl:variable name="groupe"><xsl:value-of select="@Groupe" /></xsl:variable>
	<xsl:if test="(position() mod 3) = 1">
		<tr>
			<td nowrap="true" valign="top" class="formContenuToLeft" style="border-top-width:1px; border-top-style:solid; border-top-color:#000000;">
				<xsl:apply-templates select="node()"/>
			</td>
			<xsl:choose>
				<xsl:when test="following-sibling::groupeSite[1]">
					<xsl:apply-templates select="following-sibling::groupeSite[position()=1 and @Groupe=$groupe]"/>
				</xsl:when>
				<xsl:otherwise>
					<td>&#160;</td>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:choose>
				<xsl:when test="following-sibling::groupeSite[2]">
					<xsl:apply-templates select="following-sibling::groupeSite[position()=2 and @Groupe=$groupe]"/>
				</xsl:when>
				<xsl:otherwise>
					<td>&#160;</td>
				</xsl:otherwise>
			</xsl:choose>
		</tr>
	</xsl:if>
</xsl:template>
	
<xsl:template match="/sectionSite/groupeSite" mode="premiers_4col">
	<xsl:variable name="groupe"><xsl:value-of select="@Groupe" /></xsl:variable>
	<xsl:if test="(position() mod 4) = 1">
		<tr>
			<td nowrap="true" valign="top" class="formContenuToLeft" style="border-top-width:1px; border-top-style:solid; border-top-color:#000000;">
				<xsl:apply-templates select="node()"/>
			</td>
			<xsl:choose>
				<xsl:when test="following-sibling::groupeSite[1]">
					<xsl:apply-templates select="following-sibling::groupeSite[position()=1 and @Groupe=$groupe]"/>
				</xsl:when>
				<xsl:otherwise>
					<td>&#160;</td>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:choose>
				<xsl:when test="following-sibling::groupeSite[2]">
					<xsl:apply-templates select="following-sibling::groupeSite[position()=2 and @Groupe=$groupe]"/>
				</xsl:when>
				<xsl:otherwise>
					<td>&#160;</td>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:choose>
					<xsl:when test="following-sibling::groupeSite[3]">
					<xsl:apply-templates select="following-sibling::groupeSite[position()=3 and @Groupe=$groupe]"/>
				</xsl:when>
				<xsl:otherwise>
					<td>&#160;</td>
				</xsl:otherwise>
			</xsl:choose>
		</tr>
	</xsl:if>
</xsl:template>
	
<xsl:template match="/sectionSite/groupeSite">
	<td nowrap="true" valign="top" class="formContenuToLeft" style="border-top-width:1px; border-top-style:solid; border-top-color:#000000;">
		<xsl:apply-templates select="child::node()" />
	</td>
</xsl:template>
	
<xsl:template match="/sectionSite/groupeSite/elementSite">
	<b><xsl:value-of select="@Nom" /> : </b>
	<xsl:value-of select="@Valeur" />
	<xsl:if test="@Nom='Adresse IP fixe'">
		<small>
			(<a href="telnet://{@Valeur}" target="_BLANK">telnet</a>) 
			(<a href="http://{@Valeur}" target="_BLANK">http</a>)
		</small>
	</xsl:if>
	<br />
</xsl:template>
Bon, y a quand même un défaut, c'est que je suis obligé de créer un template différent suivant que je veuille 3 ou 4 colonnes...

Enfin bon, le principe général reste clair : au lieu de s'occuper des <groupeSite> élément par élément, on va le faire ligne par ligne : on récupère donc les premiers de chaque ligne (position() mod N = 1 pour une ligne à N colonnes), et on place à la main les noeuds suivants pour compléter la ligne. Ce n'est pas vraiment très souple, mais bon...

Bref, voilà, quoi, c'est résolu ^^

Xavier
6
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
11 janv. 2007 à 16:04
J'ai peut être une piste...

Mais pour ça, j'aurais une autre question...
Récupérer le 5e élément, ok : Element[position() = 5]
Récupérer un élément dont l'attribut groupe vaut "chose", ok : Element[@groupe="chose"].

Mais comment récupérer le 5e élément dont l'attribut vaut chose ??

Merci !

Xavier
2
Element[position()=5/@groupe="chose"] ??
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
18 nov. 2011 à 15:36
Oula !
C'est déjà résolu depuis presque 5 ans, heureusement que mon client ne t'a pas attendu :)
Dans la réponse, je l'avais résolu comme ça :
groupeSite[position()=3 and @Groupe=$groupe]
0