Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lecture d'un fichier xml

    29 septembre 2010 à 18:21:00

    Bonjour

    J'ai par exemple ce fichier xml :
    <parameters>
      <separator name="general" >
       <i type="string" name="SYSTEM">unknown system</i>
       <i type="logical" name="LCOMPAT"> F  </i>
      </separator>
      <separator name="electronic" >
       <i type="string" name="PREC">normal</i>
       <i name="ENMAX">    400.00000000</i>
       <i name="ENAUG">    322.06900000</i>
       <i name="EDIFF">      0.00000100</i>
       <i type="int" name="IALGO">    68</i>
       <i type="int" name="IWAVPR">    11</i>
       <i type="int" name="NBANDS">    21</i>
       <i name="NELECT">     32.00000000</i>
       </separator>
      <i type="logical" name="LREAL_COMPAT"> F  </i>
      <i type="logical" name="GGA_COMPAT"> T  </i>
      <i type="logical" name="LBERRY"> F  </i>
      <i type="int" name="ICORELEVEL">     0</i>
      <i type="logical" name="LDAU"> F  </i>
      <i type="int" name="I_CONSTRAINED_M">     0</i>
     </parameters>
    


    Je le lis avec un petit code python

    import xml.dom.minidom
    
    # parse le fichier xml
    dom = xml.dom.minidom.parse("vasprun.xml")
    
    parameters = dom.getElementsByTagName("parameters")[0]
    separators = parameters.getElementsByTagName("separator")
    
    for separator in separators:
    	# titre du groupe de flag
    	title = separator.getAttribute("name")
    
    	# recuperation des flag dans le groupe
    	flags = separator.getElementsByTagName("i")
    
    	for flag in flags:
    		typeFlag, nomFlag, valeurFlag = lectureFlagParametre( flag )
    
    		# impression
    		ligne = "\t" + nomFlag.ljust(15) + " = %s" % valeurFlag + "\n"
    		print(ligne)
    


    Sur le fichier xml vous pouvez voir qu'à la fin il y a des tag i qui n'appartiennent pas à un bloc separator. Mon problème c'est que si je fais :

    flags = parameters.getElementsByTagName("i")
    


    Dans flags je vais avoir tous les tags qui s'appellent i, pas seulement ceux inclus dans parameters. Je veux dire que je n'aurai pas que les enfants, j'aurais aussi les petits enfants (les i qui sont dans des separators).

    Comment je peux récupérer uniquement la liste de ceux qui sont dans parameters et qui ne sont pas inclus dans un separator ?

    Merci d'avance
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      29 septembre 2010 à 18:53:43

      C'est quoi lectureFlagParametre(flag) ???
      • Partager sur Facebook
      • Partager sur Twitter
        30 septembre 2010 à 9:58:25

        Pardon j'ai oublié de la mettre, c'est une fonction à moi :euh:

        def __lectureFlagParametre( self, node ) :
        		valeur = node.childNodes[0].data
        
        		# attributs
        		nomFlag = node.getAttribute("name")
        		typeFlag = node.getAttribute("type")
        
        		if typeFlag == "string" or typeFlag == "logical":
        			valeurFlag = valeur
        		elif typeFlag == "int" :
        			valeurFlag = int(valeur)
        		elif typeFlag == "" :
        			valeurFlag = float(valeur)
        
        		return typeFlag, nomFlag, valeurFlag
        


        ça m'intéresse d'avoir un avis sur la façon dont je lis le fichier xml. Sachant que le fichier xml est créé par un autre programme qui est un programme commercial de calcul que j'utilise et que je ne suis donc pas maitre de ce qu'il contient.

        EDIT : remis le bon nom de la fonction.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          30 septembre 2010 à 11:28:07

          Faut rester cohérent

          Ta fonction n'a pas le même nom que l'appel de cette même fonction

          __lectureFlag différent de lectureFlagParametre

          On corrige simplement

          typeFlag, nomFlag, valeurFlag = __lectureFlag( flag )
          


          Après c'est vrai que je n'utilise pas trop le xml, mais si je comprend bien tu voudrais juste afficher

          SYSTEM unknown system
          LCOMPAT  F
          • Partager sur Facebook
          • Partager sur Twitter
            30 septembre 2010 à 13:12:11

            Pardon j'ai changé effectivement le nom de la fonction depuis la première ecriture ...

            En fait si tu regardes le fichier xml il y a plein de tag "i". Quand je lit les tag separator les uns après les autres j'ai effectivement que les tags i dans le separator. Par contre quand je demande les tags i qui sont dans parameters j'ai ceux dans parameters + ceux dans des separators et je voudrais que ceux dans parameters.

            • Partager sur Facebook
            • Partager sur Twitter
              2 octobre 2010 à 14:25:35

              Salut ladgaren,

              Si j'ai bien compris tu veux ajouter un bout de script pour lister les noeuds xml qui :
              - ont le tag "i",
              - et ne sont pas contenus dans les noeuds "separator" donc sont des enfants "directs" du noeud "parameters" ?

              Une solution vite torchée :

              directchilds = parameters.childNodes # Une liste des enfants directs du noeud "parameters"
              flags = [dirchild for dirchild in directchilds if dirchild.localName == "i"] # sélectionne dans la liste précedente uniquement les noeuds "i"
              



              Bon c'est moche et je n'ai pas testé. Il y a surement moyen de faire mieux mais essaye voir si ça te donne satisfaction.
              • Partager sur Facebook
              • Partager sur Twitter
                4 octobre 2010 à 9:43:52

                Bonjour

                ça ne fonctionne pas, il me donne l'erreur suivante :

                AttributeError: 'NodeList' object has no attribute 'childNodes'


                • Partager sur Facebook
                • Partager sur Twitter
                  4 octobre 2010 à 10:38:20

                  Poum poum pidoum... parcours d'arbre facile :

                  from BeautifulSoup import BeautifulSoup
                  
                  soup = BeautifulSoup( """
                  <parameters>
                    <separator name="general" >
                     <i type="string" name="SYSTEM">unknown system</i>
                     <i type="logical" name="LCOMPAT"> F  </i>
                    </separator>
                    <separator name="electronic" >
                     <i type="string" name="PREC">normal</i>
                     <i name="ENMAX">    400.00000000</i>
                     <i name="ENAUG">    322.06900000</i>
                     <i name="EDIFF">      0.00000100</i>
                     <i type="int" name="IALGO">    68</i>
                     <i type="int" name="IWAVPR">    11</i>
                     <i type="int" name="NBANDS">    21</i>
                     <i name="NELECT">     32.00000000</i>
                     </separator>
                    <i type="logical" name="LREAL_COMPAT"> F  </i>
                    <i type="logical" name="GGA_COMPAT"> T  </i>
                    <i type="logical" name="LBERRY"> F  </i>
                    <i type="int" name="ICORELEVEL">     0</i>
                    <i type="logical" name="LDAU"> F  </i>
                    <i type="int" name="I_CONSTRAINED_M">     0</i>
                   </parameters>
                   """ )
                  
                  def parcours( soup, indent = "" ):
                  	for sep in soup.findAll( "separator", recursive = False ):
                  		print indent, sep['name']
                  		parcours( sep, indent + "\t" )
                  		
                  	for i in soup.findAll( "i", recursive = False ):
                  		print indent, [ i.get("type"), i.get("name"), i.renderContents().strip() ]
                  
                  parcours( soup.find( "parameters" ))
                  
                  • Partager sur Facebook
                  • Partager sur Twitter
                    5 octobre 2010 à 15:42:17

                    Merci

                    Ce module a l'air sympathique, j'ai deux questions. En sortie, j'ai ça :

                    general
                            [u'string', u'SYSTEM', 'unknown system']
                            [u'logical', u'LCOMPAT', 'F']
                     electronic
                            [u'string', u'PREC', 'normal']
                            [None, u'ENMAX', '400.00000000']
                            [None, u'ENAUG', '322.06900000']
                            [None, u'EDIFF', '0.00000100']
                            [u'int', u'IALGO', '68']
                            [u'int', u'IWAVPR', '11']
                            [u'int', u'NBANDS', '21']
                            [None, u'NELECT', '32.00000000']
                     [u'logical', u'LREAL_COMPAT', 'F']
                     [u'logical', u'GGA_COMPAT', 'T']
                     [u'logical', u'LBERRY', 'F']
                     [u'int', u'ICORELEVEL', '0']
                     [u'logical', u'LDAU', 'F']
                     [u'int', u'I_CONSTRAINED_M', '0']


                    Qu'est ce que c'est le u qui est devant à chaque fois ?

                    L'autre question c'est que j'utilise python3 (on m'a conseillé de me mettre à python3 vu que je connaissais pas python il y a 2 semaines). Je n'arrive pas à passer le module en version 3. Le test de python tout seul fonctionne puis il exécute 2to3 :

                    ..............................................................
                    ----------------------------------------------------------------------
                    Ran 62 tests in 0.115s
                    
                    OK
                    RefactoringTool: Skipping implicit fixer: buffer
                    RefactoringTool: Skipping implicit fixer: idioms
                    RefactoringTool: Skipping implicit fixer: set_literal
                    RefactoringTool: Skipping implicit fixer: ws_comma
                    RefactoringTool: Refactored BeautifulSoup.py
                    RefactoringTool: Files that need to be modified:
                    RefactoringTool: BeautifulSoup.py
                    patching file python3/BeautifulSoup.py
                    patching file python3/BeautifulSoup.py
                    Reversed (or previously applied) patch detected!  Assume -R? [n]


                    Là je répond n ?

                    et ça fini par ça :

                    ======================================================================
                    ERROR: testTextArea (__main__.YoureSoLiteral)
                    ----------------------------------------------------------------------
                    Traceback (most recent call last):
                      File "BeautifulSoupTests.py", line 459, in testTextArea
                        self.assertEqual(soup.textarea.contents[0],
                      File "/home/gvallver/Programme/MesSources/Python/classes/BeautifulSoup-3.1.0.1/python3/BeautifulSoup.py", line 595, in __getattr__
                        return self.find(tag)
                      File "/home/gvallver/Programme/MesSources/Python/classes/BeautifulSoup-3.1.0.1/python3/BeautifulSoup.py", line 769, in find
                        l = self.findAll(name, attrs, recursive, text, 1, **kwargs)
                      File "/home/gvallver/Programme/MesSources/Python/classes/BeautifulSoup-3.1.0.1/python3/BeautifulSoup.py", line 789, in findAll
                        return self._findAll(name, attrs, text, limit, generator, **kwargs)
                      File "/home/gvallver/Programme/MesSources/Python/classes/BeautifulSoup-3.1.0.1/python3/BeautifulSoup.py", line 338, in _findAll
                        i = g.next()
                    AttributeError: 'generator' object has no attribute 'next'
                    
                    ----------------------------------------------------------------------
                    Ran 62 tests in 0.063s
                    
                    FAILED (errors=47)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      5 octobre 2010 à 17:38:36

                      Le module en question existe déjà pour python 3 :

                      http://www.crummy.com/software/BeautifulSoup/

                      Les petits 'u' ça signifie que la chaîne est unicode (enfin, en python 2.x)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        5 octobre 2010 à 23:24:25

                        En tout cas merci à Lord Casque Noir pour ce module, ça me servira bientôt ;)

                        J'ai bien aimé dom.xml pour la compréhension de l'arborescence (étant débutant pour tout ce qui est xml) mais là il n'y a pas photo c'est sur.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 octobre 2010 à 23:46:27

                          En fait j'utilise ce truc surtout pour extraire des données de pages HTML pompées du web, ça digère n'importe quoi.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Lecture d'un fichier xml

                          × 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