59
[email protected] XSLT 3 Elektronisk publicering

XSLT 3

Embed Size (px)

DESCRIPTION

XSLT 3. Elektronisk publicering. XSLT 3. Repetition Genomgång av övningsuppgifter Importering av XML- och XSL-filer i ett (X)HTML-dokument Variabler Parametrar Number Funktioner Dynamik. Operatorer. A=A (A är ekvivalent med A) A!=B (A är inte ekvivalent med B) - PowerPoint PPT Presentation

Citation preview

[email protected]

XSLT 3

Elektronisk publicering

XSLT 3

• Repetition• Genomgång av övningsuppgifter• Importering av XML- och XSL-filer i ett

(X)HTML-dokument• Variabler• Parametrar• Number• Funktioner• Dynamik

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

• + addition 5+2• - subtraktion 7-2• * multiplikation 8*3• div division 6 div 3• mod modulus 9 mod 2

Rendering av XML-innehåll

• Kopiera element• Utesluta element• Flytta element• bland annat…

En receptsamling

<!ELEMENT receptsamling (recept*)><!ELEMENT recept (namn, ingrediens+)>

<!ATTLIST recept id CDATA ""><!ELEMENT namn (#PCDATA)><!ELEMENT ingrediens (namn, kategori,

mangd)><!ELEMENT namn (#PCDATA)><!ELEMENT kategori (#PCDATA)><!ELEMENT mangd (#PCDATA)>

<!ATTLIST mangd enhet CDATA "st">

XML-filen

Kopiera element

• Navigationssystem• Till exempel kan alla namn-element

som är barn till recept kopieras och placeras i en lista i början av texten

• Listans element kan sedan länkas till respektive namn-element

• För kopiering kan for-each användas med fördel

Exempel: kopiera element<xsl:template match="receptsamling">

<div> <ul id="index"> <xsl:for-each select="//recept/namn"> <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="recept"><h1 id="{@id}">

<a href="#"><xsl:apply-templates

select="namn"/></a>

</h1></xsl:template>

• Länkar varje namn-element tillbaka till index

Exempel

Sortering i for-each<xsl:template match="receptsamling">

<div> <ul id="index"> <xsl:for-each select="//recept/namn">

<xsl:sort select="."/> <li> <a href="#{../@id}">

<xsl:value-of select="."/> </a>

</li> </xsl:for-each> </ul> <xsl:apply-templates/>

</div></xsl:template>

Utesluta element

• Vi kanske inte vill visa all info om ett recept?

• Eller vi kanske inte vill visa alla recept?

• Om vi utesluter ett element utesluter vi också dess barn och ättlingar

• Vi skulle t ex kunna utesluta ett element vars id är lika med carb

Utesluta element, exempel

<xsl:template match="X-PATH-uttryck"/>

<xsl:template match="ingrediens"/>

<xsl:template match="ingrediens[kategori='Grönsak'"]/>

<xsl:template match="recept[@id='carb']"/>

Utesluta element, exempel

<ingrediens><namn>Vitlök</namn><kategori>Grönsak</kategori><mangd enhet="st">1-2 klyftor</mangd>

</ingrediens>

Exempel

Flytta element

• Template-anrop utförs i den ordning de är skrivna i:

<xsl:apply-templates select="mangd[@enhet]"/>

<xsl:apply-templates select="mangd"/><xsl:apply-templates select="kategori"/>

• Här kommer attributet enhet skrivas ut först, sedan mangd och sist namn, t ex: 400 gram köttfärs

Sammanfattning: 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 skiljer sig något från X-PATH

• A=A A är ekvivalent med A• A!=B A är inte ekvivalent med B• 8 &gt; 6 8 är större än 6• 6 &lt; 8 6 är mindre än 8• A &gt;= B A är större än eller lika

med B• B &lt;= A 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, finns det någon logik?

• Kan vi inte helt enkelt nöja oss med att skriva ett antal value-of select-satser i det obligatoriska templatet?

• Nej• Vi måste ta oss ner på en nivå där

syskon inte finns

Nu då?

<xsl:template match="/"><xsl:apply-templates select="receptsamling"/></xsl:template><xsl:template match="recept"> <h2 class="rubrik"><xsl:value-of

select="namn"/></h2><xsl:value-of select="ingrediens/namn"/>&#32;

(<xsl:value-of select="ingrediens/kategori"/>)<br /><xsl:value-of select="ingrediens/mangd"/>&#32;<xsl:value-of select="ingrediens/mangd/@enhet"/><br />

</xsl:template>Exempel

Varför?

• template match matchar varje receptnod en gång

• För varje gång en receptnod matchas genomförs här fem value-of select -satser

• Dessa satser genomförs noll eller en gång, inte en gång för varje ingrediensnod

• Alltså skrivs bara första ingrediensen ut

Förra veckans sista övning

