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 :

Changer l'ordre des noeuds enfants [XSLT 1.0]


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
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Par défaut Changer l'ordre des noeuds enfants
    Bonjour à tous,

    Je patauge un peu sur ce problème depuis un moment maintenant sans parvenir à trouver la solution. La transformation XSLT sert à changer le format d'un fichier XML vers un XML légèrement différent. Je décrirai d'abord brièvement les formats d'entrée et de sortie, puis vous donnerai le code XSL que j'utilise. Enfin, je décrirai le problème auquel je me heurte.

    Format d'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
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    <IX_PH>
    	<PH>
    		<CDL>
    		(...)
    		</CDL>
    		<WH>
    			<WL>
    			(...)
    			</WL>
    			<WEL>
    			(...)
    			</WEL>
    			<PNRF>
    				<PN (...) />
    				<PN (...) />
    				(...)
    			</PNRF>
    		</WH>
    		<GH>
    		(...)
    		</GH>
    		<R>
    		(...)
    		</R>
    	</PH>
    </IX_PH>
    En sortie, il faut :
    - renommer IX_PH en IX_WH
    - renommer PH en WH
    - renommer les nœuds PN en EF et le nœud PNRF en EFRF
    - "ramener" les nœuds WL, WEL et PNRF un niveau au-dessus
    - mettre le nœud PNRF à la fin (après le nœud R)

    Ça donne le format de sortie 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
     
    <IX_WH>
    	<WH>
    		<CDL>
    		(...)
    		</CDL>
    		<WL>
    		(...)
    		</WL>
    		<WEL>
    		(...)
    		</WEL>
    		<GH>
    		(...)
    		</GH>
    		<R>
    		(...)
    		</R>
    		<EFRF>
    			<EF (...) />
    			<EF (...) />
    			(...)
    		</EFRF>
    	</PH>
    </IX_WH>
    Le code XSL utilisé est le suivant (avec les modifs proposées ci-dessous) :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     
    	<xsl:template match="IX_PH">
    		<xsl:element name="IX_WH">
    			<xsl:copy-of select="@*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="PH">
    		<WH>
    			<xsl:copy-of select="@*[not(name()='Version')]"/>
    			<xsl:attribute name="VersionNb"><xsl:value-of select="@Version"/></xsl:attribute> <!-- Renommage d'un attribut -->
    			<xsl:apply-templates/>
    			<xsl:apply-templates select="WH/PNRF"/>
    		</WH>
    	</xsl:template>
     
     	<xsl:template match="WH">
     		<xsl:apply-templates select="*[not(self::PNRF)]"/>
      	</xsl:template>
     
    	<xsl:template match="CDL">
    		<xsl:element name="CDL">
    			<xsl:copy-of select="@*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<!-- Renommer les nœuds CDL/CD/CA en CDL/CD/A -->
    	<xsl:template match="CD">
    		<xsl:element name="CD">
    			<xsl:copy-of select="@* | node()[name()='P'][name()='S'][name()='Version'][name()='UA']"/>
    			<xsl:for-each select="./CA">
    				<xsl:element name="A">
    					<xsl:copy-of select="@*"/>
    				</xsl:element>
    			</xsl:for-each>
    			<xsl:copy-of select="node()[not(name()='P')][not(name()='S')][not(name()='Version')][not(name()='UA')][not(name()='CA')]"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="WL">
    		<xsl:element name="WL">
    			<xsl:copy-of select="*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="WEL">
    		<xsl:element name="WEL">
    			<xsl:copy-of select="*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="GH">
    		<xsl:element name="GH">
    			<xsl:copy-of select="*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="R">
    		<xsl:element name="R">
    			<xsl:copy-of select="*"/>
    			<xsl:apply-templates/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="PNRF">
    		<xsl:element name="EFRF">
    			<xsl:for-each select="./PN">
    				<xsl:element name="EF">
    					<xsl:copy-of select="@*"/>
    					<xsl:apply-templates/>
    				</xsl:element>
    			</xsl:for-each>
    		</xsl:element>
    	</xsl:template>
     
    </xsl:stylesheet>
    Mon problème est qu'en output, le nœud EFRF se situe entre les nœuds WEL et GH au lieu de se trouver à la fin. Voilà.

    Désolé si mon post est compliqué, brouillon, pas clair ou autre, mais j'ai réellement besoin d'aide sur cette affaire Je peux tout à fait faire un post explicatif simplifié si nécessaire.

    Merci d'avance pour vos lumières !

  2. #2
    Membre Expert
    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
    Par défaut
    C'est dans ton template PH (noeud qui contient les fils que tu veux réordonner) qu'il faut que tu dises dans quel ordre tu veux lire ces noeuds :
    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
    	<xsl:template match="PH">
    		<xsl:element name="WH">
    			<xsl:copy-of select="@*[not(name()='Version')]"/>
    			<xsl:attribute name="VersionNb"><xsl:value-of select="@Version"/></xsl:attribute> <!-- Renommage d'un attribut -->
    			<xsl:for-each select="CDL">
    				<xsl:apply-templates select="."/>
    			</xsl:for-each>
    			<xsl:for-each select="WL">
    				<xsl:apply-templates select="."/>
    			</xsl:for-each>
    			<!-- ... -->
    			<xsl:for-each select="PNRF">
    				<xsl:apply-templates select="."/>
    			</xsl:for-each>
    		</xsl:element>
    	</xsl:template>

  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
    Citation Envoyé par hobotalker Voir le message
    Désolé si mon post est compliqué, brouillon, pas clair ou autre, mais j'ai réellement besoin d'aide sur cette affaire Je peux tout à fait faire un post explicatif simplifié si nécessaire.
    Honnêtement, il me semble pile-poil comme il faut, ton post. C'est la bonne manière de présenter les choses, et il est à peu près aussi simple et court que la description du problème le permet.
    Ne change rien, fais toujours comme ça, et tu rendras heureux les gens d'ici ('fin bon, on t'en voudra pas si tu progresses au point de te débrouiller, hein ).


    La réponse de Loceka me semble correcte, je te propose une alternative : tu appliques les templates sur tous les enfants de <WH> sauf celui que tu veux déplacer. Celui-là, tu l'appelles séparément dans le niveau au-dessus.

    À peu près comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <xsl:template match="PH">
      <WH>
        <xsl:apply-templates/>
        <xsl:apply-templates select="WH/PNRF"/>
      </WH>
    </xsl:template>
     
    <xsl:template match="WH">
      <xsl:apply-templates select="*[not(PNRF)]"/>
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Par défaut
    Bonjour, et merci pour vos réponses.

    J'ai essayé a solution de Loceka mais cette dernière donnait des résultats plutôt exotiques ! De nombreux noeuds enfants avaient disparu.

    La deuxième proposition de solution, celle de thelvin, donne un résultat strictement identique que mon code initial.

    Toutefois, je n'avais pas précisé un détail du code XSL qui peut avoir son importance !
    Je m'en excuse d'ailleurs, mais je comprends tellement peu ce que je fais que j'ai volontairement occulté cette partie en me disant qu'elle était forcément "ignorable" (non, ce n'est pas français ).

    Le fichier d'entrée comprend un nœud source IX_PH qui doit être renommé en IX_WH en sortie. Voilà, vous savez quasiment tout. J'ai également occulté des modifications que je fais dans les enfants noeuds (de CDL, notamment). Pour le coup, je ne pense vraiment pas que cela influe sur le résultat final, mais je vais inclure la totalité de mon code XSL pour que vous ayez bien toutes les données en main. J'édite tout ça dans le post initial.

    Merci d'avance pour votre aide, encore une fois.

  5. #5
    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
    Citation Envoyé par hobotalker Voir le message
    La deuxième proposition de solution, celle de thelvin, donne un résultat strictement identique que mon code initial.
    Pas avec l'exemple que tu nous as donné, non. Par ailleurs le raisonnement que j'ai exposé n'a pas de faille.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Pas avec l'exemple que tu nous as donné, non. Par ailleurs le raisonnement que j'ai exposé n'a pas de faille.
    Je n'en doute pas, mais j'avais omis un détail sur les formats de fichier. C'est maintenant édité.

  7. #7
    Membre Expert
    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
    Par défaut
    Citation Envoyé par hobotalker Voir le message
    J'ai essayé a solution de Loceka mais cette dernière donnait des résultats plutôt exotiques ! De nombreux noeuds enfants avaient disparu.
    Effectivement, si tu l'as repris tel quel sans chercher à comprendre, il ne reprend que les noeuds enfants CDL, WL et PNRF.

    J'ai volontairement et explicitement (<!-- ... --> signifie que c'est à toi de compléter le code) occulté une partie du traitement qui était inutile car exactement pareil que ce que j'avais déjà écrit mais pour les autres fils.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par Loceka Voir le message
    Effectivement, si tu l'as repris tel quel sans chercher à comprendre, il ne reprend que les noeuds enfants CDL, WL et PNRF.

    J'ai volontairement et explicitement (<!-- ... --> signifie que c'est à toi de compléter le code) occulté une partie du traitement qui était inutile car exactement pareil que ce que j'avais déjà écrit mais pour les autres fils.
    Bien que je ne sois pas expert en XSLT, j'avais bien remplacé par tout ce qu'il faut, et cela ne fonctionnait pas.

    Encore une fois, j'avais omis un détail des formats d'entrée/sortie, cela est maintenant édité. J'ai aussi édité le code XSL que j'utilise, qui a été modifié selon les remarques de thelvin. Le problème reste identique.

    Peut-être que le fait de faire la transformation XSL par C# pose un problème, mais j'en doute fort.

  9. #9
    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
    Argh. Mon raisonnement était bon, mais pas le code qui l'implémente -_-°.

    C'est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="WH">
      <xsl:apply-templates select="*[not(self::PNRF)]"/>
    </xsl:template>
    Stupide erreur de copier/coller.

    Pour info c'est presque équivalent à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="WH">
      <xsl:apply-templates select="*[name() != 'PNRF']"/>
    </xsl:template>

    Note : le changement de nom de l'élément racine n'a aucune incidence sur le reste.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Thunderbird] changer l'ordre des comptes
    Par Eusebius dans le forum Thunderbird
    Réponses: 2
    Dernier message: 26/07/2006, 09h08
  2. [C#-XML] Récupérer les valeurs des noeuds enfants
    Par cyllix dans le forum Windows Forms
    Réponses: 1
    Dernier message: 23/06/2006, 11h54
  3. Rajout colonne - changer l'ordre des colonnes ?
    Par Coptere dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 13/09/2005, 10h56
  4. changer l'ordre des dates dans table
    Par lordyan dans le forum Requêtes
    Réponses: 11
    Dernier message: 14/01/2005, 11h12
  5. [XML] Parser selon des noeuds enfants
    Par GLDavid dans le forum Modules
    Réponses: 5
    Dernier message: 20/08/2004, 20h42

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