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 :

Transformation Flux XML, problème namespace [XSLT 1.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut Transformation Flux XML, problème namespace

    Rapidement, je transmet un flux XML à l'aide de SOAP. Mon problème est de type XSL et pas Web Service ce qui explique ce post dans ce forum .
    Je transforme donc ce flux à l'aide d'un fichier XSL.
    Voilà mon entrée XML (simplifiée) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <web:testA  xmlns:web="http://lien/">
    	<Livre>Dune</Livre>
    	<Magie>1</Magie>
    	<Useless>INUTILE</Useless>
    </web:testA>
    Le rôle du xsl est de supprimer la balise "Useless", et de renommer la balise "testA" en "test".
    Autre chose, le a un namespace qui peut être variable et que l'on ne connaît pas à l'avance, donc pas forcément "web". J'ai donc fait en sorte que mon xslt prenne en compte ce problème.
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:plop="http://lien/">
     
    	<xsl:output method="xml" encoding="UTF-8" indent="no"
    		standalone="no" omit-xml-declaration="yes" />
    	<xsl:template match="node() | @*"
    		xmlns="http://lien/">
    		<xsl:choose>
    			<xsl:when test="local-name() = 'testA'">
    				<xsl:element name="plop:test">
    					<xsl:apply-templates />
    				</xsl:element>
    			</xsl:when>
    			<xsl:when test="local-name() = 'Livre'">
    				<xsl:element name="Livre">
    					<xsl:apply-templates />
    				</xsl:element>
    			</xsl:when>
    			<xsl:when test="local-name() = 'Magie'">
    				<xsl:element name="Magie">
    					<xsl:apply-templates />
    				</xsl:element>
    			</xsl:when>
    			<xsl:otherwise>
    				<xsl:copy>
    					<xsl:apply-templates select="node() | @*" />
    				</xsl:copy>
    			</xsl:otherwise>
    		</xsl:choose>
    	</xsl:template>
    	<xsl:template match="Useless" />	
    </xsl:stylesheet>
    Et en sortie j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <plop:test xmlns:plop="http://lien/">
    	<Livre xmlns:="http://lien/">Dune</Livre>
    	<Magie xmlns="http://lien/">1</Magie>
     
    </plop:test>
    Mon problème : Je veux faire disparaître les à côté de "Livre" et "Magie" et quoi que je fasse je n'y arrive pas...
    J'aimerai également avoir des avis sur le code du xslt en lui même (notamment pour la gestion du namespace variable).

    Merci d'avance pour votre aide !

  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
    Mon problème : Je veux faire disparaître les
    xmlns:="http://lien/"
    La mesure minimale à prendre pour le faire disparâitre est de corriger les lignes #7-8 en enlevant la déclaration pas du tout nécessaire de xmlns.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	<!--
    	<xsl:template match="node() | @*"
    		xmlns="http://lien/">
    	-->
    	<xsl:template match="node() | @*">
    J'aurais écrit le xslt largement differamment: mais je prends conscient de plus en plus que ça serait une question de style personnel qui ne plâit pas tout le monde - même grandement déplâit pour certaines - dont je vais m'épagner de montrer d'une réécriture qui serait fondamentalement différente que la vôtre.

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut
    Effectivement ça marche, et ça résout par ailleurs un problème que j'ai depuis longtemps donc merci car tu m'aides beaucoup plus que ce que tu pensais en répondant !
    Hop résolu

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 635
    Points
    21 635
    Par défaut
    Moi je ne pense pas que c'est une question de style et je ne veux pas que quelqu'un voit ça et pense que c'est la meilleure chose à faire.
    Le premier template, sur match="node() | @*" est bien trop compliqué. Le choose est inutile. Remplacer par :

    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
    <!-- replace *:testA -->
    <xsl:template match="*[local-name() = 'testA']">
      <plop:test>
        <xsl:apply-templates/>
      </plop:test>
    </xsl:template>
     
    <!-- remove namespaces from Livre and Magie -->
    <xsl:template match="*[local-name() = 'Livre' or local-name() = 'Magie']">
      <xsl:element name="{local-name()}">
        <xsl:apply-templates/>
      </xsl:element>
    </xsl:template>
     
    <!-- copy everything else as-is -->
    <xsl:template match="node() | @*">
      <xsl:copy>
        <xsl:apply-templates select="nodes() | @*"
      </xsl:copy>
    </xsl:template>

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut
    En réalité j'ai beaucoup simplifié l'exemple. Il est possible que des lignes ne soient pas forcément connues ce qui explique le choose et otherwise.
    Désolé que le code soit moche Thelvin, je n'ai jamais eu la prétention que des gens pensent qu'ils est "le meilleur possible", au contraire je suis conscient qu'il est pourri.
    Je vais essayer de l'adapter par rapport à ce que tu as écrit

    edit : ça marche parfaitement

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut
    j'ai juste apporté une petite modification pour que les cas inconnus soient pris et ce sans le namespace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="*[local-name() != '' and local-name() != 'testA']">
    		<xsl:element name="{local-name()}">
    			<xsl:apply-templates />
    		</xsl:element>
    	</xsl:template>

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 635
    Points
    21 635
    Par défaut
    Citation Envoyé par bugger31 Voir le message
    Désolé que le code soit moche Thelvin, je n'ai jamais eu la prétention que des gens pensent qu'ils est "le meilleur possible", au contraire je suis conscient qu'il est pourri.
    Pas de quoi s'excuser, mais je tiens à dire quand un code est beaucoup plus compliqué qu'il n'avait besoin de l'être.
    Parce que quand un débutant voit ça ensuite, il se dit que c'est la seule manière de faire, et que XSLT c'est drôlement compliqué.
    XSLT est compliqué, oui, mais pas à ce point-là, pas pour faire ce genre de choses. Alors je le montre.

    Citation Envoyé par bugger31 Voir le message
    j'ai juste apporté une petite modification pour que les cas inconnus soient pris et ce sans le namespace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="*[local-name() != '' and local-name() != 'testA']">
    		<xsl:element name="{local-name()}">
    			<xsl:apply-templates />
    		</xsl:element>
    	</xsl:template>
    Pas compris ce que tu essaies de faire. local-name() ne peut jamais être égal à la chaîne vide.

  8. #8
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut
    L'idée c'est que je ne connais pas forcément toutes mes balises donc je fais un traitement différent.
    En revanche tu as raison, il est stupide de comparer un localname() à une chaine vide (surtout que avec ou sans, le résultat est le même ).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="*[local-name() != 'testA' and local-name() != 'Useless']">
    		<xsl:element name="{local-name()}">
    			<xsl:apply-templates />
    		</xsl:element>
    	</xsl:template>
    Ainsi toutes les balises inconnues sont prises en compte, et sans le namespace (si je ne mets pas le "!='Useless'" la balise ne disparaît pas).
    C''est également plus clair et plus rapide que mettre un "local-name() = " pour chaque balise existante.

  9. #9
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 635
    Points
    21 635
    Par défaut
    D'accord donc tu veux le faire pour toutes les balises sauf ces deux-là.

    Vu que tu as déjà un template pour testA et pour Useless, tu n'as pas besoin de préciser tout ça pour faire un template sur "tous les autres éléments" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:template match="*">
    Ça suffit. Les deux autres templates étant plus spécifiques, ils ont priorité. node() étant moins spécifique, * a priorité.

  10. #10
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 45
    Points
    45
    Par défaut
    Ok, merci pour ton aide

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

Discussions similaires

  1. [XSLT][JavaScript] Transformation à partir d'un flux xml
    Par tatemilio2 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 21/07/2009, 11h16
  2. Lire un flux XML : problème d'adresse.
    Par sliderman dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 12/06/2008, 17h10
  3. [JDOM] Problème d'accents à la lecture d'un flux XML
    Par mofovox dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 06/04/2007, 11h19
  4. [XSLT] Transformer un xml en HTML : problème sur les liens
    Par elhout dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 19/03/2007, 10h46
  5. problème dans la transformation du XML
    Par Edta dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 09/11/2006, 10h20

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