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 :

Regrouper par elements identiques [XSLT 2.0]


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut Regrouper par elements identiques
    Bonjour,
    A partir de ce 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
    <?xml version="1.0" encoding="UTF-8"?>
    <doc>
    	<spe>
    		<id>1</id>
    		<ci>a</ci>
    		<ci>b</ci>
    	</spe>
    	<spe>
    		<id>2</id>
    		<ci>a</ci>
    		<ci>b</ci>
    		<ci>c</ci>
    	</spe>
    	<spe>
    		<id>3</id>
    		<ci>a</ci>
    		<ci>b</ci>
    		<ci>d</ci>
    	</spe>
    </doc>
    j'aimerai obtenir le résultat 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
    <?xml version="1.0" encoding="UTF-8"?>
    <doc>
    	<commun>
    		<id>1</id>
    		<id>2</id>
    		<id>3</id>
    		<ci>a</ci>
    		<ci>b</ci>
    	</commun>
    	<commun>
    		<id>2</id>
    		<ci>c</ci>
    	</commun>
    	<commun>
    		<id>3</id>
    		<ci>d</ci>
    	</commun>
    </doc>
    voici un essai d'xsl qui ne donne pas le 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
    20
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    	<xsl:output method="xml" indent="yes"/>
    	<xsl:template match="/">
    		<doc>
    			<xsl:for-each-group select="//ci" group-by="text()">
    				<commun>
    					<xsl:for-each select="current-group()">
    						<id>
    							<xsl:value-of select="preceding-sibling::id"/>
    						</id>
    					</xsl:for-each>
    					<ci>
    						<xsl:value-of select="current-grouping-key()"/>
    					</ci>
    				</commun>
    			</xsl:for-each-group>
    		</doc>
    	</xsl:template>
    </xsl:stylesheet>
    Merci pour votre aide.

  2. #2
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    L'idée essentielle de ce rendrement est d'avoir les notions de séquence des valeurs distingues ci puisse prendre ("a", "b", "c", "d"), de séquence des valeurs commune à tous les spe et de séquence du reste ("c", "d"). Sans ces notions implémentées implicitement ou explicitement, on peut y avoir de difficulté comme témoignée ici. On peut faire un regroupement comme montré, on peut faire travailler directement avec des séquences de valeurs atomiques... Ma préférence n'a pas d'importance.

    Si vous voulez faire avec la notion de regroupement, on peut faire comme ça sans faisant de raffinement pas toujours nécessaire.
    Code xml : 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:template match="/">
        <doc>
            <commun>
                <xsl:for-each-group select="for $ci in //ci return $ci[every $spe in //spe satisfies (count($spe[ci = $ci]) ge 1)]" group-by="text()">
                    <xsl:if test="position()=1">
                        <xsl:for-each select="current-group()">
                            <id>
                                <xsl:value-of select="preceding-sibling::id"/>
                            </id>
                        </xsl:for-each>
                    </xsl:if>
                    <ci>
                        <xsl:value-of select="current-grouping-key()"/>
                    </ci>
                </xsl:for-each-group>
            </commun>
            <xsl:for-each-group select="for $ci in //ci return $ci[some $spe in //spe satisfies (count($spe/ci[. = $ci]) eq 0)]" group-by="text()">
                <commun>
                    <xsl:for-each select="current-group()">
                        <id>
                            <xsl:value-of select="preceding-sibling::id"/>
                        </id>
                    </xsl:for-each>
                    <ci>
                        <xsl:value-of select="current-grouping-key()"/>
                    </ci>
                </commun>
            </xsl:for-each-group>
        </doc>
    </xsl:template>

  3. #3
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Excellent, c'est parfait
    Merci beaucoup tsuji,
    Merci aussi pour les explications.

  4. #4
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Merci tsuji pour ton aide.
    Juste un petit souci si on ajoute un nouvel élément <ci>e</ci> comme suite:
    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" encoding="UTF-8"?>
    <doc>
    	<spe>
    		<id>1</id>
    		<ci>a</ci>
    		<ci>b</ci>
    	</spe>
    	<spe>
    		<id>2</id>
    		<ci>a</ci>
    		<ci>b</ci>
    		<ci>c</ci>
    	</spe>
    	<spe>
    		<id>3</id>
    		<ci>a</ci>
    		<ci>b</ci>
    		<ci>d</ci>
    		<ci>e</ci>
    	</spe>
    </doc>
    On obtient:
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <doc>
    	<commun>
    		<id>1</id>
    		<id>2</id>
    		<id>3</id>
    		<ci>a</ci>
    		<ci>b</ci>
    	</commun>
    	<commun>
    		<id>2</id>
    		<ci>c</ci>
    	</commun>
    	<commun>
    		<id>3</id>
    		<ci>d</ci>
    	</commun>
    	<commun>
    		<id>3</id>
    		<ci>e</ci>
    	</commun>
    </doc>
    au lieu de:
    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="UTF-8"?>
    <doc>
    	<commun>
    		<id>1</id>
    		<id>2</id>
    		<id>3</id>
    		<ci>a</ci>
    		<ci>b</ci>
    	</commun>
    	<commun>
    		<id>2</id>
    		<ci>c</ci>
    	</commun>
    	<commun>
    		<id>3</id>
    		<ci>d</ci>
    		<ci>e</ci>
    	</commun>
    </doc>
    Merci encore pour votre aide

  5. #5
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    Je ne sais pas si vous comprenez bien que le template je vous ai montré regroupe tous les id pour chacun de ci qui ne sont pas apparus dans tous les spe. Il a bien le mérite de lui-même. Par exemple, si la valeur c apparu dans les spe de id (2, 5, 9), il donnerait un résultat comme ça.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <commun>
        <id>2</id>
        <id>5</id>
        <id>9</id>
        <ci>c</ci>
    </commun>
    et il n'est pas du tout déraisonnable qu'on veut en avoir pour ce genre de ci qui n'apparaît dans tous les spe.

    Pourtant, si vous désirez d'en avoir un rendrement différent comme demandé, c'est bien possible, bien entendu; mais pour le faire on est en effet demandé de faire un regroupement radicalement différent par rapport aux ci qui apparaîent dans tous les spe. Et maintenet, le regoupement est pour les ci mais avec la clé de id. Il faut faire attention de cela.

    Concrètement, on peut faire comme ça remplaçant la deuxième partie du template montré.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
            <xsl:for-each-group select="for $ci in //ci return $ci[some $spe in //spe satisfies count($spe/ci[. = $ci]) eq 0]" group-by="preceding-sibling::id/text()">
                <commun>
                    <xsl:for-each select="current-group()">
                        <xsl:if test="position()=1">
                            <id>
                                <xsl:value-of select="current-grouping-key()"/>
                            </id>
                        </xsl:if>
                        <ci>
                            <xsl:value-of select="." />
                        </ci>
                    </xsl:for-each>
                </commun>
            </xsl:for-each-group>
    Il peut y avoir d'amélioration si vous voulez, mais c'est ce que j'écrirerais rapidement et en premier temps.

  6. #6
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Merci tsuji pour ta réponse et ta disponibilité.
    Désolé je n'étais pas assez clair dans ma demande car l'idée est de faire un double groupement <ci><id> ou plus précisément de regrouper les liens <id><ci>, si par exemple l'<id> 1 est lié aux <ci> a et b et l'<id> 2 est lié aux <ci> a, b, d et f on obtient donc une fois le regroupement réalisé: les <id> 1 et 2 liés aux <ci> a et b et l'<id> 2 lié aux <ci> d et f.
    Merci pour votre aide.

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

Discussions similaires

  1. [PHP 5.3] Comment regrouper des elements d'un tableau par paire de 2
    Par Jarod51 dans le forum Langage
    Réponses: 2
    Dernier message: 23/04/2010, 11h02
  2. [dico]recherhce par element de la cle
    Par deeal dans le forum Général Python
    Réponses: 3
    Dernier message: 08/04/2005, 17h35
  3. Réponses: 5
    Dernier message: 29/09/2004, 11h05
  4. [DB2]Requête regroupement par intervals
    Par sm dans le forum DB2
    Réponses: 8
    Dernier message: 01/09/2004, 17h19
  5. Regroupement par mois
    Par fplanglois dans le forum SQL
    Réponses: 7
    Dernier message: 29/07/2003, 16h32

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