logo
Split
Velkommen > Eksempler > Sonetter >Split
../../common/gfx/prev.gif ../../common/gfx/home.gif ../../common/gfx/next.gif

Splitting av sonettene

Hva:
Vise en transformasjon som tar en fil og lager et nettsted, Pythonkode.

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:

split

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)

Referanser og eksempler:

Pythonprogrammet kan kopieres rett fra teksten.

Andre filer: site/splitfiles.zip

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.

Produksjon, kontroll og vedlikehold:
Børre Stenseth, jan 2003

Markup og web fra Høgskolen i Østfold: http://www.ia.hiof.no/~borres/ml/

../../common/gfx/prev.gif ../../common/gfx/home.gif ../../common/gfx/next.gif
skjema popup

Valid XHTML 1.0 Strict
popup card
Bygget med WXT