600 likes | 845 Views
XSLT 2. Digitalisering av kulturarvet. Idag. Repetition XSLT och TEI Referenser Läsa in XSLT- och XML-dokument i XHTML-dokument Skicka med variabler och argument. XSL-språk. XSLT Ett språk för att transformera XML-dokument X-PATH Ett språk för att navigera i XML-dokument XSL-FO
E N D
XSLT 2 Digitalisering av kulturarvet david.gunnarsson@hb.se
Idag • Repetition • XSLT och TEI • Referenser • Läsa in XSLT- och XML-dokument i XHTML-dokument • Skicka med variabler och argument
XSL-språk • XSLT • Ett språk för att transformera XML-dokument • X-PATH • Ett språk för att navigera i XML-dokument • XSL-FO • Ett språk för att formatera XML-dokument
Den röda tråden… DATA LOGIK GRÄNSSNITT XML XSLT XHTML(+CSS)
XML, XSLT, XHTML och CSS XML XSLT CSS Transformation (XSLT-processor) XHTML
Transformation • Sker med en XSLT-processor • Finns inbyggd i Internet Explorer… • …men inte i alla webbläsare • Därför använder vi JEdits XSLT-processor XALAN
XPath - noder <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE TEI.2 SYSTEM "teilitex.dtd"> <TEI.2> <teiHeader/> <text> <front/> <body> <div> <div1 id="OTS1" n="I" type="book"> <head>The Life and Opinions of Tristram Shandy, Gentleman, by Laurence Sterne </head> </div1> </div> </body> </text> </TEI.2>
XPath – Relationer mellan noder • Varje element och attribut har en och endast en förälder • Elementnoder har noll till många barn • Noder med samma förälder kallas syskon • Det första syskonet är äldst, det näst första är näst äldst och så vidare… • En förfader är en förälders förälder • En ättling är ett barns barn
XPath – Peka ut noder • /TEI2 – Pekar ut rotelementet TEI2 • TEI2/text – Pekar ut alla text-element som är barn till TEI2 • text//* – Pekar ut alla noder inuti elementet text • //p – pekar ut samtliga p-element, oavsett var de befinner sig i hierarkin • text//p – Pekar ut samtliga p-element som är ättlingar till text, oavsett var de befinner sig i hierarkin • //@n – Pekar ut samtliga attributnoder med namnet n
Exempel: peka ut alla p som är barn till div1 <xsl:template match="TEI2/text"> <xsl:apply-templates select="body/div/div1/p"/> </xsl:template> • Gör att vi är säkra på att rätt p hämtas, dvs det som är barn till div1, som i sin tur är barn till div, som i sin tur är barn till body
En annan variant <xsl:template match="TEI2/text"> <xsl:apply-templates select="//div1/p"/> </xsl:template>
Templates • Innehåller regler som appliceras vid matchning av en specificerad nod • Syntax: <xsl:template name=”namn" match=”mönster" mode=”form" priority=”siffra"> … </xsl:template> • Samtliga attribut är valfria, men minst ett av attributen name och match måste återfinnas
Exempel, templates <xsl:template match="/"> <xsl:apply-templates select="TEI.2/text/body"/> </xsl:template> <xsl:template match="div"> <div id="container"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="p"> <p class="text"> <xsl:apply-templates/> </p> </xsl:template> Anropar alla barn (och ättlingar) till body Matchar noder med namnet div, dock endast de som är barn eller ättlingar till body Matchar noder med namnet p, dock endast de som är barn eller ättlingar till body
Exempel, templates med villkor <xsl:template match="rs[@key='mrpitt']"> <span class="mrpitt"> <xsl:apply-templates/> </span> </xsl:template> <xsl:template match="rs[@key='puffen']"> <span class="puffen"> <xsl:apply-templates/> </span> </xsl:template>
Exempel, templates med villkor <xsl:apply-templates select="rs[@key='mrpitt']"/> <xsl:template match="rs"> <span class="mrpitt"> <xsl:apply-templates/> </span> </xsl:template>
apply-templates • När processorn stöter på apply-templates undersöker den det första elementet och ser om det finns ett template som matchar den • Så länge det finns ett template som matchar aktuellt element kommer processorn att fortsätta på samma sätt till nästa element
Repetitioner i XSLT: for-each <xsl:for-each select=“X-PATH-uttryck”> …kod som utförs på varje nod som överensstämmer med X-PATH-uttrycket </xsl:for-each>
for-each Notera krullparenteserna som används när man vill använda ett värde i ett icke xsl-element <ul id="index"> <xsl:for-each select="//head"> <li> <a href="#{../@id}"> <xsl:value-of select="."/> </a> </li> </xsl:for-each> </ul> ../@id pekar här ut attributet id hos heads förälder: <div1 id="OTS1" n="I" type="book">
Styrstrukturer i XSLT om (villkor a) utför a annars om (villkor b) utför b annars utför c
Med if <xsl:if test=”villkor a"> …kod som utförs om villkor a är sant </xsl:if> <xsl:if test=”villkor b"> …kod som utförs om villkor b är sant </xsl:if> <xsl:if test=”villkor c"> …kod som utförs om villkor c är sant </xsl:if>
Exempel: if <xsl:template match="rs"> <xsl:if test="@key='mrpitt' or @key='puffen'"> <span style="color: red"> <xsl:apply-templates/> </span> </xsl:if> <xsl:if test="@key!='mrpitt' and @key!='puffen'"> <span style="color: blue"> <xsl:apply-templates/> </span> </xsl:if> </xsl:template> Jodå, det funkar faktiskt
Med choose <xsl:choose> <xsl:when test=”villkor a"> ...kod som utförs om villkor a är sant </xsl:when> <xsl:when test=”villkor b"> ...kod som utförs om villkor b är sant </xsl:when> <xsl:otherwise> …kod som utförs om varken villkor a eller b är sant </xsl:otherwise> </xsl:choose>
Exempel: choose <xsl:template match="rs"> <xsl:choose> <xsl:when test="@key='mrpitt' or @key='puffen'"> <span style="color: red"> <xsl:apply-templates/> </span> </xsl:when> <xsl:otherwise> <span style="color: blue"> <xsl:apply-templates/> </span> </xsl:otherwise> </xsl:choose> </xsl:template> Även detta funkar
XSLT och TEI • Källan kan ses som en linjär sekvens • Det TEI-kodade innehållet är mer likt en databas • Flera olika outputs är möjliga
Varför transformera TEI med XSLT? • Förändra en icke presentabel fil till en webbsida • Formatera ett dokument till PDF eller liknande • Förändra en XML-vokabulär till en annan • Extrahera specifik information från ett dokument och formatera på ett annat sätt
Rendering av TEI-text • Kopiera element • Utesluta element • Flytta element • Generera element
Kopiera element • Navigationssystem • Till exempel kan alla head-element kopieras och placeras i en lista i början av texten • Listans element kan sedan länkas till respektive head-element • För kopiering kan for-each användas med fördel
Exempel: kopiera element <xsl:template match="div"> <div> <ul id="index"> <xsl:for-each select="//head"> <li> <a href="#{../@id}"> <xsl:value-of select="."/> </a> </li> </xsl:for-each> </ul> <xsl:apply-templates/> </div> </xsl:template>
Matchande template <xsl:template match="head"> <h1 id="{../@id}"> <a href="#index"> <xsl:apply-templates/> </a> </h1> </xsl:template> • Länkar varje head-element tillbaka till index Exempel 4
Utesluta element • TEI Header innehåller enbart metadata • Vi kanske inte vill visa texten på bokens baksida • Redaktionella noter bör inte visas • Eller varför inte enbart visa vissa element för vissa läsare och andra element för andra läsare?
Utesluta element, exempel <xsl:template match="X-PATH-uttryck"/> <xsl:template match="teiHeader"/> <xsl:template match="back"/> <xsl:template match="note[@type='editorial']"/>
Utesluta element, exempel <p>To the Right Honourable <rs type="person" key="mrpitt">Mr Pitt</rs>. <note place="end" type="editorial">Sex tecken används för attributet key</note> Sir, Never poor Wight of a Dedicator had less hopes from his Dedication, than I have from this of mine; for …</p>
Uteslutning av note <xsl:template match="note[@type='editorial']"/> Exempel 5
Flytta element • Template-anrop utförs i den ordning de är skrivna i: <xsl:apply-templates select="body"/> <xsl:apply-templates select="back"/> <xsl:apply-templates select="front"/> • Här kommer body skrivas ut först, sedan back och sist front
Generera element • Rahtz exempel något modifierat: • Varje namn ska transformeras till en länk vars titel-attribut får värdet This name occurs x times • Dvs, när muspekaren förs över namnet Toby ska en gul ruta med texten This name occurs 3 times dyka upp
Generera element, exempel • TEI-kod <rs type="person" key="tobysh">Toby Shandy</rs> • XSLT-kod <xsl:key name="names" match="rs" use="@key"/> <xsl:template match="rs"> <a href="#" title="This name occurs {count(key('names',@key))} times"> <xsl:apply-templates/> </a> </xsl:template> Exempel 5
TEI-länkar • Länkning inom dokumentet • ref och ptr • Länkning inom dokumentet och till externa dokument • xref och xptr
ptr Kräver att det finns ett element med attributet id="preface", detta id måste vara unikt för filen • TEI <ptr target="preface"/> • XSLT <xsl:template match="ptr"> <p> Go to <a href="#{@target}"> <xsl:value-of select="@target"/></a> </p> </xsl:template> Notera också fyrkanten (#) som gör det möjligt att länka till ett ankare inom ett dokument
Mer ptr • ptr kan tilldelas attributet type • På så vis kan vi skilja olika typer av länkar ifrån varandra <ptr type="navigation" target="top"/> <ptr type="secref" target="preface"/>
Matchande template <xsl:template match="ptr"> <xsl:choose> <xsl:when test="ptr[@type='navigation']"> … </xsl:when> <xsl:when test="ptr[@type='secref']"> <p>Go to <a href="#{@target}"> <xsl:value-of select="@target"/></a> </p> </xsl:when> <xsl:otherwise> … </xsl:otherwise> </xsl:choose> <xsl:template>
ref • TEI <ref target="preface"> Go to preface </ref> • XSLT <xsl:template match="ref"> <p><a href="#{@target}"> <xsl:value-of select="."/></a> </p> </xsl:template> • Nackdel med denna variant är att man infogar text som inte hör till originalkällan
xptr, tei-kod <xptr doc="DOC1"/> • DOC1 måste definieras i DTD:n: <!ENTITY DOC1 SYSTEM "Fig1.jpg" NDATA jpeg>
xptr, xslt-kod <xsl:template match="xptr"> <p> <img src="{unparsed-entity-uri(@doc)}" /> </p> </xsl:template>
xref, tei-kod The <xref doc="http://themystica.com/mystica/articles/h/homunculus.html"> HOMUNCULUS</xref>, Sir…
xref, xslt-kod <xsl:template match="xref"> <a href="{unparsed-entity-uri(@doc)}"> <xsl:apply-templates /> </a> </xsl:template>
Notera… • att url:en http://themystica.com/mystica/articles/h/homunculus.html egentligen ska deklareras i DTD:n: • <!ENTITY HOMUN SYSTEM " http://themystica.com/mystica/articles/h/homunculus.html " NDATA HTML>
Och i tei-koden… • …ska vi istället skriva: <xref doc="HOMUN">HOMUNCULUS </xref>… <!ENTITY HOMUN SYSTEM " http://themystica.com/mystica/articles/h/homunculus.html " NDATA HTML>
Bilder (figurer) • Elementet figure används: <figure entity="pullman"> <head>Above:</head> <p>The drawing room…</p> <figDesc>The figure shows…</figDesc> </figure> • Detta kräver att pullman är definierad i DTD:n: <!ENTITY pullman SYSTEM ”pullman.jpg” NDATA jpeg>
xslt-kod <xsl:template match="figure"> <p> <img src="{unparsed-entity-uri(@entity)}" /> </p> </xsl:template>
Inläsning av XSLT- och XML-dokument i XHTML-dokument • Vi kan med ett (hyfsat) enkelt JavaScript läsa in XSLT- och XML-dokument i XHTML-dokument • Vi utgår från en skapad .htm-fil • Vi skriver sedan ett JavaScript som läser in bägge filerna