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 :

Précédent élément en fonction d'un attribut


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Précédent élément en fonction d'un attribut
    Bonjour,

    J'ai un document XML que je dois transformer en un fichier CSV, en calculant un élément à partir des attributs existants.

    Le fichier XML est le suivant :
    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
    <?xml version="1.0" encoding="utf-8"?>
    <document>
        <vueObjet typePagination="N" typePage="N" ordre="1" numeroPage="NP">
            <image>url_image_1</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="2" numeroPage="NP">
            <image>url_image_2</image>
        </vueObjet>
        <vueObjet typePagination="A" typePage="N" ordre="3" numeroPage="1">
            <image>url_image_3</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="4" numeroPage="NP">
            <image>url_image_4</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="5" numeroPage="NP">
            <image>url_image_5</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="6" numeroPage="NP">
            <image>url_image_6</image>
        </vueObjet>
        <vueObjet typePagination="A" typePage="N" ordre="7" numeroPage="5">
            <image>url_image_7</image>
        </vueObjet>
        <vueObjet typePagination="A" typePage="N" ordre="8" numeroPage="6">
            <image>url_image_8</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="9" numeroPage="NP">
            <image>url_image_9</image>
        </vueObjet>
        <vueObjet typePagination="N" typePage="N" ordre="10" numeroPage="NP">
            <image>url_image_10</image>
        </vueObjet>
    </document>
    Je veux aboutir à un fichier csv comme celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Page courante   Numéro  Images précédentes Images suivantes Image suivante Suivante numérotée Image précédente    Précédente numérotée    Nom page  Url
    NP              1       0                  9                2              3                                                              Image 1   url_image_1
    NP              2       1                  8                3              3                  1                                           Image 2   url_image_2
    1               3       2                  7                4              7                  2                                           1         url_image_3
    NP              4       3                  6                5              7                  3                   3                       2         url_image_4
    NP              5       4                  5                6              7                  4                   3                       3         url_image_5
    NP              6       5                  4                7              7                  5                   3                       4         url_image_6
    5               7       6                  3                8              8                  6                   3                       5         url_image_7
    6               8       7                  2                9                                 7                   7                       6         url_image_8
    NP              9       8                  1                10                                8                   7                       Image 9   url_image_9
    NP              10      9                  0                                                  9                   7                       Image 10  url_image_10
    J'ai donc fait une feuille xsl comme ceci (simplifiée ici pour faciliter la lecture) :
    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" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" media-type="text/csv" encoding="UTF-8" omit-xml-declaration="yes"/>
     
    <xsl:param name="délimiteur"><xsl:text>&#x9;</xsl:text></xsl:param>
    <xsl:param name="saut_ligne"><xsl:text>&#x0A;</xsl:text></xsl:param>
     
    <xsl:template match="/document/vueObjet">
        <xsl:text>Page courante </xsl:text><xsl:value-of select="@numeroPage"/> 
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text>Numéro </xsl:text><xsl:value-of select="@ordre"/> 
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Images précédentes </xsl:text><xsl:value-of select="count(preceding::image)"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Images suivantes </xsl:text><xsl:value-of select="count(following::image)"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> image suivante </xsl:text><xsl:value-of select="following-sibling::*[1]/@ordre"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Suivante numérotée </xsl:text><xsl:value-of select="following-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Image précédente </xsl:text><xsl:value-of select="preceding-sibling::vueObjet[1]/@ordre"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Précédente numérotée </xsl:text><xsl:value-of select="preceding-sibling::vueObjet[1][@typePagination != 'N']/@ordre"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Nom page </xsl:text>
            <!-- TODO à déterminer avec les éléments ci-dessus -->
            <xsl:choose>
                <xsl:when test="true()">
                    <xsl:text> TODO </xsl:text>
                </xsl:when>
            </xsl:choose>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text> Url </xsl:text><xsl:value-of select="image"/>
        <xsl:value-of select="$saut_ligne"/>    
    </xsl:template>
     
    <xsl:template match="text()">
        <!-- Ignore tout le reste -->
    </xsl:template>
     
    </xsl:stylesheet>
    Je n'arrive pas à déterminer le précédent élément en fonction du type de pagination, c'est-à-dire le numéro d'ordre de la page précédente qui est numérotée (colonne "Précédente numérotée").

    Ensuite, il faudra définir le nom réel de la page, mais cela devrait aller.

    Quelqu'un a une idée ?

  2. #2
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 842
    Points
    4 842
    Par défaut
    Citation Envoyé par Depolip Voir le message
    Je n'arrive pas à déterminer le précédent élément en fonction du type de pagination, c'est-à-dire le numéro d'ordre de la page précédente qui est numérotée (colonne "Précédente numérotée").
    Pourtant tu l'as fait correctement dans la "Suivante numérotée" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="following-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
    Ben là c'est pareil :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
    Toi tu avais écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling::vueObjet[1][@typePagination != 'N']/@ordre"/>
    donc tu prenais le premier "vueObjet" précédent et tu testais si son type de pagination différait de 'N', alors qu'il faut prendre le premier précédent dont le type diffère de 'N'.

    Citation Envoyé par Depolip Voir le message
    Ensuite, il faudra définir le nom réel de la page, mais cela devrait aller.
    Ben ça tombe bien parce que moi je n'ai pas du tout compris comment tu arrivais à tel ou tel résultat en fonction de tes données.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci de la réponse.

    On s'approche, mais
    <xsl:value-of select="preceding-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
    donne toujours la première page numérotée (ici 3), alors que pour la page 8, il faut renvoyer 7 et pour les pages 9 et 10, il faut renvoyer 8. En fait, il y a une erreur dans le résultat que j'indiquais. C'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Page courante   Numéro  Images précédentes Images suivantes Image suivante Suivante numérotée Image précédente    Précédente numérotée    Nom page  Url
    NP              1       0                  9                2              3                                                              Image 1   url_image_1
    NP              2       1                  8                3              3                  1                                           Image 2   url_image_2
    1               3       2                  7                4              7                  2                                           1         url_image_3
    NP              4       3                  6                5              7                  3                   3                       2         url_image_4
    NP              5       4                  5                6              7                  4                   3                       3         url_image_5
    NP              6       5                  4                7              7                  5                   3                       4         url_image_6
    5               7       6                  3                8              8                  6                   3                       5         url_image_7
    6               8       7                  2                9                                 7                   7                       6         url_image_8
    NP              9       8                  1                10                                8                   8                       Image 9   url_image_9
    NP              10      9                  0                                                  9                   8                       Image 10  url_image_10
    Il faut donc prendre la dernière page numérotée précédente.
    Ben ça tombe bien parce que moi je n'ai pas du tout compris comment tu arrivais à tel ou tel résultat en fonction de tes données.
    Pour la détermination du nom de page, je mettrais le xsl complet ensuite.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 561
    Points : 21 624
    Points
    21 624
    Par défaut
    Citation Envoyé par Depolip Voir le message
    On s'approche, mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
    donne toujours la première page numérotée (ici 3)
    Ça devrait pas. Il doit y avoir autre chose.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Je m'approche encore plus avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling::vueObjet[@ordre = last()][@typePagination != 'N']/@ordre"/>
    qui renvoie bien 3 pour la page numéro 4, 7 pour la page 8 et 8 pour la page 9. Les autres numéro sont cependant absents (par exemple 3 pour la page 5 et 8 pour la page 10).

  6. #6
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 842
    Points
    4 842
    Par défaut
    Citation Envoyé par Depolip Voir le message
    Je m'approche encore plus avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling::vueObjet[@ordre = last()][@typePagination != 'N']/@ordre"/>
    Nope, là tu t'en éloignes.

    Il faut faire le filtre sur la position après à la rigueur, mais pas avant. Tu peux tester ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="(preceding-sibling::vueObjet[@typePagination != 'N']/@ordre)[last()]"/>
    mais normalement ce que je t'avais donné aurait dû marcher.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="(preceding-sibling::vueObjet[@typePagination != 'N']/@ordre)[last()]"/>
    Merci, cela marche !

    Le premier select renvoyait toujours le premier preceding-sibling des vueObjet. Là, j'ai bien le dernier.

    Je mettrais le xsl complet lundi.

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 561
    Points : 21 624
    Points
    21 624
    Par défaut
    Citation Envoyé par Depolip Voir le message
    Le premier select renvoyait toujours le premier preceding-sibling des vueObjet.
    Peut-être, mais ça aurait pas dû. Les outils que tu utilises, ont un bug quelque part dans la gestion de preceding-sibling::

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 5
    Points : 1
    Points
    1
    Par défaut [Résolu] Précédent élément en fonction d'un attribut
    Voila mon xsl final pour info.

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" media-type="text/csv" encoding="UTF-8" omit-xml-declaration="yes"/>
     
    <xsl:param name="délimiteur"><xsl:text>&#x9;</xsl:text></xsl:param>
    <xsl:param name="saut_ligne"><xsl:text>&#x0A;</xsl:text></xsl:param>
     
    <xsl:template match="/document/vueObjet">
        <xsl:variable name="précédente_numérotée" select="(preceding-sibling::vueObjet[@typePagination != 'N']/@ordre)[last()]"/>
        <xsl:variable name="précédente_numérotée_page" select="(preceding-sibling::vueObjet[@typePagination != 'N']/@numeroPage)[last()]"/>
        <xsl:variable name="suivante_numérotée" select="(following-sibling::vueObjet[@typePagination != 'N']/@ordre)[1]"/>
        <xsl:variable name="nom_page">
            <xsl:choose>
                <xsl:when test="@typePagination = 'A'">
                    <xsl:text>page </xsl:text>
                    <xsl:value-of select="@numeroPage"/>
                </xsl:when>
                <xsl:when test="@typePagination = 'N' and not($précédente_numérotée)">
                    <xsl:text>page non paginée, image </xsl:text>
                    <xsl:value-of select="@ordre"/>
                </xsl:when>
                <xsl:when test="@typePagination = 'N' and not($suivante_numérotée)">
                    <xsl:text>page non paginée, image </xsl:text>
                    <xsl:value-of select="@ordre"/>
                </xsl:when>
                <!-- Le numéro de page est déterminable avec une bonne probabilité. -->
                <xsl:otherwise>
                    <xsl:text>page </xsl:text>
                    <xsl:value-of select="$précédente_numérotée_page - $précédente_numérotée + @ordre"/>
                    <xsl:text> (non paginée)</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
     
        <xsl:text>Numéro </xsl:text><xsl:value-of select="@ordre"/>
        <xsl:value-of select="$délimiteur"/>    
        <xsl:text>Page </xsl:text><xsl:value-of select="@numeroPage"/>
        <xsl:value-of select="$délimiteur"/>
        <xsl:text>Nom réel de la page : </xsl:text>
        <xsl:value-of select="$nom_page"/>
     
        <xsl:value-of select="$saut_ligne"/>    
    </xsl:template>
     
    <xsl:template match="text()">
        <!-- Ignore tout le reste -->
    </xsl:template>
     
    </xsl:stylesheet>
    Peut-être, mais ça aurait pas dû. Les outils que tu utilises, ont un bug quelque part dans la gestion de preceding-sibling::
    J'utilise jEdit et Xml Copy Editor sous Linux pour tester. Le résultat est le même pour le xsl initial. C'est en changeant la structure comme ci-dessus que le problème a disparu et que la présence ou non du [last()] ne change rien.

Discussions similaires

  1. [SimpleXML] accéder à un contenu d'élément en fonction de son attribut
    Par jfvlasic dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 07/02/2012, 10h53
  2. autoriser contenu nul d'un élément en fonction de l'attribut
    Par Waldoo dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 15/06/2011, 15h07
  3. [VBA-W] : Fonction Dir et attributs
    Par Mersenne dans le forum VBA Word
    Réponses: 32
    Dernier message: 04/07/2010, 21h47
  4. [XPath]récupération d'éléments en fonction d'attributs
    Par ep31 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 10/06/2006, 11h58
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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