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

Python Discussion :

Suppression noeud XML en fonction d'une balise [Python 3.X]


Sujet :

Python

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut Suppression noeud XML en fonction d'une balise
    Bonjour,

    je lis un fichier XML en python. Lors de la lecture si je rencontre une certaine valeur, je dois supprimer tout un nœud.

    Ex :
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <Simple>
       <cle>TOTO</cle>
       <val>35</val>
    </Simple>

    Si je rencontre "TOTO", je dois supprimer tout le bloc <Simple></<Simple>.

    Une idée ?

    Merci.

  2. #2
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 369
    Par défaut
    Bonjour,

    Peut-être...
    Un bout de code de ce que tu as commencé à faire ?

    Quand tu dis tout le bloc, si celui-ci est aussi dans un bloc qui est aussi dans un bloc, que doit on faire ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    Peut-être...
    Un bout de code de ce que tu as commencé à faire ?

    Quand tu dis tout le bloc, si celui-ci est aussi dans un bloc qui est aussi dans un bloc, que doit on faire ?
    Salut,

    merci pour ton retour. Je n'ai pas encore commencé le code. Pour le moment je réfléchis à mon algo sur le comment je vais faire et avec quels outils. De ce que j'ai listé, ma difficulté serait à ce niveau, c'est à dire supprimer un noeud. Le bloc que j'ai indiqué sera dans un autre bloc, mais il faut supprimer ou modifier uniquement ce que j'ai indiqué si la valeur entre les balises <cle></cle> est celle testée.

    Je vais commencer mes recherches côté librairie xml python, mais je ne souhaite pas un truc lourd.
    L'objectif du script c'est de prendre un fichier xml en entrée, de le lire et en fonction de certaines valeurs, modifier le contenu <cle></cle> ou supprimer le noeud pour en faire un autre XML(modifié, épuré).

    @+

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Salut,

    je reviens sur mon message. J'ai avancé dans mon script python. Mais, je bloque toujours pour supprimer un noeud. J'ai isolé la partie du code qui me pose problème pour travailler dessus.

    Voici le 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
     
    XML_data = '''<root>
    <Element>
    <Simple>
    <Cle>blabla</Cle>
    <Val>toto</Val>
    </Simple>
    </Element>
    </root>'''
    root = et.XML(XML_data)
    p = root.find('Element')  # le père
    e = p.find('Simple')  # le fils
    p.remove(e)  # supression
    print (et.tostring(root))  # affichage du document mis à jour.
    Ce code fonctionne bien, je supprime bien le noeud <Simple></Simple>. Mais si je mets :
    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_data = '''<root>
    <Element item="VAR">
    <Simple>
    <Cle>blabla</Cle>
    <Val>toto</Val>
    </Simple>
    </Element>
    </root>'''
    root = et.XML(XML_data)
    p = root.find('Element item="VAR"')  # le père
    e = p.find('Simple')  # le fils
    p.remove(e)  # supression
    print (et.tostring(root))  # affichage du document mis à jour.
    ça ne fonctionne plus. Pourquoi ? Je suis obligé de spécifier l'attribut item car dans le fichier xml d'origine, il y aura d'autres balises <Element> avec des item différents.

    Merci pour vos retours.

    Bonne journée.

    Cdt,

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 768
    Par défaut
    Salut,

    Citation Envoyé par lasnico37 Voir le message
    ça ne fonctionne plus. Pourquoi ?
    Parce que rechercher le nœud <Element item=XXX>...</Element> ou XXX est "VAR" ne se fait pas via root.find('Element item="VAR"') qui devrait retourner None (et la conséquence sera qu'on ne supprime pas <Simple>...</Simple>) mais avec une syntaxe Xpath: root.find('.//Element[@item="VAR"]').

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Parce que rechercher le nœud <Element item=XXX>...</Element> ou XXX est "VAR" ne se fait pas via root.find('Element item="VAR"') qui devrait retourner None (et la conséquence sera qu'on ne supprime pas <Simple>...</Simple>) mais avec une syntaxe Xpath: root.find('.//Element[@item="VAR"]').

    - W
    Merci ! ça fonctionne très bien. Je vais pouvoir me baser là-dessus pour le reste. Je vais intégrer cette portion de code dans mon script principal, effectuer quelques ajustements, et ça devrait le faire.

    Bonne journée.

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Je rencontre un problème dans mon script principal.

    Mon XML est chargé de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tree = etree.parse("fichier_XML")
    et derrière, cette portion de code ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    root = tree .XML(XML_data)
    p = root.find('.//Element[@item="VAR"]')
    Est-il possible de combiner etree.parse avec find ou je m'y prends mal ?

    Je continue de chercher et de tester. Je vais finir par y arriver !

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    J'ai réussi.

    En fonction de la valeur de la balise, j'arrive à supprimer le noeud.

    Prochaine étape : ajouter un nouveau noeud dans la section <Element VAR> et modifier un attribut.

    @+

  9. #9
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    J'ai réussi à faire l'essentiel.

    Mais, il me reste un gros problème. Le traitement ne fonctionne que sur la première occurrence trouvée dans le XML.

    Dans mon XML j'ai
    Code XML : 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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <Message 1>
       <Vars>
          <Element item="A">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="B">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="C">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="C">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
      </vars>
    </Message 1>
    <Message 2>
       <Vars>
          <Element item="A">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="B">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="C">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
         <Element item="C">
               <Simple>
                  <Cle>Nom</Cle>
                  <Val>Nico</Val>
              </Simple>
         </Element>
      </vars>
    </Message 2>
    Si je décide de supprimer le noeud simple dans Element item = "C" , il faut que ça le fasse partout dans le fichier (dans une autre section Element ou dans une autre section Message). Même chose si je renomme un attribut (item = "C" devient item="zoneC") ou un ajout de balise dans une section Element. Dans mon code de test, tout fonctionne uniquement sur le premier élément trouvé...

    Voici mon 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    import xml.etree.ElementTree as et
     
    tree = et.parse("fichier.xml")
    root = tree.getroot()
    elementC = root.find('.//Element[@item="C"]')
    listCle = []
    listVal = []
    simple = elemenC.findall('Simple')
    for cles in simple:
        cle = cles.find('Cle')# le fils
        valeurcles = cle.text
        listCle.append(valeurcles)
        if valeurcles == "Nom":
            elementC.remove(cles)
    for vals in simple:
        val = vals.find('Val')
        valeursval = val.text
        listVal.append(valeursval)
     
    for elements in root.iter('Element'):
        if elements.get("item") == "A":
            elements.set('item', 'zoneA')
        if elements.get("item") == "B":
            elements.set('item', 'zoneB')
        if elements.get("item") == "C":
            elements.set('item', 'zoneC')
    # Ajout d'une balise dans la section zoneC
    simple = et.SubElement(root.find('.//Element[@item="zoneC"]'), 'Simple')
    cle = et.SubElement(simple, 'Cle')
    cle.text = "VAR_DAT_01"
    val = et.SubElement(simple, 'Val')
    val.text = newDtn
    tree.write("output.xml")
    Comment faire pour que ce traitement s'applique à l'ensemble du fichier xml ?

    Merci pour vos retours.

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 768
    Par défaut
    Salut,

    Citation Envoyé par lasnico37 Voir le message
    Comment faire pour que ce traitement s'applique à l'ensemble du fichier xml ?
    L'appliquer à l'ensemble du fichier, c'est l'appliquer à toutes les occurrences de Element item="C"...
    ce qui dans votre code doit se traduire par une itération de.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    L'appliquer à l'ensemble du fichier, c'est l'appliquer à toutes les occurrences de Element item="C"...
    ce qui dans votre code doit se traduire par une itération de.

    - W
    Pffff, je galère... il y a un truc que je ne dois pas piger. J'ai le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    for elements in root.iter('Element'):
     
        elementVAR = root.find('.//Element[@item="C"]')
        simple = elementVAR.findall('Simple')
        for cles in simple:
            cle = cles.find('Cle')  # le fils
            valeurcles = cle.text
            listCle.append(valeurcles)
            if valeurcles == "Nom":
                elementVAR.remove(cles)
     
    tree.write("output.xml")
    ça fonctionne, tous les elements item = C ont le noeud "nom" de supprimer. Par contre, si j'ajoute la même chose pour A et B (il peut m'arriver à avoir à supprimer des noeuds dans ces élements) ça ne fonctionne pas.

    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
     
    for elements in root.iter('Element'):
     
    elementC = root.find('.//Element[@item="C"]')
        simple = elementC.findall('Simple')
        for cles in simple:
            cle = cles.find('Cle')  # le fils
            valeurcles = cle.text
            listCle.append(valeurcles)
            if valeurcles == "Nom":
                elementC.remove(cles)
     
        elementB = root.find('.//Element[@item="B"]')
        simple = elementB.findall('Simple')
        for cles in simple:
            cle = cles.find('Cle')  # le fils
            valeurcles = cle.text
            listCle.append(valeurcles)
            if valeurcles == "Nom":
                elementB.remove(cles)
     
    tree.write("output.xml")
    Ne fonctionne pas pour B. Il fonctionne si je supprime les sections C dans le fichier XML. Il prend le dernier élément de la boucle d'itération root.iter... Je dois me planter à ce niveau...Mais j'avoue, je cale, j'ai beau retourner le truc, je ne trouve pas. et ça m'énerve ! Qu'est-ce qui cloche ? peux-tu m'aider stp ?

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 768
    Par défaut
    Salut,

    Citation Envoyé par lasnico37 Voir le message
    Mais j'avoue, je cale, j'ai beau retourner le truc, je ne trouve pas. et ça m'énerve ! Qu'est-ce qui cloche ? peux-tu m'aider stp ?

    Si vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for elements in root.iter('Element'):
     
        elementVAR = root.find('.//Element[@item="C"]')
        simple = elementVAR.findall('Simple')
    vous commencez par avoir l'intention de faire une boucle sur tous les Elements,
    puis plutôt que de filtrer les Element qui ont l'attribut "item" égal à C, vous recherchez le premier Element avec item="C" depuis la racine... puis vous recherchez tous les Simple alors qu'il n'y en a qu'un...

    C'est juste incohérent (pour ne pas dire n'importe quoi).

    Ecrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for e in tree.findall('.//Element[@item="C"]'):
        s = e.find('Simple')
    serait bien plus cohérent avec l'intention (que çà marche ou pas...).


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2015
    Messages : 90
    Par défaut
    Merci. Je vais reprendre tout ça.

    Cdt,

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

Discussions similaires

  1. appel d'une fonction dans une balise img
    Par DiverSIG dans le forum Langage
    Réponses: 1
    Dernier message: 10/09/2009, 09h00
  2. Mettre le return d'une fonction dans une balise input
    Par khaled.mann dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 21/04/2009, 06h55
  3. Suppression de ligne en fonction d'une colonne
    Par PPLILH2008 dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 23/06/2008, 10h43
  4. Récupérer le résultat d'une fonction dans une balise html
    Par Hayato dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 19/06/2006, 17h04
  5. Réponses: 2
    Dernier message: 14/06/2006, 10h34

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