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 &gt; 6
6 &lt; 8
A &gt;= B
B &lt;= 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 &lt; 10 and kategori = 'Deckare’
– pris &lt; 10 or kategori = 'Deckare’
– pris &lt; 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 &lt; 10 and
kategori != 'Deckare'">
<xsl:value-of
select="forfattare/eNamn"/>:&#32;
<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"/>,&#32;
är en deckare
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="titel"/>,&#32;
ä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