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 :

[XSL] for-each + sort, et comparaison current previous value


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre régulier
    Inscrit en
    Septembre 2005
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 114
    Points : 103
    Points
    103
    Par défaut [XSL] for-each + sort, et comparaison current previous value
    Hello,

    j'ai eu du mal à faire un titre évocateur et pas trop long, désolé...

    Voici mon problème : je récupère un flux XML généré par plusieurs requêtes SQL. Je ne peux faire de tri dans ces requêtes parce qu'elles sont imbriquées (je ne vais pas rentrer dans les détails : des ORBER BY sont exclus).
    Du coup, je le fais dans mon XSL, après un for-each.

    Je pars d'un template DUTYPARTS
    Dans ce template, je fais appel à mon for-each pour parcourir des noeuds : DUTYPART/USED_VHJO
    Puis je trie selon certains éléments (je n'ai donc plus l'ordre, à l'affichage, que j'ai originellement dans mon flux XML).
    Je cherche ensuite à comparer la valeur d'un élément X avec la valeur de l'élément X précédent. Sans for-each, cela a toujours fonctionné à merveille, qu ece soit en utilisant preceding:: ou en assignant à une variable la valeur de position() - 1...bref, ici, je montre une de ces manières, mais croyez-moi, j'en ai essayé tout un tas aussi !! Rien ne fonctionne. Voici mon code actuel, qui présente quelques résultats, mais pas tout à fait ceux attendus :

    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
     
    <xsl:for-each select="DUTYPART/USED_VHJO">
    								<xsl:sort select="TVER_ID"/>
    								<xsl:sort select="VHJO_DAYTYPE"/>
    								<xsl:sort select="VHJO_DEPTIME"/>
    								<xsl:variable name="MyPos">
    									<xsl:value-of select="position()"/>
    								</xsl:variable>
    								<!--
    								<xsl:variable name="MyPrecPos">
    									<xsl:value-of select="position() - 1"/>
    								</xsl:variable>
    								-->
    								<xsl:variable name="MyCurDesc">
    									<xsl:value-of select="VHJO_DAYTYPE"/>
    								</xsl:variable>
    								<xsl:variable name="MyDesc">
    									<xsl:value-of select="(preceding::DUTYPART)[position() = last()]/USED_VHJO/VHJO_DAYTYPE"/>
    								</xsl:variable>
    Bien sûr, il ne s'agit que d'une partie du code.
    En fait, si j'affiche ma position courante et ma position précédente, j'obtiens de curieuses choses; par exemple :

    position 1 - Previous value : 15 - Current value : 15
    position 2 - Previous value : 15 - Current value : 15
    position 3 - Previous value : 15 - Current value : 15
    position 4 - Previous value : 16 - Current value : 16
    position 5 - Previous value : - Current value : 16

    La position 5 était la position 1 dans mon flux xml (et est devenue la position 5 après mes sort), c'est pourquoi la valeur précédente de l'élément était 'null'.
    De même pour ma position 1, on a une valeur précédente, parce qu'il n'a pas la position 1 dans mon flux xml.
    Idem pour la position 4 : la valeur précédente ne correspond pas avec la valeur courante de la position 3.
    Et c'est très gênant...vu que je dois, en gros, me baser sur ces valeurs pour délimiter l'affichage (je change de couleur, en gros, lorsque la valeur précédente ne correspond pas à la valeur courante de la position - 1).

    Bref, il semblerait que le for-each se cale sur le flux xml, et que les sort modifie ce flux, mais qu'il y a décalage entre mon affichage, et mes position (). Je ne suis pas très sûr de moi sur ce coup... : ai-je mes position ici en fonction du flux xml originel, ou du flux xml après les sort ? Cela expliquerait les décalages curieux que j'ai.
    Mais si c'est le cas...comment se fait il que mesposition soient dans l'ordre (1, 2, 3...), et que un ELEMENT[position() - 1]/CHILD à la position 3 ne me donne pas la même valeur qu'un ELEMENT[position()]/CHILD à la position 2 ?

    Voilà...je ne suis pas sûr d'avoir été très clair. C'est en grande partie parce que je ne comprends pas très bien comment le moteur XSL fonctionne, sur ce coup.
    Si quelqu'un a une explication, et éventuellement un début de solution à me proposer...ce serait parfait :-)

    Merci par avance![/code]

  2. #2
    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
    Bonsoir,

    position() renvoie bien la position du noeud courant parmi les noeuds triés. Mais le problème vient de cette expression XPath :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preceding::DUTYPART)[position() = last()]/USED_VHJO/VHJO_DAYTYPE
    l'axe preceding va non pas parcourir la liste des noeuds triés sélectionnés par le for-each, mais la liste des noeuds tels qu'ils apparaîssent dans le XML et position() renvoie évidemment une valeur différente pour les deux contextes.

  3. #3
    Membre régulier
    Inscrit en
    Septembre 2005
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 114
    Points : 103
    Points
    103
    Par défaut
    Hello,

    merci :-)

    Mais alors, comment récupérer la valeur dans le bon contexte ?
    J'ai aussi essayé en récupérant position dans une variable, et en faisant simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DUTYPART[position() = last()]/USED_VHJO/VHJO_DAYTYPE
    simplement, ou même en mettant une valeur fixe entre les crochets, et je ne récupère rien.

    Il y a un truc qui m'échappe... :-(

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 34
    Points : 39
    Points
    39
    Par défaut
    là comme ça à froid sans réfléchir je dirais que si tu faisais 2 xsl qui se suivent celà devrait marcher : dans le premier tu effectues le tri, dans le deuxième tu récupères les valeurs précédentes dans le fichier xml produit par la première transformation XSL. Tu évites ainsi le problème évoqué précedemment.

    Mais il doit sûrement y avoir une solution en un seul xsl...

  5. #5
    Membre régulier
    Inscrit en
    Septembre 2005
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 114
    Points : 103
    Points
    103
    Par défaut
    Hello,

    ça parait une bonne idée, à ceci près que, si je ne m'abuse, un sort ne créera aucun xml "tangible" (pas de flux xml dans un fichier, auquel je puisse appliquer ma 2ème tranformation).

    J'avais pensé à la même solution, peu ou prou... : me taper le tri côté serveur, après avoir récupéré le 1er flux xml généré par mes requêtes sql.
    Seul bémol, je n'ai absolument pas envie de me taper ce tri en Delphi, sachant qu'il doit agir sur 3 éléments. Bref, trier un tableau sur 3 entrées, déjà...mais alors trier un flux xml ur 3 éléments enfants de ma liste d'éléments principaux (root mis à part)...boaf ;-)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 34
    Points : 39
    Points
    39
    Par défaut
    Tu peux toujours faire un tri et afficher "bêtement" les données triées. Certes le sort n'affiche rien, mais on peut quand même afficher le résultat d'un sort avec d'autres tags xsl

    De plus, dans ce cas tu peux effectuer tes 2 transformations en XSL, et tu évites le Delphi !

Discussions similaires

  1. xsl:for-each avec un parametre pour select
    Par arnog dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 26/08/2008, 13h09
  2. boucle <xsl:for-each>
    Par Mike35 dans le forum XSL/XSLT/XPATH
    Réponses: 17
    Dernier message: 13/02/2006, 11h58
  3. [XSL] for-each et variable
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 12/01/2006, 11h42
  4. xsl:for-each
    Par ashurai dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 10/01/2006, 11h54
  5. [XML/XSL] for-each imbriqués
    Par grome dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 11/11/2005, 12h44

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