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]Dupliquer un noeud


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 167
    Par défaut [XSL]Dupliquer un noeud
    Bonjour,

    J'essais de dupliquer le premier noeud sous la racine, en conservant les namespaces mais pas les valeurs.

    Exemple:
    J'ai en entrée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance" xsi:type="xsd:StrArray">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">titi</tns:code>
      	<tns:message xmlns:tns="monNamespace">toto</tns:message>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">tata</tns:code>
      	<tns:message xmlns:tns="monNamespace">tutu</tns:message>
      </tns:value>
    </xsd:root>
    Je veux que ça donne en sortie :
    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
     
    <xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance" xsi:type="xsd:StrArray">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">titi</tns:code>
      	<tns:message xmlns:tns="monNamespace">toto</tns:message>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">tata</tns:code>
      	<tns:message xmlns:tns="monNamespace">tutu</tns:message>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace"/>
      	<tns:message xmlns:tns="monNamespace"/>
      </tns:value>
    </xsd:root>
    Vous pouvez m'aider à faire ça ?

    Merci.

  2. #2
    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
    J'ai pas compris l'exemple.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 167
    Par défaut
    Je veux que le script duplique le noeud fils du noeud racine (avec les elements qu'il contient).

    Dans mon exemple, le noeud racine est "root".
    Son premier noeud fils est "value" qui contient les éléments "code" et "message".

    Ce noeud à été dupliqué et rajouté à la fin du noeud racine, et les éléments ont été vidés.

    Ca se comprend, ou c'est toujours flou ?

  4. #4
    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
    Ben maintenant que tu nous as bien expliqué ce qui change entre les exemples et quel est le raisonnement qui provoque ce changement, c'est plus clair. Il faut reconnaître que l'idée de faire ça ne vient pas spontanément à l'esprit.

    Je pense que tu peux :

    - appeler un template spécial à la fin de ton template de base, pour lequel tu select="/*/*[1]"
    - Dans ce template spécial, tu fais un <copy> du nœud en cours pour avoir son nom et son namespace
    - Dans ce copy, tu fais un for-each pour lequel tu select="*"
    - Dans ce for-each, tu fais juste un <copy/> pour avoir le nom et le namespace de l'élément mais pas son contenu.

    Ça devrait faire l'affaire
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 167
    Par défaut
    Merci pour ces instructions.
    J'ai essayé de les suivre. Voilà ce que j'ai fait :
    - appeler un template spécial à la fin de ton template de base, pour lequel tu select="/*/*[1]"
    - Dans ce template spécial, tu fais un <copy> du nœud en cours pour avoir son nom et son namespace
    Soit le XSL 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
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
      <xsl:output method="xml"/>
     
    <xsl:template match="/node()">
      <xsl:copy>
        <xsl:apply-templates/>
        <xsl:call-template name="duplicate">
          <xsl:with-param name="myNode">
            <xsl:value-of select="/*/*[1]" />
          </xsl:with-param>
        </xsl:call-template>
      </xsl:copy>
    </xsl:template>
     
    <xsl:template match="node()|@*">
       <xsl:copy>
           <xsl:apply-templates select="@*"/>
           <xsl:apply-templates/>
       </xsl:copy>
    </xsl:template>
     
    <xsl:template name="duplicate">
      <xsl:param name="myNode" />
     
      <xsl:copy>
        <xsl:value-of select="myNode" />
      </xsl:copy>
    </xsl:template>
     
    </xsl:stylesheet>
    Ce qui me donne en sortie (avec en entrée le code de mon premier post) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8"?><xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code>titi</tns:code>
      	<tns:message>toto</tns:message>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code>tata</tns:code>
      	<tns:message>tutu</tns:message>
      </tns:value>
    <xsd:root/></xsd:root>
    Donc déjà, il y'a un problème : le noeud récupéré est <root> alors que ça aurait dû être <tns:value>.

    Vous pouvez m'aider à avancer ?

    Merci.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 167
    Par défaut
    Ok, c'est bon, j'y suis arrivé en suivant tes consignes thelvin, merci.
    Voila 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
      <xsl:output method="xml"/>
     
      <xsl:template match="/node()">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
      </xsl:template>
     
      <xsl:template match="/*/*[last()]">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
        <xsl:call-template name="duplicate" />
      </xsl:template>
     
      <xsl:template match="node()|@*">
         <xsl:copy>
             <xsl:apply-templates select="@*"/>
             <xsl:apply-templates/>
         </xsl:copy>
      </xsl:template>
     
      <xsl:template name="duplicate">
        <xsl:copy>
          <xsl:for-each select="./*">
           <xsl:copy />
          </xsl:for-each>
        </xsl:copy>
      </xsl:template>
     
    </xsl:stylesheet>
    et en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8"?><xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code>titi</tns:code>
      	<tns:message>toto</tns:message>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code>tata</tns:code>
      	<tns:message>tutu</tns:message>
      </tns:value><tns:value xmlns:tns="monNamespace"><tns:code/><tns:message/></tns:value>
    </xsd:root>
    Par contre ça ne marche que pour un niveau de profondeur donné.
    Si je modifie le fichier en entrée avec un niveau de profondeur supplémentaire pour le noeud premier noeud fils, ça ne fonctionne plus.

    Exemple :
    Si j'ai en entrée :
    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
    <xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance" xsi:type="xsd:StrArray">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">titi</tns:code>
      	<tns:message xmlns:tns="monNamespace">toto</tns:message>
      	<tns:description xmlns:tns="monNamespace">
    	  <tns:sujet xmlns:tns="monNamespace">pif</tns:sujet>
     	  <tns:contenu xmlns:tns="monNamespace">paf</tns:contenu>
    	</tns:description>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">tata</tns:code>
      	<tns:message xmlns:tns="monNamespace">tutu</tns:message>
      	<tns:description xmlns:tns="monNamespace">
    	  <tns:sujet xmlns:tns="monNamespace">pof</tns:sujet>
     	  <tns:contenu xmlns:tns="monNamespace">puf</tns:contenu>
    	</tns:description>
      </tns:value>
    </xsd:root>
    Avec ma feuille XSL actuelle, ça ne va PAS me donner :
    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
    <xsd:root xmlns:xsd="monNamespace" xmlns:xsi="http://www.w3.org/2delegatedCn001/XMLSchema-instance" xsi:type="xsd:StrArray">
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">titi</tns:code>
      	<tns:message xmlns:tns="monNamespace">toto</tns:message>
      	<tns:description xmlns:tns="monNamespace">
    	  <tns:sujet xmlns:tns="monNamespace">pif</tns:sujet>
     	  <tns:contenu xmlns:tns="monNamespace">paf</tns:contenu>
    	</tns:description>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace">tata</tns:code>
      	<tns:message xmlns:tns="monNamespace">tutu</tns:message>
      	<tns:description xmlns:tns="monNamespace">
    	  <tns:sujet xmlns:tns="monNamespace">pof</tns:sujet>
     	  <tns:contenu xmlns:tns="monNamespace">puf</tns:contenu>
    	</tns:description>
      </tns:value>
      <tns:value xmlns:tns="monNamespace">
      	<tns:code xmlns:tns="monNamespace" />
      	<tns:message xmlns:tns="monNamespace" />
      	<tns:description xmlns:tns="monNamespace">
    	  <tns:sujet xmlns:tns="monNamespace" />
     	  <tns:contenu xmlns:tns="monNamespace" />
    	</tns:description>
      </tns:value>
    </xsd:root>
    -----------

    Autrement dit, il me faudrait modifier ma feuille XSL pour qu'elle soit plus générique, et qu'elle me duplique le premier noeud du schéma en entrée, quel que soit le niveau de profondeur de ce noeud.

    Je pense qu'il faudrait je modifie le template "duplicate" pour qu'il soit récursif.
    Mais je sais pas trop à quoi devrait ressembler mon algorithme après ça.

    Je sais pas si j'ai été assez clair dans mes explications ?
    Vous pouvez m'aider ?

Discussions similaires

  1. Réponses: 1
    Dernier message: 01/06/2006, 17h18
  2. [XSL] egalité de noeud
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 11
    Dernier message: 14/01/2006, 23h58
  3. [xml/xsl] Problème de noeuds et attributs
    Par Avallach dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 14/01/2006, 14h31
  4. [XSL] Accès à un noeud dans une boucle
    Par Trin dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 15/11/2005, 14h32
  5. xsl ---> filtrage des noeuds avec "not"
    Par yos dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 12/07/2005, 11h26

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