[XSL] Filtre et regroupement selon balise

Filtre et regroupement selon balise [XSL] - XML/XSL - Programmation

Marsh Posté le 13-12-2010 à 12:41:15    

Bonjour à tous :)
 
J'ai un problème sur lequel je me casse la tête depuis un moment déjà...
J'ai le XML suivant fourni par un site ( donc que je ne peux pas modifier ) :

Code :
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <liste>
  3.     <fournisseur name="toto">
  4.         <loisir name="loisir1">
  5.             <description>bla bla bla</description>
  6.         </loisir>
  7.         <loisir name="loisir2">
  8.             <description>bla bla bla</description>
  9.         </loisir>
  10.             <loisir name="loisir3">
  11.             <description>bla bla bla</description>
  12.         </loisir>
  13.         <service name="service1">
  14.             <description>bla bla bla</description>
  15.         </service>
  16.         <service name="service2">
  17.             <description>bla bla bla</description>
  18.         </service>
  19.     </fournisseur>
  20.     <fournisseur name="titi">
  21.         <loisir name="loisir1">
  22.             <description>bla bla bla</description>
  23.         </loisir>
  24.         <loisir name="loisir4">
  25.             <description>bla bla bla</description>
  26.         </loisir>
  27.         <service name="service5">
  28.             <description>bla bla bla</description>
  29.         </service>
  30.         <service name="service6">
  31.             <description>bla bla bla</description>
  32.         </service>
  33.     </fournisseur>
  34. ....
  35. </liste>

Il doit être converti au format suivant :

Code :
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <liste>
  3.     <fournisseur name="toto">
  4.         <sports>
  5.             <sport name="loisir1">
  6.                 <description>bla bla bla</description>
  7.             </sport>
  8.             <sport name="loisir3">
  9.                 <description>bla bla bla</description>
  10.             </sport>
  11.         </sports>
  12.         <animations>
  13.             <animation name="loisir2">
  14.                 <description>bla bla bla</description>
  15.             </animation>
  16.         </animations>
  17.         <services>
  18.             <service name="service1">
  19.                 <description>bla bla bla</description>
  20.             </service>
  21.         </services>
  22.     </fournisseur>
  23.     <fournisseur name="titi">
  24.         <sports>
  25.             <sport name="loisir1">
  26.                 <description>bla bla bla</description>
  27.             </sport>
  28.         </sports>
  29.         <services>
  30.             <service name="service5">
  31.                 <description>bla bla bla</description>
  32.             </service>       
  33.             <service name="service6">
  34.                 <description>bla bla bla</description>
  35.             </service>
  36.         </services>
  37.     </fournisseur>   
  38.     ...
  39. </liste>


 
En gros, j'ai un fichier XSL qui fait des correspondances ( avec des xsl:if ) pour savoir quel loisir est un sport ou une animation. Il me précise aussi lesquels je dois sélectionner parmi les loisirs et services dans le nouveau XML, car tout ne va pas forcément dans le nouveau XML. Et souvent le nom du service ou du loisir change.
On peut ainsi avoir un fournisseur avec des loisirs et des services dans le premier xml, et juste des services dans le second xml...
 
J'arrive actuellement à faire ce tri selon les balises avec le XSL suivant, mais le problème est que j'obtiens le XML que je mets plus bas, et donc les balises <sports> <animations> et <services> sont dupliquées, ce qui ne devrait pas être le cas !
Je devrais regrouper tous les sports dans <sports>, toutes les animations dans <animations>, pareil pour les services, mais vu que le XML original ne suit aucun ordre, c'est très difficile...
J'ai entendu parler de la méthode de Muench mais je ne vois pas comment l'appliquer à un regroupement par noms de balises...
 
Le XSL que j'appelle