• Klicka här…

Styrstrukturer i XSLT

om (villkor a) utför aannars om (villkor b) utför bannars 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>

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

bok.htm

<body>

<script type="text/javascript">

</script>

...lite kod...

</body>

</html>

(följande exempel är omarbetat efter http://msdn2.microsoft.com/en-gb/library/ms763742.aspx)

bok.htm

<body>

<script type="text/javascript">

</script>

...lite kod...

</body>

</html>

(följande exempel är omarbetat efter http://msdn2.microsoft.com/en-gb/library/ms763742.aspx)

Skapa variabler och tilldela värden

<script type="text/javascript">var xslt = new ActiveXObject("Msxml2.XSLTemplate.3.0");

var xsldoc = new ActiveXObject ("Msxml2.FreeThreadedDOMDocument.3.0");

var xslproc;

Ladda filer

xsldoc.async = false;xsldoc.load("bok.xsl");xslt.stylesheet = xsldoc;var xmldoc = new ActiveXObject("Msxml2.DOMDocument.3.0");

xmldoc.async = false;xmldoc.validateOnParse = false;xmldoc.load("bok.xml");

Lägg in denna rad ifall resultatet uteblir (detta beror sannolikt på att validering gentemot DTD:n misslyckas)

Utför transformation

xslproc = xslt.createProcessor();xslproc.input = xmldoc;xslproc.transform();document.write(xslproc.output);</script>

Resultatet av transformationen skrivs ut här

Variabler

• En behållare som innehåller information av något slag

• Kan vara av olika datatyper, till exempel sträng, heltal, decimaltal etc

• Namnges förslagsvis med ett beskrivande ord

Variabler i XSLT

• Syntax:<xsl:variable name="namn">

<!-- innehåll -->

</xsl:variable>

• Eller:<xsl:variable name="namn" select="uttryck"/>

• name=variabelns namn (måste anges)• select=variabelns värde (valfritt)

Variabler, exempel från w3schools

<xsl:variable name="color" select="'red'" />

<xsl:variable name="header">

<tr>

<th>Element</th> <th>Description</th>

</tr>

</xsl:variable>

Behandla variabler

• Utskrift– <xsl:copy-of select="$header" /> – <xsl:value-of select="$header" />

• Beräkning och utskrift– <xsl:copy-of select="$value*7" /> – <xsl:value-of select="$value*7" />

• En variabels värde kan inte ändras efter att den tilldelats ett värde

Variabler ska deklareras• Global variabel

– Deklareras före dokumentets första template<xsl:variable name="sort"/><xsl:template match="/">…</xsl:template>– Är åtkomlig överallt

• Lokal variabel– Deklareras i aktuellt template<xsl:template match="value"><xsl:variable name="value" select="."/>…

</xsl:template>– Är åtkomlig endast inom templatet

Hopkoppling av olika objekt

• Motsvarande join-operation i en relationsdatabas• Två olika objekt kopplas ihop med hjälp av en

gemensam nämnare• I en databas:

– bok.forfattarid=forfattare.id• I en XML-fil:

<bok><forfattarid>1</forfattarid><titel>…</titel>

</bok><forfattare>

<id>1</id><namn>…</namn>

</forfattare>

Exempel<player>

<name><first>Andres</first><last>D'Alessandro</last>

</name><clubid>1</clubid><position>Midfielder</position><side>Left</side><side>Centre</side><value currency="gbp">4</value>

</player>…<club>

<clubname>Zaragoza</clubname><id>1</id><location>Zaragoza</location><country>Spain</country>

</club>

Jämför<player>

<name><first>Andres</first><last>D'Alessandro</last>

</name><club>

<clubname>Zaragoza</clubname><location>Zaragoza</location><country>Spain</country>

</club><position>Midfielder</position><side>Left</side><side>Centre</side><value currency="gbp">4</value>

</player>…

Matchning med gemensam nämnare

<xsl:template match="player">...<xsl:apply-templates select="clubid"/>...

</xsl:template><xsl:template match="clubid">

<xsl:variable name="clubid" select="."/><xsl:for-each select="//players/club">

<xsl:if test="id=$clubid"> <xsl:value-of select="clubname"/> </xsl:if> </xsl:for-each></xsl:template>

Parametrar

• Ungefär samma som variabler…• …men till skillnad från variabler

kan parametrar skickas med ett template

• Parametrar kan också ta emot värden som skickas in till xls-filen

Parametrar

• Syntax:<xsl:param name="namn">

<!-- innehåll -->

</xsl:param>

• Eller:<xsl:param name="namn" select="uttryck"/>

• name är obligatoriskt…• …men inte select

Parametrar ska också deklareras

• Global parameter– Deklareras före dokumentets första template<xsl:param name="sort"/><xsl:template match="/">…</xsl:template>– Är åtkomlig överallt

• Lokal parameter– Deklareras i aktuellt template<xsl:template match="value"><xsl:param name="value" select="."/>…

</xsl:template>– Är åtkomlig endast inom templatet men kan skickas med

till ett annat template

Template-anrop med parametrar

<xsl:template match="player"><xsl:param name="clubid" select="clubid"/><xsl:apply-templates select="//players/club">

<xsl:with-param name="clubid" select="$clubid"/></xsl:apply-templates>

</xsl:template><xsl:template match="//players/club">

<xsl:param name="clubid"/> <xsl:if test="id=$clubid"> <xsl:value-of select="clubname"/> </xsl:if></xsl:template>

Parametrar utanför X-PATH

• Parametrar kan även användas i attribut som inte är X-PATH-attribut

• Krullparenteser omsluter då parametern:

<a href="{$file}">Next page</a>

Number

• Används för att bestämma en nods position i XML-dokumentet

• Kan också formatera ett nummer• Syntax:

<xsl:number count="uttryck" level="single|multiple|any" from="uttryck" value="uttryck" format="formatsträng" lang="språkkod" letter-value="alphabetic|traditional" grouping-separator="tecken" grouping-size="siffra"/>

• Samtliga attribut är valfria• Exempel:

<xsl:number count="player" format="i. "/>

Lite funktioner…

• sum – räknar summan av noder med numeriska värden<xsl:value-of select="sum(value)"/>

<xsl:if test="sum(value)&gt;50)">

</xsl:if>

• count – räknar antalet noder<xsl:value-of select="count(player)"/>

<xsl:if test="count(player)&gt;10)">

</xsl:if>

Funktionen position()

• Återger ett numeriskt värde på en nods position<xsl:if test="position()!=last()">

<xsl:text>, </xsl:text>

</xsl:if>

<xsl:choose>

<xsl:when test="position() mod 2 = 0">

<span class="rowA">…innehåll…</span>

</xsl:when>

<xsl:otherwise>

<span class="rowB">…innehåll…</span>

</xsl:otherwise>

</xsl:choose>

Mer om position()

• Användbar till exempel då listan ska numreras

<xsl:template match="player"><tr>

<td><xsl:value-of select="position()"/>.&#32;<span class="lName">

<xsl:value-of select="name/last"/>,&#32;</span><xsl:value-of select="name/first"/>

</td></tr>

</xsl:template>

Dynamik

• En dynamisk hemsida kan förändras

• Förändringen kan ske på servern…• …men även hos klienten• Vår dynamik sker med hjälp av

Javascript, det vill säga hos klienten

Skicka en parameter

• Kan göras med hjälp av en url, så kallade GET-variabler

• Görs vanligtvis med ett frågetecken och en efterföljande textsträng eller någon typ av id-nummer

• Exempel: players.htm?value– Skickar med textsträngen value till (x)html-

dokumentet players.htm• Med parameternamn: players.htm?sortby=value• Flera parametrar: players.htm?

sortby=value&order=desc

Ta emot en parameter

var str = '' + this.location;

str = str.substring((str.indexOf('?')) + 1);

Skapar variabeln str och tilldelar den värdet av

aktuell url

Plockar ut allt som finns efter frågetecknet

Skicka vidare till XSL-dokumentet

• Hela Javascriptet:var str = '' + this.location;str = str.substring((str.indexOf('?')) + 1);var xslt = new ActiveXObject("Msxml2.XSLTemplate.3.0");var xsldoc = new

ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");var xslproc;xsldoc.async = false;xsldoc.load("xsl-fil.xsl");xslt.stylesheet = xsldoc;var xmldoc = new ActiveXObject("Msxml2.DOMDocument.3.0");xmldoc.async = false;xmldoc.load("xml-fil.xml");xslproc = xslt.createProcessor();xslproc.input = xmldoc;xslproc.addParameter("sortby", str);xslproc.transform();document.write(xslproc.output);

Ta emot parametern i XSL-dokumentet

• Måste göras globalt, det vill säga före första templatet:

<xsl:param name="sortby"/>

<xsl:template match="/">

</xsl:template>

Användning av parametern

<xsl:template match="players"><xsl:choose>

<xsl:when test="$sortby='lname'"><xsl:apply-templates select="player">

<xsl:sort select="name/last"/></xsl:apply-templates>

</xsl:when><xsl:when test="$sortby='fname'">

<xsl:apply-templates select="player"><xsl:sort select="name/first"/>

</xsl:apply-templates></xsl:when>

</xsl:choose></xsl:template>

Infoga ett Javascript i XSLT-koden

<script>

<xsl:comment>

<![CDATA[

function confirmSort(x) {

var x=x;

alert("Du har klickat på "+x);

}

]]>

</xsl:comment>

</script>

Övningsmaterialet

• http://www.adm.hb.se/~dgu/elpub/xslt2.htm