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 :

Problème d'arborescence XML/XSLT


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Par défaut Problème d'arborescence XML/XSLT
    Bonjour,
    Je débute dans ce domaine qui semble passionnant !
    Je vous expose mon problème :
    Je souhaite reformater un fichier XML. Je passe donc par XSL.
    Mon fichier XML d'origine :
    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
     
    <Produits>
      <FicheProduit>
        <Famille>AA</Famille>
        <Article>AAAA</Article>
        <Libelle>AAAAAA</Libelle>
      </FicheProduit>
      <FicheProduit>
        <Famille>BB</Famille>
        <Article>BBBB</Article>
        <Libelle>BBBBBB</Libelle>
      </FicheProduit>
      <FicheProduit>
        <Famille>AA</Famille>
        <Article>CCCC</Article>
        <Libelle>CCCCCC</Libelle>
      </FicheProduit>
    </Produits>
    Par une transformation XSL, je souhaite obtenir un 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
     
    <Produits>
      <Famille CodFam="AA">
        <Article>
          <Produit>AAAA</Article>
          <Libelle>AAAAAA</Libelle>
        </Article>
        <Article>
          <Produit>CCCC</Article>
          <Libelle>CCCCCC</Libelle>
        </Article>
      </Famille>
      <Famille CodFam="BB">
        <Article>
          <Produit>BBBB</Article>
          <Libelle>BBBBBB</Libelle>
        </Article>
      </Famille>
    </Produits>
    Voici mon XSL :
    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
     
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    <xsl:element name="Produits">
      <xsl:for-each-group select="Produits/FicheProduit" group-by="Famille">
      <xsl:element name="Famille"><xsl:attribute name="CodFam"><xsl:value-of select="Famille"/></xsl:attribute>
        <xsl:for-each select=".">
        <xsl:element name="Article">
        <xsl:element name="Produit"><xsl:value-of select="Article"/></xsl:element>
        <xsl:element name="Libelle"><xsl:value-of select="Libelle"/></xsl:element>
        </xsl:element>
        </xsl:for-each>
      </xsl:element>
      </xsl:for-each-group>
    </xsl:element>
    </xsl:template>
    </xsl:stylesheet>
    En gros, je souhaite regrouper les articles par famille.

    Merci de votre aide.

  2. #2
    Membre Expert
    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
    Par défaut
    Inutile de s'embetter avec des for-each, le XSL est un langage récursif alors il faut éviter au maximum de penser itératif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <xsl:template match="/Produits">
      <Produits>
        <xsl:apply-templates select="FicheProduit/Famille" />
      </Produits>
    </xsl:template>
     
    <xsl:template match="Famille">
      <Famille CodFam="{.}">
        <Article>
          <Produit><xsl:value-of select="../Article" /></Produit>
          <Libelle><xsl:value-of select="../Libelle" /></Libelle>
        </Article>
      </Famille>
    </xsl:template>
    Edit : j'avais pas vu qu'une même famille pouvait être présente plusieurs fois.

    Dans ce cas le mieux (je pense) est de passer par des clefs (méthode de muench) :
    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
    <xsl:key name="famille" match="/Produits/FicheProduit/Famille" use="."/>
     
    <xsl:template match="/Produits">
      <Produits>
        <xsl:for-each select="FicheProduit/Famille[generate-id() = generate-id(key('famille', .)[1])]">
          <xsl:variable name="cod_fam" select="."/>
          <Famille CodFam="{$cod_fam}">
            <xsl:apply-templates select="/Produits/FicheProduit/Famille[text() = $cod_fam]" />
          </Famille>
        </xsl:for-each>
      </Produits>
    </xsl:template>
     
    <xsl:template match="Famille">
      <Article>
        <Produit><xsl:value-of select="../Article" /></Produit>
        <Libelle><xsl:value-of select="../Libelle" /></Libelle>
      </Article>
    </xsl:template>
    J'ai pas testé mais ça devrait le faire.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Par défaut
    Citation Envoyé par Loceka Voir le message
    Inutile de s'embetter avec des for-each, le XSL est un langage récursif alors il faut éviter au maximum de penser itératif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <xsl:template match="/Produits">
      <Produits>
        <xsl:apply-templates select="FicheProduit/Famille" />
      </Produits>
    </xsl:template>
     
    <xsl:template match="Famille">
      <Famille CodFam="{.}">
        <Article>
          <Produit><xsl:value-of select="../Article" /></Produit>
          <Libelle><xsl:value-of select="../Libelle" /></Libelle>
        </Article>
      </Famille>
    </xsl:template>
    Edit : j'avais pas vu qu'une même famille pouvait être présente plusieurs fois.

    Dans ce cas le mieux (je pense) est de passer par des clefs (méthode de muench) :
    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
    <xsl:key name="famille" match="/Produits/FicheProduit/Famille" use="."/>
     
    <xsl:template match="/Produits">
      <Produits>
        <xsl:for-each select="FicheProduit/Famille[generate-id() = generate-id(key('famille', .)[1])]">
          <xsl:variable name="cod_fam" select="."/>
          <Famille CodFam="{$cod_fam}">
            <xsl:apply-templates select="/Produits/FicheProduit/Famille[text() = $cod_fam]" />
          </Famille>
        </xsl:for-each>
      </Produits>
    </xsl:template>
     
    <xsl:template match="Famille">
      <Article>
        <Produit><xsl:value-of select="../Article" /></Produit>
        <Libelle><xsl:value-of select="../Libelle" /></Libelle>
      </Article>
    </xsl:template>
    J'ai pas testé mais ça devrait le faire.
    Merci pour cette réponse rapide.
    Cependant, je pense être obligé d'utiliser for-each-group car je souhaite regrouper par famille.
    Merci encore en tout cas.

    Edit: Désolé, j'avais pas vu l'edit ! Oui, j'ai testé. Ca marche. A moi de regarder maintenant et de comprendre le mécanisme.
    Merci beaucoup.

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    En effet, pour le regroupement un for-each-group est plus pratique qu'un Muench... Encore faut-il être en XSLT version 2.

    Mais rien ne t'empêche d'user du <xsl:apply-templates> à l'intérieur du regroupement.
    Au fait, tu avais un problème, ou tu nous parles juste des choses passionnantes que tu fais dans la vie ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Système d'arborescence XML/XSLT
    Par babyben2 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 27/10/2011, 17h00
  2. [XSLT] Problème de liaison XML<->XSLT
    Par kalimatchoum dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 12/03/2007, 10h59
  3. [XSLT] Problème de transformation XML avec un fichier xslt
    Par seb35 dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 24/04/2006, 22h02
  4. [XML][XSLT] Débutant {Probléme avec For-each-group}
    Par Silvia12 dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 29/01/2006, 21h38
  5. [XSLT][sablotron]Problème de parser XML
    Par sheura dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 14/11/2005, 17h39

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