IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XSL/XSLT/XPATH XML Discussion :

[XSLT 1.0]Yet another Problème de filtrage Dynamique


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2007
    Messages : 19
    Points : 13
    Points
    13
    Par défaut [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 .

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 dans mon approche du codage.

    J’aimerais donc savoir si quelqu’un ici peut me proposer une piste pour continuer, la je bloque , 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 .

    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 )
    - 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.

    @++

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2007
    Messages : 19
    Points : 13
    Points
    13
    Par défaut [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 ).

    Je suis en train d'essayer avec un <xsl:when test='position() = "1"'> et current() - 1 etc...

    Je vous tiens au courent.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2007
    Messages : 19
    Points : 13
    Points
    13
    Par défaut
    Toujours aucune solution de mon coté.

    J'abandonne pour aujourd'hui

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Si le critère de regroupement est bien Object[@Name='obj1']/Value alors peut être que ça peut marcher (ça reste assez lourd, mais je sais pas encore faire mieux):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <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:key name="id" match="Container" use="Object[@Name='obj1']/Value"/> 
     
    <xsl:template match="/">
     
    	<body>
    		<xsl:for-each select="//Container[generate-id()=generate-id(key('id', Object[@Name='obj1']/Value)[1])]">
    		<xsl:variable name="value" select="Object[@Name='obj1']/Value"/>
    		<xsl:value-of select="$value"/>
    		<table>
    			<xsl:for-each select="//Container[Object[@Name='obj1' and Value/. = $value]]">
    			<tr>
    				<xsl:for-each select="Object[@Name!='obj1']">
    				<td>
    				<xsl:value-of select="Value"/>
    				</td>
    				</xsl:for-each>
    			</tr>
    			</xsl:for-each>
    		</table>
    		</xsl:for-each>
    	</body>
     
    </xsl:template>
    </xsl:stylesheet>
    Si c'est plus complex, tu peux créer une clef composée d'une concaténation de plusieurs attributs/éléments.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2007
    Messages : 19
    Points : 13
    Points
    13
    Par défaut
    Hello.

    Ta méthode marche !, en tout cas ça donne vraiment quelque chose de mieux que tout ce à quoi j'étais parvenu jusqu'à maintenant en utilisant les clefs.

    Je te remercie beaucoup vraiment, pour le temps accordé car ça me donne une piste de démarche à suivre pour faire quelque chose de plus complexe.


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. yet another problème d'encodage !
    Par sopsag dans le forum Général Python
    Réponses: 4
    Dernier message: 10/11/2009, 18h24
  2. [XSLT ]<xsl:attribute name="href"> --> problème
    Par vatzyaya dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 10/10/2007, 09h44
  3. Probléme de filtrage dans une boucle
    Par Gad29 dans le forum Langage
    Réponses: 5
    Dernier message: 04/05/2007, 09h16
  4. [ETATS] Problème de filtrage de date
    Par Ithilien dans le forum IHM
    Réponses: 2
    Dernier message: 02/01/2007, 17h11
  5. Réponses: 5
    Dernier message: 15/08/2006, 16h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo