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 de fragment XML basé sur attribut [XSLT 1.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre régulier
    Profil pro
    ERP + Oracle + VBA Excel
    Inscrit en
    Juin 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : ERP + Oracle + VBA Excel
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2005
    Messages : 58
    Points : 78
    Points
    78
    Par défaut Copie de fragment XML basé sur attribut
    Bonjour,

    Je ne trouve pas la bonne méthode pour arriver à filtrer un fichier XML proprement.

    J'ai un fichier avec 4 niveaux : echange = root, puis des noeuds institutions qui contiennent des noeuds structures qui contiennent des noeuds prestations.





    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="ISO-8859-1"?>
    <echange echange_date="2014-11-03">
    	<institution id_tiers="408209644" >
    		<structure id_tiers="408209644" id_structure="299734199" >
    			<prestation id_tiers="408209644" id_structure="299734199" id_prestation="303341377" flag="oui"/>
    		</structure>
    	</institution>
     
    	<institution id_tiers="408210515" >
    		<structure id_tiers="408210515" id_structure="21560434">
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="1254115" flag="oui"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="21560981" flag="non"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="29041603" flag="non"/>
    		</structure>
    	</institution>
     
    </echange>
    Le but est de produire un nouveau xml contenant que l’arborescence qui correspond à flag='oui'
    comme ci-dessous

    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <echange echange_date="2014-11-03">
    	<institution id_tiers="408209644" >
    		<structure id_tiers="408209644" id_structure="299734199" >
    			<prestation id_tiers="408209644" id_structure="299734199" id_prestation="303341377" flag="oui"/>
    		</structure>
    	</institution>
     
    	<institution id_tiers="408210515" >
    		<structure id_tiers="408210515" id_structure="21560434">
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="1254115" flag="oui"/>
    		</structure>
    	</institution>
     
    </echange>
    J'ai utilisé le code ci-après pour "remonter" sur le grand-père, mais du coup j'ai tout les enfants et petit-enfants du noeud, donc mon filtre ne sert plus à rien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:copy-of select="../parent::node()|@*"/>

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 613
    Points
    21 613
    Par défaut
    Hello,

    En effet tu ne peux pas utiliser copy-of, car il fait la copie complète de l'élément avec son contenu, et toi tu veux modifier le contenu.

    À la place tu peux toujours utiliser <xsl:copy>, qui n'a rien à voir.

    Essaie de mettre juste cette règle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
        <toto>J'ajoute toto</toto>
      </xsl:copy>
    </xsl:template>
    Tu remarques que le document a été entièrement copié. Sauf que tous les éléments ont leur contenu changé : il y a une nouvelle balise <toto> dedans.
    Vois si tu arrives à en faire quelque chose pour exclure les <prestation> que tu veux exclure.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Profil pro
    ERP + Oracle + VBA Excel
    Inscrit en
    Juin 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : ERP + Oracle + VBA Excel
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2005
    Messages : 58
    Points : 78
    Points
    78
    Par défaut
    Merci pour la réponse, je ne vois pas bien comment utiliser cette fonction. Je suis rendu compte que la problématique est plus pointue que j'avais prévu. Ce filtre est pour recomposer un XML qui est utilisé pour nourrir des combo. Je ne pense pas qu'un simple traitement XSLT sera suffisant. Mais merci quand même.

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 613
    Points
    21 613
    Par défaut
    Citation Envoyé par EJO64 Voir le message
    Merci pour la réponse, je ne vois pas bien comment utiliser cette fonction.
    ? Ben ? Il marche pas mon exemple ? Il montre comment utiliser cette fonction, non ?

    Pour information, XSLT, bien que pas très adapté comme langage de programmation (mais plutôt de transformation) est tout de même Turing Complete, donc si tu peux le faire avec un langage, tu peux le faire avec XSLT (par contre c'est pas forcément le meilleur choix, en effet.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre régulier
    Profil pro
    ERP + Oracle + VBA Excel
    Inscrit en
    Juin 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : ERP + Oracle + VBA Excel
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2005
    Messages : 58
    Points : 78
    Points
    78
    Par défaut
    Pardon, je me suis mal exprimé, je ne vois pas comment utiliser cette fonction dans ma problématique.

    Je tourne un peu en rond dans l'analyse :

    si j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <prestation id_tiers="408210515" id_structure="21560434" id_prestation="1254115" flag="oui"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="21560981" flag="non"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="29041603" flag="non"/>
    Pas de problème car le couple "408210515" id_structure="21560434" est unique

    en revanche si j'ai

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <prestation id_tiers="408210515" id_structure="21560434" id_prestation="1254115" flag="oui"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="21560981" flag="oui"/>
    			<prestation id_tiers="408210515" id_structure="21560434" id_prestation="29041603" flag="non"/>
    avec un traitement linéaire j'ai un produit cartésien de 2 x le couple "408210515" id_structure="21560434"

    Donc je pense qu'il me faut faire des lectures avec rupture, mais je ne suis pas assez spécialiste pour trouver la bonne formulation.

  6. #6
    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
    Le but est de produire un nouveau xml contenant que l’arborescence qui correspond à flag='oui'
    L'approache première, pour moi, serait de le faire comme ça.
    Code xslt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="*[descendant-or-self::prestation[@flag='oui']]|text()|@*">
        <xsl:copy>
            <xsl:apply-templates select="*[descendant-or-self::prestation[@flag='oui']]|text()|@*" />
        </xsl:copy>
    </xsl:template>
    Un seul template suffit. Comme intégrer avec les discussions en cours, c'est à vous si nécessaire.

  7. #7
    Membre régulier
    Profil pro
    ERP + Oracle + VBA Excel
    Inscrit en
    Juin 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : ERP + Oracle + VBA Excel
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2005
    Messages : 58
    Points : 78
    Points
    78
    Par défaut
    Merci pour vos aides ! J'ai trouvé la solution.


    Il faire un copy des éléments qui nous intéresse et ne pas prendre les éléments qui nous intéresse pas :

    Comme il y a 3 niveaux, il faut faire 3 passages pour élimer progressivement les éléments.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
     
     <xsl:template match="prestation[@flag_p='non']" />
     <xsl:template match="structure[not(*)]"/>
     <xsl:template match="institution[not(*)]"/>
    Explication :

    - le 1er "template match" permet de ne pas prendre le noeud qui contient l'attribut que je souhaite testé (dans ce cas tous les attributs flag_p à non ou différent de oui)
    - le 2ème "template match" permet de ne pas prendre un noeud <structure> sans enfant
    - le 3ème "template match" permet de ne pas prendre un <institution> sans d'enfant

    - > 1 seul xsl mais appliquer trois fois

    Fichier d'origine
    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
    <institution id_tiers="1" >
    		<structure id_tiers="1" id_structure="1-1" >
    			<prestation id_tiers="1" id_structure="1-1" id_prestation="1-1-1" flag_p="oui"/>
    		</structure>
    	</institution>
     
    	<institution id_tiers="2" >
    		<structure id_tiers="2" id_structure="2-2">
    			<prestation id_tiers="2" id_structure="2-2" id_prestation="2-2-1" flag_p="oui"/>
    			<prestation id_tiers="2" id_structure="2-2" id_prestation="2-2-2" flag_p="non"/>
    			<prestation id_tiers="2" id_structure="2-2" id_prestation="2-2-3" flag_p="non"/>
    		</structure>
    	</institution>
     
     
     
    	<institution id_tiers="3" >
    		<structure id_tiers="3" id_structure="3-3">
    			<prestation id_tiers="3" id_structure="3-3" id_prestation="3-3-1" flag_p="non"/>
    			<prestation id_tiers="3" id_structure="3-3" id_prestation="3-3-2" flag_p="non"/>
    			<prestation id_tiers="3" id_structure="3-3" id_prestation="3-3-3" flag_p="non"/>
    		</structure>
    	</institution>
     
     
    	<institution id_tiers="4" >
    		<structure id_tiers="4" id_structure="4-4">
    			<prestation id_tiers="4" id_structure="4-4" id_prestation="4-4-1" flag_p="non"/>
    		</structure>
    		<structure id_tiers="4" id_structure="4-5">
    		<prestation id_tiers="4" id_structure="4-5" id_prestation="4-4-5" flag_p="oui"/>
    		</structure>
     
    	</institution>
    Le 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
    <?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="ISO-8859-1" indent="yes"/>
     
     
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
     
     <xsl:template match="prestation[@flag_p='non']" />
     
     <xsl:template match="structure[not(*)]"/>
     <xsl:template match="institution[not(*)]"/>
     
     
    </xsl:stylesheet>
    Après 3 passages

    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="ISO-8859-1"?>
    <echange>
    	<institution id_tiers="1">
    		<structure id_tiers="1" id_structure="1-1">
    			<prestation id_tiers="1" id_structure="1-1" id_prestation="1-1-1" flag_p="oui"/>
    		</structure>
    	</institution>
    	<institution id_tiers="2">
    		<structure id_tiers="2" id_structure="2-2">
    			<prestation id_tiers="2" id_structure="2-2" id_prestation="2-2-1" flag_p="oui"/>
    		</structure>
    	</institution>
    	<institution id_tiers="4">
    		<structure id_tiers="4" id_structure="4-5">
    			<prestation id_tiers="4" id_structure="4-5" id_prestation="4-4-5" flag_p="oui"/>
    		</structure>
    	</institution>
    </echange>

  8. #8
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 613
    Points
    21 613
    Par défaut
    Bon ben... j'ai toujours pas compris qu'est-ce que tu essayais de dire avant -_-°. Tant pis, hein.
    Apparemment il faut pas garder non plus les éléments auxquels on a tout enlevé.

    Pour information, voici la même chose en un seul passage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>
     
    <xsl:template match="*[not(descendant-or-self::*[@flag='oui'])]" />
    descendant-or-self, donc, qui sélectionne l'élément en cours et tous ses descendants.
    Ici nous vérifions si dans tout ce petit monde, il n'y en a aucun qui possède le flag à 'oui'. S'il n'y en a aucun, on garde pas.

    Autre manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="*">
      <xsl:if test="descendant-or-self::*[@flag='oui']">
        <xsl:apply-templates select="node()|@*"/>
      </xsl:if>
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre régulier
    Profil pro
    ERP + Oracle + VBA Excel
    Inscrit en
    Juin 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : ERP + Oracle + VBA Excel
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2005
    Messages : 58
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Bon ben... j'ai toujours pas compris qu'est-ce que tu essayais de dire avant -_-°. Tant pis, hein.
    Apparemment il faut pas garder non plus les éléments auxquels on a tout enlevé.
    Désolé la formulation comme d'habitude d'un problème semble évident à la personne qui pose la question, mais n'est pas toujours bien formulé .

    En tout cas ta dernière réponse permet en effet de passer en une fois.


    Voici le code du xsl final qui grâce aux infos reçues ici est ok.

    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
     
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!--Tri et selection fichier XML origine  -->
     
    <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"/>
     
    <!--Phase 1 tri alpha sur nom du tiers -->
     <xsl:template match="/">
    		<xsl:element name="echange">
    			<xsl:apply-templates select="echange/institution"><xsl:sort select="@nom_tiers"/></xsl:apply-templates>
    		</xsl:element>
    	</xsl:template>
     
    <!--phase 2  prendre dans la liste globale que les institutions XXXX -->	
     
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
     
     <xsl:template match="*[not(descendant-or-self::*[@service_prestation='XXXX'])]" /> 
     
    </xsl:stylesheet>

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/07/2015, 15h50
  2. [XML] Quizz basé sur fichier XML
    Par Heilong dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 29/10/2007, 14h16
  3. CMS ou Portail basé sur XML
    Par php_de_travers dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 08/11/2006, 20h02
  4. menu js, basé sur un fichier xml
    Par nagty dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/09/2006, 11h17
  5. Question moteur de recherche basé sur XML
    Par Royd938 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 04/05/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