SAX i Python
Python har et apparat for SAX. Siden SAX er en eventdrevet mekanisme, finner vi en implementasjon som ligner den vi finner i andre eventdrevne omgivelser. Python har en parser som leser en string og detekterer de substringene som skal gi opphav til et event. Det er vår oppgave å fortelle Pythonparseren hva som skal skje når et event intreffer. Dette gjør vi ved å angi callback-funksjoner. Det vil si at vi forteller parseren hvilke av våre egendefinerte funksjoner som skal kalles ved de respektive begivenhetene. Dette er en strategi som er helt parallell til den vi bruker når vi lager programmer som er styrt av brukerbegivenheter. Vi skriver da metoder for å plukke opp museklikk osv. Her ligger det også en "parser" i bakgrunnen som sender en melding eller kaller opp vår funksjon når det inntreffer en begivenhet som vi har meldt vår interesse i. I en SAX-parsing er ikke begivenhetene museklikk men symboler i den stringen som analyseres.
Vi bruker resultatfila fra olympiade-eksempelet, se modulene: Olympiade og Noen datasett . De aktuelle resultatene er ordnet i en XML-fil: all_results.xml
Eksempel 1
import xml.parsers.expat
"""
Simple demo of sax.
B. Stenseth 2002
Use:
Show(filename)
See below for default filename
"""
#---------------------
# helper to load a text file
def getTextFile(filename):
try:
file=open(filename,'r')
intext=file.read()
file.close()
return intext
except:
print 'Error reading file ',filename
return None
#-------------------------------------------------------
# 3 primitive handler functions used by show
def start_element(name, attrs):
print 'Start:', name, attrs
def end_element(name):
print 'End:', name
def char_data(data):
#print 'Data:', repr(data)
if(not data.isspace()):
print 'Data:', data
def showAll(afile):
p = xml.parsers.expat.ParserCreate()
p.returns_unicode = 0
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
content=getTextFile(afile)
if(content!=None):
p.Parse(content)
def showData(afile):
p = xml.parsers.expat.ParserCreate()
p.returns_unicode = 0
p.CharacterDataHandler = char_data
content=getTextFile(afile)
if(content!=None):
p.Parse(content)
# basic testing
if __name__=="__main__":
showData('c:\\web\\dw\\pydom\\all_results.xml')
#showAll('c:\\web\\dw\\pydom\\all_results.xml')
Det er disse linjene som setter opp koplingen:
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
der start_element, end_element og char_data er våre funksjoner. Se Python dokumentasjonen for en komplett liste av hvilke events vi kan plukke opp.
Eksempel 2
Nedenfor finner du et eksempel som plukker ut og rapporterer verdien til alle elementer med tagnavn "name".
import xml.parsers.expat,string
"""
Simple demo of sax. demosax2
selects content of element: name
B. Stenseth 2002
Use:
Show(filename)
See below for default filename
"""
# helper to load a text file
def getTextFile(filename):
try:
file=open(filename,'r')
intext=file.read()
file.close()
return intext
except:
print 'Error reading file ',filename
return None
# global flag
navnFlag=-1
#-------------------------------------------------------
# 3 primitive handler functions used by show
def start_element(name, attrs):
global navnFlag
navnFlag= string.find(name,'name')
def end_element(name):
global navnFlag
navnFlag=-1
def char_data(data):
global navnFlag
if navnFlag>=0:
print data
# doit
def show(afile):
p = xml.parsers.expat.ParserCreate()
p.returns_unicode = 0
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
content=getTextFile(afile)
if content!=None:
p.Parse(content)
# basic testing
if __name__=="__main__":
show('c:\\web\\dw\\pydom\\all_results.xml')
Eksempel 3
Nedenfor finner du et eksempel som skriver en indentert utskrift av alle olympiader, øvelser og deltagere.
import xml.parsers.expat,string
"""
Simple demo of sax. demosax2
selects content of element: name
B. Stenseth 2006
Use:
Show(filename)
"""
# helper to load a text file
def getTextFile(filename):
try:
file=open(filename,'r')
intext=file.read()
file.close()
return intext
except:
print 'Error reading file ',filename
return None
# global flag
navnFlag=-1
# indentation when writing
indent=' '
#-------------------------------------------------------
# 3 primitive handler functions used by show
def start_element(name, attrs):
global navnFlag
navnFlag= string.find(name,'name')
if name.find('OlympicGame')!=-1:
print attrs['place']
if name.find('event')!=-1:
print indent+attrs['dist']
def end_element(name):
global navnFlag
navnFlag=-1
def char_data(data):
global navnFlag
if navnFlag>=0:
print indent+indent+data
# default filename for demopurposes, change it
def show(afile):
p = xml.parsers.expat.ParserCreate()
p.returns_unicode = 0
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
content=getTextFile(afile)
if content!=None:
p.Parse(content)
# basic testing
if __name__=="__main__":
show('c:\\web\\dw\\pydom\\all_results.xml')