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 :

débutant parsing de XML


Sujet :

Python

  1. #1
    Membre émérite Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Par défaut débutant parsing de XML
    Bonjour à tous

    Je travaille en python 3.3 et j'ai grand besoin d'un coup de main !

    Je récupère dans un traitement un bout de XML et je dois en extraire des données.


    Exemple de XML :
    <?xml version=1.0" ?><t><h t="Link/Namespace Attribute Content" u=""><d n="id" t="long"/><d n="scopeId" t="long"/><d n="type" t="String"/><d n="name" t="String"/><d n="no" t="long"/><d n="qual" t="String"/><d n="language" t="String"/></h><r><c>9117</c><c>0</c><c>NAM/SERVICE</c><c>DSC</c><c>1</c></r><r><c>9122</c><c>0</c><c>NAM/SERVICE</c><c>Gestions</c><c>1</c></r><r><c>9550</c><c>0</c><c>NAM/SERVICE</c><c>Juridique</c><c>1</c></r><r><c>16443</c><c>0</c><c>NAM/SERVICE</c><c>Ingénierie Produit</c><c>1</c></r></t>"
    Résultat attendu : une chaine de caractères "DSC,Gestions,Juridique,Ingénierie Produit"


    J'ai donc commencé par essayer de parser mon XML ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def parseXML(file):
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
        xml_file_handle.close()
     
        xml_cleaned = re.sub(u'[^\n\r\t\x20-\x7f]+',u'',xml_as_string)
        root = ET.fromstring(xml_cleaned)
    Ca ne fonctionne pas parce que mon XML est "not well-formed"
    Il y a des quotes à des endroits bizarres.

    Je change de stratégie et j'essaye des regexeps.
    J'arrive à quelque chose ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def findInXML(file):
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
     
        m = re.search(r'(.*)<c>NAM(.*)</c><c>(.*)</c><c>(.*)</c>',xml_as_string)
        if m:
            print(m.group(3))
     
        else:
            print('No Match !')
    Manque de bol, ça ne récupère qu'une des occurences et non pas toutes.

    Après un tour dans la doc, je tente avec findall()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def findInXML2(file):
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
     
        p = re.compile(r'<c>NAM/SERVICE</c><c>(.*)</c><c>[0-9]</c><c>')
        result = p.findall(xml_as_string)
        print(result[0])
    Là ça ne marche pas du tout, la regexp me ressort tout le fichier...
    Est-ce que vous sauriez comment
    • Faire le parsing d'un XML "not well-formed"
    • Utiliser findall() pour enfin arriver à mes fins ?
    • Une autre méthode plus adaptée ?



    En pièce jointe le XML d'exemple.
    Je vous remercie !





    le code complet
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #!/usr/bin/env python3
    # -*- coding: iso-8859-15 -*-
    # tested with python 3.3
     
    import xml.etree.ElementTree as ET
    import re
     
    def main():
        file = 'exemple 2.xml'
        findInXML2(file)
     
    def findInXML2(file):
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
     
        p = re.compile(r'<c>NAM/SERVICE</c><c>(.*)</c><c>[0-9]</c><c>')
        result = p.findall(xml_as_string)
        print(result[0])
     
     
     
    def findInXML(file):
        # ...
        #<c>0</c>
        #<c>NAM/SERVICE</c>
        #<c>DSC</c>
        #<c>1</c>
        # ...
        #<c>0</c>
        #<c>NAM/SERVICE</c>
        #<c>Gestions</c>
        #<c>1</c>
        #...
        #find = 'NAM/SERVICE'
        #return 'DSC,Gestions,Juridique'
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
     
        m = re.search(r'(.*)<c>NAM(.*)</c><c>(.*)</c><c>(.*)</c>',xml_as_string)
        if m:
            print(m.group(3))
     
        else:
            print('No Match !')
     
     
     
    def parseXML(file):
        #ne fonctionne "XML declaration not well-formed"
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
        xml_file_handle.close()
     
        xml_cleaned = re.sub(u'[^\n\r\t\x20-\x7f]+',u'',xml_as_string)
        root = ET.fromstring(xml_cleaned)
     
    if __name__ == "__main__":
        main()
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 589
    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 589
    Par défaut
    Salut,
    Je récupère dans un traitement un bout de XML et je dois en extraire des données.
    Soit mais vous avez déjà un soucis dans cette récupération.
    Et la vous êtes en train de patauger pour vivre avec plutôt que de le corriger.

    Ca ne fonctionne pas parce que mon XML est "not well-formed"
    Ben oui:
    En XML la valeur des attributs est entre double ou simple quotes.
    Et comme "Ingénierie" contient un "é", il manque aussi les informations d'encoding.

    Là ça ne marche pas du tout, la regexp ne trouve rien...
    Est-ce que vous sauriez comment
    Votre fichier contient une suite de blocks délimites par <r>*</r>.
    et les données sont dans des <c>*</c> de ces blocks.
    Vous pouvez construire une regexp qui attrape toutes les données d'un coup mais je trouve plus souple de travailler en 2 temps:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for g in re.findall(r'<r>(.*?)</r>', DATA):
        for h in re.findall(r'<c>(.*?)</c>', g):
            print ('h: %s' % h)
    Ceci dit, pas la peine d'utiliser une techno comme XML en arriver a la traiter comme de la soupe.

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

  3. #3
    Membre émérite Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Par défaut
    Merci de ton retour, je vais essayé ta méthode.

    Le XML que je récupère vient d'un progiciel et je ne peux que le prendre tel qu'il est.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il y a une solution que je connais mal mais dont on dit beaucoup de bien: BeautifulSoup (http://www.crummy.com/software/BeautifulSoup/).

    Il peut parser du HTML et du XML, et il semble assez "permissif" quant au XML mal formé.

    Alors, j'ai essayé sur l'exemple fourni, et j'arrive assez facilement à ceci:

    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
    DSC
    1
    9122
    0
    NAM/SERVICE
    Gestions
    1
    9550
    0
    NAM/SERVICE
    Juridique
    1
    16443
    0
    NAM/SERVICE
    Ingénierie Produit
    1
    Voilà mon code (très rustique!):

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division, print_function
    # Python 2.7
     
    from bs4 import BeautifulSoup
     
    soup = BeautifulSoup(open("./exemple.xml"))
    texte = soup.prettify() # permet d'écrire en plusieurs lignes
    soup2 = BeautifulSoup(texte)
    texte2 = soup2.get_text()
    for mot in texte2.split('\n'):
        mot = mot.strip()
        if mot!="":
            print(mot)
    La ligne "texte = soup.prettify()" est très intéressante. Voilà ce qu'elle donne en affichage:

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    <?xml version=1.0" ?>
    <t>
     <h t="Link/Namespace Attribute Content" u="">
      <d n="id" t="long">
      </d>
      <d n="scopeId" t="long">
      </d>
      <d n="type" t="String">
      </d>
      <d n="name" t="String">
      </d>
      <d n="no" t="long">
      </d>
      <d n="qual" t="String">
      </d>
      <d n="language" t="String">
      </d>
     </h>
     <r>
      <c>
       9117
      </c>
      <c>
       0
      </c>
      <c>
       NAM/SERVICE
      </c>
      <c>
       DSC
      </c>
      <c>
       1
      </c>
     </r>
     <r>
      <c>
       9122
      </c>
      <c>
       0
      </c>
      <c>
       NAM/SERVICE
      </c>
      <c>
       Gestions
      </c>
      <c>
       1
      </c>
     </r>
     <r>
      <c>
       9550
      </c>
      <c>
       0
      </c>
      <c>
       NAM/SERVICE
      </c>
      <c>
       Juridique
      </c>
      <c>
       1
      </c>
     </r>
     <r>
      <c>
       16443
      </c>
      <c>
       0
      </c>
      <c>
       NAM/SERVICE
      </c>
      <c>
       Ingénierie Produit
      </c>
      <c>
       1
      </c>
     </r>
    </t>

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 589
    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 589
    Par défaut
    Citation Envoyé par Mathusalem Voir le message
    Le XML que je récupère vient d'un progiciel et je ne peux que le prendre tel qu'il est.
    Vous faites ce que vous pouvez mais pourquoi appeler cela du XML?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre émérite Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Par défaut
    Merci à tous les deux pour votre aide.

    Voici un code qui fait exactement ce que j'attends

    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
    #!/usr/bin/env python3
    # -*- coding: iso-8859-15 -*-
    # tested with python 3.3
     
    import re
     
    def main():
        file = 'exemple 2.xml'
        r = findInXML(file)
        print(','.join(r))
     
    def findInXML(file):
        xml_file_handle = open(file,'r')
        xml_as_string = xml_file_handle.read()
        results = []
        for g in re.findall(r'<r>(.*?)</r>', xml_as_string):
            for h in re.findall(r'<c>NAM/SERVICE</c><c>(.*?)</c>', g):
                results.append(h)
        return(results)
     
    if __name__ == "__main__":
        main()

Discussions similaires

  1. Débutant parsing fichier XML
    Par jameson dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 28/11/2010, 18h26
  2. [ Tomcat ] [ débutant ] config web.xml
    Par TeTram dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 09/02/2009, 11h22
  3. [Choix] [Débutant] SOAP ou XML-RPC ?
    Par Noisette dans le forum XML/XSL et SOAP
    Réponses: 7
    Dernier message: 15/01/2009, 18h31
  4. [débutant] interet de XML
    Par unNew dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 09/09/2005, 10h48
  5. [débutant] faire du xml...
    Par Mathusalem dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 24/03/2005, 12h39

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