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 :

Plusieurs enfants avec le même nom et Remplacement d'un SEUL noeud selon la valeur d'un autre noeud suivant


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Femme Profil pro
    Responsable intéropérabilité
    Inscrit en
    Novembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Responsable intéropérabilité
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Plusieurs enfants avec le même nom et Remplacement d'un SEUL noeud selon la valeur d'un autre noeud suivant
    Bonjour,

    Je suis nouvelle sur le forum.
    Je souhaite modifier dans un fichier xml un SEUL noeud selon la valeur d'un autre noeud.

    Le 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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <root>
    <PID>
    <PID.4.1>PID41_1</PID.4.1>
    <PID.4.4>PID44_1</PID.4.4>
    <PID.4.5>PID45_1</PID.4.5>
    <PID.4.1>PID41_2</PID.4.1>
    <PID.4.4>PID44_2</PID.4.4>
    <PID.4.5>PID45_2</PID.4.5>
    <PID.4.1>PID41_3</PID.4.1>
    <PID.4.2/>
    <PID.4.3>PID43_3</PID.4.3>
    <PID.4.4>PID44_3</PID.4.4>
    <PID.4.5>PID45_3</PID.4.5>
    <PID.4.6/>
    <PID.4.7>PID47_3</PID.4.7>
    <PID.6.1>PID61_1</PID.6.1>
    <PID.6.2>PID62_1</PID.6.2>
    <PID.6.3>PID63_1</PID.6.3>
    <PID.6.4/>
    <PID.6.5>PID65_1</PID.6.5>
    <PID.6.6/>
    <PID.6.7>PID67_1</PID.6.7>
    <PID.6.1>PID61_2</PID.6.1>
    <PID.6.2>PID62_2</PID.6.2>
    </PID>
    </root>
    Je veux modifier le PID.4.4 quand le PID.4.5='PID45_2'.

    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node() | @*">
    		<xsl:copy>
    			<xsl:apply-templates select="@* | node()"/>
    		</xsl:copy>
    	</xsl:template>
    <xsl:template name="remplacerPID44">
         <PID.4.4>
              <xsl:value-of select="99999" />
         </PID.4.4>
    </xsl:template>
    <xsl:template match="PID.4.5">
            <xsl:variable name="pos" select="position()"/>
               <xsl:choose>
                  <xsl:when test=".='PID45_2'">
                     <xsl:call-template name="remplacerPID44"/>
                  </xsl:when>
               </xsl:choose>
         <PID.4.5>
            <xsl:value-of select="."/>
         </PID.4.5>
    </xsl:template>
    </xsl:stylesheet>
    J'obtiens :
    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
    <root>
       <PID>
          <PID.4.1>PID41_1</PID.4.1>
          <PID.4.4>PID44_1</PID.4.4>
          <PID.4.5>PID45_1</PID.4.5>
          <PID.4.1>PID41_2</PID.4.1>
          <PID.4.4>PID44_2</PID.4.4>    ------> Ce noeud est en trop
          <PID.4.4>99999</PID.4.4>
          <PID.4.5>PID45_2</PID.4.5>
          <PID.4.1>PID41_3</PID.4.1>
          <PID.4.2/>
          <PID.4.3>PID43_3</PID.4.3>
          <PID.4.4>PID44_3</PID.4.4>
          <PID.4.5>PID45_3</PID.4.5>
          <PID.4.6/>
          <PID.4.7>PID47_3</PID.4.7>
          <PID.6.1>PID61_1</PID.6.1>
          <PID.6.2>PID62_1</PID.6.2>
          <PID.6.3>PID63_1</PID.6.3>
          <PID.6.4/>
          <PID.6.5>PID65_1</PID.6.5>
          <PID.6.6/>
          <PID.6.7>PID67_1</PID.6.7>
          <PID.6.1>PID61_2</PID.6.1>
          <PID.6.2>PID62_2</PID.6.2>
          <PID.6.3/>
          <PID.6.4/>
          <PID.6.5/>
          <PID.6.6/>
          <PID.6.8/>
       </PID>
    </root>
    Je voulais remplacer et j'obtiens l'ajout du noeud tout en conservant l'ancien.
    Mon problème vient du fait que j'ai plusieurs PID.4.4 et PID.4.5 enfants de PID.
    Merci d'avance pour votre aide.

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Hello,

    c'est normal que tu aies création d'un élément et non pas modification, puisque ton code demande à créer un élément et non pas à en modifier un.
    Bref, c'est pas bon, ce code. Ça ne va pas. Jette-le et on recommence du début.

    On repart du code qui fait juste la copie telle que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="node() | @*">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:template>
    Ensuite 'faut ajouter le traitement des nœuds qu'on ne veut pas garder tels que.
    Les nœuds que tu veux modifier, ce sont les <PID.4.4> et pas les <PID.4.5>. Donc c'est sur les <PID.4.4> qu'il faut faire un match particulier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <xsl:template match="PID.4.4">
      <xsl:copy>
    Pour savoir s'il faut faire un traitement particulier ou non, il faut regarder le nœud suivant. Je suppose que tu ne sais pas comment on fait ça. C'est avec following-sibling::*[1]

    Ce qu'il faut regarder, c'est si le nœud suivant est un <PID.4.5>, d'une part, et si son contenu est PID45_2, d'autre part.

    Ça peut s'écrire comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:when test="following-sibling::*[1][self::PID.4.5 and . = 'PID45_2']">
    Et voilà.

  3. #3
    Candidat au Club
    Femme Profil pro
    Responsable intéropérabilité
    Inscrit en
    Novembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Responsable intéropérabilité
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut MERCI
    Merci infiniment Thelvin,

    Je voyais bien que la méthode n'était pas bonne mais je ne m'en sortais pas.

    J'ai donc tout repris selon tes indications et voilà ce que ç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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node() | @*">
    		<xsl:copy>
    			<xsl:apply-templates select="@* | node()"/>
    		</xsl:copy>
    </xsl:template>
     
    <xsl:template match="PID.4.4">
      <xsl:copy>
               <xsl:choose>
                    <xsl:when test="following-sibling::*[1][self::PID.4.5 and . = 'PID45_2']">99999</xsl:when>
                    <xsl:otherwise> 
                       <xsl:value-of select="."/>
                    </xsl:otherwise> 
               </xsl:choose>
      </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>
    Merci encore et Bonne fin de journée

  4. #4
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Simplement ça, moins de code, plus de contrôle.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="PID.4.4[normalize-space(following-sibling::PID.4.5)='PID45_2']">
    	<xsl:copy><xsl:value-of select="'99999'" /></xsl:copy>
    </xsl:template>
    Si il faut que le following-sibling immédiat soit PID.4.5 pas d'autre, ajoutez la condition dans le prédicat.

  5. #5
    Candidat au Club
    Femme Profil pro
    Responsable intéropérabilité
    Inscrit en
    Novembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Responsable intéropérabilité
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut MERCI
    Merci à tous pour vos réponses .
    C'est parfait.

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Et il se passe quoi si le <PID.4.5> n'est pas immédiatement après mais plus loin après ?

  7. #7
    Candidat au Club
    Femme Profil pro
    Responsable intéropérabilité
    Inscrit en
    Novembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Responsable intéropérabilité
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Effectivement dans le doute j'ai gardé la première solution mais je garde sous le coude la 2ème proposition.
    Je pourrai en avoir besoin dans un autre cas ;-).

  8. #8
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Si il faut que le following-sibling immédiat soit PID.4.5 pas d'autre, et qu'il ait comme contenu textuel PID45_2 à part des espaces blancs possibles devant et après aussi, comme ça.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="PID.4.4[local-name(following-sibling::*[1])='PID.4.5' and normalize-space(following-sibling::PID.4.5)='PID45_2']">
    	<xsl:copy><xsl:value-of select="'99999'" /></xsl:copy>
    </xsl:template>

  9. #9
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Eh bah dis donc, il commence à être loin, le "moins de code", et avec lui le "plus de contrôle"

  10. #10
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    [A] moins de code
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <xsl:choose>
    <xsl:when test="test-condition">
    	<!-- etc -->
    </xsl:when>
    <xsl:otherwise> 
    	<xsl:value-of select="."/>
    </xsl:otherwise>
    Sans xsl:choose, xsl:otherwise etc., c'est déjà pas mal. La longueur du code est evidemment proportionale à des conditions acquises, c'est évident et on ne peut comparer une pomme à une orange ou l'inverse. Mais croyez-moi, la longueur du code et c'est la moindre des choses qu'on doit inquiéter, en général, au début, et surtout quand les versions sont équivalentes, comme node() par rapporte de *|text() qui vous est cher. La clarté aide encore plus. La partie xsl:otherwise étant écrite dans le template d'identité, déjà, et l'épargner dans un template spécialisé contribut en plus une consistence et une séparation de concerne, et à part encore, plus de clarté. C'est déjà quelque chose de bien plus que la longueur du codage et encore, je répète, c'est la moindre des choses qu'on doit inquiéter au début, en général.

    [B] plus de contrôle

    [B.1]
    Voilà
    . = 'PID45_2'
    et
    normalize-space() = 'PID45_2'
    ce n'est déjà pas équivalent. Pour faire une comparison d'un noeud de texte à un texte, c'est avec un normalize-space() qui est plus prudent et professionnel à faire. Mais à aucun moment que je ne vous en critique pas, il faut commencer avec quelque chose, n'est-ce pas? Mais si vous prenez mal de ces choses, ce n'est pas moi qui puisse vous soigner et vous donner satisfaction, c'est un docteur en médecine.

    [B.2] Laisser le template d'identité de faire son travail, c'est déjà plus de contrôle sur le comportement des éléments avec d'attributs ou du contentu complexe si il en existe. Donc, du coup, ça élargit la portée d'applicabilité de ce document xslt. Ce n'est pas dans le mandat de la question posée à faire cette économie: on peut le faire mais pas comme montrer l'op. Mais encore une fois, il ne s'agit pas du tout que je en critique quiconque. Je fais mon travail comme quelqu'un qui aide d'une façon professionnelle et vous le prenez mal même? C'est indigne.

Discussions similaires

  1. Metadata XML - plusieurs balises avec le même nom
    Par Viceloque dans le forum Développement de jobs
    Réponses: 5
    Dernier message: 05/03/2020, 13h23
  2. [XL-2007] Plusieurs formes avec le même nom : est-ce dangereux ?
    Par MicroMatz dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 21/11/2015, 16h41
  3. Plusieurs <html:text> avec le même nom ?
    Par hisoft dans le forum Struts 1
    Réponses: 4
    Dernier message: 26/02/2010, 13h23
  4. Réponses: 3
    Dernier message: 29/12/2008, 15h22
  5. Problème pour différencier plusieurs select avec le même nom
    Par vallica dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 24/04/2006, 11h35

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