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] Méthode muench


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut [XSLT] Méthode muench
    Bonjour,

    Je reviens avec un nouveau soucis pour appliquer cette fameuse méthode.

    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
    <sdx:result>
    	<article id="N2004-LA-0151">
            <info> 
    			<coverage>
    				<place>
    					<geoname>
    						<location>
    							<region code="91" role="region" scheme="insee"> Languedoc-Roussillon </region>
    							<region code="11" role="departement" scheme="insee"> Aude </region>
    							<locality code="396" role="commune" scheme="insee"> Trausse </locality>
    						</location>
    					</geoname>
    				</place>
    			</coverage>
    			<coverage>
    				<place>
    					<geoname>
    						<location>
    			                <region code="91" role="region" scheme="insee"> Languedoc-Roussillon </region>
    							<region code="11" role="departement" scheme="insee"> Aude </region>
    							<locality code="315" role="commune" scheme="insee"> Rieux-Minervois </locality>
    						</location>
    					</geoname>
    			    </place>
    			</coverage>
    			<coverage>
    				<place>
    					<geoname>
    						<location>
    							<region code="91" role="region" scheme="insee"> Languedoc-Roussillon </region>
    							<region code="11" role="departement" scheme="insee"> Aude </region>
    							<locality code="433" role="commune" scheme="insee"> Villeneuve-Minervois </locality>
    						</location>
    					</geoname>
    				</place>
    			</coverage>
    		</info>
    	</article>
    	<article id="N2004-LA-0341">
            <info> 
    			<coverage>
    				<place>
    					<geoname>
    						    <region code="91" role="region" scheme="insee">    Languedoc-Roussillon   </region>
    							<region code="30" role="departement" scheme="insee"> Gard </region>
    							<locality code="006" role="commune" scheme="insee"> Aimargues </locality>
    					</geoname>
    				</place>
    			</coverage>
    			<coverage>
    				<place>
    					<geoname>
    						<location>		        
    						    <region code="91" role="region" scheme="insee"> Languedoc-Roussillon </region>
    							<region code="30" role="departement" scheme="insee"> Gard </region>
    							<locality code="169" role="commune" scheme="insee"> Milhaud </locality>
    						</location>
    					</geoname>
    			    </place>
    			</coverage>
    			<coverage>
    				<place>
    					<geoname>
    						<location>					
    							<region code="91" role="region" scheme="insee"> Languedoc-Roussillon </region>
    						    <region code="34" role="departement" scheme="insee"> Hérault </region>
    							<locality code="145" role="commune" scheme="insee"> Lunel </locality>
    						</location>
    					</geoname>
    				</place>
    			</coverage>
    		</info>
    	</article>
    </sdx:result>
    Je voudrai extraire les données géographiques par article sans faire de répétitions sur les régions et les départements. Dans l'exemple, cela donnerai quelque chose de ce style :

    article N2004-LA-0151
    Languedoc-Roussillon > Aude > Trausse ; Rieux-Minervois ; Villeneuve-Minervois

    article N2004-LA-0341
    Languedoc-Roussillon > Gard > Aimargues ; Milhaud
    Hérault > Lunel
    Mon fichier XSL pour le moment :

    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
     
    <xsl:key name="region" match="adfi:location/adfi:region[@role='region']" use="."/>
    <xsl:key name="dpt" match="adfi:location/adfi:region[@role='departement']" use="."/>
    <xsl:key name="commune" match="adfi:location/adfi:locality" use="."/>
     
     
     
    <xsl:template match="adfi:article">
     
    	<xsl:value-of select='@id'/> 
     
    	<xsl:for-each select="//adfi:region[@role='region' and generate-id() = generate-id(key('region', .)[1])]"> 
     
    		<xsl:variable name="vregion" select="." />
    		<xsl:value-of select="$vregion" />
     
    		<xsl:for-each select="//adfi:region[@role='departement' and generate-id() = generate-id(key('dpt', .)[1]) and ../adfi:region[@role='region']=$vregion]"> 
     
    			<xsl:variable name="vdpt" select="." />
    			<xsl:value-of select="$vdpt" />
    			<xsl:text> (</xsl:text>
    			<xsl:value-of select="@code" />
    			<xsl:text>) > </xsl:text>
     
    			<xsl:for-each select="//adfi:locality[generate-id() = generate-id(key('commune', .)[1]) and ../adfi:region[@role='region']=$vregion and ../adfi:region[@role='departement']=$vdpt]"> 
     
    				<xsl:value-of select="." />
    				<xsl:text> ; </xsl:text>
     
    			</xsl:for-each>
    			<br/>
    		</xsl:for-each>
    	</xsl:for-each>
    	<br/>
     
    </xsl:template>
    Je dois forcément être dans cette template. Je me demandais si je devais ajouter une xsl-key sur mon id d'article, car pour le moment, à cause des // devant mes for-each, j'ai tous mes articles qui sont traités... Mais en étant dans la template, je devrai avoir un traitement par article...

    J'ai testé plusieures choses, mais je me suis emmêlée, n'hésitez pas à me donner un coup de main si vous y voyez clair.

  2. #2
    Expert confirmé
    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
    Points : 4 842
    Points
    4 842
    Par défaut
    Chose promise, chose dûe !

    En une seule template je ne pense pas que ce soit possible vu qu'il faut au moins un traitement sur les données, mais en 2 templates c'est faisable (pour les balises HTML faut pas faire attention, c'était juste pour voir l'apparence graphique) :

    Code XSL : 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
    <?xml version="1.0"?>
     
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:template match="result">
    		<html>
    		<xsl:apply-templates select="article" />
    		</html>
    	</xsl:template>
     
    	<xsl:template match="article">
    		<pre>
    		<xsl:call-template name="process-location">
    			<xsl:with-param name="locations" select="info/coverage/place/geoname/location" />
    			<xsl:with-param name="output" select="concat('article ',@id,'&# 10;')" />
    		</xsl:call-template>
    		</pre>
    	</xsl:template>
     
    	<xsl:template name="process-location">
    		<xsl:param name="locations" />
    		<xsl:param name="output" />
     
    		<xsl:variable name="prefix" select="concat($locations[position()=1]/region[@role='region'],' &gt; ', $locations[position()=1]/region[@role='departement'], ' &gt; ')" />
     
    		<xsl:variable name="new-output">
    			<xsl:choose>
    				<xsl:when test="contains($output, $prefix)">
    					<xsl:value-of select="concat(substring-before($output,$prefix),$prefix,$locations[position()=1]/locality,' ; ',substring-after($output,$prefix))" />
    				</xsl:when>
    				<xsl:otherwise>
    					<xsl:value-of select="concat($output,$prefix,$locations[position()=1]/locality,'&# 10;')" />
    				</xsl:otherwise>
    			</xsl:choose>
    		</xsl:variable>
     
    		<xsl:choose>
    			<xsl:when test="$locations[position()&gt;1]">
    				<xsl:call-template name="process-location">
    					<xsl:with-param name="locations" select="$locations[position()&gt;1]" />
    					<xsl:with-param name="output" select="$new-output" />
    				</xsl:call-template>
    			</xsl:when>
    			<xsl:otherwise>
    				<xsl:value-of name="output" select="concat($new-output,'&# 10;')" />
    			</xsl:otherwise>
    		</xsl:choose>
     
    	</xsl:template>
    </xsl:stylesheet>

    En gros, tu récupères d'abord toutes les balises "location" d'un article (ton XML est mal formé d'ailleurs vu qu'il y'a un article où la balise location manque ), puis pour chaque "location" tu regardes si tu as de la redondance d'information.
    Si tu as de la redondance, tu insères juste la partie "locality" et sinon tu ajoutes tout.

    Bon, comme apparement le contenu (texte) de tes balises est non-uniformément formaté au niveau des espaces, il serait plus sûr de lui appliquer un normalize-space() à chaque fois.

    En espérant que ça aide
    Loceka.

  3. #3
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Merci beaucoup
    A première vue, cela m'a l'air d'être une bonne idée, et ça devrait marcher.
    Pour le XML mal formé, c'est un mauvais copier/coller
    Je teste ça lundi et je confirme si c'est résolu

  4. #4
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Salut,

    la méthode Muench est applicable ici, ce qui permet de tout traiter itérativement et dans un seul template. Du fait que l'on a deux niveaux de regroupement, il faut utiliser des clés composées pour les index, avec l'id de l'article et le nom de l'item. Pour l'index des départements la logique voudrait que la clé comprenne également le nom de la région, mais la connaissance du fait qu'un département ne peut appartenir qu'à une seule région nous en dispense.
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output method="text" encoding="ISO-8859-1"/>
    	<xsl:key name="regions" match="region[@role='region']" use="concat(ancestor::article/@id, '|', normalize-space(.))"/>
    	<xsl:key name="departements" match="region[@role='departement']" use="concat(ancestor::article/@id, '|', normalize-space(.))"/>
    	<xsl:key name="localites" match="locality" use="concat(ancestor::article/@id, '|', normalize-space(preceding-sibling::region[@role='departement']))"/>
    	<xsl:variable name="nl" select="'
    '"/>
    	<xsl:template match="article">
    		<xsl:variable name="article" select="@id"/>
    		<xsl:value-of select="concat('article ', $article, $nl)"/>
    		<xsl:for-each select="descendant::region[@role='region' and generate-id() = generate-id(key('regions', concat($article, '|', normalize-space(.)))[1])]">
    			<xsl:variable name="region" select="normalize-space(.)"/>
    			<xsl:value-of select="concat($region, ' &gt; ')"/>
    			<xsl:for-each select="ancestor::article/descendant::region[@role='departement' and generate-id() = generate-id(key('departements', concat($article, '|', normalize-space(.)))[1])]">
    				<xsl:variable name="departement" select="normalize-space(.)"/>
    				<xsl:value-of select="concat($departement, ' &gt;')"/>
    				<xsl:for-each select="key('localites', concat($article, '|', $departement))">
    					<xsl:value-of select="concat(' ', normalize-space(.))"/>
    					<xsl:if test="position() != last()">
    						<xsl:text> ;</xsl:text>
    					</xsl:if>
    				</xsl:for-each>
    				<xsl:value-of select="$nl"/>
    			</xsl:for-each>
    		</xsl:for-each>
    		<xsl:value-of select="$nl"/>
    	</xsl:template>
    </xsl:stylesheet>

  5. #5
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Merci Loceka, ta solution fonctionne bien, mis à part qu'elle ne prend pas en compte les doublons sur la région, mais on peut l'améliorer

    Merci GrandFather, ta solution avec la méthode que je voulais utiliser est parfaite

    Problème résolu !

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

Discussions similaires

  1. [XSLT] Méthode Muench avec les attributs
    Par prgasp77 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 17/02/2008, 16h20
  2. [DEBUTANT][XSL]Méthode muench et suppression de doublons
    Par jerome.balland dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 30/08/2007, 09h47
  3. Réponses: 8
    Dernier message: 04/05/2007, 14h33
  4. [XSLT] Méthode Muench et formatage
    Par iDaaX dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/11/2006, 18h36
  5. [msxml][xslt] méthode put_nodevalue() de IXMLDOMNodePtr ?
    Par sdkddk dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 04/08/2006, 00h26

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