SAX((Simple API for XML))
Datagrunnlaget er (igjen) fila all_results.xml med resultater fra sprintfinalene i olymiske leker de siste årene.
Du vil se av koden nedenfor at det er tre begivenheter som plukkes opp når XML-fila leses: StartElementHandler, EndElementHandler, CharacterDataHandler.
Eksempel 1
Koden nedenfor tar ganske enkelt å rapporterer når et element starter, når vi får textdata og når et element slutter. Hvis du kjører koden mot det datagrunnlaget som er foreslått ovefor blir dette ganske mange linjer med utskrift
""" SAX Simply report event as they appear """ import xml.parsers.expat import sys """ 3 primitive handler functions used by the parser """ def start_element(name, attrs): print('Start:'+name+str(attrs)) def end_element(name): print ('End:', name) def char_data(data): # drop whitespace if(not data.isspace()): print('Data:'+data) # make parser p = xml.parsers.expat.ParserCreate() # assign handlers p.StartElementHandler = start_element p.EndElementHandler = end_element p.CharacterDataHandler = char_data #start parsing try: p.ParseFile(open('all_results.xml','rb')) except: res=sys.exc_info() print ('Coud not read from file because: '+str(res[1]))
Eksempel 2
Koden nedenfor plukker bare ut tekstinnholdet i elementer og skriver det ut i komprimert form. Inhholdet i elementer som bare inneholder blake, tabulatorer og linjeskift droppes, if(not data.isspace())
""" SAX Just dump the comprimated textcontent """ import xml.parsers.expat import sys T="" """ 1 primitive handler function used by the parser """ def char_data(data): global T # drop whitespace if(not data.isspace()): T+=data """ when sorting the result """ def counter(n): return -int(n[1]) # make parser p = xml.parsers.expat.ParserCreate() # assign 1 handler p.CharacterDataHandler = char_data #start parsing try: p.ParseFile(open('all_results.xml','rb')) print (T) except: res=sys.exc_info() print ('Coud not read from file because: '+str(res[1]))
Eksempel 3
Koden finner forekomsten av deltagende nasjoner. Det vil si antall ganger en nasjon har stilt med en løper i en finale. For å få til dette må vi drive litt bokføring slik at vi vet når tekstinnholdet i elementet nation kommer. Det er lett å se at dette kan bli ganske komplisert med mange flag og betingelser dersom vi skal ha med spesifikke utdrag fra fila, f.eks. navnet på alle løpere fra USA som deltok i Barcelona. Prøv!
""" SAX How many starts from each country """ import xml.parsers.expat import sys # are we waiting for char-data for nation element nationFlag=False # accumulate findings here starters={} """ 3 primitive handler functions used by the parser """ def start_element(name, attrs): global nationFlag nationFlag=name == 'nation' def end_element(name): global nationFlag nationFlag=False def char_data(data): if(nationFlag): if data in starters: starters[data]=int(starters[data])+1 else: starters[data]=1; """ when sorting the result """ def counter(n): return -int(n[1]) # make parser p = xml.parsers.expat.ParserCreate() # assign handlers p.StartElementHandler = start_element p.EndElementHandler = end_element p.CharacterDataHandler = char_data #start parsing try: p.ParseFile(open('all_results.xml','rb')) # sort and present items=starters.items() sortedtems=sorted(items,key=counter) for it in sortedtems: print(it[0],it[1]) except: res=sys.exc_info() print ('Coud not read from file because: '+str(res[1]))
Resultatet blir:
USA 40 JAM 20 GBR 11 TTO 10 NAM 6 NGR 5 BRB 4 BRA 3 FRA 3 BAM 3 BEL 3 CUB 2 ANT 2 GRE 2 KNA 2 SAF 2 CAN 2 NED 2 POR 2 KEN 1 StK 1 SWE 1 GB 1 UGA 1 ECU 1 DOM 1 GER 1 POL 1 QAT 1 GRN 1 JPN 1 MUS 1 AUS 1