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]Comportement d'un noeud crée dynamiquement


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut [xslt]Comportement d'un noeud crée dynamiquement
    Bon, je vais essayer d'être le plus claire possible...

    Voici mon 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
    <?xml version="1.0" encoding="UTF-8"?>
    <List>
        </ListItem>
            <Item>
                <City><![CDATA[Antony]]></City>
                <FirstName><![CDATA[John]]></FirstName>
                <LastName><![CDATA[Smith]]></LastName>
                <Age><![CDATA[35]]></Age>
            </Item>
            <Item>
                <City><![CDATA[Paris]]></City>
                <FirstName><![CDATA[Carl]]></FirstName>
                <LastName><![CDATA[Black]]></LastName>
                <Age><![CDATA[30]]></Age>
            </Item>
            <Item>
                <City><![CDATA[Paris]]></City>
                <FirstName><![CDATA[Mark]]></FirstName>
                <LastName><![CDATA[Smith]]></LastName>
                <Age><![CDATA[35]]></Age>
            </Item>
            <Item>
                <City><![CDATA[Antony]]></City>
                <FirstName><![CDATA[Joe]]></FirstName>
                <LastName><![CDATA[Brown]]></LastName>
                <Age><![CDATA[25]]></Age>
            </Item>
        </ListItem>
    </List>
    Voici maintenant un résumé de mon xslt:
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:param name="sortKeys" select="'LastName~~City~~Age~~'" />
     
        <xsl:param name="parentSortKeys" select="''" />
        <xsl:param name="parentSortValues" select="''" />
     
        <xsl:template match="/">
     
            <xsl:variable name="levelKey" select="substring-before($sortKeys, '~~')"/>
     
            <xsl:choose>
                <xsl:when test="$parentSortKeys != ''">
                    <xsl:call-template name="TREEVIEWAPPLYFILTER">
                        <xsl:with-param name="levelKey" select="$levelKey"/> 
                        <xsl:with-param name="parentSortKeys" select="$parentSortKeys"/>
                        <xsl:with-param name="parentSortValues" select="$parentSortValues"/>
                        <xsl:with-param name="builtSortKeys" select="$sortKeys"/>
                        <xsl:with-param name="items" select="//Item"/> 
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="TREEVIEWBUILDRESULTS">
                        <xsl:with-param name="items" select="//Item"/>
                        <xsl:with-param name="builtSortKeys" select="$sortKeys"/>
                        <xsl:with-param name="levelKey" select="$levelKey"/> 
                    </xsl:call-template> 
                </xsl:otherwise>
            </xsl:choose>
     
        </xsl:template>
     
     
        <xsl:template name="TREEVIEWAPPLYFILTER">
            <xsl:param name="items"/>
            <xsl:param name="levelKey"/>
            <xsl:param name="parentSortKeys"/>
            <xsl:param name="parentSortValues"/>
            <xsl:param name="builtSortKeys"/>
            <xsl:param name="results"/>
     
            <xsl:variable name="key" select="substring-before($parentSortKeys, '~~')"/>
            <xsl:variable name="value" select="substring-before($parentSortValues, '~~')"/>
            <xsl:choose>
                <xsl:when test="$key != '' and $key != $levelKey">
                    <xsl:call-template name="TREEVIEWAPPLYFILTER">
                        <xsl:with-param name="items" select="$items[child::*[name() = $key and text() = $value]]"/>
                        <xsl:with-param name="results" select="$items[child::*[name() = $key and text() = $value]]"/>
                        <xsl:with-param name="parentSortKeys" select="substring-after($parentSortKeys, '~~')"/>
                        <xsl:with-param name="parentSortValues" select="substring-after($parentSortValues, '~~')"/>
                        <xsl:with-param name="builtSortKeys" select="$builtSortKeys"/>
                        <xsl:with-param name="levelKey" select="$levelKey"/> 
                    </xsl:call-template> 
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="TREEVIEWBUILDRESULTS">
                        <xsl:with-param name="items" select="$results"/>
                        <xsl:with-param name="builtSortKeys" select="$builtSortKeys"/>
                        <xsl:with-param name="levelKey" select="$levelKey"/> 
                    </xsl:call-template> 
                </xsl:otherwise> 
            </xsl:choose>
        </xsl:template>
     
        <xsl:template name="TREEVIEWBUILDRESULTS">
            <xsl:param name="levelKey"/>
            <xsl:param name="builtSortKeys"/>
            <xsl:param name="items"/>
     
            <br/>
            <xsl:for-each select="$items">
                <xsl:copy-of select="."/><br/>
            </xsl:for-each>
            <br/>
     
            <xsl:copy-of select="$levelKey"/><![CDATA[:]]><br/>
     
            <xsl:for-each select="$items[not(preceding-sibling::*/child::*[name()=$levelKey] = child::*[name()=$levelKey])]">
                <xsl:copy-of select="child::*[name()=$levelKey]"/>
                <![CDATA[ --> ]]>
                <xsl:copy-of select="."/><br/>
            </xsl:for-each>
     
        </xsl:template>
     
    </xsl:stylesheet>
    Directement comme ça, tout fonctionne parfaitement. C'est à dire qu'il me retournera uniquement un enregistrement par nom de famille. Avec ce XML, il me retournera:

    Smith
    Black
    Brown

    Mais il ne passe pas par le template TREEVIEWAPPLYFILTER. si dans le cas où il y a un filtre a appliquer:

    Pour en faire le test, il faut changer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        <xsl:param name="sortKeys" select="'LastName~~City~~Age~~'" />
     
        <xsl:param name="parentSortKeys" select="''" />
        <xsl:param name="parentSortValues" select="''" />
    Pour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        <xsl:param name="sortKeys" select="'City~~Age~~'" />
     
        <xsl:param name="parentSortKeys" select="'LastName~~'" />
        <xsl:param name="parentSortValues" select="'Smith~~'" />
    Dans ce cas, en passant par le template TREEVIEWAPPLYFILTER il nettoie le noeud item pour en garder que ceux dont le LastName est Smith. Cela fonctionne aussi très bien puisque dans le template TREEVIEWBUILDRESULTS j'affiche un à un les résultats trouvés et il me retourne effectivement les deux enregistrements:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            <xsl:for-each select="$items">
                <xsl:copy-of select="."/><br/>
            </xsl:for-each>
    Antony John Smith 35
    Paris Mark Smith 35

    Le problème vient lorse que j'essaie de faire le distinct:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="$items[not(preceding-sibling::*/child::*[name()=$levelKey] = child::*[name()=$levelKey])]">
    Il ne me retourne que le premier:

    Antony --> Antony John Smith 35

    C'est comme si lorse que je construit le noeud le preceding-sibling ne fonctionne plus...

    J'ai aussi fait le test suivant: Premièrement, j'ai retiré les noeuds du XML qui ne sont pas des Smith et j'ai modifié mes paramètres comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        <xsl:param name="sortKeys" select="'City~~Age~~'" />
     
        <xsl:param name="parentSortKeys" select="''" />
        <xsl:param name="parentSortValues" select="''" />
    Encore une fois, ce que je m'attendait, le résultat est bon puisqu'il ne passe pas par le TREEVIEWAPPLYFILTER et ne fabrique pas le noeud...

    Antony --> Antony John Smith 35
    Paris --> Paris Carl Black 30

    Je dois avouer que je suis un peu perdu là!!! Est-ce qu'il y a une différence si je fait un for-each "directement" du XML ou si je fabrique un noeud???

    J'espère que j'ai été assez claire...

    Merci de votre aide...

  2. #2
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Bon, je me rends compte que d'avoir laissé autant de code "inutile" fait un peu peur et avec raison, c'est un peu emmerdant de devoir déchiffrer un code pour en extraire le vrai problème... Mon erreur, je m'en excuse...

    Voici, j'ai reproduit le même problème à plus petite échelle:

    Alors, toujours avec le même XML, voici mon 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
        <xsl:template match="/">
     
            <xsl:call-template name="SHOWRESULT" >
                <xsl:with-param name="items" select="//Item" />
                <xsl:with-param name="title" select="'WITHOUT CLEANING'" />
            </xsl:call-template>
     
            <xsl:call-template name="SHOWRESULT" >
                <xsl:with-param name="items" select="//Item[LastName = 'Smith']" />
                <xsl:with-param name="title" select="'WITH CLEANING'" />
            </xsl:call-template>
     
        </xsl:template>
     
        <xsl:template name="SHOWRESULT">
            <xsl:param name="items" />
            <xsl:param name="title" />
     
            <xsl:value-of select="$title" /><BR />
            <b><![CDATA[All Nodes:]]></b><BR />
            <xsl:for-each select="$items">
                <xsl:copy-of select="." /><BR />
            </xsl:for-each>
            <BR />
            <b><![CDATA[Distinct cities:]]></b><BR />
            <xsl:for-each select="$items[not(child::*[name()='City'] = preceding-sibling::*/child::*[name()='City'])]">
                <xsl:copy-of select="." /><BR />
            </xsl:for-each>
            <BR />
     
        </xsl:template>
     
    </xsl:stylesheet>
    Le résultat parle de lui-même. En utilisant le même processus pour me faire un "SELECT DISTINCT", j'arrive avec deux résultats bien différents... Dans un premier cas, je fais mon for-each sur l'ensemble de mes noeuds Item dans un second cas, je le fais uniquement sur les noeuds donc le LastName est "Smith"

    Voici le résultat que je fais afficher:
    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
    WITHOUT CLEANING
    All Nodes:
    Antony John Smith 35 
    Paris Carl Black 30 
    Paris Mark Smith 35 
    Antony Joe Brown 25 
     
    Distinct cities:
    Antony John Smith 35 
    Paris Carl Black 30 
     
    WITH CLEANING
    All Nodes:
    Antony John Smith 35 
    Paris Mark Smith 35 
     
    Distinct cities:
    Antony John Smith 35
    Comme vous pouvez le remarquer, dans la section "WITH CLEANING" malgré que mon noeud de référence aie deux villes différentes, il m'en retourne qu'un quand je fais mon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="$items[not(child::*[name()='City'] = preceding-sibling::*/child::*[name()='City'])]">
    Je ne comprend vraiment pas...

    Quelqu'un aurait une idée?

    Merci,

    -Capt!

  3. #3
    Membre expérimenté
    Avatar de virgul
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 625
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 625
    Points : 1 666
    Points
    1 666
    Par défaut
    Je suis pas sure mais faudrait pas plutot faire comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="$items[not(child::*[name()='City'] = preceding-sibling::*//child::*[name()='City'])]">
    Pour matcher tout les child ou lieu d'un seul!

  4. #4
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Non, exactement le même résultat...

  5. #5
    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,

    en fait, ça ne peut pas marcher : le preceding-sibling part certes d'un des noeuds de $items, mais il ne parcourt pas uniquement les noeuds se trouvant dans la variable, mais tous les noeuds de la source XML !

    Pour s'en sortir, une solution est d'itérer sur tous les éléments City, et de tester à chaque fois s'il est le premier parmi tous les noeuds contenant la même ville :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            <xsl:for-each select="$items/child::*[name()='City']">
    			<xsl:if test="generate-id(current()) = generate-id($items/child::*[name()='City' and . = current()][1])">
    				<xsl:copy-of select="." /><BR /> 			
    			</xsl:if>
            </xsl:for-each>

  6. #6
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    cool Cool COol COOl COOL COOOOOOOOOOOL!!!

    Enfin, ça fonctionne!!!

    Merci beaucoup GF!!!!

    Je t'en dois deux maintenant!!!

    En espérant que tu sois pas trop loin de Paris!!!

    Merci encore!

    -Capt!

  7. #7
    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
    Citation Envoyé par Capt. Flame
    Je t'en dois deux maintenant!!!
    En attendant, un petit tag "Résolu" (bouton en bas à gauche) me satisfairait totalement...

  8. #8
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Oui Ô mon Maître



    -Capt!

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

Discussions similaires

  1. [XSLT] Intégrer une image SVG créée dynamiquement
    Par HomoErectus dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 01/09/2009, 10h32
  2. Problèmes avec une TForm créée dynamiquement
    Par Pascal Jankowski dans le forum Composants VCL
    Réponses: 5
    Dernier message: 30/03/2005, 11h55
  3. Composant crée dynamiquement & Access in invalid memory
    Par Sunchaser dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/02/2005, 01h03
  4. [XSLT][VARIABLE] comment un noeud est-il stocké?
    Par Devotion dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 02/11/2004, 14h19
  5. Réponses: 5
    Dernier message: 12/07/2004, 21h00

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