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 :

Trier un fichier XML


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Août 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 11
    Par défaut Trier un fichier XML
    J'ai un long fichier XML ayant cette structure :

    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
        <settings>
    	<settinggroup name="nom_groupe" autres attributs>
    		<setting name="nom_paramètre">
    			contenant plusieurs balises enfant...
    		</setting>
                    <setting name="nom_paramètre">
    			contenant plusieurs balises enfant...
    		</setting>
                    etc...
           <settinggroup>
           <settinggroup name="nom_groupe" autres attributs>
    		<setting name="nom_paramètre">
    			contenant plusieurs balises enfant...
    		</setting>
    		<setting name="nom_paramètre">
    			contenant plusieurs balises enfant...
    		</setting>
    		<setting name="nom_paramètre">
    			contenant plusieurs balises enfant...
    		</setting>
                    etc...
           <settinggroup>
           etc...
       </settings>
    Chaque "settinggroup" contient un nombre de "setting" différent, mais tous ces "setting" ont la même structure interne.

    Je voudrais :
    - trier les <settinggroup> selon l'ordre alphabétique de leur attribut "name" et conserver tous leurs autres attributs tels quels.
    - à l'intérieur de chaque <settinggroup>, trier les <setting> également selon l'ordre alphabétique de leur attribut "name" tout en conservant leur structure interne telle quelle.

    Je découvre XSL et j'ai beaucoup de mal avec cette syntaxe !!!
    Voici le fichier auquel je suis arrivé :

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
      <xsl:output method="xml" indent="yes"/>
      <xsl:strip-space elements="*"/>
     
      <xsl:template match="/settings">
          <xsl:apply-templates select="/settings/settinggroup">
            <xsl:sort select="@name"/>
          </xsl:apply-templates>
      </xsl:template>
     
      <xsl:template match="/settings/settinggroup">
        <xsl:copy>
          <xsl:apply-templates select="*|@*"/>
        </xsl:copy>
      </xsl:template>
     
      <xsl:template match="/settings/settinggroup/setting">
        <xsl:copy>
          <xsl:apply-templates select="*|@*"/>
        </xsl:copy>
      </xsl:template>
     
      <xsl:template match="*|@*">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
      </xsl:template>
     
    </xsl:stylesheet>
    Les <settinggroup> sont bien triés selon l'ordre alphabétique et tous les contenus sont conservés.
    Mais les <setting> à l'intérieur de chaque <settinggroup> ne sont évidemment pas triés et je ne vois pas comment je peux faire.

    Question subsidiaire et moins importnte : la sortie n'est pas indentée malgré la commande <xsl:output method="xml" indent="yes"/>. Pourquoi ?

    Merci pour votre aide...

  2. #2
    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
    Ma foi c'est un bon début.

    Vu que tu veux trier les <setting>, de la même manière que tu veux trier les <settinggroup>, alors le template sur <settinggroup> doit forcément ressembler au template sur <settings>

    Tu as trois choses à faire :
    - copier le <settinggroup> en encadrant le tout de <xsl:copy> ... </xsl:copy>.
    - copier les attributs tels que. Le plus simple est <xsl:copy-of select="@*"/>.
    - traiter les <setting> par ordre de @name. Tu l'as déjà fait avec les <settinggroup>, c'est pareil.

    Pour copier un <setting> tel que, tu ferais mieux de faire <xsl:copy-of select="."/>. C'est plus simple. Ailleurs tu pouvais pas parce que ailleurs tu veux remanier le contenu et pas le garder tel que. Mais pour les <setting>, si.

    Du coup le template sur <xsl:template match="*|@*"> ne sert plus à rien. Ce genre de choses c'est bon quand on veut faire des trucs plus compliqués. D'ailleurs il ne copie pas tout, écrit comme ça.

    Question subsidiaire et moins importnte : la sortie n'est pas indentée malgré la commande <xsl:output method="xml" indent="yes"/>. Pourquoi ?
    Tu ne produis pas d'élément racine pour ton document de sortie, ce qui n'est pas conforme à XML. Ton moteur XSLT n'est sans doute pas capable de s'adapter à ça pour produire l'indentation.
    Ajoute un élément racine, après tout il n'y a pas de raison d'enlever le <settings>. Sans ça, ce n'est pas un document XML de toute façon.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    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 suggère de penser avec plus de vigeur et rigeur sur quel template est appelé pas quel d'autre. Comme ça ce serait mois confus.

    Ligne #9
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <!--
    <xsl:apply-templates select="/settings/settinggroup">
    -->
    <xsl:apply-templates select="settinggroup">
    Ligne #14
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <!--
    <xsl:template match="/settings/settinggroup">
    -->
    <xsl:template match="settinggroup">
    Ligne #19
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <!--
    <xsl:apply-templates select="*|@*"/>
    -->
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="setting">
        <xsl:sort select="@name" />
    </xsl:apply-templates>
    Lignes #20
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <!--
    <xsl:template match="/settings/settinggroup/setting">
    -->
    <xsl:template match="setting">

  4. #4
    Membre habitué
    Inscrit en
    Août 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 11
    Par défaut
    J'ai bien tout suivi et appliqué correctement les corrections proposées par tsuji.
    J'obtiens ça :

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
      <xsl:output method="xml" indent="yes"/>
      <xsl:strip-space elements="*"/>
     
      <xsl:template match="/settings">
        <settings version="1400" exported="1178692706">
          <xsl:apply-templates select="settinggroup">
            <xsl:sort select="@name"/>
          </xsl:apply-templates>
        </settings>
      </xsl:template>
     
      <xsl:template match="settinggroup">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="setting">
            <xsl:sort select="@name" />
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
     
      <xsl:template match="setting">
        <xsl:copy>
          <xsl:apply-templates select="*|@*"/>
        </xsl:copy>
      </xsl:template>
     
      <xsl:template match="*|@*">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
      </xsl:template>
     
    </xsl:stylesheet>
    Je pense que là, la sortie est correcte.
    Merci.

    Cependant toujours pas d'indentation en sortie. J'utilise la commande DOS msxml.exe pour produire le fichier XML trié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    msxsl settings.xml tri.xsl -o result.xml
    Mais c'est un détail. J'indenterai avec un éditeur XML.

    Je vais quand même marquer le sujet comme résolu.

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

Discussions similaires

  1. Trier un fichier XML
    Par Kreepz dans le forum VB.NET
    Réponses: 4
    Dernier message: 07/08/2014, 16h55
  2. trier un fichier xml dans un ordre précis
    Par xps1616 dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 01/12/2011, 08h23
  3. [XML] Trier les doublons d'un fichier xml
    Par jameson dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 29/11/2010, 10h50
  4. [XML] Lire un fichier XML, le trier et le sauvegarder
    Par sami_c dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 26/08/2010, 16h41
  5. [XSL] Trier un fichier xml
    Par yann290276 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 25/03/2010, 07h41

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