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 :

Namespace xsl cop-of


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut Namespace xsl cop-of
    Bonjour,
    J'ai un problème de namespace xsl.
    Je voudrais copier les éléments d'un xml pour générer un xml comme suit:

    XML d'entrée:
    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
     
    <autnresponse xmlns:autn="http://mon.namespace1.com/">
        <responsedata>
            <autn:numhits>10</autn:numhits>
            <autn:totalhits>490</autn:totalhits>
            <autn:hit>
                <autn:content>
                    <DOCUMENTS>
                       <DOCUMENT>
                           <SOME_TAG/>
                       </DOCUMENT>
                    </DOCUMENTS>
                </autn:content>
            </autn:hit>
           </responsedata>
    </autnresponse>
    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
     
    Il me faudrait générer un xml de la sorte:
    <?xml version="1.0" encoding="utf-8"?>
    <searchResults xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns="http://mon.namespace2.com/search"
                   xsi:schemaLocation="http://mon.namespace2.com/search    file:somewhere_on_computer.xsd">
       <numhits>10</numhits>
       <totalhits>490</totalhits>
       <language/>
       <result>
          <content>
                   <DOCUMENT>
                         <SOME_TAG/>
                    </DOCUMENT>
           </content>
       </result>
    </searchResults>
    Comme vous pouvez le voir, le contenu du tag <content> contient tous les noeuds présents dans <autn:content>/<DOCUMENTS>, sauf que le namespace de ceux est devenu celui par default: http://mon.namespace2.com/search alors qu'avant il avait le ns par default null (car pas de déclaration xmlns="...").

    Pour ce faire, j'utilise la xsl 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:autn="http://mon.namespace1.com/"
        xmlns="http://mon.namespace2.com/search"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        exclude-result-prefixes="autn" version="2.0">
        <xsl:output method="xml" encoding="utf-8" indent="yes" />
     
       <xsl:template match="/">
            <searchResults xsi:schemaLocation="file:somewhere_on_computer.xsd">
                <numhits><xsl:value-of select="//autn:numhits"/></numhits>
                <totalhits><xsl:value-of select="//autn:totalhits"/></totalhits>
                <xsl:apply-templates select="//autn:hit"/>
            </searchResults>
        </xsl:template>
     
        <xsl:template match="//autn:hit">
            <result >
                <content >
                    <xsl:apply-templates select="//DOCUMENTS/"/>
                </content>
            </result>		
        </xsl:template>
     
        <xsl:template match="DOCUMENTS">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:template>
     
         <xsl:template match="@* | node()">
            <xsl:copy copy-namespaces="no" >
                <xsl:copy-of select="@*"  />
                <xsl:apply-templates select="node()" >
                    <xsl:sort select="name()"/>
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>
     
    </xsl:stylesheet>
    ce qui me génère
    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
     
    Il me faudrait générer un xml de la sorte:
    <?xml version="1.0" encoding="utf-8"?>
    <searchResults xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns="http://mon.namespace2.com/search"
                   xsi:schemaLocation="http://mon.namespace2.com/search    file:somewhere_on_computer.xsd">
       <numhits>10</numhits>
       <totalhits>490</totalhits>
       <language/>
       <result>
          <content>
                   <DOCUMENT xmlns="">
                         <SOME_TAG/>
                    </DOCUMENT>
           </content>
       </result>
    </searchResults>
    Donc le tag Document possède le namespace vide, mais je voudrais qu'il possède le ns par défaut:"http://mon.namespace2.com/search"

    A cause de cela ma validation xsd ne passe pas.

    Quelqu'un connait il un moyen pour faire cela?

    Je précise que je n'ai pas la main sur le xml d'entrée.

    Merci d'avance

  2. #2
    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
    Modifiez cette partie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         <xsl:template match="@* | node()">
            <xsl:element name="{local-name()}" namespace="http://mon.namespace2.com/search">
                <xsl:copy-of select="@*"  />
                <xsl:apply-templates select="node()" >
                    <xsl:sort select="name()"/>
                </xsl:apply-templates>
            </xsl:element>
        </xsl:template>

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Merci pour votre réponse rapide.
    Lorsque je modifie le template j'obtiens une erreur:

    Description: Invalid element name. Invalid QName {}
    URL: http://www.w3.org/TR/xslt20/#err-XTDE0820
    Je modifie de nouveau le template par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        <xsl:template match="@* | node()">
            <xsl:if test="string-length(local-name()) > 0">
                <xsl:element name="{local-name()}" namespace="http://mon.namespace2.com/search">
                <xsl:copy-of select="@*"  />
                <xsl:apply-templates select="node()" >
                    <xsl:sort select="name()"/>
                </xsl:apply-templates>
            </xsl:element>
            </xsl:if>
        </xsl:template>
    ce qui fonctionne. Cependant je ne comprends pas pourquoi, à certains moments, le local-name() est vide, j'ai l'impression qu'il passe trop de fois dans le template. Avez-vous une idée?

    Merci d'avance,

    Bien à vous.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Je viens de comprendre. En réalité, en les différents noeuds, le retour à la ligne est considéré comme un text-node ce qui implique qu'il n'a pas de local-name().

    Il faut rajouter une partie de code:
    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
     
        <xsl:template match="@* | node() ">
            <xsl:choose>
                <xsl:when test="string-length(local-name()) > 0">
                    <xsl:element name="{local-name()}" namespace="http://mon.namespace2.com/search">
                        <xsl:copy-of select="@*"  />
                        <xsl:apply-templates select="node()" >
                            <xsl:sort select="name()"/>
                        </xsl:apply-templates>
                    </xsl:element>
                </xsl:when>
                <xsl:when test="string-length(normalize-space(.))>0">
                    <xsl:value-of select="normalize-space(.)"/>
                </xsl:when>
            </xsl:choose>
        </xsl:template>
    Je suis pas sur que la solution soit très propre cependant.

  5. #5
    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 dirais changer node() à *. La raison de n'avoir local-name() c'est que le contexte soit un text().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <xsl:template match="@* | * ">
        <!-- etc... -->
    </xsl:template>

  6. #6
    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
    Remarque, il faudrait peut-être enlever le traitement des attributs @* aussi.
    Là il n'y en a pas donc ça fait pas de différence, m'enfin...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    Mettons un issue plus focalisant sur les templates, je proposerais ceci.

    D'abord je prefère rajouter un attribut mode pour ces templates specialisés. Puis, je propose isoler les attributs pourque vous pouvez rajouter plus de specialisation pasque en cas général, il est tout à fait possible ils soient dans une espace différente. En tout cas, c'est applicable pour beaucoup de cas possibles de semble structure.

    Pour entamer le mode.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <xsl:template match="DOCUMENTS">
        <xsl:apply-templates select="@*|*|text()" mode="ns-transpose" />
    </xsl:template>
    Et puis, trois templates spécialisés.
    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
     
    <xsl:template match="*" mode="ns-transpose">
        <xsl:element name="{local-name()}" namespace="http://mon.namespace2.com/search">
            <xsl:apply-templates select="@*|text()" mode="ns-transpose" />
            <xsl:apply-templates select="*" mode="ns-transpose">
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*" mode="ns-transpose">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="." />
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="text()" mode="ns-transpose">
        <xsl:value-of select="." />
    </xsl:template>

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Merci pour votre aide, le problème est donc clos.

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

Discussions similaires

  1. [XSL] Comment générer un préfixe pour un namespace "inconnu"?
    Par GentooGeek dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 12/07/2006, 09h13
  2. [xsl] namespace dans le html apres transformation xslt...
    Par -ADX- dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 15/05/2006, 14h16
  3. Importer via asp.net c# des variables dans mon namespace xsl
    Par akaii dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 23/01/2006, 08h41
  4. xsl:Template sur un élément sans namespace
    Par dust45 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 27/10/2005, 16h52
  5. [XSLT]petit(s) pb(s) avec les xmlns et <xsl:namespace-ali
    Par Swoög dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 08/01/2005, 17h04

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