intermediate xslt bob ducharme snee/bob bob@snee these slides: snee/xml 1.0

33
©CSW Group Ltd 2005 Intermediate XSLT Bob DuCharme www.snee.com/bob [email protected] these slides: www.snee.com/xml 1.0

Upload: ashley

Post on 06-Jan-2016

39 views

Category:

Documents


0 download

DESCRIPTION

Intermediate XSLT Bob DuCharme www.snee.com/bob [email protected] these slides: www.snee.com/xml 1.0. Outline. Variables and parameters Named templates and parameters xsl:for-each and “looping” XSLT extensions and EXSLT Using keys for faster lookups XSLT and browsers. Variables. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

©CSW Group Ltd 2005

Intermediate XSLTBob DuCharme

www.snee.com/[email protected]

these slides: www.snee.com/xml

1.0

Page 2: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Outline

• Variables and parameters

• Named templates and parameters

• xsl:for-each and “looping”

• XSLT extensions and EXSLT

• Using keys for faster lookups

• XSLT and browsers

Page 3: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Variables

<xsl:stylesheet version="1.0"      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output omit-xml-declaration="yes"/>

<xsl:variable name="winnerName">John</xsl:variable>

<xsl:template match="test">  <xsl:text>Congratulations, </xsl:text>  <xsl:value-of select="$winnerName"/>  <xsl:text>, you are a winner!</xsl:text>  <xsl:apply-templates/></xsl:template>

</xsl:stylesheet>

Input document:

     <test/> Output:

    Congratulations, John, you are a winner!

Page 4: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Passing Parameters to Stylesheets

<xsl:stylesheet version="1.0"      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output omit-xml-declaration="yes"/>

<xsl:param name="winnerName">John</xsl:param>

<xsl:template match="test">  <xsl:text>Congratulations, </xsl:text>  <xsl:value-of select="$winnerName"/>  <xsl:text>, you are a winner!</xsl:text>  <xsl:apply-templates/></xsl:template>

</xsl:stylesheet>

Same input document, same result, but when we override the default parameter value:

C:\>saxon temp.xml test.xsl winnerName=JaneCongratulations, Jane, you are a winner!

Page 5: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Named Templates

<xsl:template name="boldIt">  <b><xsl:apply-templates/></b></xsl:template>

<xsl:template match="winery">  <p><xsl:call-template name="boldIt"/></p></xsl:template>

<xsl:template match="product">  <p><xsl:call-template name="boldIt"/></p></xsl:template>

<xsl:template match="year | price">  <p><xsl:apply-templates/></p></xsl:template>

Page 6: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Passing Parameters to Named Templates

  <xsl:template name="titles">    <xsl:param name="headerElement">h4</xsl:param>    <xsl:element name="{$headerElement}">      <xsl:apply-templates/>    </xsl:element>  </xsl:template>

  <xsl:template match="chapter/title">    <xsl:call-template name="titles">      <xsl:with-param name="headerElement">h1</xsl:with-param>    </xsl:call-template>  </xsl:template>

  <xsl:template match="section/title">    <xsl:call-template name="titles">      <xsl:with-param name="headerElement" select="'h2'"/>    </xsl:call-template>  </xsl:template>

Page 7: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Iterating across a set of nodes<a> <b>3</b> <c>10</c> <b>4</b> <c>20</c> <b>5</b></a>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="a"> <xsl:for-each select="b"> <xsl:value-of select=". + 5"/> <xsl:text> </xsl:text> </xsl:for-each> </xsl:template></xsl:stylesheet>

output:

<?xml version="1.0" encoding="UTF-8"?>8 9 10

Page 8: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Repetition

<xsl:template name="hyphens"> <xsl:param name="howMany">1</xsl:param> <xsl:if test="$howMany &gt; 0">

<!-- Add 1 hyphen to result tree. --> <xsl:text>-</xsl:text>

<!-- Print remaining ($howMany - 1) hyphens. --> <xsl:call-template name="hyphens"> <xsl:with-param name="howMany" select="$howMany - 1"/> </xsl:call-template> </xsl:if></xsl:template>

Page 9: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Testing the recursive template rule

<xsl:template match="sample">

Print 1 hyphen: <xsl:call-template name="hyphens"/>

Print 20 hyphens: <xsl:call-template name="hyphens"> <xsl:with-param name="howMany" select="20"/> </xsl:call-template>

Print 0 hyphens: <xsl:call-template name="hyphens"> <xsl:with-param name="howMany" select="0"/> </xsl:call-template>

</xsl:template>

Page 10: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Recursive template rule: result

Print 1 hyphen:

-

Print 20 hyphens:

--------------------

