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 :

Copie filtrée copy/element


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Russie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 14
    Par défaut Copie filtrée copy/element
    Bonjour,
    A partir du fichier XML suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?xml version="1.0"  ?>
    <?xml-stylesheet href="monfichier.xsl" type="text/xsl" ?>
    <a>
    <ab x="x"><b>Test</b><a>z</a></ab>
    <z x="x"><a>z</a></z>
    </a>
    Je cherche à obtenir une copie filtrée (le même fichier sans la déclaration xml-stylesheet et avec uniquement les éléments dont le nom contient “a”):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <a>
    <ab x="x"><a>z</a></ab>
     
    </a>
    Pour ça, j’examine les différences entre deux solutions possibles, les instructions ‘copy’ et ‘element’ :

    AVEC COPY :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>
    <xsl:variable name="var" select="//[contains(name(),'a')]"/>
    <xsl:template match="/">
    <xsl:copy select="$v"/>
    </xsl:template>
    </xsl:stylesheet>
    Avec un ‘if’ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>
    <xsl:template match="/">
    <xsl:if test="*[contains(name(),'a')]">
    <xsl:copy select="."/>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>
    AVEC ELEMENT:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>
    <xsl:variable name="ele" select="//[contains(name(),'a')]"/>
    <xsl:template match="/">
    <xsl:element name="{$ele}"/>
    </xsl:template>
    </xsl:stylesheet>
    Malheureusement, les deux codes me renvoient la même erreur dans Firefox :
    « Erreur lors du chargement de la feuille de style : Échec de l'analyse XPath : test de Name ou de Nodetype attendu: »

    Je dois dire que je ne comprends pas !!

    Merci pour vos lumières !

  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
    Oui, on ne peut pas mettre de [ et ] juste après un /
    Il faudrait d'abord sélectionner des nœuds, avec par exemple * ou un nom d'élément, puis après seulement mettre le prédicat.

    Mais bon peu importe. Une variable ne va pas stocker là où sont les nœuds, et en gros ta méthode n'a pas de sens.

    Voici un code pour ne garder que les balises <a>. Tu peux l'adapter à ton problème :

    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
    <xsl:template match="a">
      <!-- reproduire élément de même nom -->
      <xsl:copy>
        <!-- copier les attributs-->
        <xsl:copy-of select="@*"/>
     
        <!-- traiter le contenu de l'élément -->
        <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template>
     
    <xsl:template match="text()">
      <!-- Ne rien faire : ignorer les textes -->
    </xsl:template>
     
     
    <!-- Mais copier les textes dont le parent est un <a> -->
    <xsl:template match="a/text()">
      <xsl:copy/>
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Russie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 14
    Par défaut Filtre avec xsl:element
    Merci pour votre aide Thelvin ! Je souhaiterais en fait utiliser xsl:element (plutôt que copy) pour effectuer un filtre (afin dans un second temps ajouter de nouvelles informations et pas seulement en soustraire). J'ai essayé une autre version dérivé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
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
     
    <xsl:template match="node()">
     
    <xsl:element name=".">
    <xsl:apply-templates select="node()|@*"/>
    <xsl:element/>
    </xsl:template>
     
    <xsl:template match="text()">
    <xsl:value-of select="."/>
    </xsl:template>
     
    <xsl:template match="@*">
    <xsl:attribute name="{name()}">
    <xsl:value-of select="."/>
    </xsl:attribute>
    </xsl:template>
     
    <xsl:template match="//*[not(contains(name(),'a'))]"></xsl:template>
    </xsl:stylesheet>
    Merci pour vos lumières !

  4. #4
    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
    Et concrètement, qu'est-ce qui ne va pas avec cette version dérivée ? Elle ne ressemble pas du tout à ce que j'ai montré, du coup je ne comprends pas ce que tu veux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Russie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 14
    Par défaut Filtre avec xsl:element (plutôt que xsl:copy)
    Bonjour, le code que vous m’avez proposé permet effectivement de copier les balises ‘a’ avec ce résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="windows-1252"?>
    <a>
    	<a>z</a>
     
    	<a>z</a>
    </a>
    L’idée est en fait de sélectionner les balises dont le nom contient ‘a’ (comme les balises ‘ab’) mais aussi d’exclure les balises qui seraient imbriquées dans des balises qui ne correspondraient pas à ce schéma.

    J’ai pris le problème autrement avec :

    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
    <xsl:template match="node()">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    <xsl:template match="text()">
    <xsl:value-of select="."/>
    </xsl:template>
    <xsl:template match="@*">
    <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>
    <xsl:template match="//*[not(contains(name(),'a'))]"></xsl:template>
    </xsl:stylesheet>
    Ce qui me donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="windows-1252"?>
    <?xml-stylesheet href="source4_fichiers/monfichier.xml" type="text/xsl"?>
    <a>
    	<ab x="x">
     
    		<a>z</a>
    	</ab>
     
     
    </a>
    Je voudrais utiliser xsl:element plutôt que xsl :copy afin de pouvoir ajouter de nouvelles informations et pas seulement en soustraire. J’ai donc essayé le même code avec une simple substitution des balises xsl:copy par des balises xsl:element :
    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
    <xsl:template match="node()">
    <xsl:element>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
    </xsl:template>
    <xsl:template match="text()">
    <xsl:value-of select="."/>
    </xsl:template>
    <xsl:template match="@*">
    <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>
    <xsl:template match="//*[not(contains(name(),'a'))]"></xsl:template>
    </xsl:stylesheet>
    Mais cela me donne l’erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur lors du chargement de la feuille de style : Échec de l'analyse d'une feuille de style XSLT.
    Je ne comprends pas pourquoi il doit y avoir des contraintes de syntaxe différentes.

    Merci pour vos lumières !

  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
    D'accord, je vois que ma première proposition ne répondait pas à l'exemple donné (ça n'aurait pourtant pas été compliqué de me montrer où en rouge gras.)

    Citation Envoyé par radulew Voir le message
    Je voudrais utiliser xsl:element plutôt que xsl :copy afin de pouvoir ajouter de nouvelles informations et pas seulement en soustraire
    Modifier, je pourrais encore comprendre. Mais ajouter, je ne vois pas ce qui t'en empêche avec <xsl:copy>
    Citation Envoyé par radulew Voir le message
    Je ne comprends pas pourquoi il doit y avoir des contraintes de syntaxe différentes.!
    Le nom de l'élément à créer, ne va pas sortir de nulle part. Il va bien falloir que tu lui dises.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Russie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 14
    Par défaut Filtre avec xsl:element (plutôt que xsl:copy)
    Voilà qui fonctionne pas mal ! Un grand merci à vous Thelvin !

    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
    <xsl:template match="node()">
    <xsl:element name="{name(.)}">
    <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
    </xsl:template>
    <xsl:template match="text()">
    <xsl:value-of select="."/>
    </xsl:template>
    <xsl:template match="@*">
    <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>
    <xsl:template match="//*[not(contains(name(),'a'))]"></xsl:template>
    </xsl:stylesheet>

  8. #8
    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
    Ben du coup, <xsl:copy> fonctionne encore mieux -_-°.
    Tu n'as rien fait que tu ne pouvais pas faire avec. Mais tu le fais en te compliquant la vie
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Russie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 14
    Par défaut Filtre avec xsl:element (plutôt que xsl:copy)
    Ok et en deux mots, à quoi est-ce que vous réserveriez l'usage de <xsl:element> ? dans quelles conditions/situations est-ce que vous l'utiliseriez? Quel est son intérêt et sa spécificité? Je me référais à cela : http://infohost.nmt.edu/tcc/help/pub...l-element.html Mais effectivement, cette page web ne motive pas ce choix.

  10. #10
    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
    Créer des éléments dont le nom est calculé dynamiquement et n'est pas copié de l'élément en cours.

    Normalement on n'en a pas besoin à moins de faire dans le vraiment, vraiment compliqué.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. [XL-2007] Erreur 1004, Filtre + copie
    Par iperkut dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 10/12/2010, 15h17
  2. Macro filtre copie erronée
    Par kikim78 dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 03/11/2009, 08h20
  3. multiplication des copies et copie de copie
    Par rogerone dans le forum Excel
    Réponses: 1
    Dernier message: 29/03/2009, 16h23
  4. [JDOM] Copie d'un element vers un nouveau document
    Par Le Singe dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 08/03/2006, 12h00

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