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]Comment faire une rupture ?


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut [XSLT]Comment faire une rupture ?
    Bonjour,

    Je suis confronté au problème suivant :

    j'ai le fichier XML suivant (source.xml) :

    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
     
    <?xml version="1.0"?>
    <root>
        <list>
            <object>
                <family>house</family>
                <name>door</name>
                <price>100</price>
            </object>
            <object>
                <family>house</family>
                <name>window</name>
                <price>200</price>
            </object>
            <object>
                <family>house</family>
                <name>bedroom</name>
                <price>300</price>
            </object>
            <object>
                <family>human</family>
                <name>arm</name>
                <price>400</price>
            </object>
            <object>
                <family>human</family>
                <name>foot</name>
                <price>600</price>
            </object>
            <object>
                <family>house</family>
                <name>bathroom</name>
                <price>700</price>
            </object>
            <object>
                <family>human</family>
                <name>hand</name>
                <price>300</price>
            </object>
        </list>
    </root>
    Et je veux obtenir un fichier XML qui a la forme suivante (target.xml) :

    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
     
    <?xml version="1.0"?>
    <root>
        <list>
            <family name="house">
                <object>
                    <name>door</name>
                </object>
                <object>
                    <name>window</name>
                </object>
                <object>
                    <name>bedroom</name>
                </object>
                <object>
                    <name>bathroom</name>
                </object>
            </family>
            <family name="human">
                <object>
                    <name>arm</name>
                </object>
                <object>
                    <name>foot</name>
                </object>
                <object>
                    <name>hand</name>
                </object>
            </family>
        </list>
    </root>
    Pour l'instant je fais ça, mais cela ne me donne pas encore le bon résultat (somework.xsl) :

    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
     
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes"/>
        <xsl:template match="/root">
            <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <anotherlist>
                    <xsl:for-each select="list">
                        <xsl:if test="object">
                            <xsl:for-each select="object" order-by="+family">
                                <family name="{family}">
                                    <object>
                                        <name>
                                            <xsl:value-of select="name"/>
                                        </name>
                                        <price>
                                            <xsl:value-of select="price"/>
                                        </price>
                                    </object>
                                </family>
                            </xsl:for-each>
                        </xsl:if>
                    </xsl:for-each>
                </anotherlist>
            </root>
        </xsl:template>
    </xsl:stylesheet>
    Quelqu'un peut-il m'aider ?

    Merci.

  2. #2
    Membre éprouvé
    Profil pro
    Responsable Dev
    Inscrit en
    Décembre 2003
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable Dev

    Informations forums :
    Inscription : Décembre 2003
    Messages : 788
    Points : 1 063
    Points
    1 063
    Par défaut
    qu'est ce qui te manque exactement

  3. #3
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Citation Envoyé par fraoustin
    qu'est ce qui te manque exactement
    et bien, au lieu d'obtenir ce que j'ai mis plus haut, j'obtiens ça :

    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <anotherlist>
          <family name="house">
             <object>
                <name>door</name>
                <price>100</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>window</name>
                <price>200</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>bedroom</name>
                <price>300</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>arm</name>
                <price>400</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>foot</name>
                <price>600</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>bathroom</name>
                <price>700</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>hand</name>
                <price>300</price>
             </object>
          </family>
       </anotherlist>
    </root>
    ce qui n'est pas vraiement ce que je veux !!!

    Je veux qu'il y ait une seule balise "house" et une seule balise "human".

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 9
    Points : 8
    Points
    8
    Par défaut
    Bonjour domiq44,

    bien sur que tu obtient un résultat faut, parce que l'emplacement de la deuxième boucle for-each est faut. en faite, si la balise family se situe après la boucle for-each, elle sera repetée autant de fois que la boucle for-each.

    Donc inverse l'ordre de la deuxième boucle et la balise family.

    si ça ne marche pas dit le moi je verrai ça.

  5. #5
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Merci belibech.

    Mais je vois bien ce que tu veux me dire mais je ne parviens pas à produire le résultat voulu !!!

    Du coup, j'ai essayé ça :

    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
     
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes"/>
        <xsl:template match="/root">
            <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <anotherlist>
                    <xsl:for-each select="list/object">
                        <xsl:variable name="objectFamily" select="family"/>
                        <family name="{$objectFamily}">
                            <xsl:for-each select="//list/object[family=$objectFamily]">
                                <object>
                                    <name>
                                        <xsl:value-of select="name"/>
                                    </name>
                                    <price>
                                        <xsl:value-of select="price"/>
                                    </price>
                                </object>
                            </xsl:for-each>
                        </family>
                    </xsl:for-each>
                </anotherlist>
            </root>
        </xsl:template>
    </xsl:stylesheet>
    Et ça ne marche toujours pas

    Qui peut m'aider ?

    Merci

  6. #6
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Pour l'instant, le XSL que j'utilise (cf. post précédent) me donne ça :

    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
    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <anotherlist>
          <family name="house">
             <object>
                <name>door</name>
                <price>100</price>
             </object>
             <object>
                <name>window</name>
                <price>200</price>
             </object>
             <object>
                <name>bedroom</name>
                <price>300</price>
             </object>
             <object>
                <name>bathroom</name>
                <price>700</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>door</name>
                <price>100</price>
             </object>
             <object>
                <name>window</name>
                <price>200</price>
             </object>
             <object>
                <name>bedroom</name>
                <price>300</price>
             </object>
             <object>
                <name>bathroom</name>
                <price>700</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>door</name>
                <price>100</price>
             </object>
             <object>
                <name>window</name>
                <price>200</price>
             </object>
             <object>
                <name>bedroom</name>
                <price>300</price>
             </object>
             <object>
                <name>bathroom</name>
                <price>700</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>arm</name>
                <price>400</price>
             </object>
             <object>
                <name>foot</name>
                <price>600</price>
             </object>
             <object>
                <name>hand</name>
                <price>300</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>arm</name>
                <price>400</price>
             </object>
             <object>
                <name>foot</name>
                <price>600</price>
             </object>
             <object>
                <name>hand</name>
                <price>300</price>
             </object>
          </family>
          <family name="house">
             <object>
                <name>door</name>
                <price>100</price>
             </object>
             <object>
                <name>window</name>
                <price>200</price>
             </object>
             <object>
                <name>bedroom</name>
                <price>300</price>
             </object>
             <object>
                <name>bathroom</name>
                <price>700</price>
             </object>
          </family>
          <family name="human">
             <object>
                <name>arm</name>
                <price>400</price>
             </object>
             <object>
                <name>foot</name>
                <price>600</price>
             </object>
             <object>
                <name>hand</name>
                <price>300</price>
             </object>
          </family>
       </anotherlist>
    </root>
    Hormis le problème de performance, je récupère bien ce que je veux, mais avec des doublons !!!

    Quelqu'un a-t-il un idée ?

  7. #7
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Excusez-moi de réiterer ma demande, mais quelqu'un peut-il m'aider ?

    Merci.

  8. #8
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Ca y est, j'ai trouvé

    Voilà ma solution :

    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
     
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="xml" indent="yes"/>
        <xsl:template match="/">
            <root>
                <anotherlist>
                    <xsl:for-each select="root/list/object[not(family = preceding-sibling::object/family)]">
                        <xsl:variable name="family" select="family"/>
                        <family name="{$family}">
                            <xsl:for-each select="../object[family=$family]">
                                <object>
                                    <name>
                                        <xsl:value-of select="name"/>
                                    </name>
                                    <price>
                                        <xsl:value-of select="price"/>
                                    </price>
                                </object>
                            </xsl:for-each>
                        </family>
                    </xsl:for-each>
                </anotherlist>
            </root>
        </xsl:template>
    </xsl:stylesheet>

    Par contre, si quelqu'un a une solution différente, plus élégante et plus performante : je suis preneur

    Merci encore à tous.

  9. #9
    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
    Salut,
    Je crois que la méthode de muench est plus efficace dans ce cas, ça donne :
    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
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="xml" indent="yes"/>
     
        <xsl:key name="family" match="/root/list/object" use="family"/> 
     
     
        <xsl:template match="/">
            <root>
                <anotherlist>
                	<xsl:for-each select="/root/list/object[generate-id(.)=generate-id(key('family', family)[1])]"> 
                		<xsl:variable name="family" select="family"/>
    			    	<family name="{$family}">
                            <xsl:for-each select="/root/list/object[family=$family]">
                                <object>
                                    <name>
                                        <xsl:value-of select="name"/>
                                    </name>
                                    <price>
                                        <xsl:value-of select="price"/>
                                    </price>
                                </object>
                            </xsl:for-each>
                        </family>
    				</xsl:for-each>
                </anotherlist>
            </root>
        </xsl:template>
    </xsl:stylesheet>
    En s'inspirant de http://xml.developpez.com/faq/?page=3#xslt_regroup

  10. #10
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Citation Envoyé par Morbo Voir le message
    Salut,
    Je crois que la méthode de muench est plus efficace dans ce cas
    ...
    En s'inspirant de http://xml.developpez.com/faq/?page=3#xslt_regroup
    Merci pour le coup de main

    Maintenant, sachant que mon fichier de données fait environ 100 Mo !!!
    (Ne me denamandez pas pourquoi, c'est comme ça, je dois faire avec ...)
    J'ai de gros soucis de performance !!!

    Comment puis-je optimiser cela ?

    Si quelqu'un a des pistes ?

    Merci.

  11. #11
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    tu peux déjà remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="/root/list/object[family=$family]">
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="key('family', $family)">
    Puisque l'on a pris la peine de créer un index, autant l'exploiter au maximum...

  12. #12
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Merci
    Ca fonctionne super.

    Par contre, je ne comprends pas très bien comment ça marche !

    Il y a d'abord cette première ligne au début du XSL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <xsl:key name="family" match="/root/list/object" use="family"/>
    Ensuite la série des 2 boucles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <xsl:for-each select="/root/list/object[generate-id(.)=generate-id(key('family', family)[1])]"> 
        <xsl:variable name="family" select="family"/>
        <xsl:for-each select="key('family', $family)">
    Est-ce que quelqu'un peut m'expliquer comment ça fonctionne; « comme si j'avais 5 ans » ?

    Cela intéressera très certainement beaucoup de monde !

    Merci.

  13. #13
    Membre habitué Avatar de domiq44
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 301
    Points : 135
    Points
    135
    Par défaut
    Pas de réponse ?
    Tant pis !

    Encore un très grand merci à tous ceux qui m'ont aider.

    Merci.

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

Discussions similaires

  1. Comment faire une interface de ce type....
    Par SpiderAlpha dans le forum C++Builder
    Réponses: 6
    Dernier message: 30/04/2007, 13h50
  2. [XSLT] comment faire une sum(1 div @attribute)?
    Par pierre-yves de brito dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 05/07/2006, 10h04
  3. Réponses: 2
    Dernier message: 03/05/2004, 12h13
  4. [VB6] Comment faire une fonction qui renvoie 2 résultats
    Par tazarine dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 15/01/2004, 00h13
  5. Réponses: 10
    Dernier message: 10/10/2003, 14h25

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