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 :

Regroupement d'éléments et élimination de doublons.


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Regroupement d'éléments et élimination de doublons.
    Bonjour,

    Je cherche à réaliser la transformation suivante:

    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
    <DATA>
    	<S1>
    		<dossier>
    			<details>
    				<A>1A</A>
    				<B>1B</B>
    			</details>
    			<conf>conf1</conf>
    		</dossier>
    		<action>action1</action>
    	</S1>
    	<S2>
    		<dossier>
    			<details>
    				<C>
    					<test>2A</test>
    				</C>
    				<A>1A</A>
    				<B>2B</B>
    			</details>
    			<conf>conf</conf>
    		</dossier>
    	</S2>
    </DATA>
    XSLT=
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <xsl:template match="/">
    	<DOSSIER>
    		<DETAILS>
    			<xsl:copy-of select="//details/*[not(preceding::node()=node())]"/>
    		</DETAILS>
    	</DOSSIER>
    </xsl:template>
    J'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <DOSSIER>
    	<DETAILS>
    		<A>1A</A>
    		<B>1B</B>
    		<B>2B</B>
    	</DETAILS>
    </DOSSIER>
    Alors que je souhaiterais obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <DOSSIER>
    	<DETAILS>
    		<A>1A</A>
    		<B>1B</B>
    		<C>
    			<test>2A</test>
    		</C>
    	</DETAILS>
    </DOSSIER>
    En fait je ne comprends pas:
    1- pkoi la balise "C" est ignorée
    2- comment faire en sorte que la balise B ne soit pas répétée (en fait le test "preceding::node=node()" que je fais compare le noeud dans son intégralité (c'ets pourquoi "<A>1A</A>" n'est pas répétée alors que je voudrais juste une vérification sur le nom de l'élément.

    En fait de manière plus globale je souhaite "merger" tous les éléments "dossier" des différents "Sx" dasn un seul élément global "DOSSIER". Comme cela me paraissait un peu compliqué je me suis attaqué d'abord au contenu de "détails" en pensant ensuite appliquer la même logique pour les autres contenus ("conf" ici dans cet exemple mais il y en a plus dans mon scénario réel)

    J'ai fait pas mal de recherche et j'ai regardé les entrées de la FAQ sur la méthode de Muench et ses variations mais j'ai pas trop réussi à l'appliquer... :/

    Quelqu'un pourrait-il m'aider s'il vous plait?

    Merci d'avance,
    Seb!

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Citation Envoyé par seb.wytt Voir le message
    1- pkoi la balise "C" est ignorée
    - Dans le contexte de <C>, node() sélectionne trois choses : <test>2A</test>, le whitespace avant et le whitespace après.

    - Dans preceding::node(), il y a sûrement des whitespaces correspondants. Par exemple le whitespace après <A> est sûrement égal au whitespace après <test>.

    Conclusions :
    - node() ne s'improvise pas, on s'en sert quand on le comprend
    - Muench c'est le bien.

    Il te faut une clé genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:key name="details" match="details/*" use="name()"/>
    name() donne le nom de la balise.

    Pour choper la première occurence de chaque balise, c'est comme d'hab Muench-style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:copy-of select="//details/*[generate-id(.) = generate-id(key('details', name()))]"/>

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Wow! Merci cette solution fonctionne du premier coup..
    J'avais essayé la méthode mais je n'avais pas réussi je ne sais plus pourquoi et je m'étais emmêlé...

    J'aurais une question bonus si possible: comment pourrais-je faire pour ramener au même niveau que details tous les autres éléments fils de "dossier" mais qui n'ont pas eux même de noeuds fils (genre l'élément "conf" dans l'exemple).

    J'ai essayé de compléter la méthode de Muench avec une configuration "conf" comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <xsl:key name="details" match="details/*" use="name()"/>
    <xsl:key name="conf" match="conf" use="name()"/>
     
    <xsl:template match="/">
    	<DOSSIER>
    		<DETAILS>
    			<xsl:copy-of select="//details/*[generate-id(.) = generate-id(key('details', name()))]"/>
    		</DETAILS>
    		<xsl:copy-of select="//conf[generate-id(.) = generate-id(key('conf', name()))]"/>
    	</DOSSIER>
    </xsl:template>
    Cela semble bien fonctionner mais si j'en ai pleins d'autres je suis obligé de les rajouter tous un par un (or je ne les connais pas forcément statiquement à l'avance).

    Merci encore!!

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 66
    Points : 42
    Points
    42
    Par défaut
    Salut à tous,
    Je crois que moi aussi j'ai le même genre de problème, voici mon fichier.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
    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
     
    <release-notes>
     
    	<release-note>
     
    <info>
        <module-name>nirm</module-name>
        <module-version>1.7</module-version>
    </info>
     
    </release-note>
     
     
    <release-note>
    	<info>
    <module-name>av-control</module-name>
    <module-version>1.10</module-version>
            </info>
    </release-note>
     
     
    <release-note>
     
    <info>
        <module-name>nirm</module-name>
        <module-version>1.8</module-version>
    </info>
    </release-note>
     
     <release-note>
     
    <info>
        <module-name>epg</module-name>
        <module-version>1.4</module-version>
    </info>
    </release-note>
     
     <release-note>
     
    <info>
        <module-name>epg</module-name>
        <module-version>1.5</module-version>
    </release-note>
     
    <release-note>
     
    <info>
        <module-name>av-control</module-name>
        <module-version>1.1</module-version>
    </info>
    </release-note>
    <release-note>
     
    <info>
        <module-name>epg </module-name>
        <module-version>1.8</module-version>
    </info>
    </release-note>
    <release-note>
     
    <info>
        <module-name>epg </module-name>
        <module-version>1.11</module-version>
    </info>
    </info>
    </release-note>
        <release-note>
     
    <info>
        <module-name>av-control </module-name>
        <module-version>1.12</module-version>
    </info>
    </release-note>
        <release-note>
    <info>
        <module-name>nirm </module-name>
        <module-version>1.12</module-version>
    </info>
    </release-note>
    </release-notes>
    et mon fichier.xsl pour qu'il fasse la transformation et affiche en html pour chaque "module-name" la valeur commune suivi de différentes valeurs de "module-version" c'est à dire:
    av-control: 2.4, 6.4,...
    nirm: 1.2, 1.6,...
    epg: 3.5, 8.4,...

    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
     
    <?xml version="1.0"?>
     
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="mod-name" match="info" use="module-name"/> 
    <xsl:template match="/">
    <h3>
                Product Modules
     </h3>
     
        <ul>
    	    <b>
     
     
    <xsl:for-each select="//info[generate-id(.)=generate-id(key('mod-name', module-name)[1])]">
    <xsl:sort select="concat(info/module-name,(substring-before(info/module-version,'.')) * 100000 + ((substring-after(info/module-version,'.')) * 100))" data-type="text" order="ascending" />
    <li><b><A><xsl:attribute name="href">#<xsl:value-of select="info/module-name" /></xsl:attribute><xsl:value-of select="info/module-name" /></A>: </b><xsl:value-of select="info/module-version"/> <br /><br /></li>			
    </xsl:for-each>
    </b> <br/>
        </ul>
        <br />
    et cela m'affiche comme résultat:
    :
    :
    :
    :
    :
    :
    Je ne comprends pas ce qui ne marche pas.
    Merci pour votre aide.

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Citation Envoyé par chougadosu Voir le message
    Je ne comprends pas ce qui ne marche pas.
    À l'intérieur du for-each tu es déjà dans le contexte d'un élément <info>.
    Il ne faut donc pas faire select="info/module-name" mais select="module-name" .

    Etc, etc.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 66
    Points : 42
    Points
    42
    Par défaut
    Salut thelvin, tout d'abord merci pour ton intervention en modifiant mon fichier.xsl j'ai un affichage du genre avec ce code:
    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"?>
     
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="mod-name" match="info" use="module-name"/> 
    <xsl:template match="/">
    <h3>
                Product Modules
     </h3>
     
        <ul>
     
     
     
    <xsl:for-each select="//info[generate-id(.)=generate-id(key('mod-name', module-name)[1])]">
    <xsl:sort select="concat(module-name,(substring-before(module-version,'.')) * 100000 + ((substring-after(module-version,'.')) * 100))" data-type="text" order="ascending" />
    <li><b><A><xsl:attribute name="href">#<xsl:value-of select="module-name" /></xsl:attribute><xsl:value-of select="module-name" /></A>: </b>
     
    <xsl:for-each select="key('mod-name', module-name)">
     
    <xsl:sort select="concat(module-name,(substring-before(module-version,'.')) * 1000 + ((substring-after(module-version,'.'))))" data-type="text" order="descending" /> 
     
    <xsl:value-of select="module-version"/> <xsl:text> &#xA0;</xsl:text> 
    </xsl:for-each></li>			
    </xsl:for-each> <br/>
        </ul>
        <br />

    av-control: 1.10 1.1

    av-control : 1.12

    epg: 1.5 1.4

    epg : 1.11 1.8

    nirm: 1.8 1.7

    nirm : 1.12

    or j'aimerai avoir un affichage du genre:

    av-control: 1.10 1.1 1.12

    epg: 1.5 1.4 1.11 1.8

    nirm: 1.8 1.7 1.12

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 66
    Points : 42
    Points
    42
    Par défaut
    c'est bon j'ai pu trouver l'erreur, mon fichier.xml avait des espaces entres balises.

Discussions similaires

  1. comment éliminer les doublons
    Par fk04 dans le forum Requêtes
    Réponses: 1
    Dernier message: 09/08/2006, 17h22
  2. Éliminer les doublons d'une BDD MySQL
    Par sansouna24 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 21/05/2006, 11h26
  3. Réponses: 2
    Dernier message: 12/05/2006, 08h35
  4. [Débutant] regroupement d'éléments dans une listBox
    Par fast&furious dans le forum Access
    Réponses: 2
    Dernier message: 15/10/2005, 15h05
  5. [sql] [oracle] éliminer les doublons dans sum ?
    Par trungsi dans le forum Langage SQL
    Réponses: 14
    Dernier message: 04/03/2005, 12h29

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