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 :

Hierarchisation d'un XML [XPATH 2.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Hierarchisation d'un XML
    Bonjour,
    Cela fait plusieurs heures que je cherche (sans résultat parfait) à hiérarchiser mon fichier.
    Voici mon fichier test :
    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
     
    <body>
     
        <Intro>Element d'intro <span>01</span></Intro>
        <Intro>Element d'intro  02</Intro>
        <Intro>Element d'intro  03</Intro>
        <Intro>Element d'intro  04</Intro>
     
        <Preface>PREFACE</Preface>
        <p>Texte de préface ou autre</p>
     
        <h1>GROS TITRE A</h1>
            <p><span>Texte</span> sous le gros titre</p>
            <p>Texte sous le gros titre</p>
     
        <h2>SOUS TITRE A1</h2>
            <p>Texte <span>A1</span></p>
            <p>Texte A1</p>
            <p>Texte A1</p>
     
        <h2>SOUS TITRE A2</h2>
            <p>Texte A2</p>
            <p>Texte A2</p>
            <p>Texte A2</p>
     
        <h2>SOUS TITRE A3</h2>
            <p>Texte A3</p>
            <p>Texte A3</p>
            <p>Texte A3</p>
     
        <h1>GROS TITRE B</h1>
            <p>Texte B0</p>
     
        <h2>SOUS TITRE B1</h2>
            <p>Texte <span>B1</span></p>
            <p>Texte B1</p>
            <p>Texte B1</p>
     
    </body>
    Voici ce que j'aimerai obtenir :
    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
     
    <body>
     
        <Intro>Element d'intro <span>01</span></Intro>
        <Intro>Element d'intro 02</Intro>
        <Intro>Element d'intro 03</Intro>
        <Intro>Element d'intro 04</Intro>
     
        <Preface>PREFACE</Preface>
        <p>Texte de préface ou autre</p>
     
        <div1>
            <h1>GROS TITRE A</h1>
            <p><span>Texte</span> sous le gros titre</p>
            <p>Texte sous le gros titre</p>
            <div2>
                <h2>SOUS TITRE A1</h2>
                <p>Texte <span>A1</span></p>
                <p>Texte A1</p>
                <p>Texte A1</p>
            </div2>
            <div2>
                <h2>SOUS TITRE A2</h2>
                <p>Texte A2</p>
                <p>Texte A2</p>
                <p>Texte A2</p>
            </div2>
            <div2>
                <h2>SOUS TITRE A3</h2>
                <p>Texte A3</p>
                <p>Texte A3</p>
                <p>Texte A3</p>
            </div2>
        </div1>
     
        <div1>
            <h1>GROS TITRE B</h1>
            <p>Texte B0</p>
            <div2>
                <h2>SOUS TITRE B1</h2>
                <p>Texte <span>B1</span></p>
                <p>Texte B1</p>
                <p>Texte B1</p>
            </div2>
        </div1>
    </body>
    Voici la transformation que j'ai écrite jusqu'à présent :
    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
     
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output indent="yes"/>
     
        <xsl:template match="/">
            <header>
                <xsl:copy-of select="descendant::Intro"/>
            </header>
            <document>
                <xsl:copy-of select="descendant::Preface"/>
                <xsl:apply-templates select="descendant::h1"/>
            </document>
        </xsl:template>
     
        <xsl:template match="Intro"/>
     
        <xsl:template match="h1">
            <div1>
                <xsl:copy>
                    <xsl:apply-templates/>
                </xsl:copy>
                <xsl:if test="name(following-sibling::*[1])!='h1'">
                    <xsl:apply-templates select="following-sibling::*[1]" mode="pas"/>
                </xsl:if>
            </div1>
        </xsl:template>
     
        <xsl:template match="h1" mode="pas"/>
     
        <xsl:template match="*" mode="pas">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
            <xsl:apply-templates select="following-sibling::*[1]" mode="pas"/>
        </xsl:template>
     
        <xsl:template match="h2" mode="pas">
            <div2>
                <xsl:copy>
                    <xsl:apply-templates/>
                </xsl:copy>
                <xsl:if test="name(following-sibling::*[1])!='h2'">
                    <xsl:apply-templates select="following-sibling::*[1]" mode="pas2"/>
                </xsl:if>
            </div2>
        </xsl:template>
     
        <xsl:template match="h2" mode="pas2"/>
     
        <xsl:template match="*" mode="pas2">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
            <xsl:apply-templates select="following-sibling::*[1]" mode="pas2"/>
        </xsl:template>
     
        <xsl:template match="*">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:template>
     
    </xsl:stylesheet>
    Cependant, cette transformation pose problème :
    - l.12 : la transformation ne fonctionne pas si je ne fais pas spécifiquement un <xsl:apply-templates select="descendant::h1"/>, ce qui m'oblige à appeler les autres éléments spécifiquement aussi dans mon <xsl:template match="/">, sauf que ceux-ci sont variables ;
    - l.38 : <xsl:template match="h2" mode="pas"> ne fonctionne pas, mais je pense que je ne suis pas loin.

    Pour l'instant j'arrive à ce résultat:
    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
     
    <header>
       <Intro>Element d'intro <span>01</span></Intro>
       <Intro>Element d'intro  02</Intro>
       <Intro>Element d'intro  03</Intro>
       <Intro>Element d'intro  04</Intro>
    </header>
    <document>
       <Preface>PREFACE</Preface>
       <div1>
          <h1>GROS TITRE A</h1>
          <p>
             <span>Texte</span> sous le gros titre</p>
          <p>Texte sous le gros titre</p>
          <div2>
             <h2>SOUS TITRE A1</h2>
             <p>Texte <span>A1</span></p>
             <p>Texte A1</p>
             <p>Texte A1</p>
          </div2>
       </div1>
       <div1>
          <h1>GROS TITRE B</h1>
          <p>A0 A0 A0</p>
          <div2>
             <h2>SOUS TITRE B1</h2>
             <p>Texte <span>B1</span></p>
             <p>Texte B1</p>
             <p>Texte B1</p>
          </div2>
       </div1>
    </document>
    Merci pour l'aide éventuelle que vous pourriez m'apporter pour faire fonctionner correctement cette transformation !

  2. #2
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Il y a quelque décalage entre le xslt essayé et le xml sorti qu'on aimerait obtenir : des éléments header, document etc. Mais, peu importe et on se concentre sur h1 et h2.

    On peut utiliser templates nommés; on peut aussi utiliser mode aussi et on peut passer paramètres comme pour templates nommés : seulement c'est un peu moins souvent de faire.

    Dans cette solution, je jongle avec un peu plus plus avec la fonction generate-id() cette fois. Ce n'est certainement pas la seulement façon d'y parvenir. Et je ne réclame meilleurs éfficacité, non; mais on peut renforcer le raisonnement qui reste chaque fois le même malgré l'implémentation qui peut paraître différente toutefois. Voici les trois templates pour la fonctionnalité.
    Code xslt1 : 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
    <xsl:template match="h1">
        <div1>
            <xsl:copy-of select="." />
            <xsl:variable name="gid" select="generate-id()" />
            <xsl:apply-templates select="following-sibling::*[1][name()!='h2' 
                and generate-id(preceding-sibling::h1[1])=$gid]"
                mode="pas"
            />
            <xsl:apply-templates select="following-sibling::h2[generate-id(preceding-sibling::h1[1])=$gid]" mode="pas">
                <xsl:with-param name="gid" select="$gid" />
            </xsl:apply-templates>
        </div1>
    </xsl:template>
     
    <xsl:template match="*[name()!='h2']" mode="pas">
        <xsl:copy-of select="." />
        <xsl:if test="name(following-sibling::*[1])!='h2'">
            <xsl:apply-templates select="following-sibling::*[1]" />
        </xsl:if>
    </xsl:template>
     
    <xsl:template match="h2" mode="pas">
        <xsl:param name="gid" />
        <div2>
            <xsl:variable name="gid2" select="generate-id()" />
            <xsl:copy-of select="." />
            <xsl:apply-templates select="following-sibling::*[1][name()!='h2'
                and name()!='h1' 
                and generate-id(preceding-sibling::h2[1])=$gid2
                and generate-id(preceding-sibling::h1[1])=$gid]"
                mode="pas"
            />
        </div2>
    </xsl:template>

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Bonjour tsuji,
    Merci pour ta réponse rapide ! Malheureusement, ta solution ne semble pas fonctionner.
    Mais, peu importe et on se concentre sur h1 et h2.
    Ce qui en dehors des h1 et h2 fait aussi parti du problème : j'arrive à hiérarchiser mon fichier .xml au niveau du h1 mais cela supprime tout ce qui est autour.

  4. #4
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Malheureusement, ta solution ne semble pas fonctionner.
    D'accord, le template qui matche "*[name()!='h2']" en mode="pas" a besoin quelques élaborations. Voici une version corrigée pour ce template.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <xsl:template match="*[name()!='h2']" mode="pas">
        <xsl:copy-of select="." />
        <!-- xsl:if test="name(following-sibling::*[1])!='h2'" -->
        <xsl:if test="name(following-sibling::*[1])!='h2' and name(following-sibling::*[1])!='h1'">
            <!-- xsl:apply-templates select="following-sibling::*[1]" / -->
            <xsl:apply-templates select="following-sibling::*[1]" mode="pas"/>
        </xsl:if>
    </xsl:template>
    Je suis satisfait que ça va matcher exactement ce que tu veux. Fait voir dans ton côté.

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup ! Ça fonctionne ! Je vais essayer de l'améliorer encore un peu de mon côté !

  6. #6
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    J'ai fini par dénicher un autre sujet similaire sur le forum : [XSLT] Regroupement et imbrication hierarchique d'un fichier Xml Plat
    J'ai donc procédé en 3 étapes :
    1. J'ai renommé mes titres pour en faire des <titre niv="[Chiffre]">
    2. (A partir du code de Yann) Regroupement des différentes parties
    3. (A partir du code de Yann) Imbrication des différentes parties
    Ça marche parfaitement et je peux ajouter des niveaux de titres à volonté sans trop me casser la tête.

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

Discussions similaires

  1. xml -> xsl -> xml
    Par virgile04 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 10/10/2002, 16h53
  2. Balises HTML dans un fichier XML
    Par Bastet79 dans le forum XML/XSL et SOAP
    Réponses: 12
    Dernier message: 04/09/2002, 15h29
  3. delphi XML / HTML caractéres speciaux !
    Par adem dans le forum EDI
    Réponses: 2
    Dernier message: 29/08/2002, 17h48
  4. Débutant XML
    Par viny dans le forum XML/XSL et SOAP
    Réponses: 8
    Dernier message: 25/07/2002, 12h07
  5. Pas de casse dans les XML
    Par :GREG: dans le forum Composants VCL
    Réponses: 4
    Dernier message: 17/07/2002, 13h51

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