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 :

L'ajout d'un namespace fait perdre un attribut [XSLT 1.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut L'ajout d'un namespace fait perdre un attribut
    Bonjour,

    J'ai un fichier XML de départ que je désire transformer en un autre fichier XML.
    Au départ, je n'ai pas de namespace et je désire ajouter un namespace.
    Voici mon fichier XML de départ
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <Document>
    		<PmtInf>
    			<ReqdColltnDt>2018-03-18</ReqdColltnDt>
    			<DrctDbtTxInf>
    				<PmtId>
    					<EndToEndId>voice0116</EndToEndId>
    				</PmtId>
    				<!-- Attention cet element a un Attribut ! ! -->
    				<InstdAmt Ccy="EUR">1242.19</InstdAmt>
    			</DrctDbtTxInf>
    		</PmtInf>
    		<PmtInf>
    			<ReqdColltnDt>2018-03-19</ReqdColltnDt>
    			<DrctDbtTxInf>
    				<PmtId>
    					<EndToEndId>voice0349</EndToEndId>
    				</PmtId>
    				<InstdAmt Ccy="EUR">1055.12</InstdAmt>
    			</DrctDbtTxInf>
    			<DrctDbtTxInf>
    				<PmtId>
    					<EndToEndId>voice0143</EndToEndId>
    				</PmtId>
    				<InstdAmt Ccy="EUR">750.32</InstdAmt>
    			</DrctDbtTxInf>
    		</PmtInf>
    </Document>
    Comme vous le voyez, la racine est simplement <Document>
    Je désire obtenir une racine comme ceci <Document xmlns="urn:iso:std:iso:202:tech">
    Pour y parvenir, j'applique la transformation xslt suivante
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<!-- <xsl:strip-space elements="*"/> -->
    	<xsl:output method="xml" indent="yes" encoding="utf-8"/>
     
    	<xsl:template match="*[ancestor::Document]">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:iso:202:tech">
    			<xsl:apply-templates select="*|text()"/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="Document|@*">
    		<Document xmlns="urn:iso:std:iso:202:tech">
    			<xsl:apply-templates select="*|text()"/>
    		</Document>
    	</xsl:template>
     
    </xsl:stylesheet>
    Cela fonctionne plutôt bien si ce n'est que je perds l'attribut Ccy
    Voici le résultat que j'obtiens :
    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
    <?xml version="1.0" encoding="utf-8"?>
    <Document xmlns="urn:iso:std:iso:202:tech">
    	<PmtInf>
    		<ReqdColltnDt>2018-03-18</ReqdColltnDt>
    		<DrctDbtTxInf>
    			<PmtId>
    				<EndToEndId>voice0116</EndToEndId>
    			</PmtId>
    			<InstdAmt>1242.19</InstdAmt>
    		</DrctDbtTxInf>
    	</PmtInf>
    	<PmtInf>
    		<ReqdColltnDt>2018-03-19</ReqdColltnDt>
    		<DrctDbtTxInf>
    			<PmtId>
    				<EndToEndId>voice0349</EndToEndId>
    			</PmtId>
    			<InstdAmt>1055.12</InstdAmt>
    		</DrctDbtTxInf>
    		<DrctDbtTxInf>
    			<PmtId>
    				<EndToEndId>voice0143</EndToEndId>
    			</PmtId>
    			<InstdAmt>750.32</InstdAmt>
    		</DrctDbtTxInf>
    	</PmtInf>
    </Document>
    Mes noeuds InstdAmt ont perdu leur attribut !!
    Là où j'ai <InstdAmt>1242.19</InstdAmt> ,
    j'aurais dû garder<InstdAmt Ccy="EUR">1242.19</InstdAmt>

    Comment puis-je faire pour garder l'attribut Ccy ?

    Merci pour vos explications

  2. #2
    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
    Hello,

    ben quand tu crées un nouvel élément, 'faudrait pas oublier de copier les attributs dedans !

    Un simple <xsl:copy-of select="@*"/> devrait faire l'affaire...

  3. #3
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    OK, Merci.

    Voici donc la solution complète :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?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" encoding="utf-8"/>
    	<xsl:template match="*[ancestor::Document]">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:iso:202:tech">
    			<xsl:apply-templates select="*|text()"/>
    		</xsl:element>
    	</xsl:template>
    	<xsl:template match="Document">
    		<Document xmlns="urn:iso:std:iso:202:tech">
    			<xsl:copy-of  select="*|text()"/>
    		</Document>
    	</xsl:template>
    </xsl:stylesheet>

  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
    Chez moi cela ne fait pas du tout ce que tu as demandé... Seule la racine a un namespace avec ce code. J'imagine, et ton exemple confirmait, que tu voulais que tous les éléments héritent du namespace de la racine.

  5. #5
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    Oui, j'ai repondu un peu trop vite...
    Ce que je viens de publier ne fait pas le job voulu.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <Document xmlns="urn:iso:std:iso:202:tech">  <!-- parfait ! -->
    	<PmtInf xmlns="">        <!--   je ne veux pas de ce xmlns ici -->
    		<ReqdColltnDt>2018-03-18</ReqdColltnDt>
    		<DrctDbtTxInf>
    			<PmtId>
    				<EndToEndId>voice0116</EndToEndId>
    			</PmtId>
    			<InstdAmt Ccy="EUR">1242.19</InstdAmt>   <!-- Parfait : l attribut Ccy est présent -->

  6. #6
    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
    Voilà. Donc plutôt le copy-of que j'ai dit, à l'endroit où j'ai dit (quand tu crées tes éléments !)

  7. #7
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    Je ne comprends pas...
    Le Copy-of ne fait pas l'affaire mais on se rapproche du résultat.
    Cette fois-ci on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="utf-8"?>
    <Document xmlns="urn:iso:std:iso:202:tech">
    	<PmtInf>
    		<ReqdColltnDt>2018-03-18</ReqdColltnDt>
    		<DrctDbtTxInf>
    			<PmtId>
    				<EndToEndId>voice0116</EndToEndId>
    			</PmtId>
    			<InstdAmt>EUR1242.19</InstdAmt>  <!-- c est mieux : il y a EUR mais toujours l attribut Ccy -->
    		</DrctDbtTxInf>
    	</PmtInf>
    J'utilise ce 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
    <?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" encoding="utf-8"/>
     
    	<xsl:template match="*[ancestor::Document]">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:iso:202:tech">
    			<xsl:apply-templates select="@*|*|text()"/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="Document">
    		<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02">
    			<xsl:apply-templates select="@*|*|text()"/>
    		</Document>
    	</xsl:template>
     
    </xsl:stylesheet>
    Si j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:copy-of select="@*"/>
    alors il me met et ça ce n'est pas bon non plus.

  8. #8
    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
    Si tu l'utilises... Où ?

  9. #9
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    Bonjour,

    Voici le XSLT avec copy-of :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?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" encoding="utf-8"/>
    	<xsl:template match="*[ancestor::Document]">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:1.02">
    			<xsl:copy-of select="*"/>
    		</xsl:element>
    	</xsl:template>
    	<xsl:template match="Document">
    		<Document xmlns="urn:iso:std:1.02">
    			<xsl:apply-templates select="*|text()" />
    		</Document>
    	</xsl:template>
    </xsl:stylesheet>
    Par rapport aux versions avec apply-templates, cette version avec copy-of a l'avantage de copier l'attribut Ccy="EUR".
    Il crée bien la racine avec le nouveau namespace mais pour les éléments enfants de Document, il les copie avec l'ancien namespace c'est-à-dire pas de namespace. D'où le xmlns = "".

    Voici ce que ce XSLT me donne :
    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
    <?xml version="1.0" encoding="utf-8"?>
    <Document xmlns="urn:iso:std:1.02">           <!-- Parfait !  -->
    	<PmtInf>
    		<ReqdColltnDt xmlns="">2018-03-18</ReqdColltnDt>    <!-- Mauvais namespace -->
    		<DrctDbtTxInf xmlns="">                                  <!-- Mauvais namespace -->
    			<PmtId>
    				<EndToEndId>voice0116</EndToEndId>
    			</PmtId>
    			<InstdAmt Ccy="EUR">1242.19</InstdAmt>             <!-- Parfait !  -->
    		</DrctDbtTxInf>
    	</PmtInf>
    	<PmtInf>
    		<ReqdColltnDt xmlns="">2018-03-19</ReqdColltnDt>
    		<DrctDbtTxInf xmlns="">
    			<PmtId>
    				<EndToEndId>voice0349</EndToEndId>
    			</PmtId>
    			<InstdAmt Ccy="EUR">1055.12</InstdAmt>
    		</DrctDbtTxInf>
    		<DrctDbtTxInf xmlns="">
    			<PmtId>
    				<EndToEndId>voice0143</EndToEndId>
    			</PmtId>
    			<InstdAmt Ccy="EUR">750.32</InstdAmt>
    		</DrctDbtTxInf>
    	</PmtInf>
    </Document>
    Je ne parviens pas à éliminer ce xmlns=""

    Soit j'ai le bon namespace mas sans l'attribut Ccy="EUR".
    Soit j'ai lattribut Ccy="EUR" correct mais alors j'ai des problèmes de namespace.

    Comment avoir l'un et l'autre corrects ?

    Merci.

  10. #10
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    Bon, comme je ne parviens pas avoir l'un et l'autre, j'ai essayé d'avoir l'un puis l'autre.

    En créant un template supplémentaire et surtout en spécifiant explicitement dans le 3ième § que je veux pour tous les éléments le namespace "urn:iso.." je parviens à mes fins.
    Voici ce que j'ai :
    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
    <?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" version="1.0" encoding="UTF-8" indent="yes"/>
     
    	 <xsl:template match="@*|text()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
     
        <xsl:template match="Document">
    		<Document xmlns="urn:iso:std:1.02">
    			<xsl:apply-templates select="@*|node()" />
    		</Document>
    	</xsl:template>
     
     
    		<xsl:template match="*">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:1.02">
    			<xsl:apply-templates select="@*|node()"/>
    		</xsl:element>
    	</xsl:template>
     
    </xsl:stylesheet>
    Merci encore pour votre aide. ....ensemble, on est plus fort.

  11. #11
    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
    Bon, si tu y arrives...

    Enfin, la solution était de faire exactement ce que j'ai dit et absolument pas autre chose que ça. Dans une feuille XSLT complète ça donne :

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<!-- <xsl:strip-space elements="*"/> -->
    	<xsl:output method="xml" indent="yes" encoding="utf-8"/>
     
    	<xsl:template match="*[ancestor::Document]">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:iso:202:tech">
    			<xsl:copy-of select="@*"/>
    			<xsl:apply-templates select="*|text()"/>
    		</xsl:element>
    	</xsl:template>
     
    	<xsl:template match="Document|@*">
    		<Document xmlns="urn:iso:std:iso:202:tech">
    			<xsl:apply-templates select="*|text()"/>
    		</Document>
    	</xsl:template>
     
    </xsl:stylesheet>
    Ce qui au passage, se simplifie en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<!-- <xsl:strip-space elements="*"/> -->
    	<xsl:output method="xml" indent="yes" encoding="utf-8"/>
     
    	<xsl:template match="*">
    		<xsl:element name="{local-name()}" namespace="urn:iso:std:iso:202:tech">
    			<xsl:copy-of select="@*"/>
    			<xsl:apply-templates select="node()"/>
    		</xsl:element>
    	</xsl:template>
     
    </xsl:stylesheet>

  12. #12
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    466
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 466
    Points : 550
    Points
    550
    Par défaut
    Bonjour,

    Oui, en effet votre solution est bonne et est nettement plus élégante que la mienne. Félicitations.
    Désolé si je n'avais pas compris la première fois.
    Encore merci pour votre précieuse aide.

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

Discussions similaires

  1. probleme de conflit d adresse lors de l ajout d un namespace
    Par ryoussef19 dans le forum VC++ .NET
    Réponses: 7
    Dernier message: 26/04/2007, 09h39
  2. [DOM] Ajout d'un namespace par defaut
    Par DC dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 19/02/2007, 13h29
  3. [Access] un group by qui me fait perdre la tete
    Par gusrom86 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 04/10/2006, 11h37
  4. TweakUI fait perdre ses couleurs a XP.
    Par Bejaia-In dans le forum Windows XP
    Réponses: 3
    Dernier message: 29/05/2006, 18h57
  5. [XHTML] Ajout d'un namespace personnalisé et validation
    Par siddh dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 10/01/2006, 00h29

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