aboutsummaryrefslogtreecommitdiff
path: root/src/XmlParser.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/XmlParser.py')
-rw-r--r--src/XmlParser.py449
1 files changed, 449 insertions, 0 deletions
diff --git a/src/XmlParser.py b/src/XmlParser.py
new file mode 100644
index 0000000..1af755b
--- /dev/null
+++ b/src/XmlParser.py
@@ -0,0 +1,449 @@
+# -*- coding: iso-8859-1 -*-
+
+#########################################
+######## PARSER XML #####################
+#########################################
+
+# imports
+import sys
+import os
+import math
+import string
+import random
+
+#test du module expat
+try:
+ from xml.parsers import pyexpat
+except ImportError:
+ # Possibly the pyexpat module hasn't been installed; we may be
+ # running an initial "make test" just after compiling the
+ # package. Try importing pyexpat directly.
+ import pyexpat
+
+
+##
+# classe entry
+# cette classe est un representation d'un noeud en xml (entree)
+#
+class entry:
+
+ ##
+ # methode __init__
+ # methode initialisant les attributs de la classe
+ #
+ def __init__(self):
+ self.type = '' # Type de la données (déclarée dans DTD)
+ self.name = '' # Nom de la donnée : si Présence de l'attribut 'name'
+ self.cdata = '' # Données CDATA de l'élément (entre la balise ouvrante et la balise fermante
+ self.attribs = {} # Attributs : Clé nom de l'attribut
+ self.entries = [] # Liste des sous éléments
+ self.namedentries = {} # Dictionnaire des sous éléments nommés (recherche accélérée)
+
+ ##
+ # methode setname
+ # mutateur de l'attribut name
+ # @param name : nom du noeud
+ #
+ def setname(self, name):
+ self.name = name
+
+ ##
+ # methode getname
+ # accesseur à l'attribut name
+ # @return self.name
+ #
+ def getname(self):
+ return self.name
+
+ ##
+ # methode setcdata
+ # mutateur de l'attribut cdata
+ # @param cdata : données entre balise ouvrantes et fermantes
+ #
+ def setcdata(self, cdata):
+ self.cdata = cdata
+
+ ##
+ # methode getcdata
+ # accesseur à l'attribut cdata
+ # @return self.cdata
+ #
+ def getcdata(self):
+ return self.cdata
+
+ ##
+ # methode setattribs
+ # mutateur de l'attribut attribs
+ # @param attribs : attribut du noeuds
+ #
+ def setattribs(self, attribs):
+ self.attribs = attribs
+
+ ##
+ # methode getattribs
+ # accesseur à l'attribut attribs
+ # @return self.attribs
+ #
+ def getattribs(self):
+ return self.attribs
+
+ ##
+ # methode hasattrib
+ # methode verifiant si un attribut de nom attribname est dans la liste des attributs
+ # @param attribname : nom de l'attribut
+ # @return true ou false
+ #
+ def hasattrib(self, attribname):
+ if self.attribs.has_key (attribname):
+ return 1
+ else:
+ return 0
+
+ ##
+ # methode findattrib
+ # methode recherchant un attribut dans la liste et renvoyant sa valeur ou la valeur par default en cas d'abscense
+ # @param attribname : nom de 'attribut dont on charche la valeur
+ # @param defaultvalue :valeur a retourner en cas d'abscence de l'attribut
+ # @return valeur de l'attribut ou la valeur par default
+ #
+ def findattrib(self, attribname, defaultvalue):
+ if self.attribs.has_key (attribname):
+ return self.attribs[attribname]
+ else:
+ return defaultvalue
+
+ ##
+ # methode findforceattrib
+ # methode cherchant la valeur d'un attribut et forçant une valeur non nulle comme valeur de retour
+ # @param attribname: nom de l'attribut
+ # @param defalutvalue : valeur par default
+ # @return une valeur non nulle
+ #
+ def findforceattrib(self, attribname, defaultvalue):
+ if self.attribs.has_key (attribname):
+ ret = self.attribs[attribname]
+ if ret == None or ret == "":
+ return defaultvalue
+ return ret
+ else:
+ return defaultvalue
+
+ ##
+ # methode settype
+ # mutateur de l'attribut type
+ # @param type : le type du noeud
+ #
+ def settype(self, type):
+ self.type = type
+
+ ##
+ # methode gettype
+ # accesseur à l'attribut type
+ # @return le type du noeud
+ #
+ def gettype(self):
+ return self.type
+
+ ##
+ # methode addentry
+ # methode ajoutant une entry à la liste des sous noeuds
+ # @param entry : reference au noeud
+ # @param name : nom du noeuds
+ #
+ def addentry(self, entry, name):
+ self.entries.append (entry)
+ if name != "":
+ self.namedentries[name] = entry
+
+ ##
+ # methode printlevel_recurs
+ # methode affichant recursivement les attributs se trouvant sous le noeud
+ # @param level : le niveau du noeud pour debuter l'affichage
+ #
+ def printlevel_recurs(self, level):
+ #affichage des attributs.
+ space = ' '*level
+ attstr = ''
+ for attkey in self.attribs.keys ():
+ attrib = self.attribs[attkey]
+ attstrloc = attkey + ' = ' + attrib + ', '
+ attstr = attstr + attstrloc
+ toprint = space + 'Node type : ' + self.type + ', CData : ' + self.cdata + ', Attributes : ' + attstr
+ try:
+ print toprint
+ except:
+ print "##################################################"
+ print "Erreur de DUMP"
+ print self.__dict__
+ print "##################################################"
+
+ #affichage des fils.
+ for entry in self.entries:
+ entry.printlevel_recurs (level + 1)
+
+ ##
+ # methode findentry
+ # methode recherchant un noeud dans la liste des sous noeuds en utilisant son type, un attribut et la valeur de celui-ci
+ # @param entrytype : type du noeuds recherche
+ # @param attribname : nom de l'attribut rechercher
+ # @param attribvalue : valeur de l'attribut
+ # @return l'attribut trouve ou None
+ #
+ def findentry(self, entrytype, attribname, attribvalue):
+ for entry in self.entries:
+ if entry.type == entrytype:
+ if entry.attribs.has_key (attribname):
+ attrib = entry.attribs[attribname]
+ if attrib == attribvalue:
+ return entry
+ return None
+
+ ##
+ # methode findtype
+ # methode rechercahant un noeuds en fnction de son type
+ # @param entrytype : type du noeud
+ # @return le noeud ou None
+ #
+ def findtype(self, entrytype):
+ for entry in self.entries:
+ if entry.type == entrytype:
+ return entry
+ return None
+
+ ##
+ # methode findnamedentry
+ # methode recherchant un noeud par son nom
+ # @param entryname : nom du noeud
+ # @return le noeud ou None
+ #
+ def findnamedentry(self, entryname):
+ if self.namedentries.has_key (entryname):
+ return self.namedentries[entryname]
+ else:
+ return None
+
+
+
+#
+# Cette classe implemente un l'objet issue de la configuration
+#
+
+##
+# classe property_server
+# cette classe est en charge de parser le fichier xml et de fournir les informations
+# contenu dans le fichiers
+#
+class property_server:
+
+ ##
+ # methode __init__
+ # initialisation des attributs
+ #
+ def __init__(self):
+ self.configurationread = 0
+ self.verbose = 0
+ # Parametres de la ligne de commande
+ self.config_file = 'Message.xml'
+ self.messageDict = {}
+ self.regexpDict = {}
+
+ ##
+ # methode setconfigfile
+ # mutateur de l'attribut config_file contenant le nom du fichier xml
+ # @param configfile : nouveau nom du fichier à parser
+ #
+ def setconfigfile (self, configfile):
+ self.config_file = configfile
+
+ ##
+ # methode readconfig
+ # methode lisant et parsant le fichier xml
+ # @param verbose : falg d'affichage du resultat du parsing
+ #
+ def readconfig (self, verbose=0):
+ if self.configurationread != 0:
+ return
+
+ self.verbose = verbose
+ self.configurationread = 1
+ self.out = Outputter()
+ self.parser = pyexpat.ParserCreate()
+ self.parser.StartElementHandler = self.out.startelt
+ self.parser.EndElementHandler = self.out.endelt
+ self.parser.CharacterDataHandler = self.out.cdata
+ self.parser.ProcessingInstructionHandler = self.out.inst
+ if self.verbose == 1:
+ print ("Configuration file used : %s" % self.config_file)
+ self.data = open (self.config_file).read()
+ self.rv = self.parser.Parse (self.data, 1)
+
+ if self.verbose == 1:
+ print ("Parser returned %s" % self.rv)
+ if self.rv == 0:
+ print ("** Error %s" % self.parser.ErrorCode)
+ print ("** Line %s" % self.parser.ErrorLineNumber)
+ print ("** Column %s" % self.parser.ErrorColumnNumber)
+ print ("** Byte %s" % self.parser.ErrorByteIndex)
+ print ('Summary of XML parser upcalls:')
+ print ("start elements: %s" % self.out.startcount)
+ print ("end elements: %s" % self.out.endcount)
+ print ("character data: %s" % self.out.cdatacount)
+ print ("processing instructions: %s" % self.out.instcount)
+ print ('browsing Tree')
+
+ self.root = self.out.getroot ()
+
+ if self.verbose == 1:
+ self.root.printlevel_recurs (1)
+
+ ##
+ # methode readMessages
+ # parsing des messages et regular expressions
+ # rangement des regexp et messages dans des dictionanires
+ #
+ def readMessages(self):
+ root = self.root.findtype("ivytester")
+ messages = root.findtype("messages")
+ i = 0
+ for entry in messages.entries:
+ regexp = entry.findtype("regexp")
+ msg = entry.findtype("msg")
+ self.regexpDict[i] = regexp.findattrib("value","")
+ self.messageDict[i] = msg.findattrib("value","")
+ i = i+1
+
+ self.dictionnarySize = i
+
+ ##
+ # methode getRandomMessage
+ # methode renvoyant aleatoirement un message du dictionnaire
+ # @return une string contenant le message à envoyer
+ #
+ def getRandomMessage(self):
+ value = random.randint(0, self.dictionnarySize-1)
+ return self.messageDict[value]
+
+ ##
+ # methode getDictionnarySize
+ # methode renvoyant la taille des dictionnaires
+ # @return int repesentant le nombre d'element dans les dictionnaires regex et messages
+ #
+ def getDictionnarySize(self):
+ return self.dictionnarySize
+
+ ##
+ # methode getMessages
+ # accesseur au dictionnaire de messages
+ # @return le dictionnaire de message
+ #
+ def getMessages(self):
+ return self.messageDict
+
+ ##
+ # methode getRegexp
+ # accesseur au dictionnaire de regexp
+ # @return le dictionnaire de regexp
+ #
+ def getRegexp(self):
+ return self.regexpDict
+
+
+##
+# classe Outputter
+# classe permettant la recuperation du parsing du fichier xml
+#
+class Outputter:
+
+ ##
+ # methode __init__
+ # initialisation des attributs
+ #
+ def __init__(self):
+ self.startcount = 0
+ self.endcount = 0
+ self.cdatacount = 0
+ self.instcount = 0
+ self.indlevel = 0
+ self.currlevel = {}
+ new_entry = entry ()
+ self.currlevel[self.indlevel] = new_entry
+
+ ##
+ # methode startelt
+ # callaback de recuperation de l'element parse
+ # @param type : type du noeuds
+ # @param attrs : attribut du noeuds
+ #
+ def startelt(self, type, attrs):
+ father = self.currlevel[self.indlevel]
+ self.indlevel = self.indlevel + 1
+ new_entry = entry ()
+ self.currlevel[self.indlevel] = new_entry
+ attribs = {}
+ name = ''
+ self.startcount = self.startcount + 1
+ if (sys.version[:3] == "1.5"):
+ for i in range(0, len(attrs), 2):
+ attribs[attrs[i]] = attrs[i+1]
+ if attrs[i] == 'name':
+ name = attrs[i+1]
+ else:
+ for attkey in attrs.keys ():
+ attrib = attrs[attkey]
+ attribs[attkey] = attrib
+ if attkey == 'name':
+ name = attrib
+
+ new_entry.settype (type)
+ new_entry.setname (name)
+ new_entry.setattribs (attribs)
+ if name == '':
+ father.addentry (new_entry, type)
+ else:
+ father.addentry (new_entry, name)
+
+ ##
+ # methode endelt
+ # callback appele sur parsing du dernier element
+ # @param name : nom de l'element (non utilise)
+ #
+ def endelt(self, name):
+ self.indlevel = self.indlevel - 1
+ self.endcount = self.endcount + 1
+
+ ##
+ # methode cdata
+ # callback de recuperation des characteres data
+ # @param data : les characteres data parses
+ #
+ def cdata(self, data):
+ new_entry = self.currlevel[self.indlevel]
+ new_entry.setcdata (data)
+ self.cdatacount = self.cdatacount + 1
+
+ ##
+ # methode inst
+ # methode recuperant les instructions de parsing
+ # @param target : cible de l'instruction
+ # @param data : donnees recuperees
+ #
+ def inst(self, target, data):
+ self.instcount = self.instcount + 1
+
+ ##
+ # methode getroot
+ # methode recuperrant le noeud racine de l'arbre
+ # @return noeud racine
+ #
+ def getroot(self):
+ return self.currlevel[0]
+
+
+Properties = property_server ()
+
+if __name__ == '__main__':
+ print "programme main"
+ Properties.setconfigfile ("Message.xml")
+ Properties.readconfig (verbose=0)
+ Properties.readMessages()
+ print Properties.getRandomMessage() \ No newline at end of file