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 :

Comparaison de chaînes de caractères dans deux fichiers XML, puis insertion de données issues du 2ème fichier [XSLT 2.0]


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut Comparaison de chaînes de caractères dans deux fichiers XML, puis insertion de données issues du 2ème fichier
    Bonjour à tous,

    Je cherche à modifier un fichier XML, et en créer un nouveau en output grâce à de l'XSLT, dans lequel seraient insérées des données contenues dans un second fichier XML.
    Pour cela, j'ai besoin de comparer le contenu d'éléments de chacun des fichiers.

    Pour mieux comprendre, voici des extraits des fichiers en question :

    Le premier :


    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"?>
     
    <DICTIONNAIRE departement="Ain" dep="01">
     
    <article id="1" pg="1">
    <vedette><sm>Abergement (L'),</sm></vedette>
    <definition><typologie>maison isolée</typologie>, <localisation>commune de Forens</localisation>.</definition>
    </article>
     
    <article id="2" pg="1">
    <vedette><sm>Abergement-Clémenciat (L'),</sm></vedette>
    <definition><typologie>commune</typologie> du <localisation>canton de Châtillon-sur-Chalaronne</localisation>.</definition>
    <commentaire><p>Cette commune fut formée, en <date>1857</date>, des anciennes paroisses de l'Abergement et de Clémenciat qui dépendaient auparavant de la commune de Châtillon-sur-Chalaronne.</p></commentaire>
    <forme_ancienne>- <i>Châtillon-les-Dombes : l'Abergement, hameau ; Clémenciat, hameau,</i> <date>1847</date> <reference>(stat. post.)</reference>.</forme_ancienne>
    </article>
     
    </DICTIONNAIRE>
    Le second :

    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"?>
    <communes_dt>
        <toponyme>
            <CODE_DEPT>01</CODE_DEPT>
            <DEPARTEMENT>Ain</DEPARTEMENT>
            <COMMUNE_DT>Abergement-Clémenciat (L')</COMMUNE_DT>
            <NOM_COMMUNE>L'ABERGEMENT-CLEMENCIAT</NOM_COMMUNE>
            <INSEE>01001</INSEE>
        </toponyme>
        <toponyme>
            <CODE_DEPT>01</CODE_DEPT>
            <DEPARTEMENT>Ain</DEPARTEMENT>
            <COMMUNE_DT>Abergement-de-Varey (L')</COMMUNE_DT>
            <NOM_COMMUNE>L'ABERGEMENT-DE-VAREY</NOM_COMMUNE>
            <INSEE>01002</INSEE>
        </toponyme>
    </communes_dt>

    Je souhaiterais donc ici par exemple insérer le code INSEE de la commune de L'Abergement-Clémenciat (<INSEE>01001</INSEE> dans le second fichier) dans l'élément <article> correspondant à cette commune dans mon premier fichier, après avoir procédé à une comparaison de chaînes de caractères (du contenu de<vedette><sm> dans le premier fichier et de <COMMUNE_DT> dans le second), mais je ne sais pas comment faire...

    Je suppose qu'il faut utiliser xsl:document, xsl:analyze-string et des expressions régulières, mais j'avoue que je suis un peu perdue...

    Si quelqu'un a une idée qui pourrait m'aider, je lui serais très reconnaissante !

    Merci par avance !

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Hello,

    Citation Envoyé par Kamkamy Voir le message
    Je suppose qu'il faut utiliser xsl:document,
    Non. On utilise xsl:document quand on veut produire plusieurs documents. Or, si je ne me trompe pas, tu veux juste produire une seule version modifiée de ton document de départ. Aucune raison de faire du xsl:document.

    Par contre, tu vas avoir besoin de la fonction XPath document(), qui va lire des données dans un autre document que celui que tu es en train de transformer.

    Citation Envoyé par Kamkamy Voir le message
    xsl:analyze-string et des expressions régulières
    Je vois pas trop l'intérêt. Peut-être à la rigueur pour se débarrasser de la virgule à la fin du <sm>. Mais tu pourrais peut-être le faire avec substring(), et surtout tu pourrais ajouter une virgule au lieu d'en enlever une.

    Bon, faisons un exemple.

    Si j'ai un document XML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <root>
      <a name="fleur"/>
      <a name="arbre"/>
    </root>
    et que je veux le compléter avec le document de référence reference.xml situé dans le même répertoire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <reference>
      <b name="buisson">nourriture ornement</b>
      <b name="arbre">nourriture ornement opacité bois</b>
      <b name="fleur">ornement</b>
      <b name="herbe">pâturage</b>
    </reference>
    pour que ça donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <root>
      <a name="fleur">ornement</a>
      <a name="arbre">nourriture ornement opacité bois</a>
    </root>
    On peut le faire avec cette feuille de style :

    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:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     
      <!-- copy as-is template -->
      <xsl:template match="node() | @*">
        <xsl:copy>
          <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
      </xsl:template>
     
      <!-- template for the element to modify -->
      <xsl:template match="a">
        <xsl:copy>
          <xsl:copy-of select="@*"/> <!-- copy attributes -->
     
          <!-- insert info completion -->
          <xsl:value-of select="document('reference.xml')/reference/b[@name = current()/@name]"/>
        </xsl:copy>
      </xsl:template>
     
    </xsl:stylesheet>
    Avec cet exemple, tu as tout ce qu'il faut. Plus qu'à adapter à ta situation.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut
    Merci beaucoup pour votre aide @thelvin !!!

    Du coup j'ai fait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        <xsl:template match="article">
            <xsl:copy>
                <xsl:copy-of select="node() | @*"/>
                <xsl:if test="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/COMMUNE_DT = current()/vedette/sm">
                    <xsl:element name="insee">
                        <xsl:value-of select="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/INSEE[preceding-sibling::COMMUNE_DT = current()/vedette/sm]"/>
                    </xsl:element>
                </xsl:if>
            </xsl:copy>
        </xsl:template>
    Et ça fonctionne !

    Encore merci !

  4. #4
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut
    Bonjour, c'est encore moi !

    Maintenant je souhaiterais ajouter un attribut @ref dans l'élément <article> pour tous les lieux qui ne sont pas des communes, et qui comportent l'élément <localisation>commune de...</localisation>. Cet attribut @ref ferait référence à l'id de l'article concernant la commune que l'on retrouve dans <localisation> (désolée, c'est un peu compliqué).

    Du coup j'ai complété mon précédent code avec ça (le 2ème <xsl:if>) :

    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
    <xsl:template match="article">
            <xsl:copy>
                <xsl:copy-of select="node() | @*"/>
                <xsl:if test="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/COMMUNE_DT = current()/vedette/sm">
                    <xsl:element name="insee">
                        <xsl:value-of select="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/INSEE[preceding-sibling::COMMUNE_DT = current()/vedette/sm]"/>
                    </xsl:element>
                </xsl:if>
                <xsl:if test="contains(definition/localisation,vedette/sm)">
                    <xsl:attribute name="ref">
                        <xsl:value-of select="vedette[@id]"/>
                    </xsl:attribute>
                </xsl:if>
            </xsl:copy>
        </xsl:template>
    Mais oXygen me met ce message d'erreur : "Creating an attribute here will fail if previous instructions create any children"...

    Pourquoi ça ne marche pas ? Qu'est-ce que je dois faire ?

    Merci encore d'avance !

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Hello,

    Je te suggère de nous donner une traduction française, faite par tes soins, du message d'erreur que donne oXygen. Nous verrons si cela mène quelque part.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut
    Je traduirais ça comme ça :

    Créer un attribut ici échouera si les instructions précédentes créent un enfant

  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
    Mais oXygen me met ce message d'erreur : "Creating an attribute here will fail if previous instructions create any children"...
    D'abord, ça n'est pas oXygen spécifique si ça pourrait induire quelqu'un à penser, c'est tout-à-fait générique. Cela veut dire qu'on ne peut pas faire appeler à un constructeur d'attribut pour un élément après que les enfants du type d'élément ou de text() de ce même élément parental soient construits, complètement ou partiellement pareillement.

    Dans ce cas-ci, il faut remonter le constructeur de @ref avant <xsl:copy-of select="*|text()" /> et <xsl:element name="insee"> etc... concrètement comme ça.
    Code xslt : 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
    <xsl:template match="article">
            <xsl:copy>
     
                <xsl:if test="contains(definition/localisation,vedette/sm)">
                    <xsl:attribute name="ref">
                        <xsl:value-of select="vedette[@id]"/>
                    </xsl:attribute>
                </xsl:if>
     
                <xsl:copy-of select="node() | @*"/>
     
                <xsl:if test="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/COMMUNE_DT = current()/vedette/sm">
                    <xsl:element name="insee">
                        <xsl:value-of select="document('../Fichiers_XML/appariement.xml')/communes_dt/toponyme/INSEE[preceding-sibling::COMMUNE_DT = current()/vedette/sm]"/>
                    </xsl:element>
                </xsl:if>
     
            </xsl:copy>
        </xsl:template>
    Je n'ai pas envie de commenter sur vedette[@id], je ne sais pas quoi il est, et en tout cas ce n'est pas clairement démontrer, prenant l'échantillon du document posté.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 09/11/2015, 13h14
  2. [XL-2013] Récupérer des données issues d'un fichier XML en ligne
    Par pierrotjj dans le forum Excel
    Réponses: 4
    Dernier message: 08/09/2015, 11h13
  3. Réponses: 1
    Dernier message: 30/07/2009, 15h32
  4. regénération d'un fichier xml et insertion des donnés
    Par totomimi dans le forum Format d'échange (XML, JSON...)
    Réponses: 0
    Dernier message: 24/06/2009, 18h42
  5. Fichier XML et insertion de données
    Par will2taz dans le forum VB.NET
    Réponses: 0
    Dernier message: 04/09/2007, 10h35

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