Code :
  1. <xsl:template name="writeActivite">
  2.     <!-- pour les loisirs -->
  3.     <xsl:for-each select="loisir">
  4.    
  5.         <!-- on cherche le nouveau nom -->
  6.         <xsl:variable name="newNomActivite">
  7.             <xsl:call-template name="nomActiviteSiteToNew">
  8.             <xsl:with-param name="nomActivite" select="@name"></xsl:with-param>
  9.             </xsl:call-template>
  10.         </xsl:variable>
  11.         <!-- on cherche le nouveau type : sport ou animation -->
  12.         <xsl:variable name="typeActiviteNew">
  13.             <xsl:call-template name="typeActiviteSiteToNew">
  14.             <xsl:with-param name="nomActivite" select="@name"></xsl:with-param>
  15.             </xsl:call-template>
  16.         </xsl:variable>
  17.         <!-- si on a trouvé quelque chose dans la correspondance -->
  18.         <xsl:if test="$newNomActivite != '' and $typeActiviteNew != ''">
  19.             <!-- on écrit le bloc -->
  20.             <xsl:call-template name="writeBlocActivite">
  21.                 <xsl:with-param name="typeActivite" select="$typeActiviteNew"></xsl:with-param>
  22.                 <xsl:with-param name="nomActivite" select="$newNomActivite"></xsl:with-param>
  23.             </xsl:call-template>
  24.         </xsl:if>
  25.     </xsl:for-each>
  26.    
  27.     <!-- pareil pour les services -->
  28.     <xsl:for-each select="service">
  29.    
  30.         <!-- on cherche le nouveau nom -->
  31.         <xsl:variable name="newNomActivite">
  32.             <xsl:call-template name="nomActiviteSiteToNew">
  33.             <xsl:with-param name="nomActivite" select="@name"></xsl:with-param>
  34.             </xsl:call-template>
  35.         </xsl:variable>
  36.         <!-- on cherche le nouveau type ( sert à rien dans l'absolu, c'est juste un filtre ) -->
  37.         <xsl:variable name="typeActiviteNew">
  38.             <xsl:call-template name="typeActiviteSiteToNew">
  39.             <xsl:with-param name="nomActivite" select="@name"></xsl:with-param>
  40.             </xsl:call-template>
  41.         </xsl:variable>
  42.         <!-- si on a trouvé quelque chose dans la correspondance -->
  43.         <xsl:if test="$newNomActivite != '' and $typeActiviteNew != ''">
  44.             <!-- on écrit le bloc -->
  45.             <xsl:call-template name="writeBlocActivite">
  46.                 <xsl:with-param name="typeActivite" select="$typeActiviteNew"></xsl:with-param>
  47.                 <xsl:with-param name="nomActivite" select="$newNomActivite"></xsl:with-param>
  48.             </xsl:call-template>
  49.         </xsl:if>
  50.     </xsl:for-each>
  51. </xsl:template>
  52. <!-- ecriture du nouveau bloc -->
  53. <xsl:template name="writeBlocActivite">
  54. <xsl:param name="typeActivite" />
  55. <xsl:param name="nomActivite" />
  56.     <xsl:element name="{concat($typeActivite, 's')}"> <!-- c'est là le problème !!! Où mettre cela ? -->
  57.         <xsl:element name="{$typeActivite}">
  58.         <xsl:attribute name="name"><xsl:value-of select="$nomActivite"/></xsl:attribute>
  59.             <xsl:element name="description">
  60.                 <xsl:value-of select="translate(description,'&#10;','&#32;')" />
  61.             </xsl:element>
  62.         </xsl:element>
  63.     </xsl:element>
  64.        
  65. </xsl:template>

Et ce que j'obtiens ( donc mal trié ) :

Code :
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <liste>
  3.     <fournisseur name="toto">
  4.         <sports>
  5.             <sport name="loisir1">
  6.                 <description>bla bla bla</description>
  7.             </sport>
  8.         </sports>
  9.         <sports> <!-- ne devrait pas être là -->
  10.             <sport name="loisir3">
  11.                 <description>bla bla bla</description>
  12.             </sport>
  13.         </sports>
  14.         <animations>
  15.             <animation name="loisir2">
  16.                 <description>bla bla bla</description>
  17.             </animation>
  18.         </animations>
  19.         <services>
  20.             <service name="service1">
  21.                 <description>bla bla bla</description>
  22.             </service>
  23.         </services>
  24.     </fournisseur>
  25.     <fournisseur name="titi">
  26.         <sports>
  27.             <sport name="loisir1">
  28.                 <description>bla bla bla</description>
  29.             </sport>
  30.         </sports>
  31.         <services>
  32.             <service name="service5">
  33.                 <description>bla bla bla</description>
  34.             </service>
  35.         </services>
  36.         <services> <!-- pareil -->
  37.             <service name="service6">
  38.                 <description>bla bla bla</description>
  39.             </service>
  40.         </services>
  41.     </fournisseur>   
  42.     ...
  43. </liste>

Merci d'avance pour votre aide ! :jap:


Message édité par DaSayan le 13-12-2010 à 12:43:34
Reply

Marsh Posté le 13-12-2010 à 12:41:15   

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed