Python
Børre Stenseth

SAX((Simple API for XML))

Hva

Her skal vi se hvordan vi kan parse en XML-fil og notere oss hvilke begivenheter som inntreffer. Vi bygger altså ikke hele treet før vi begynner å se på innholdet. Du kan finne nyttige SAX-linker hos Wikipedia [1]

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
Referanser
  1. Simple API for XML Wikipedia en.wikipedia.org/wiki/Simple_API_for_XML 14-03-2014