Print 0 hyphens:

Page 11: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

XSLT Extension functions

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:saxon="http://saxon.sf.net/">

<xsl:template match="*">

<xsl:value-of select="saxon:path()"/>

<xsl:text>

</xsl:text>

<xsl:apply-templates/>

</xsl:template>

</xsl:stylesheet>

Page 12: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Testing the extension function

• Source document:<a>

<b/>

<b><c color="red">test</c></b>

<b/>

</a>

• Result:

/a /a/b[1] /a/b[2]/a/b[2]/c[1]test /a/b[3]

Page 13: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Extension elements (and attributes)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" extension-element-prefixes="saxon">

<xsl:variable name="i" select="0" saxon:assignable="yes"/>

<xsl:template match="/">

<saxon:while test="$i &lt; 10"> The value of i is <xsl:value-of select="$i"/> <saxon:assign name="i" select="$i+1"/> </saxon:while>

</xsl:template>

</xsl:stylesheet>

Page 14: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Extension element test output

The value of i is 0

The value of i is 1

The value of i is 2

The value of i is 3

The value of i is 4

The value of i is 5

The value of i is 6

The value of i is 7

The value of i is 8

The value of i is 9

Page 15: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Checking for extension support (option 1)

<saxon:while test="$i &lt; 10">

The value of i is <xsl:value-of select="$i"/>

<xsl:fallback>

<xsl:message>Your XSLT processor doesn't

support saxon:while.</xsl:message>

</xsl:fallback>

<saxon:assign name="i" select="$i+1"/>

</saxon:while>

Page 16: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Checking for extension support (option 2)<xsl:choose>

<xsl:when test="element-available('saxon:while')">

<saxon:while test="$i &lt; 10">

The value of i is <xsl:value-of select="$i"/>

<saxon:assign name="i" select="$i+1"/>

</saxon:while>

</xsl:when>

<xsl:otherwise>

<xsl:message>Your XSLT processor doesn't support

saxon:while.</xsl:message>

</xsl:otherwise>

</xsl:choose>

checking for extension function support: function-available()

Page 17: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

EXSLT

• Saxon documentation on its extensions:

“ Before using a Saxon extension, check whether there is an equivalent EXSLT extension available. EXSLT extensions are more likely to be portable across XSLT processors.”

• http://www.exslt.org

Page 18: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Some EXSLT extensions (pt 1)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:math="http://exslt.org/math" xmlns:date="http://exslt.org/dates-and-times">

<xsl:template match="/">

exsl:object-type(3): <xsl:value-of select="exsl:object-type(3)"/> exsl:object-type('potrzebie'): <xsl:value-of select="exsl:object-type('potrzebie')"/> exsl:object-type(2 &gt; 1): <xsl:value-of select="exsl:object-type(2 &gt; 1)"/>

Page 19: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Some EXSLT extensions (pt 2)

math:constant('PI',4): <xsl:value-of select="math:constant('PI',4)"/> math:constant('PI',12): <xsl:value-of select="math:constant('PI',12)"/> math:sqrt(256): <xsl:value-of select="math:sqrt(256)"/>

date:date-time: <xsl:value-of select="date:date-time()"/> date:day-name: <xsl:value-of select="date:day-name()"/>

</xsl:template>

</xsl:stylesheet>

Page 20: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

EXSLT demo result exsl:object-type(3): number exsl:object-type('potrzebie'): string exsl:object-type(2 &gt; 1): boolean math:constant('PI',4): 3.1415 math:constant('PI',12): 3.141592653589 math:sqrt(256): 16 date:date-time: 2005-06-25T11:24:12-04:00 date:day-name:

Saturday

• same result with Saxon and Xalan Java!

Page 21: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Declaring and using lookup keys

• we have: <shirts>

<colors> <color cid="c1">yellow</color>

<color cid="c4">blue</color>

<!-- similar color elements --> <color cid="c7">orange</color> <color cid="c7">green</color> </colors>

<shirt colorCode="c4">oxford button-down</shirt> <shirt colorCode="c1">poly blend, straight collar</shirt> <shirt colorCode="c6">monogrammed, tab collar</shirt>

</shirts>

• we want: blue oxford button-down

yellow poly blend, straight collar

white monogrammed, tab collar

Page 22: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Without keys<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/>

<xsl:template match="shirt">

<xsl:variable name="shirtColorCode"

select="@colorCode"/>

<xsl:value-of

select="/shirts/colors/color[@cid = $shirtColorCode]"/>

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

</xsl:text>

</xsl:template>

<xsl:template match="color"/>

</xsl:stylesheet>

Page 23: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

With keys

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/>

