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 - Trier/regrouper des noeuds en fonction de leur position


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut XSLT - Trier/regrouper des noeuds en fonction de leur position
    Bonjour à tous,

    Je me permets de poster un message pour avoir un peu d'aide concernant un problème que je dois résoudre.

    Je possède un fichier XML que je dois transformer à l'aide d'une feuille XSLT:

    Fichier 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <jel>
    	<admin creation="Wed Mar 05 10:45:20 CET 2014" xsdversion="1.0.0" version="1.0.0" />
    	<jelclass abstract="true" visibility="public" interface="true"  type="ConsommationService">
    	<methods>
    		<method visibility="public" name="estimation" returncomment="blabla" fulltype="java.lang.Integer" type="Integer">
    			<attribute name="@externaldataitem">
    				<description>item1</description>
    			</attribute>
    			<attribute name="@externaldatatype">
    				<description>type1</description>
    			</attribute>
    			<attribute name="@externaldatadesc">
    				<description>desc1</description>
    			</attribute>
    			<attribute name="@externaldataitem">
    				<description>item</description>
    			</attribute>
    			<attribute name="@externaldatatype">
    				<description>desc5</description>
    			</attribute>
    			<attribute name="@externaldatadesc">
    				<description>desc6</description>
    			</attribute>
    			[...]
    		</method>
    	</methods>
    </jel>
    Résultat souhaité:
    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
    <jel>
    	<admin creation="Wed Mar 05 10:45:20 CET 2014" xsdversion="1.0.0" version="1.0.0" />
    	<jelclass abstract="true" visibility="public" interface="true"  type="ConsommationService">
    	<methods>
    		<method visibility="public" name="estimation" returncomment="blabla" fulltype="java.lang.Integer" type="Integer">
    			<attribute>
    				<item>item1</item>
    				<type>type1</item>
    				<desc>desc1</item>
    			</attribute>
    			<attribute>
    				<item>item2</item>
    				<type>type2</item>
    				<desc>desc2</item>
    			</attribute>
    			[...]
    		</method>
    	</methods>
    </jel>
    Je dois donc regrouper à chaque fois 3 attributs nommés "@externaldataitem", "@externaldatatype" et "externaldatadesc" sous un nouveau noeud qui sera nommé "attribut".

    On admet que dans le fichier source, le nombre d'attribut est bien multiple de 3 et que normalement ils sont tous dans le même ordre c-a-d "@externaldataitem" puis "@externaldatatype" puis "externaldatadesc".

    J'ai pensé à boucler sur chaque attribut et en fonction de sa position modulo 3 créer un nouveau noeud nommé "attribut", du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <xsl:template match="attribute">
    	<xsl:if test="(position() = 0) or (position() mod 3) = 0">
    		<xsl:element name="attribute">
    			<xsl:element name="item">
    				<xsl:value-of select="./description"/>
    			</xsl:element>
    		</xsl:element>
    	</xsl:if>
    </xsl:template>
    Excepté le fait que se ne soit pas le résultat attendu, avec ce test, il est impossible de récupérer @externaldatatype/@externaldatadesc et les placer sous le même nœud parent que @externaldataitem.

    Il y a sûrement une solution beaucoup plus élégante avec l'utilisation de following-sibling etc..

    Voila est-il possible d'avoir un peu d'aide car je patauge avec ma feuille XSLT ;-).

    Merci d'avance.

    Cordialement.

  2. #2
    Modérateur

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

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

    - Il vaut mieux inclure ça dans le template de method. L'élément <attribute> à créer concerne <item>, <type> et <desc> à égalité, il ne doit donc pas être créé par l'un d'entre eux mais par leur parent.
    - En XSLT la position commence par 1, c'est donc ça qu'il faut tester.
    - Oui, après avoir identifié le <item> à créer, le plus simple est following-sibling:: pour mettre <type> et <desc> à côté.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Tout d'abord merci de votre réponse rapide.

    Alors j'ai pris en compte vos différentes remarques, cependant maintenant que je match sur chaque noeud "method", comment faire pour copier tout les noeuds qui ne "m’intéressent" pas.

    Puisque un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:copy-of select = "."/>
    va, il me semble tout copier (même les anciens noeuds "attributs")

    Du coup le test ci-dessous copie tout sauf que lorsque le processeur XSLT rencontre le noeud "method" il n'applique pas les modifications, assurément, je me suis trompé quelque part ;-)
    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
    <xsl:template match="method">
    	<xsl:for-each select="comment/attribute">
    		<xsl:if test="(position() = 1) or (position() mod 3) = 0">
    			<xsl:element name="attribute">
    				<!-- On creer le noeud item" -->
    				<xsl:element name="item">
    					<xsl:value-of select="./description"/>
    				</xsl:element>
    				<!-- On recupere le noeud type (frere) -->
    				<xsl:element name="type">
    					<xsl:value-of select="following-sibling::*[1]/description"/>
    				</xsl:element>
    				<!-- On recupere le noeud desc (frere) -->
    				<xsl:element name="desc">
    					<xsl:value-of select="following-sibling::*[2]/description"/>
    				</xsl:element>
    			</xsl:element>
    		</xsl:if>
    	</xsl:for-each>
    </xsl:template>
    <!-- Copie à l'identique -->
    <xsl:template match="node()|@*">
    	<xsl:copy>
    		<xsl:apply-templates select="node()|@*"/>
    	</xsl:copy>
    </xsl:template>

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Bon, on peut pas tout avoir -_-°. Très bien, oublions la modification du template method, et faisons en sorte que ce qui crée <item> crée aussi le <attribute> parent. Il doit donc aussi se charger de créer les deux suivants.

    Ça va ressembler à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <xsl:tempate match="attribute[name = '@item']">
      <attribute>
        <item>
          <xsl:apply-templates select="desc"/>
        </item>
        <type>
          <xsl:apply-templates select="following-sibling::attribute[1]/desc"/>
        </type>
        <desc>
          <xsl:apply-templates select="following-sibling::attribute[2]/desc"/>
        </desc>
      </attribute>
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    En suivant vos derniers conseils effectivement je parviens à créer ce regroupement. ;-)

    Par contre, est-ce la "bonne façon" de faire pour éviter la copie des attributs '@externaldatatype'/'@externaldatades' ' ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	<xsl:template match="attribute[@name = '@externaldatatype'] | attribute[@name = '@externaldatadesc'] " />

    Fichiers XSLT complet:

    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     
    	<xsl:template match="attribute[@name = '@externaldatatype'] | attribute[@name = '@externaldatadesc'] " />
     
    	<xsl:template match="attribute[@name = '@externaldataitem']">
    		<attribute>
    			<item>
    				<xsl:value-of select="description"/>
    			</item>
    			<type>
    				<xsl:value-of select="following-sibling::attribute[1]/description"/>
    			</type>
    			<desc>
    				<xsl:value-of select="following-sibling::attribute[2]/description"/>
    			</desc>
    		</attribute>
    	</xsl:template>
     
    	<!-- Copie à l'identique -->
    	<xsl:template match="node()|@*">
    		<xsl:copy>
    			<xsl:apply-templates select="node()|@*"/>
    		</xsl:copy>
    	</xsl:template>
    </xsl:stylesheet>

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Humm... je dirais que la bonne façon de faire, c'est avec un if comme tu voulais au début :

    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
    <xsl:tempate match="attribute">
      <xsl:if test="name = '@item'">
        <attribute>
          <item>
            <xsl:apply-templates select="desc"/>
          </item>
          <type>
            <xsl:apply-templates select="following-sibling::attribute[1]/desc"/>
          </type>
          <desc>
            <xsl:apply-templates select="following-sibling::attribute[2]/desc"/>
          </desc>
        </attribute>
      </xsl:if>
    </xsl:template>
    Mais bon, après, goûts, couleurs, tout ça...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Effectivement ;-), j'ai entendu plusieurs sons de cloche je pensais qu'il y avait peut-être une façon plus "XSL compliant" de faire ça.

    Enfin en tout cas un grand merci pour votre aide sur ce sujet !!!

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 27/10/2011, 15h54
  2. [XSLT] Regrouper des noeuds frêres
    Par topmas dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 16/06/2010, 16h20
  3. [XSLT] Elaguer des noeuds en fonction des petits-fils
    Par Willl dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 23/12/2009, 11h37
  4. [XSLT] Regrouper les noeuds en fonction d'un attribut
    Par Creuvard dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 11/12/2008, 11h31
  5. [XSLT] regrouper des noeuds identiques
    Par DelphLaga dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 14/11/2006, 17h07

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