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'indentation dans XML de sortie [XSLT 2.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut Problème d'indentation dans XML de sortie
    Voilà,
    J'ai un xml que je souhaite modifier. Je l'appelle ici xmlSource.
    J'ai un xml qui contient des descriptions (balises Description) pour certains nœuds. Je l'appelle ici xmlDescr

    L'idée est de recréer exactement le xmlSource avec des balises Descriptions qui viennent de xmlDescr. La difficulté est que dans xmlSource, il n'y a pas forcément un nœud Description pour les balises concernés. Dans ce cas il faut en créé une.
    Donc en résumé :
    - Si xmlSource contient une balise Description pour le nœud à modifier, la remplace
    - Si xmlSource ne contient pas de balise Description pour le nœud concerné

    Je précise que le nœud précédent porte le nom 'nom'.

    Voici la gueule de mon xslt :

    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE xsl:stylesheet [
      <!ENTITY nl "<xsl:text>
      </xsl:text>">
    ]>
     
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" standalone="no"/>
     
        <xsl:template match="@* | //* " priority="1">
          <xsl:if test="not(name() = 'Description')">
            <xsl:copy>
              <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
          </xsl:if>
        </xsl:template>
     
      <xsl:template match="//*[name() = 'nom']" priority="2">
        <Nom><xsl:value-of select="."/></Nom>&nl;
        <Description>C'est bien ici</Description>
      </xsl:template>
     
    </xsl:stylesheet>
    Petite précision :
    Peut être il y a mieux mais il faut être indulgent avec moi car c'est mon premier xslt, mon idée est de recopier tous les nœud sauf le nœud description puis remplacer le nœud 'nom' par le nœud 'nom' et du nœud Description (avec un saut de ligne entre les deux).

    Bon,
    si j'ai le xml suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <?xml version="1.0" encoding="utf-8"?>
    <test>
      <test1>toto</test1>
      <autre>
        <nom>essai</nom>
        <Description>titi</Description>
      </autre>
    </test>
    La sortie me donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <test>
      <test1>toto</test1>
      <autre>
        <Nom>essai</Nom>
      <Description>C'est bien ici</Description>
     
      </autre>
    </test>
    Le résultat est conforme à ce que j'attendais sauf que le nœud Description est mal indenté et quand les balise Description et fin de balise autre, se trouve un espace parasite.

  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
    [0] Si on veut faire un formatage exact via xslt, on est souvent handicapé par les bugs et/ou les comportements dépendant des implémentations. Donc, il faut prendre conscience de ça si on rencontre parfois des surprises.

    [1] Vous avez utilisé @priority et c'est bien. Mais il faut savoir que le deuxième template, étant plus réstrictif que le premier, a automatiquement acquis une priorité plus élevée que le premier, même sans @priority.

    [2] Je peux vous montrer comment faire d'une meilleure façon - mais c'est toujours relative en fin de compte.
    Code xml : 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
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="no" />
    <xsl:strip-space elements="*" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[name()='nom']">
        <xsl:choose>
            <xsl:when test="following-sibling::*[1][name()='Description']">
                <xsl:element name="Nom">
                    <xsl:apply-templates select="@*|node()" />
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="Nom">
                    <xsl:apply-templates select="@*|node()" />
                </xsl:element name="Nom">
                <xsl:element name="Description">
                    <xsl:text>C&apos;est bien ici.</xsl:text>
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    </xsl:stylesheet>

    [2.1] Si le formatage a réussite, ce qui n'est pas 100% sûr, il faut remarquer l'emploi de xsl:strip-space et indent="yes" en combinaison. Ca peut être inattendu.

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    La première chose à faire serait surtout d'enlever cette entité &nl; et de compter uniquement sur indent="yes" pour voir ce que ça donne.

    Ça devrait régler le problème avec un bon moteur XSLT. Si ça ne suffit pas, je dirais qu'il suffit de copier les nœuds textes qui séparent les éléments du document original. Ils sont correctement indentés, eux.

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    @tsuji : Merci : votre code est déjà plus joli que le mien mais il faut être indulgent avec moi, c'est mon premier xslt.
    A défaut d'avoir des balises correctement indentées et en enlevant xsl:strip-space, je pense que votre code enlèverait déjà le saut à la ligne entre la balise Description et la fin de balise autre. (Je vais le tenter et vous dire ce qu'il en ressort).

    @thelvin : En fait pour être tout à faire honnête, je me doutais qu'en introduisant &nl; j'allais probablement avoir un problème de ce genre mais si je ne le mettait pas et même en passant à la ligne entre les deux balises Nom de Description tout était collé. Après c'est peut être mon processeur xlst qui n'est pas terrible. (Celui de MS dans Visual Studio et en plus j'ai appris qu'il ne supporte pas le XSLT 2.0 ce qui me pose d'autres problèmes...)

  5. #5
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    Ca marche !

    J'y ai apporté quelques petites modifications (voire votre code modifié) mais ça marche !

    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
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="no" />
    <!--xsl:strip-space elements="*" /-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|*[name()!='Description]" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[name()='nom']">
        <xsl:choose>
            <xsl:when test="following-sibling::*[1][name()!='Description']">
                <xsl:element name="Nom">
                    <xsl:apply-templates select="@*|node()" />
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="Nom">
                    <xsl:apply-templates select="@*|node()" />
                </xsl:element name="Nom">
                <xsl:element name="Description"><xsl:text>C&apos;est bien ici.</xsl:text></xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    </xsl:stylesheet>
    J'ai tout mis Description sur la même ligne, sinon il avait tendance à mettre ma fin de balise sur la ligne suivante et oublier un peu l'indentation.

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

Discussions similaires

  1. Parser dans XML les sorties STDERR
    Par Koiky dans le forum Programmation et administration système
    Réponses: 5
    Dernier message: 23/02/2015, 18h30
  2. [SOAP] Structure d'Array, problème ajout valeur dans xml
    Par tidus_6_9_2 dans le forum Langage
    Réponses: 1
    Dernier message: 11/01/2013, 16h27
  3. Réponses: 3
    Dernier message: 17/11/2010, 21h20
  4. Problème d'écriture dans un fichier xml
    Par vanoou dans le forum C++Builder
    Réponses: 1
    Dernier message: 13/07/2005, 02h28
  5. Réponses: 2
    Dernier message: 01/06/2004, 12h47

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