Magazine Internet

QtXml

Publié le 26 juillet 2008 par Mikebrant

Courte introduction, en utilisant SAX .

Bon, on va apprendre à lire un XML  .
Voici le fichier xml que l'on va essayer de lire ( quel merveilleux site VDM ) :

<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
  <vdms>
  <vdm id="5166">
  <auteur>jojothepotatoe</auteur>
  <categorie>inclassable</categorie>
  <date>Mon, 03 Mar 2008 19:53:18 +0100</date>
  <je_valide>4559</je_valide>
  <bien_merite>403</bien_merite>
  <commentaires>5</commentaires>
  <texte>Aujourd'hui j'étais avec un pote dans le bus. Deux filles derrière nous parlent d'un mec et se foutent de sa gueule (gros nez, trop moche, boutons partout). Moi je commence a me marrer en imaginant le pauvre mec super laid. En sortant du bus, mon pote m'explique qu'elles parlaient de moi. VDM</texte>
  </vdm>
  </vdms>
  <code>1</code>
  <erreurs></erreurs>
</root>


Voilà, enregistrez le code en .xml ( je le précise on sait jamais si deux ou trois glands se baladent ici ) .
On va récupérer l'id de la VDM,  l'auteur, la catégorie, la date, le nombre de "je valide c'est une VDM", le nombre de "tu l'as bien mérité", le nombre de commentaires et la vdm .

 Bon qu'est-ce qu'il nous faut maintenant ?
- une classe héritant de QXmlDefaultHandler
- une instanciation de QXmlSimpleReader
- un objet QXmlInputSource
- 4 oeufs
- 500g de farine
- et un zeste d'intelligence

 QxmlDefaultHandler

Cette classe sert à définir ce que l'on veut prendre dans le XML , grâce entre autres à 3 méthodes:
startElement(self, namespaceURI, nomLocal, balise, attributs) : est appelé quand on rentre dans une balise, on va donc pouvoir grâce à cette méthode s'occuper des attributs des balises.
namespaceURI : c'est le namespace, vide s'il n'y en a pas.
nomLocal: le nom de notre balise, sans préfixe, vide s'il n'y a pas de namespace.
balise: le nom de notre balise (préfixe inclus).
attributs : contient les attributs de la balise.
characters(self,contenu) : est appelée quand il y a du texte entre la balise ouverte et fermante : <balise_ouverte>texte</balise_fermante> . La méthode n'indique pas entre quelle balise on se trouve .
contenu: le texte
endElement(self, namespaceURI, nomLocal, balise) : est appelée quand on ferme une balise, on va donc pouvoir affecté le texte que l'on a récupéré grâce à characters() à la variable de notre balise .
namespaceURI: c'est le namespace, vide s'il n'y en a pas.
nomLocal: le nom de notre balise, sans préfixe, vide s'il n'y a pas de namespace.
balise: le nom de notre balise (préfixe inclus).
Toutes ces méthodes doivent retourner un booléen .
Enfin, les méthodes de MaClasse ( qui hérite de QxmlDefaultHandler )  devront porter ces noms puisqu' elles sont virtuelles .

 Voilà, ne reste plus qu'à faire notre petite classe :

from PyQt4.QtXml import *
class MaClasse( QxmlDefaultHandler ):
   """ notre jolie classe """
    
   def __init__(self) :
   QxmlDefaultHandler.__init__(self)
   self.id = None
   self.auteur = None
   self.categorie = None
   self.date = None
   self.je_valide = None
   self.bien_merite = None
   self.commentaire = None
   self.texte = None
   self.contenu = None
   #les infos que l'on veut récolter : l'id de la VDM, l'auteur, la catégorie, la date , le nombre de votes, etc...
  
   def startElement(self, namespaceURI, nomLocal, balise, attributs) :
   """  déclenchée au début d'une nouvelle balise"""
    
   if balise == "vdm" :
   self.id =  attributs.value( "id" ) #l'id de la vdm
   print self.id
    
   return True # doit retourner un booléen
    
    
   def characters(self,contenu) :
   """ déclenchée quand du texte se trouve entre le début de la balise et la fin"""
   self.contenu = contenu
   return True # doit retourner un booléen
    
    
   def endElement(self, namespaceURI, nomLocal, balise) :
   """ méthode à implanter (c'est une méthode virtuelle)
   déclenchée à la fermerture de la balise """
   if balise == "auteur" : # si on est dans la balise auteur
   self.auteur = self.contenu
   print self.auteur
    
   if balise == "categorie" :
   self.categorie = self.contenu
   print self.categorie
    
   if balise == "date" :
   self.date = self.contenu
   print self.date
    
   if balise == "je_valide" :
   self.je_valide = self.contenu
   print self.je_valide
    
   if balise == "bien_merite" :
   self.bien_merite = self.contenu
   print self.bien_merite
    
   if balise == "commentaires" :
   self.commentaires = self.contenu
   print self.commentaires
    
   if balise == "texte" :
   self.texte = self.contenu
   print unicode(self.texte)
   return True # doit retourner un booléen


Bon, rien de bien difficile.
À l'initialisation on déclare quelques variables.
Dans la méthode startElement(), on ne fait pas grand chose: si la balise se nomme vdm, alors on prend la valeur de son attribut id .
Dans la méthode characters(), on met le texte dans contenu.
Et dans endElement(),on affecte le contenu à la bonne variable. En effet, startElement() est la première méthode appelée, balise prendra donc une certaine valeur , ensuite vient characters() qui affectera la valeur de balise dans contenu, et enfin endElement() qui contiendra la même balise, donc on rentrera bien dans le bon if.

Voilà voilà, il nous reste juste à instancier notre classe, et à rajouter 3- 4 lignes :

if  __name__=='__main__':
  hop = MaClasse()
  parseur = QXmlSimpleReader()
  parseur.setContentHandler( hop)
  fc = QFile('/home/MikeBrant/Bureau/vdm.xml')
  entree = QXmlInputSource( fc )
  parseur.parse( entree )
 fc.close()


Alors, alors,
on instancie notre Classe.
Ensuite, c'est au tour de la classe QXmlSimpleReader. Elle fournit juste notre parseur (analyseur ) XML qui va donc parcourir notre joli fichier xml.
Pour lui indiquer quel traitement effectué sur quel évènement il faut donc indiquer à notre parseur  notre Classe. Pour ce faire, on utilise la méthode setContentHandler().
Après, on ouvre notre fichier (pensez à changer le chemin), puis l'on indique que ce sera la source à parser .
Et on finit donc par parser , puis par fermer le fichier .
Voilà, voilà la courte intro au XML via Qt est finie.


Retour à La Une de Logo Paperblog

A propos de l’auteur


Mikebrant 9 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte