Partage
  • Partager sur Facebook
  • Partager sur Twitter

Parser XML en Python

Sujet résolu
    30 novembre 2010 à 17:18:07

    Bonjour

    Je tente désespérément de trouver une solution pour parser un fichier XML mais je me heurte à plusieurs problèmes.

    D'abord le module xml.dom n'a pas de fonction parse
    Ensuite la fonction parse du module xml.dom.minidom plante ( !! ) :
    File "P:\Developpement\Panda3D\python\lib\xml\dom\minidom.py", line 1922, in parse
        {'parser': parser, 'bufsize': bufsize})
      File "P:\Developpement\Panda3D\python\lib\xml\dom\minidom.py", line 1908, in _do_pulldom_parse
        events = func(*args, **kwargs)
      File "P:\Developpement\Panda3D\python\lib\xml\dom\pulldom.py", line 339, in parse
        return DOMEventStream(stream, parser, bufsize)
      File "P:\Developpement\Panda3D\python\lib\xml\dom\pulldom.py", line 217, in __init__
        self.reset()
      File "P:\Developpement\Panda3D\python\lib\xml\dom\pulldom.py", line 222, in reset
        self.parser.setFeature(xml.sax.handler.feature_namespaces, 1)
    AttributeError: 'str' object has no attribute 'setFeature'

    Enfin, les packages externes que je trouve sur le net (ElementTree, par exemple) sont obsolètes.

    D'où ma question : comment parser un fichier XML en Python ? Quelqu'un connait un package à jour ?

    Je précise que je travaille avec Python 2.6

    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      30 novembre 2010 à 17:26:29

      cElementTree (mais j'ai jamais pratiqué).
      • Partager sur Facebook
      • Partager sur Twitter
        30 novembre 2010 à 17:41:56

        Citation : Pouf


        Ensuite la fonction parse du module xml.dom.minidom plante ( !! ) :



        Pas chez moi. Essaye déjà de faire fonctionner le fichier d'exemple de la doc de 2.6 :


        import xml.dom.minidom
        
        document = """\
        <slideshow>
        <title>Demo slideshow</title>
        <slide><title>Slide title</title>
        <point>This is a demo</point>
        <point>Of a program for processing slides</point>
        </slide>
        
        <slide><title>Another demo slide</title>
        <point>It is important</point>
        <point>To have more than</point>
        <point>one slide</point>
        </slide>
        </slideshow>
        """
        
        dom = xml.dom.minidom.parseString(document)
        
        def getText(nodelist):
            rc = ""
            for node in nodelist:
                if node.nodeType == node.TEXT_NODE:
                    rc = rc + node.data
            return rc
        
        def handleSlideshow(slideshow):
            print "<html>"
            handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
            slides = slideshow.getElementsByTagName("slide")
            handleToc(slides)
            handleSlides(slides)
            print "</html>"
        
        def handleSlides(slides):
            for slide in slides:
                handleSlide(slide)
        
        def handleSlide(slide):
            handleSlideTitle(slide.getElementsByTagName("title")[0])
            handlePoints(slide.getElementsByTagName("point"))
        
        def handleSlideshowTitle(title):
            print "<title>%s</title>" % getText(title.childNodes)
        
        def handleSlideTitle(title):
            print "<h2>%s</h2>" % getText(title.childNodes)
        
        def handlePoints(points):
            print "<ul>"
            for point in points:
                handlePoint(point)
            print "</ul>"
        
        def handlePoint(point):
            print "<li>%s</li>" % getText(point.childNodes)
        
        def handleToc(slides):
            for slide in slides:
                title = slide.getElementsByTagName("title")[0]
                print "<p>%s</p>" % getText(title.childNodes)
        
        handleSlideshow(dom)
        
        • Partager sur Facebook
        • Partager sur Twitter
          30 novembre 2010 à 18:10:54

          ElementTree n'est pas un package externe, il est bel et bien inclus dans la bibliothèque standard de Python (y compris dans la version 2.6)...
          • Partager sur Facebook
          • Partager sur Twitter
          Zeste de Savoir, le site qui en a dans le citron !
            30 novembre 2010 à 18:47:03

            Citation : Maxibolt

            cElementTree (mais j'ai jamais pratiqué).


            cElementTree c'est pas l'implémentation C ? De plus, je disais que ElementTree plante chez moi

            @candide : Dans cet exemple, ils parsent une String. Moi j'essaie de parser un document. Mais je crois comprendre que c'est impossible, en fait, avec ElementTree. Il me faut charger mon fichier dans une String.

            Citation : NoHaR

            ElementTree n'est pas un package externe, il est bel et bien inclus dans la bibliothèque standard de Python (y compris dans la version 2.6)...



            Effectivement, je me suis rendu compte de mon erreur, mais j'ai pas jugé nécessaire de corriger mon post :) .

            Merci de votre aide, je vais charger le fichier dans une String pour la parser avec ElementTree.

            • Partager sur Facebook
            • Partager sur Twitter
              30 novembre 2010 à 19:09:27

              Avec l'approche DOM (qui revient aussi au même avec ElementTree), tu es effectivement obligé de charger tout le fichier pour le parser. Si tu as vraiment du gros gros fichier XML à traiter (1Go...) et que tu ne veux pas tout charger en mémoire d'un coup, il vaut mieux que tu te tournes vers SAX (aussi présente dans la bibliothèque standard, il me semble), mais ce genre de besoin est plutôt marginal en règle générale.
              • Partager sur Facebook
              • Partager sur Twitter
              Zeste de Savoir, le site qui en a dans le citron !
                30 novembre 2010 à 20:31:16

                Citation : NoHaR

                Avec l'approche DOM (qui revient aussi au même avec ElementTree), tu es effectivement obligé de charger tout le fichier pour le parser. Si tu as vraiment du gros gros fichier XML à traiter (1Go...) et que tu ne veux pas tout charger en mémoire d'un coup, il vaut mieux que tu te tournes vers SAX (aussi présente dans la bibliothèque standard, il me semble), mais ce genre de besoin est plutôt marginal en règle générale.



                Oui, merci, charger le fichier dans une String avant de la parser fonctionne effectivement.
                Pourtant, la doc de minidom donne cette exemple :

                from xml.dom.minidom import parse, parseString
                
                dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
                
                datasource = open('c:\\temp\\mydata.xml')
                dom2 = parse(datasource)   # parse an open file
                
                dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
                
                • Partager sur Facebook
                • Partager sur Twitter
                  30 novembre 2010 à 20:34:54

                  C'est parce que l'API est faite pour fonctionner avec tous types d'objets "se comportant comme des fichiers" (ça peut être par exemple des résultats de requête web ou autre qui ont la même interface publique "read()"...). Néanmoins, l'approche DOM impose quand même de charger tout le document d'un coup en mémoire pour le traiter.

                  Edit : il est aussi possible que l'utilisation "en chargeant un fichier passé par adresse dans un string" ne soit implémentée que depuis python 2.7 ou 3.1 et donc pas utilisable dans ta version (2.6)... Je n'ai pas regardé sur la doc, mais c'est possible et même plutôt courant comme problème.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Zeste de Savoir, le site qui en a dans le citron !
                    1 décembre 2010 à 8:44:11

                    Bonjour

                    Je reviens demander votre aide car même si j'ai pu charger mon fichier, je n'arrive pas à trouver comment itérer sur les nœuds de mon document : je ne trouve aucune méthode "getNodes()", ou attribut "nextChild", ou équivalent.

                    Documentation officielle (seulement un exemple d'utilisation pour modifier le fichier, pas vraiment pour le lire)
                    API (incomplète ?)
                    Autre exemple

                    J'ai trouvé node.ChildNodes dans le dernier lien, mais monDocument.childNodes est un NoneType...


                    Non, rien, en fait c'est bon, childNodes est pas vide. Pardon, merci.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Parser XML en Python

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown