[XSLT 1.0]Yet another Problème de filtrage Dynamique
Tout d’abord, je salue tous les développeurs de ce Forum, qui m’a beaucoup aidé au cours de mon développement.
Je suis un nouveau posteur, mais cela va faire un mois que je lis attentivement les threads de ce forum:bug: .
Présentation : Je suis actuellement stagiaire en informatique financière dans un groupe aéronautique et une partie de ma mission est d’extraire de façon automatique des données XML issues de Crystal Reports (Reporting financier), pour les transformer en HTML en utilisant XSLT.
Tout était au beau fixe jusqu'à ce que je tombe sur un os, trier des données de façon dynamique.
PS : J’ai simplifié et randomisé mon code par souci de clarté et de compréhension.
Je m’explique :
Mon XML se présente de la manière suivante :
Des éléments « <Container> » qui représentent chacun une Row de tableau.
Des sous éléments « <Object> » qui sont en fait les Cells du tableau.
Dans chaque élément « <Object> », il y a un child « Value » qui contient le texte des données.
Chaque élément <Object> contient des informations qui sont contextuelles et comptable,
Ainsi, le contexte est désigné par un attribut de la façon suivante :
obj1 => Nom de la filiale
obj2 => Nom du service
obj3 => Ecriture comptable
Voici le XML source :
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
|
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<Test>
<Container>
<Object Name="obj1">
<Value>OEM</Value>
</Object>
<Object Name="obj2">
<Value>fin</Value>
</Object>
<Object Name="obj3">
<Value>-8985</Value>
</Object>
</Container>
<Container>
<Object Name="obj1">
<Value>OEM</Value>
</Object>
<Object Name="obj2">
<Value>sec</Value>
</Object>
<Object Name="obj3">
<Value>-23</Value>
</Object>
</Container>
<Container>
<Object Name="obj1">
<Value>ETD</Value>
</Object>
<Object Name="obj2">
<Value>fin</Value>
</Object>
<Object Name="obj3">
<Value>-1524</Value>
</Object>
</Container>
<Container>
<Object Name="obj1">
<Value>ETD</Value>
</Object>
<Object Name="obj2">
<Value>sec</Value>
</Object>
<Object Name="obj3">
<Value>-365</Value>
</Object>
</Container>
</Test> |
Ce fichier XML, je le transforme en HTML par l’intermédiaire de la feuille XSL suivante :
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
|
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl = 'http://www.w3.org/1999/XSL/Transform'
xmlns:html="http://www.w3.org/TR/REC-html40"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<TABLE>
<xsl:for-each select="//Container">
<tr>
<xsl:for-each select="Object">
<td>
<xsl:value-of select="Value"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</TABLE>
</xsl:template>
</xsl:stylesheet> |
L’Output HTML est correct et me pond le tableau suivant :
Code:
1 2 3 4 5
|
OEM | fin | -8985
OEM | sec | -23
ETD | fin | -1524
ETD | sec | -365 |
PROBLEME :
Vous l’aurez remarqué, il y a des récurrences dans le tableau : OEM/fin OEM/sec ETD/fin ETD/sec.
Pour pouvoir calculer des sous totaux, j’ai donc besoin de trier ces éléments pour générer de façon automatique et dynamique différents tableaux pour chaque Filiale (ou obj1) et pour chaque Service (ou obj2).
Je voudrais arriver à générer un Output HTML qui ressemble à ça :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
Tableau 1 OEM / Fin
OEM | fin | -8985
Tableau 2 OEM / Sec
OEM | sec | -23
Tableau 3 ETD / fin
ETD | fin | -1524
Tableau 4 ETD / sec
ETD | sec | -365 |
Bien entendu, j’y parviens de façon statique, en utilisant un truc du genre :
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
|
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl = 'http://www.w3.org/1999/XSL/Transform'
xmlns:html="http://www.w3.org/TR/REC-html40"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<TABLE>
<xsl:for-each select="//Container">
<tr>
<xsl:choose>
<xsl:when test='Object[@Name="obj1"]/Value = ("OEM")'>
<xsl:for-each select="Object">
<td>
<xsl:value-of select="Value"/>
</td>
</xsl:for-each>
</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</TABLE>
</xsl:template>
</xsl:stylesheet> |
Le problème, c’est que les informations de contexte contenues dans l’input XML source peuvent varier extrêmement : Par exemple, si une nouvelle filiale est créée, un nouveau code filiale apparaîtra et sera tout bonnement ignoré par ma feuille XSL.
D’autre part, entrer des filtres statiques dans ma feuille XSL induit de dupliquer les blocs pour chaque tableaux de croisement Obj1/Obj2, ce qui risque d’alourdir mon code.
En fait, j’aimerais dire tout simplement à XSL une séquence du genre : « Pour chaque valeur texte d’un élément Obj1 rencontré, si identique au précédent continuer le Loop, sinon, construction d’un nouveau tableau avec Obj1 différent du précédent ». Et ainsi de suite, mais je n’arrive pas à le codé, n’étant par ailleurs pas très matheux :oops: dans mon approche du codage.
J’aimerais donc savoir si quelqu’un ici peut me proposer une piste pour continuer, la je bloque:bug: , et j’ai pourtant essayé pleins de balises (sort, if, for-each …):( .
J’espère avoir été assez claire dans mon approche du problème pour que ce soit compréhensible, je remercie d’avance toute les bonnes âmes qui aurait le courage de lire ce thread et d’y répondre:roll: .
Edit :: Pour quelques petites précisions :
- En fait je l'ai pas dit mais je débute méchamment en XML / XSLT ( je pense que ça se voit :mouarf: )
- Je n'ai absolument pas le droit (ni la possibilité) de toucher au document XML source, le lien vers la feuille XSL n'est la que pour des tests. Dans les faits, les utilisateurs passerons par une "moulinette" codée en PhP.
- Voila c'est tout.
@++
[XSLT 1.0]Yet another Problème de filtrage Dynamique
Je vien d'essayer la méthode de la FAQ :
http://xml.developpez.com/faq/?page=3#xslt_regroup
Sans succès, j'arrive pas à utiliser <xsl:apply-template ... > dans le sens de mon projet j'en ai jamais eu encore l'utilité ( je fonctionne avec <xsl:value-of ... > je comprend pas la différence entre les deux :aie: ).
Je suis en train d'essayer avec un <xsl:when test='position() = "1"'> et current() - 1 etc...
Je vous tiens au courent.