<xsl:key name="colorNumKey" match="color" use="@cid"/>

<xsl:template match="colors"/>

<xsl:template match="shirt"> <xsl:value-of select="key('colorNumKey',@colorCode)"/> <xsl:text> </xsl:text><xsl:apply-templates/> </xsl:template>

</xsl:stylesheet>

Page 24: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

How key lookup works

Page 25: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

More lookups (part 1)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/>

<xsl:key name="colorNumKey" match="color" use="@cid"/> <xsl:key name="colorKey" match="color" use="."/>

<xsl:variable name="testVar">c4</xsl:variable> <xsl:variable name="keyName">colorKey</xsl:variable>

<xsl:template match="colors">

Looking up the color name with the color ID: c3's color: <xsl:value-of select="key('colorNumKey','c3')"/> c4's color: <xsl:value-of select="key('colorNumKey',$testVar)"/> c8's color: <xsl:value-of select="key('colorNumKey','c8')"/> c7's colors: <xsl:for-each select="key('colorNumKey','c7')"><xsl:value-of select="."/><xsl:text> </xsl:text> </xsl:for-each>

Page 26: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

More lookups (part 2)

Looking up the color ID with the color name: blue's cid: <xsl:value-of select="key('colorKey','blue')/@cid"/> black's cid: <xsl:value-of select="key($keyName,'black')/@cid"/> gray's cid: <xsl:value-of select="key('colorKey','gray')/@cid"/>

</xsl:template>

<!-- Don't bother outputting shirt contents for this example. -->

<xsl:template match="shirt"/>

</xsl:stylesheet>

Page 27: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

More lookups: result

Looking up the color name with the color ID:c3's color: redc4's color: bluec8's color:c7's colors:orange green Looking up the color ID with the color name:blue's cid: c4black's cid: c2gray's cid:

Page 28: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Muenchian Grouping<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="files-by-project" match="file" use="@project"/>

<xsl:template match="files"> <html><body> <xsl:for-each select= "file[count(. | key('files-by-project', @project)[1]) = 1]"> <xsl:sort select="@project"/> <h1><xsl:value-of select="@project" /></h1> <xsl:for-each select="key('files-by-project', @project)"> <xsl:sort select="@name"/> <p><xsl:value-of select="@name"/> <xsl:text>,</xsl:text> <xsl:value-of select="@size"/> bytes</p> </xsl:for-each> </xsl:for-each> </body></html> </xsl:template>

</xsl:stylesheet>

Page 29: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Muenchian Grouping: result

<html> <body> <h1>jupiter</h1> <p>gadabout.pas,685 bytes</p> <p>kwatz.xom,43 bytes</p> <p>potrzebie.dbf,1102 bytes</p> <h1>mars</h1> <p>schtroumpf.txt,389 bytes</p> <p>swablr.eps,4313 bytes</p> <p>ummagumma.zip,2441 bytes</p> <h1>neptune</h1> <p>batboy.wks,424 bytes</p> <p>mondegreen.doc,1993 bytes</p> <p>paisley.doc,988 bytes</p> </body></html>

Page 30: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Web Browsers and XSLT

W3C Recommendation "Associating Style Sheets

with XML documents"

(http://www.w3.org/TR/xml-stylesheet) shows how:

<?xml-stylesheet href="squareAsHTML.xsl" type="text/xsl" ?><numbers> <number>2</number> <number>11</number> <number>100</number> <number>-5</number></numbers>

Page 31: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Web Browsers and XSLT (part 1)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><!-- squareAsHTML.xsl: create an HTML document with a statement about the square of each "number" element read from the source tree. -->

<xsl:template match="/"> <!-- Set up web page --> <html> <head> <title>Squares</title> <style> <!-- Put a little CSS in --> body { font-family: arial,helvetica; } h1 { font-size: 14pt } p { font-size: 10pt} </style> </head> <body> <h1>Squares</h1> <xsl:apply-templates/> </body> </html> </xsl:template>

Page 32: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

Web Browsers and XSLT (part 2)

<xsl:template match="number"> <xsl:variable name="value" select="."/> <p> <xsl:text>The square of </xsl:text> <xsl:value-of select="$value"/> <xsl:text> is </xsl:text> <xsl:value-of select="$value * $value"/>.</p> </xsl:template>

</xsl:stylesheet>

You could create your HTML like this:

saxon -o numbers.html numbers.xml squareAsHTML.xsl

Page 33: Intermediate XSLT Bob DuCharme snee/bob bob@snee these slides: snee/xml 1.0

XSLT 2.0

• Lots more built-in functions

• Writing your own functions

• Regular expressions

• Grouping output by values

• Tokenizing strings

• Typing awareness