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 :

parser un fichier xml avec xml.sax


Sujet :

Python

  1. #1
    Rédacteur
    Avatar de pi-2r
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2006
    Messages
    1 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 486
    Points : 2 440
    Points
    2 440
    Par défaut parser un fichier xml avec xml.sax
    BOnjour à tous,

    je viens vers vous pour soliciter votre aide sur un parsing de fichier xml... En effet, je me heurte à quelques problématiques, à savoir:
    je n'arrive pas à récupérer certainnes informations, commme la description, l'année et les images.
    mon fichier xml est le suivant:
    <?xml version="1.0" encoding="utf-8"?> <xml> <ad>
    <id><![CDATA[1]]></id> <title><![CDATA[Jaguar XKR]]></title>
    <url><![CDATA[link]]></url> <content><![CDATA[Jaguar XKR
    skqlmskmlqskml qpdqsdkqmlkdmlq qdmlkqsmldkdqsklqsml]]></content>
    <price currency="US"><![CDATA[4000.00]]></price>
    <city><![CDATA[Tokyo]]></city>
    <postcode><![CDATA[92200]]></postcode>
    <date><![CDATA[2013-10-01]]></date>
    <expiration_date><![CDATA[2017-02-27]]></expiration_date>

    <year><![CDATA[2008]]></year> <make><![CDATA[Jaguar]]></make>
    <model><![CDATA[Xkr]]></model> <fuel><![CDATA[fuel]]></fuel>
    <mileage><![CDATA[68000]]></mileage>
    <transmission><![CDATA[Automatique]]></transmission>
    <power><![CDATA[12]]></power> <pictures>
    <picture><picture_url><![CDATA[link1]]></picture_url></picture>
    <picture><picture_url><![CDATA[link2]]></picture_url></picture>
    </pictures> </ad>
    mon code python est le suivant:
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    #!/usr/bin/python
     
    import xml.sax
     
    class MovieHandler( xml.sax.ContentHandler ):
       def __init__(self):
          self.CurrentData = ""
          self.title = ""
          self.url = ""
          self.description = ""
          self.price = ""
          self.city = ""
          self.postcode = ""
          self.year = ""
          self.date = ""
          self.expiration_date =  ""
          self.brand = ""
          self.model = ""
          self.fuel = ""
          self.mileage = ""
          self.transmission = ""
          self.power = ""
          self.picture =  ""
     
     
       # Call when an element starts
       def startElement(self, tag, attributes):
          self.CurrentData = tag
     
       # Call when an elements ends
       def endElement(self, tag):
          if self.CurrentData == "title":
             print "Title:", self.title
          elif self.CurrentData == "url":
             print "Url:", self.url
          elif self.CurrentData == "content":
             print "Description:", self.description
          elif self.CurrentData == "price":
             print "price:", self.price
          elif self.CurrentData == "city":
             print "City:", self.city
          elif self.CurrentData == "postcode":
             print "Postcode:", self.postcode
          elif self.CurrentData == "date":
             print "Date:", self.date
          elif self.CurrentData == "expiration_date":
             print "expiration date:", self.expiration_date
          elif self.CurrentData == "year":
             print "year:", self.year
          '''
          elif self.CurrentData == "make":
             print "Brand:", self.brand
          elif self.CurrentData == "model":
             print "Model:", self.model
          self.CurrentData = ""
          '''
       # Call when a character is read
       def characters(self, content):
          if self.CurrentData == "title":
             self.title = content
          elif self.CurrentData == "url":
             self.url = content
          elif self.CurrentData == "content":
             self.description = content
          elif self.CurrentData == "price":
             self.price = content
          elif self.CurrentData == "city":
             self.city = content
          elif self.CurrentData == "postcode":
             self.postcode = content
          elif self.CurrentData == "date":
             self.date = content
          elif self.CurrentData == "expiration_date":
             self.expiration_date = content
          elif self.CurrentData == "year":
             self.year = content
          '''
          elif self.CurrentData == "make":
             self.brand = content
          elif self.CurrentData == "model":
             self.model = content
           '''
     
     
    if ( __name__ == "__main__"):
     
       # create an XMLReader
       parser = xml.sax.make_parser()
       # turn off namepsaces
       parser.setFeature(xml.sax.handler.feature_namespaces, 0)
     
       # override the default ContextHandler
       Handler = MovieHandler()
       parser.setContentHandler( Handler )
     
       parser.parse("myfile.xml")
    comment puis-je lire ces balises ?
    Merci d'avance.
    Les pièges de l'Internet
    Helix, réponse à une intrusion


    "La plus grande gloire n'est pas de ne jamais tomber, mais de se relever à chaque chute." Confucius
    "Si j'ai vu plus loin, c'est en me tenant sur les épaules de géants." Isaac Newton

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Simplifions:
    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
     
    #!/usr/bin/python
     
    import xml.sax
     
    class MovieHandler( xml.sax.ContentHandler ):
        def __init__(self):
            self.CurrentData = ""
            self.cars = []
            self.current_car = None
     
        def create_new_car(self):
            self.current_car = {}
     
        # Call when an element starts
        def startElement(self, tag, attributes):
            print "startElement", tag, attributes
            if tag == "xml":
                return
            elif tag == "ad":
                self.create_new_car()
     
            self.CurrentData = tag
     
        # Call when an elements ends
        def endElement(self, tag):
            if self.CurrentData:
                print " %s: %s" %(self.CurrentData, self.current_car[self.CurrentData])
     
            if tag == "ad":
                self.cars.append(self.current_car)
            self.CurrentData = ""
     
        # Call when a character is read
        def characters(self, content):
            if not self.CurrentData or not content:
                return
     
            self.current_car[self.CurrentData] = content
     
     
    if ( __name__ == "__main__"):
     
        # create an XMLReader
        parser = xml.sax.make_parser()
        # turn off namepsaces
        parser.setFeature(xml.sax.handler.feature_namespaces, 0)
     
        # override the default ContextHandler
        Handler = MovieHandler()
        parser.setContentHandler( Handler )
     
        parser.parse("car.xml")
        print Handler.cars
    Commentaire: sacrement ch..t les indentations de trois caractères

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par pi-2r Voir le message
    BOnjour à tous,
    comment puis-je lire ces balises ?
    Merci d'avance.
    Bonjour,

    Avec les données suivantes (à mettre dans un fichier my_file.xml :

    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
    <?xml version="1.0" encoding="utf-8"?>
    <xml>
        <ad>
            <id><![CDATA[1]]></id>
            <title><![CDATA[Jaguar XKR]]></title>
            <url><![CDATA[link]]></url>
            <content><![CDATA[Jaguar XKR skqlmskmlqskml qpdqsdkqmlkdmlq qdmlkqsmldkdqsklqsml]]></content>
            <price currency="USD"><![CDATA[4000.00]]></price>
            <city><![CDATA[Tokyo]]></city>
            <postcode><![CDATA[92200]]></postcode>
            <date><![CDATA[2013-10-01]]></date>
            <expiration_date><![CDATA[2017-02-27]]></expiration_date>
            <year><![CDATA[2008]]></year>
            <make><![CDATA[Jaguar]]></make>
            <model><![CDATA[Xkr]]></model>
            <fuel><![CDATA[fuel]]></fuel>
            <mileage><![CDATA[68000]]></mileage>
            <transmission><![CDATA[Automatique]]></transmission>
            <power><![CDATA[12]]></power>
            <pictures group="banners">
                <picture name="super car !">
                    <picture_url><![CDATA[link1]]></picture_url>
                </picture>
                <picture>
                    <picture_url><![CDATA[link2]]></picture_url>
                </picture>
            </pictures>
        </ad>
    </xml>

    Testez 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
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    from __future__ import unicode_literals
     
    import xml.sax
     
    class Element:
        def __init__ (self, tag, attributes):
            self.tag = str(tag)
            self.attributes = attributes
            self.cdata = ""
            self.children = []
        # end def
    # end class
     
    class DataContentHandler (xml.sax.ContentHandler):
     
        def __init__ (self):
            self.parents = []
            self.root_node = None
        # end def
     
        def startElement (self, tag, attributes):
            "opening XML element tag"
            # element inits
            element = Element(tag, attributes)
            # element is root node ?
            if not self.parents:
                self.root_node = element
                self.parents.append(self.root_node)
            # child element
            else:
                # get last registered parent element
                parent = self.parents[-1]
                # add new child element to parent element
                parent.children.append(element)
                # now child element becomes
                # a potential parent for
                # further children elements
                self.parents.append(element)
            # end if
        # end def
     
        def endElement (self, tag):
            "closing XML element tag"
            # pop last registered parent from LIFO stack
            if self.parents:
                self.parents.pop(-1)
            # end if
        # end def
     
        def characters (self, content):
            "CDATA encountered on the run"
            # get last registered parent element
            parent = self.parents[-1]
            # add CDATA char string to this element
            parent.cdata = str(content).strip() # strip useless chars
        # end def
     
        def dump (self, element=None, show_all=False):
            "showing element's contents"
            # got no initial element?
            if not element:
                # set to root node
                element = self.root_node
            # end if
            # browse element's children
            for child in element.children:
                # shortcut inits
                _tag = child.tag.capitalize()
                _attrs = child.attributes
                # print tag and cdata only
                if show_all or child.cdata:
                    print "{0}: '{1}'".format(_tag, child.cdata)
                # print tag if got some attrs to show up
                elif _attrs.getLength():
                    print "{0}:".format(_tag)
                # end if
                # showing attributes
                for attribute in _attrs.getNames():
                    print " |---> {0}: '{1}'"\
                        .format(attribute, _attrs.getValue(attribute))
                # end for
                # then recursively dump child's children and so on
                self.dump(child, show_all)
            # end for
        # end def
    # end class DataContentHandler
     
    if __name__ == "__main__":
     
        # handler init
        handler = DataContentHandler()
     
        # parsing file
        xml.sax.parse("my_file.xml", handler)
     
        # change 'show_all' flag
        # to meet your needs (True or False)
        handler.dump(show_all=True)
     
    # end if
    Note : les balises CDATA ne sont vraiment utiles que là où vous craignez des injections XML, ce n'est donc pas la peine d'en mettre partout (sauf si le fichier XML est généré par un automate).

    Note 2 : le module xml.sax est plutôt destiné aux personnes qui cherchent à implémenter un analyseur de type de document plutôt que des données XML.
    Ici, j'ai émulé un analyseur de données XML, mais il serait plus sage de regarder du côté de xml.etree.ElementTree pour le dépiautage facile de données XML dans une arborescence : https://docs.python.org/3/library/xm...ementtree.html

    Exercice formateur et intéressant, au demeurant.

    @+.
    Dernière modification par Invité ; 08/08/2014 à 08h37. Motif: coloration syntaxique XML

Discussions similaires

  1. parser un fichier xml avec xml.sax et la méthode "feed"
    Par louisonb dans le forum Général Python
    Réponses: 1
    Dernier message: 06/04/2009, 11h41
  2. Creation de fichier XML avec XML Builder
    Par Nicolas57 dans le forum Ruby
    Réponses: 1
    Dernier message: 10/07/2007, 09h21
  3. impossible de parser le fichier hibernate.cfg.xml
    Par paolo2002 dans le forum Wildfly/JBoss
    Réponses: 9
    Dernier message: 30/05/2007, 17h39
  4. Réponses: 2
    Dernier message: 01/01/2007, 13h04
  5. problème pour parser un fichier xml avec XML::Simple
    Par black_code dans le forum Modules
    Réponses: 3
    Dernier message: 30/01/2006, 19h32

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