!

Dette materialet blir ikke lenger vedlikeholdt. Du vil finne oppdatert materiale på siden: http://borres.hiof.no/wep/

SAX
Børre Stenseth
Python >SAX i Python

SAX i Python

Hva
SAX-programmering 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')  
Referanser

Akuelle filer er sitert i sin helhet i koden

Vedlikehold
Børre Stenseth, revidert juli 2009
( Velkommen ) Python >SAX i Python ( lxml )