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.