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-XPATH : insérer une balise sans connaitre le nom exacte de la balise précédente


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Par défaut XSLT-XPATH : insérer une balise sans connaitre le nom exacte de la balise précédente
    Bonjour,

    Je viens solliciter de l'aide sur un problème XSLT-XPATH (dont je suis loin d'être expert ^^' )

    Alors voilà, j'ai un fichier XML avec notamment la séquence de balises suivantes :
    ...
    <PID>
    <PID.4.1>6500009999</PID.4.1>
    <PID.4.2/>
    <PID.4.3/>
    <PID.4.4>Editeur</PID.4.4>
    <PID.4.5>PI</PID.4.5>
    <PID.6.1>TESTNOM</PID.6.1>
    <PID.6.2>TESTPRENOM</PID.6.2>
    <PID.6.3></PID.6.3>
    <PID.6.4/>
    <PID.6.5>M.</PID.6.5>
    <PID.6.6/>
    <PID.6.7>D</PID.6.7>
    <PID.12.1>Fin</PID.12.1>
    </PID>
    ...


    Mon objectif est d'insérer une balise <PID.10.1> avec une donnée en paramètre d'entrée de la feuille de style.
    Mais, là où ça se complique pour moi, c'est que, dans l'exemple, la balise serait juste après la balise <PID.6.7> car les balises sont ordonnées de manière logique numériquement ; or, ce n'est pas fixe et il est possible que d'autres balises soient présentes (par exemple une balise <PID.7.1> ou <PID.8.1> suivi de <PID.8.2> ...
    Bref, je ne peux pas me raccrocher à un nom de balise en particulier, si ce n'est que le nom de la balise que je cherche pour ajouter la balise <PID.10.1> doit être celle qui ce situe juste avant dans l'ordonnancement logique.

    Je ne sais pas si je suis clair.

    Dans l'exemple, mon résultat attendu est celui-là :

    ...
    <PID>
    <PID.4.1>6500009999</PID.4.1>
    <PID.4.2/>
    <PID.4.3/>
    <PID.4.4>Editeur</PID.4.4>
    <PID.4.5>PI</PID.4.5>
    <PID.6.1>TESTNOM</PID.6.1>
    <PID.6.2>TESTPRENOM</PID.6.2>
    <PID.6.3></PID.6.3>
    <PID.6.4/>
    <PID.6.5>M.</PID.6.5>
    <PID.6.6/>
    <PID.6.7>D</PID.6.7>
    <PID.10.1>maDonneeEnParametreDEntree</PID.10.1>
    <PID.12.1>Fin</PID.12.1>
    </PID>
    ...

    Donc j'ai essayé des trucs différents mais je n'arrive pas à identifier la balise avec un prédicat.

    Bref, pour conclure, je suis une quiche en XPATH

    Merci de votre aide
    Cdt

  2. #2
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Par défaut
    Bonjour,

    Pour apporter un peu d'éclaircissement sur mon besoin, j'ai besoin de matcher la balise de la forme <PID.x.x> dont le nombre 'x.x' est le plus grand mais strictement inférieur à 10.

    Dans mon exemple, je dois matcher la balise <PID.6.7> mais peut-être que dans d'autres fichiers xml, ça sera la balise <PID.9.5> ...

    D'avance merci de votre aide précieuse.
    Cdt

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Hello,

    pas facile d'être réactif de nos jours, mais je vais donner des éléments de réponse au cas où.

    A moins d'utiliser XSLT 2+ et de définir ses propres fonctions que XPATH peut ensuite appeler, on ne peut pas faire de prédicat qui indique où mettre une telle balise.

    Normalement il faudrait faire une première passe qui examiner tous les éléments <PID.x.x> et qui détermine à quelle position tu dois insérer ton élément. Puis, après avoir fait cette première passe, boucler à nouveau sur ces <PID.x.x> et les copier chacun, tout en insérant ton élément à la place déterminée à l'étape précédente.

    Pour repérer où l'insérer, ça pourrait ressembler à ç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
        <xsl:template match="PID">
            <PID>
                <xsl:variable name="insert-after">
                    <xsl:call-template name="find-max-below-10"/>
                </xsl:variable>
                <xsl:attribute name="insert-after">
                    <xsl:value-of select="$insert-after"/>
                </xsl:attribute>
            </PID>
        </xsl:template>
     
        <xsl:template name="find-max-below-10">
            <xsl:param name="position" select="1"/>
     
            <xsl:variable name="position-number">
                <xsl:call-template name="extract-middle-version">
                    <xsl:with-param name="text" select="name(*[$position])"/>
                </xsl:call-template>
            </xsl:variable>
     
            <xsl:choose>
                <xsl:when test="$position-number >= 10">
                    <xsl:value-of select="$position - 1"/>
                </xsl:when>
                <xsl:when test="$position = count(*)">
                    <xsl:value-of select="$position"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="find-max-below-10">
                        <xsl:with-param name="position" select="$position + 1"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
     
        <xsl:template name="extract-middle-version">
            <xsl:param name="text"/>
            <xsl:value-of select="substring-before(substring-after($text, '.'), '.')"/>
        </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Par défaut
    Merci thelvin pour ta réponse et les éléments apportés.
    Entre temps, je m'en suis sorti à l'aide d'un script en Python, bcp facile à mettre en place pour moi.
    Je comprends bien que ta solution est plus complexe que ce à quoi j'avais pensé initialement.
    Je note malgré tout précieusement ton code dans un coin ; sait-on jamais, cela pourrait me servir dans l'avenir.

    Encore merci
    Cordialement

Discussions similaires

  1. Ouvrir un dossier sans connaitre son nom exact
    Par goninph dans le forum Excel
    Réponses: 8
    Dernier message: 05/05/2020, 20h13
  2. Réponses: 5
    Dernier message: 05/01/2012, 11h59
  3. Instancier une classe sans connaitre son nom
    Par Molkobain dans le forum Langage
    Réponses: 8
    Dernier message: 16/02/2009, 14h49
  4. [VBA-E] imprimer une feuille sans connaitre le nom
    Par srame dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/04/2007, 09h02
  5. modifier une propriété sans connaitre son nom
    Par cyberchand dans le forum C#
    Réponses: 2
    Dernier message: 17/04/2007, 16h17

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