Splitting av sonettene
Det er kryssende interesser å ta hensyn til når vi skal presentere materiale av denne typen. Vi har en XML-fil som er på mer enn 130K og den tilsvarer nærmere 50 sider tekst. Dersom vi ønsker å legge ut informasjon som er egnet for utskrift og kopiering, må vi beholde alt i en fil. Dersom vi ønsker å lage raske oppslag på enkelte sonetter vil vi kanskje splitte opp materialet.
Vi forsøker å lage et pythonprogram som tar XML-fila og bygger opp et nettsted der begge hensynene er ivaretatt. Det vil si at vi vil lage følgende struktur:
Det betyr at vi skal lage en transformasjon som lager tre filtyper og 156 filer. Vi kaller transformasjonen shake og vil altså lage en Python-modul: shake.py.
Det er mange måter å gjøre dette på. Vi kan lage et Pythonprogram som er komplett i den forstand at det lager komplette filer inkludert stilsett. Jeg har i stedet valgt å lage tre templatefiler og et felles stilsett. Pythonprogrammet lager innhold som puttes inn i templatefilene. Fordelen med dette er at det er lettere å endre stil og layout på filene uten å endre Pythonkoden. Erfaringsmessig er det lettere å endre HTML- og CSS-kode enn det er å reprogrammere Python. Dette gjelder både under utvikling, og spesielt ved senere vedlikehold.
Pythonprogrammet
import xml.dom.minidom,string,os.path #------------------------------------------------------------- # Produces a website for Shakespeares sonnets from a XML-file # which contain all sonnetes. # See webpage: # http://www.ia.hiof.no/~borres/ml/shakespeare/p-split.html # The site is produced in same catalog as input XML-file. # The files are: # an index-fil # one file for each sonnet (154) # a file with all sonnettes(mainly for print) # The script use templates for the three filetypes # produces content that is replaced with <SL_BLOCK/> in templates # indextemplate.html, sontemplate.html, alltemplate.html # expect to find these templates in same catalog as source XML-file # Use: produce(xml-filnavn) # B. Stenseth 2003 #------------------------------------------------------------- # a few globals sitepath='' indexblock='' allblock='' sontemplate='' # collect all text in a node def getText(nodelist): rc = '' for node in nodelist: if node.nodeType == node.TEXT_NODE: t=node.data.encode('ISO-8859-1') rc += t return rc def getTextFile(filename): # load the indexfile txt="" try: file=open(filename,'r') txt=file.read() file.close() return txt except: print 'error reading:'+filename return '' def storeTextFile(filename,outtext): try: outf=open(filename,'w') outf.write(outtext) outf.close() except: print 'Error in writing'+ filename def makeFile(son,filename): # make a fresh new file for this sonnet # based on template:sontemplate.html filename=os.path.join(sitepath,filename) idtxt=getText(son.getElementsByTagName('id')[0].childNodes) T='<div class=\"s-id\">%s</div>\n'%idtxt lines=son.getElementsByTagName('line') T+='<p class=\"s-verse\">' for line in lines: T+=getText(line.childNodes) T+='<br/>\n' T+='</p>\n' outtext=string.replace(sontemplate,'<SL_BLOCK/>',T) #print filename # write it to file storeTextFile(filename,outtext) def appendIndex(son,filename): # append a reference to this sonnet as a list element # to the indexfile global indexblock # find first line in son firstline=getText(son.getElementsByTagName('line')[0].childNodes) entry=""" <li> <span class="i-ref"> <a href="%s">%s</a></span> </li>\n"""%(filename,firstline) indexblock+=""" <li> <span class="i-ref"> <a href="%s">%s</a></span> </li>"""%(filename,firstline) def appendAll(son): # append this sonnet to all sonnets global allblock idtxt=getText(son.getElementsByTagName('id')[0].childNodes) allblock+='<div class=\"a-id\">'+idtxt allblock+='</div>\n' lines=son.getElementsByTagName('line') allblock+='<p class=\"a-verse\">' for line in lines: allblock+=getText(line.childNodes) allblock+='<br/>\n' allblock+='</p>' def build(doc): # run through sonnets once and do all three tasks sonnetlist=doc.getElementsByTagName('sonnet') for son in sonnetlist: # make filename for this sonnet filename='sonnet' filename+=getText(son.getElementsByTagName('id')[0].childNodes) filename+='.html' # here we go makeFile(son,filename) appendIndex(son,filename) appendAll(son) def produce(afile='c:\\articles\\ml\\shakespeare\\site\\sonnetes.xml'): global sitepath global sontemplate global indexblock # extract catalog from this filename sitepath=os.path.dirname(afile) # prepare the three templatefiles sontemplate=getTextFile(os.path.join(sitepath,'sontemplate.html')) alltemplate=getTextFile(os.path.join(sitepath,'alltemplate.html')) indextemplate=getTextFile(os.path.join(sitepath,'indextemplate.html')) # set up the tree for the xml-file document=getTextFile(afile) dom = xml.dom.minidom.parseString(document) # do the job build(dom) # prepare indexblock indexblock='<ol>\n'+indexblock+'</ol>\n' # and put it in place in the template indextemplate=string.replace(indextemplate,'<SL_BLOCK/>',indexblock); # write the index-file filename=os.path.join(sitepath,'index.html') storeTextFile(filename,indextemplate) # allfile is prepared # put it in place in the template and write it alltemplate=string.replace(alltemplate,'<SL_BLOCK/>',allblock); filename=sitepath+'all.html' storeTextFile(filename,alltemplate)