Transcript Document
XSLT – en introduktion Digitalisering av kulturarvet [email protected] Idag • • • • • • Vad är XSLT? Hur fungerar XSLT? XPath och noder XSLT:s notation Templates, repetitioner och villkor TEI XSL-språk • XSLT – Ett språk för att transformera XMLdokument • X-PATH – Ett språk för att navigera i XML-dokument • XSL-FO – Ett språk för att formatera XML-dokument Vad är XSLT? • Står för eXstensible Stylesheet Language for Transformation • Ett programmeringsspråk för att transformera XML-dokument • En W3C-standard • XSLT transforms an XML sourcetree into an XML result-tree Den röda tråden… DATA LOGIK GRÄNSSNITT XML XSLT XHTML(+CSS) XML, XSLT, XHTML och CSS XML XSLT CSS Omvandling XHTML Hur fungerar XSLT? <?xml version="1.0" encoding="iso8859-1"?> <!DOCTYPE boksamling SYSTEM "boksamling.dtd"> <?xml-stylesheet type="text/xsl" href="boksamling.xsl"?> <boksamling> <bok/> </boksamling> En post i XML-filen <bok> <forfattare> <fNamn>Sue</fNamn> <eNamn>Grafton</eNamn> </forfattare> <titel>L som i laglös</titel> <kategori>Deckare</kategori> <pris valuta="gbp">20</pris> </bok> XSLT-kod <?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="boksamling"/> </xsl:template> <xsl:template match="boksamling"> <xsl:apply-templates select="bok"/> </xsl:template> <xsl:template match="bok"> Författare: <xsl:value-of select="forfattare/fNamn"/> <xsl:text> </xsl:text> <xsl:value-of select="forfattare/eNamn"/><br /> Titel: <xsl:value-of select="titel"/><br /> Kategori: <xsl:value-of select="kategori"/><hr /> </xsl:template> </xsl:stylesheet> XPath • Ett språk för att navigera i XMLdokument • En syntax för att definiera delar av ett XML-dokument • En W3C-standard • XSLT använder XPath för att navigera i XML-dokument XPath - noder • XML-dokument behandlas som träd bestående av noder • Typer av noder – Element – Attributes – Text – Namespaces – Processing instruction – Comment <!-- kommentar --> – Document node (dokumentets rotelement) XPath - noder <?xml version="1.0" encoding="iso-8859-1"?> <boksamling> Dokumentnod <bok> (rotelement) <forfattare> <fNamn>Sue</fNamn> Elementnod <eNamn>Grafton</eNamn> </forfattare> <titel>L som i laglös</titel> <kategori>Deckare</kategori> <pris valuta="gbp">20</pris> </bok> </boksamling> Attributnod Textnod 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 • Nodnamn – Pekar ut samtliga barn till noden • / - Pekar ut från rotelementet • // - Pekar ut noder i dokumentet från den aktuella nod som matchar utpekningen • . – Pekar ut aktuell nod • .. – Pekar ut föräldern till aktuell nod • @ - Pekar ut attribut XPath – Peka ut noder • boksamling – Pekar ut samtliga barn till noden boksamling • /boksamling – Pekar ut rotelementet boksamling • boksamling/bok – Pekar ut alla bok-element som är barn till boksamling • //bok – pekar ut samtliga bok-element, oavsett var de befinner sig i hierarkin • boksamling//titel – Pekar ut samtliga titel-element som är ättlingar till boksamling, oavsett var de befinner sig i hierarkin • //@currency – Pekar ut samtliga attributnoder med namnet currency Exempel: template-anrop <xsl:template match="boksamling"> <xsl:apply-templates select="bok/forfattare/eNamn"/> </xsl:template> • Gör att vi är säkra på att rätt eNamn hämtas, dvs det som är barn till forfattare som i sin tur är barn till bok En annan variant <xsl:template match="boksamling"> <xsl:apply-templates select="bok//eNamn"/> </xsl:template> • Gör att vi är säkra på att rätt eNamn hämtas, dvs det som är ättling till bok En tredje variant <xsl:template match="boksamling"> <xsl:apply-templates select="//forfattare/eNamn"/> </xsl:template> • Gör att vi är säkra på att rätt eNamn hämtas, dvs det som är barn till forfattare En fjärde variant <xsl:template match="boksamling"> <xsl:apply-templates select="//eNamn"/> </xsl:template> • Fungerar om eNamn finns på endast en nivå i trädet • Skulle eNamn finnas på flera nivåer förväxlar tolken noderna med varandra • Att ha samma namn på noder på olika nivå i XML-trädet är dock ingen optimal lösning Exempel: anropat template <xsl:template match="eNamn"> <xsl:value-of select="."/> <xsl:value-of select="../fNamn"/> <xsl:value-of select="../../titel"/> <xsl:value-of select="../../kategori"/> </xsl:template> Pekar ut aktuell nod (eNamn) Pekar ut eNamns förälders (forfattare) barn (fNamn) (enkelt uttryckt: eNamns syskon) Pekar ut eNamns förfäders barn Operatorer • • • • • • • A=A (A är ekvivalent med A) A!=B (A är inte ekvivalent med B) A>B (A är större än B) A<C (A är mindre än C) A>=D (A är större än eller lika med D) A<=E (A är mindre än eller lika med E) Ett uttryck av detta slaget är antingen sant (true) eller falskt (false) Operatorer • A=A and B!=C – Sant om och endast om A är ekvivalent med A och B inte är ekvivalent med C • A=A or B=C – Sant om A är ekvivalent med A eller om B är ekvivalent med C – Om första påståendet är sant kollas inte fler påståenden • not (A=B) – Sant om och endast om A inte är ekvivalent med B Aritmetiska operatorer • • • • • + * div mod addition subtraktion multiplikation division modulus 5+2 7-2 8*3 6 div 3 9 mod 2 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 XSLT:s notation • Alla element i XSLT innehåller prefixet xsl: <xsl:choose> </xsl:choose> <xsl:sort select="name"/> <xsl:value-of select="name"/> Operatorer i XSLT • • • • • • A=A A!=B 8 > 6 6 < 8 A >= B B <= A A är ekvivalent med A A är inte ekvivalent med B 8 är större än 6 6 är mindre än 8 A är större än eller lika med B B är mindre än eller lika med A Operatorer i XSLT • AND, OR och AND…! – pris < 10 and kategori = 'Deckare’ – pris < 10 or kategori = 'Deckare’ – pris < 10 and kategori != 'Deckare’ 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="boksamling"> <xsl:apply-templates select="bok/forfattare/eNamn"/> </xsl:template> <xsl:template match="eNamn"> <xsl:value-of select="."/> <xsl:value-of select="../fNamn"/> <xsl:value-of select="../../titel"/> <xsl:value-of select="../../kategori"/> </xsl:template> Exempel, templates med villkor <xsl:template match="boksamling"> <xsl:apply-templates select="bok/forfattare[eNamn='Grafton']"/> </xsl:template> <xsl:template match="forfattare"> <xsl:value-of select="eNamn"/> <xsl:value-of select="fNamn"/> <xsl:value-of select="../titel"/> <xsl:value-of select="../kategori"/> </xsl:template> Repetitioner i XSLT: for-each <xsl:for-each select=“X-PATH-uttryck”> …kod som utförs på varje nod som överensstämmer med X-PATHuttrycket </xsl:for-each> Exempel: for-each <xsl:template match="/"> <xsl:for-each select="boksamling/bok"> <xsl:value-of select="forfattare/eNamn"/> <xsl:value-of select="forfattare/fNamn"/> <xsl:value-of select="titel"/> <xsl:value-of select="kategori"/> </xsl:for-each> </xsl:template> Exempel: for-each med villkor <xsl:template match="/"> <xsl:for-each select ="boksamling/bok/forfattare[eNamn ='Grafton']"> <xsl:value-of select="eNamn"/> <xsl:value-of select="fNamn"/> <xsl:value-of select="../titel"/> <xsl:value-of select="../kategori"/> </xsl:for-each> </xsl:template> 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:if test="pris < 10 and kategori != 'Deckare'"> <xsl:value-of select="forfattare/eNamn"/>:  <xsl:value-of select="titel"/> </xsl:if> 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:choose> <xsl:when test="kategori='Deckare'"> <xsl:value-of select="titel"/>,  är en deckare </xsl:when> <xsl:otherwise> <xsl:value-of select="titel"/>,  är inte en deckare </xsl:otherwise> </xsl:choose> TEI och XSLT • På samma sätt som en XML-fil kan transformeras med XSLT kan text uppmärkt med TEI transformeras • Även här används XPath för navigering Den TEI-uppmärkta texten <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE TEI.2 SYSTEM "http://www.adm.hb.se/~mg/dig/XMLLab/teilitex.dtd"> <?xml-stylesheet type="text/xsl" href="tei.xsl"?> <TEI.2> <teiHeader> <fileDesc> <titleStmt> <title>The Life and Opinions of Tristram Shandy, Gentleman, by Laurence Sterne: Electronic edition</title> … </TEI.2> Ett XSLT-skal <?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <html> <head> </head> <body> </body> </html> </xsl:template> </xsl:stylesheet> Lite innehåll… <html> <head> <title><xsl:value-of select="TEI.2/teiHeader/fileDesc/ titleStmt/title"/></title> </head> <body> <h1><xsl:value-of select="TEI.2/teiHeader/fileDesc/ titleStmt/title"/></h1> </body> </html> Hämta allt med for-each <h1> <xsl:value-of select="TEI.2/teiHeader/fileDesc/ titleStmt/title"/> </h1> <xsl:for-each select="/TEI.2//*"> <p> <xsl:value-of select="."/> </p> </xsl:for-each> OK, men det ser ju inte så lyckat ut… • /TEI.2//* matchar alla noder som befinner sig i TEI.2 • <xsl:value-of select="."/> skriver ut värdet på den nod som XSLTprocessorn pekar på • Om en nod har fler än ett barn kommer innehållet i denna nod (plus dess barn) att skrivas ut lika många gånger som antalet barn Templates <body> <xsl:apply-templates/> </body> • Skriver ut allt • Ytterligare templates och mer styrning behövs Placering av nytt template <xsl:template match="/"> <html> <head> <title> <xsl:value-of select="TEI.2/teiHeader/fileDesc/titleStmt/title"/> </title> </head> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="div"> </xsl:template> Två templates infogas… <xsl:template match="div"> <div style="border: 3px double black; padding: 50px; width: 750px;"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="p"> <p> <xsl:apply-templates/> </p> </xsl:template> Varför skrivs headern ut igen? <body> <xsl:apply-templates/> </body> • Skriver ut allt (inklusive teiHeadernoden) • Detta åtgärdas med hjälp av select Uteslutning av överflödig headerinformation <body> <h1><xsl:value-of select ="TEI.2/teiHeader/fileDesc/ titleStmt/title"/></h1> <xsl:apply-templates select="TEI.2/text/body"/> </body> Att titta på över sommaren • http://www.w3schools.com/xsl/ • http://www.w3.org/TR/xslt • Ray, Eric T. (2003). Learning XML. 2. ed. Sebastopol: OReilly. 399 s. • Kompendiet Digitalisering av text