Introduction to XSLT
2
Introduction to XSLT
Agenda
The X* Ecosystem (XSL, XPath, XQuery...)
XML Refresh/Terminology
XPath: Addresses for XML documents
XSLT Basics: template and value-of
XSLT Loops: apply-templates and for-each
XSLT Decisions: if and choose
XSLT Variables: variable and param
XSLT Extras: sort, copy-of, document…
Why/When XSLT?
3
The X* Ecosystem
• XSL(T): Extensible Stylesheet Language
(Transforms)
– Like a giant function with a domain of XML and a
range of XML, HTML and Text
– XSL-FO (Formatting Objects) is a related,
graphics/print-oriented language
• XPath: XML Path (addressing)
– Like a filesystem path in an XML document
– Also like RegEx
– a language for navigating in XML documents
4
XML Refresh/Terminology
XML Nodes
 Processing instruction: <?pi ... ?>
 Element: <element /> or
<element></element>
 Attribute: <element attribute="value" />
 Comment: <!-- comment -->
 Entity: &amp;
 Text node (just plain text)
5
XML Refresh/Terminology
XML Syntax Rules
 Escape < > & (turn them into entities &lt;
&gt; &amp;)
 Every document has exactly one root element
 Attribute values are always quoted
 Elements are case-sensitive (and are typically
lowercase)
 You don't have to put an xml processing
instruction at the top of your document
6
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book[@name="The
Fourth Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
7
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book[@name="The
Fourth Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
8
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book[@name="The
Fourth Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
9
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book
[@name="The Fourth
Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
10
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book[@name="The
Fourth Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
11
XPath: Addresses for XML
XPath Expressions
/library
/library/book
/library/book/@name
/library/book[@name="The
Fourth Civilization"]
/library/book[1]
//book[2]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
12
XPath: Addresses for XML
XPath Node
selectors
/library/*
/library/book[1]/text()
/library/node()[1]
.
<library>
<!-- comment -->
<book>The Principles of
Computer
Hardware</book>
<book name="The Fourth
Civilization"
/>
</library>
13
XPath: Addresses for XML
XPath Node
selectors
/library/*
/library/book[1]/text()
/library/node()[1]
.
<library>
<!-- comment -->
<book>The Principles of
Computer
Hardware</book>
<book name="The Fourth
Civilization"
/>
</library>
14
XPath: Addresses for XML
XPath Node
selectors
/library/*
/library/book[1]/text()
/library/node()[1]
.
<library>
<!-- comment -->
<book>The Principles of
Computer
Hardware</book>
<book name="The Fourth
Civilization"
/>
</library>
15
XPath: Addresses for XML
XPath Node
selectors
/library/*
/library/book[1]/text()
/library/node()[1]
.
<library>
<!-- comment -->
<book>The Principles of
Computer
Hardware</book>
<book name="The Fourth
Civilization"
/>
</library>
16
XPath: Addresses for XML
XPath Axes
/library/child::book
(or /library/book for short)
/descendent-or-self::book
(or //book for short)
//book[1]/parent::*
(or //book[1]/.. for short)
//book[2]/preceding-
sibling::book
//book[1]/attribute::name
(or //book[1]/@name for
short)
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
17
XPath: Addresses for XML
XPath Axes
/library/child::book
(or /library/book for short)
/descendent-or-
self::book
(or //book for short)
//book[1]/parent::*
(or //book[1]/.. for short)
//book[2]/preceding-
sibling::book
//book[1]/attribute::name
(or //book[1]/@name for
short)
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
18
XPath: Addresses for XML
XPath Axes
/library/child::book
(or /library/book for short)
/descendent-or-self::book
(or //book for short)
//book[1]/parent::*
(or //book[1]/.. for short)
//book[2]/preceding-
sibling::book
//book[1]/attribute::name
(or //book[1]/@name for
short)
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
19
XPath: Addresses for XML
XPath Axes
/library/child::book
(or /library/book for short)
/descendent-or-self::book
(or //book for short)
//book[1]/parent::*
(or //book[1]/.. for short)
//book[2]/preceding-
sibling::book
//book[1]/attribute::name
(or //book[1]/@name for
short)
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
20
XPath: Addresses for XML
XPath Axes
/library/child::book
(or /library/book for short)
/descendent-or-self::book
(or //book for short)
//book[1]/parent::*
(or //book[1]/.. for short)
//book[2]/preceding-
sibling::book
//book[1]/
attribute::name
(or //book[1]/@name for
short)
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
21
XPath: Addresses for XML
XPath Functions
//book[last()]
count(//book)
name(/*)
//book[contains(@name,
"C++")]
//book[not(contains(
@name, "C++"))]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
22
XPath: Addresses for XML
XPath Functions
//book[last()]
count(//book)
name(/*)
//book[contains(@name,
"C++")]
//book[not(contains(
@name, "C++"))]
Returns: 2
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
23
XPath: Addresses for XML
XPath Functions
//book[last()]
count(//book)
name(/*)
//book[contains(@name,
"C++")]
//book[not(contains(
@name, "C++"))]
Returns: "library"
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
24
XPath: Addresses for XML
XPath Functions
//book[last()]
count(//book)
name(/*)
//book[contains(
@name, "C++")]
//book[not(contains(
@name, "C++"))]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
25
XPath: Addresses for XML
XPath Functions
//book[last()]
count(//book)
name(/*)
//book[contains(@name,
"C++")]
//book[not(contains(
@name, "C++"))]
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
26
XPath: Addresses for XML
Other Useful XPath Functions
position() – provides the position in a list (nice for numbering a
sequence of nodes)
sum(xpath) – takes a sequence of nodes and adds up their
numerical values – see also avg(), min(), max()
concat(string, string, …) – exactly what you think
string-length(string) – returns the number of characters
substring(string, start[, length]) – the first char is at 1
translate(source-string, find-string, replace-string) – looks
for individual chars and replaces them
Example: translate("ABCD", "BD", "bd")  "AbCd"
27
XPath: Addresses for XML
XPath Operators
//book[last() or
contains(@name,
"C++")]
//book[string-
length(@name) > 5]
//book[1] | //book[2]
Other operators:
and, =, >, <=, >=, !=, +,
-, *, div, mod
Don't forget to escape < >!
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
28
XPath: Addresses for XML
XPath Operators
//book[last() or
contains(@name,
"C++")]
//book[string-
length(@name) > 5]
//book[1] | //book[2]
Other operators:
and, =, >, <=, >=, !=, +,
-, *, div, mod
Don't forget to escape < >!
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
29
XPath: Addresses for XML
XPath Operators
//book[last() or
contains(@name,
"C++")]
//book[string-
length(@name) > 5]
//book[1] | //book[2]
Other operators:
and, =, >, <=, >=, !=, +,
-, *, div, mod
Don't forget to escape < >!
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
30
XPath: Addresses for XML
XPath Operators
//book[last() or
contains(@name,
"C++")]
//book[string-
length(@name) > 5]
//book[1] | //book[2]
Other operators:
and, =, >, <=, >=, !=,
+, -, *, div, mod
Don't forget to escape < >!
<library>
<book name="C++ How to
Program" />
<book name="The Fourth
Civilization"
/>
</library>
31
XSLT Basics
• Try it out
– Make an XML file
– Make an XSLT file
– Run the transform and
view the transformed
data
<xml />
input
<xsl:… />
transform
<xml />
(or text)
output
• <xsl:template> Element
– It details what items from the source document it should
handle and uses its content to specify what should be added to
the output when it is executed
– match attribute is used to associate a template with an XML
element and define a template for the entire document. E.g
emptyXSL.xsl
• <xsl:value-of> Element
– used to evaluate an expression and add the result to the
output
– used to extract the value of an XML element and add it to the
output stream of the transformation
• <xsl:for-each> Element
– used to select every XML element of a specified node-set
• <xsl:apply-templates> Element
– responsible for deciding which items in the source document
should be processed; they are then handled by the appropriate
template
33
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind.</quote>
</person>
Sample Output
Neil Armstrong said "...one giant
leap for mankind."
Sample XSLT
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/person">
<xsl:value-of select="concat(
name/@first, ' ', name/@last)"
/>
said "
<xsl:value-of select="quote" />"
</xsl:template>
</xsl:stylesheet>
34
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind.</quote>
</person>
Sample Output
Neil Armstrong said "...one giant
leap for mankind."
Sample XSLT
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/person">
<xsl:value-of select="concat(
name/@first, ' ', name/@last)"
/>
said "
<xsl:value-of select="quote" />"
</xsl:template>
</xsl:stylesheet>
35
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind.</quote>
</person>
Sample Output
Neil Armstrong said "...one giant
leap for mankind."
Sample XSLT
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/person">
<xsl:value-of select="concat(
name/@first, ' ', name/@last)"
/>
said "
<xsl:value-of select="quote" />"
</xsl:template>
</xsl:stylesheet>
36
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
Sample Output
<html><head><title>Neil
Armstrong</title>
</head>
<body><blockquote>…one giant
leap for mankind.</blockquote>
</body></html>
Sample XSLT  HTML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/person">
<html><head><title>
<xsl:value-of select="concat(
name/@first, ' ', name/@last)" />
</title></head><body>
<blockquote><xsl:value-of
select="quote" /></blockquote>
</body></html>
</xsl:template>
</xsl:stylesheet>
37
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
Sample Output
<html><head><title>Neil
Armstrong</title>
</head>
<body><blockquote>…one giant
leap for mankind.</blockquote>
</body></html>
Sample XSLT  HTML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/person">
<html><head><title>
<xsl:value-of select="concat(
name/@first, ' ', name/@last)" />
</title></head><body>
<blockquote><xsl:value-of
select="quote" /> </blockquote>
</body></html>
</xsl:template>
</xsl:stylesheet>
38
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
Sample Output
<quote><speaker firstname="Neil"
lastname="Armstrong"/>
<text>…one giant leap for
mankind.</text>
</quote>
Sample XSLT  XML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/person">
<quote><speaker
firstname="{name/@first}"
lastname="{name/@last}"/>
<text><xsl:value-of select="quote"
/></text>
</quote>
</xsl:template>
</xsl:stylesheet>
39
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
Sample Output
<quote><speaker firstname="Neil"
lastname="Armstrong"/>
<text>…one giant leap for
mankind.</text>
</quote>
Sample XSLT  XML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/person">
<quote><speaker
firstname="{name/@first}"
lastname="{name/@last}"/>
<text><xsl:value-of select="quote"
/></text>
</quote>
</xsl:template>
</xsl:stylesheet>
40
XSLT Basics
Sample XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
Sample Output
<quote><speaker firstname="Neil"
lastname="Armstrong"/>
<text>…one giant leap for
mankind.</text>
</quote>
Sample XSLT  XML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/person">
<quote><speaker
firstname="{name/@first}"
lastname="{name/@last}"/>
<text><xsl:value-of select="quote"
/></text>
</quote>
</xsl:template>
</xsl:stylesheet>
41
XSLT Loops: for-each
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Sample XSLT  HTML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/zoo">
<html><head><title>Zoo</title>
</head><body>
<xsl:for-each select="*">
<h1>
<xsl:value-of select="name(.)" />
</h1>
</xsl:for-each>
</body></html>
</xsl:template>
</xsl:stylesheet>
42
XSLT Loops: for-each
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title>
</head><body>
<h1>
birds
</h1>
<h1>
mammals
</h1>
</body></html>
43
XSLT Loops: for-each
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Sample XSLT  HTML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/zoo">
<html><head><title>Zoo</title>
</head><body>
<xsl:for-each select="*">
<h1><xsl:value-of select="name(.)" /></h1>
<ul><xsl:for-each select="*">
<li><xsl:value-of select="name(.)" />
(<xsl:value-of select="@pop">)</li>
</xsl:for-each></ul>
</xsl:for-each>
</body></html>
</xsl:template>
</xsl:stylesheet>
44
XSLT Loops: for-each
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title>
</head><body>
<h1>birds</h1>
<ul>
<li>albatross (4)</li>
…
</ul>
<h1>mammals</h1>
<ul>
<li>aardvark (5)</li>
…
</ul>
</body></html>
45
XSLT Loops: apply-templates
<xsl:template
match="birds | mammals">
<h1><xsl:value-of select="name(.)"
/></h1>
<ul>
<xsl:for-each select="*">
<li><xsl:value-of
select="name(.)" />
(<xsl:value-of
select="@pop"/>)</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Sample XSLT
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/zoo">
<html>
<head><title>Zoo</title></head>
<body>
<xsl:apply-templates
select="*" />
</body>
</html>
</xsl:template>
46
XSLT Decisions: if
XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
XSLT
…
<xsl:template match="birds | mammals">
<h1><xsl:value-of select="name(.)" /> </h1>
<p>We have more than 2...</p>
<xsl:if test="*[@pop &gt; 2]">
<ul>
<xsl:for-each select="*[@pop &gt; 2]">
<li><xsl:value-of select="name(.)" /></li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
…
47
XSLT Decisions: if
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title></head><body>
<h1>birds</h1>
<p>We have more than 2...</p>
<ul>
<li>albatross</li>
<li>chickadee</li>
</ul>
<h1>mammals</h1>
<p>We have more than 2...</p>
<ul>
<li>aardvark</li>
<li>bat</li>
</ul>
</body></html>
48
XSLT Decisions: choose
XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
XSLT fragment
<xsl:template match="birds | mammals">
<ul><xsl:for-each select="*">
<li><xsl:value-of select="name(.)" />
(<xsl:choose>
<xsl:when test="@pop = 2">a
couple</xsl:when>
<xsl:when test="@pop &lt;= 5">a
few</xsl:when>
<xsl:otherwise>many</xsl:otherwise>
</xsl:choose>)
</li>
</xsl:for-each></ul>
</xsl:template>
49
XSLT Decisions: choose
Sample XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title></head><body>
<ul>
<li>albatross (a few)</li>
<li>buzzard (a couple)</li>
<li>chickadee (many)</li>
</ul>
<ul>
<li>aardvark (a few)</li>
<li>bat (many)</li>
<li>cheetah (a couple)</li>
</ul>
</body></html>
50
XSLT Variables: variable
XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
XSLT fragment
<xsl:template match="birds | mammals">
<xsl:variable name="total-animals"
select="sum(*/@pop)" />
<ul><xsl:for-each select="*">
<li><xsl:value-of select="name(.)" />
(<xsl:value-of select="round(100 * @pop div
$total-animals)"/>% of all <xsl:value-of
select="name(..)"/>)
</li>
</xsl:for-each></ul>
</xsl:template>
51
XSLT Variables: variable
Source XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title></head><body>
<ul>
<li>albatross (22% of all birds)</li>
<li>buzzard (11% of all birds)</li>
<li>chickadee (67% of all birds)</li>
</ul>
<ul>
<li>aardvark (2% of all mammals)</li>
<li>bat (97% of all mammals)</li>
<li>cheetah (1% of all mammals)</li>
</ul>
</body></html>
52
XSLT Variables: parameter
<xsl:template name="animal">
<xsl:param name="total" />
<li>
<xsl:value-of select="name(.)" />
(<xsl:value-of select="round(100 *
@pop div $total)"/>%)
</li>
</xsl:template>
XSLT fragments
<xsl:template match="birds |
mammals">
<xsl:variable name="total-
animals" select="sum(*/@pop)"
/>
<ul><xsl:for-each select="*">
<xsl:call-template
name="animal">
<xsl:with-param name="total"
value="$total-animals">
</xsl:call-template>
</xsl:for-each></ul>
</xsl:template>
53
XSLT Variables: param
<xsl:template name="animal">
<xsl:param name="total" />
<li>
<xsl:value-of select="name(.)" />
(<xsl:value-of select="round(100 *
@pop div $total)"/>%)
</li>
</xsl:template>
XSLT fragments
<xsl:template match="birds |
mammals">
<xsl:variable name="total-
animals" select="sum(*/@pop)"
/>
<ul><xsl:for-each select="*">
<xsl:call-template
name="animal">
<xsl:with-param
name="total" value="$total-
animals">
</xsl:call-template>
</xsl:for-each></ul>
</xsl:template>
54
XSLT Variables: param
XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
XSLT fragment
<xsl:param name="minimum-population" select="5" />
<xsl:template match="birds | mammals">
<ul>
<xsl:for-each select="*[@pop &gt;= $minimum-
population]">
<li><xsl:value-of select="name(.)" />
(<xsl:value-of select="@pop"/>)
</li>
</xsl:for-each></ul>
</xsl:template>
55
XSLT Variables: param
Source XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title></head><body>
<ul>
<li>chickadee (12)</li>
</ul>
<ul>
<li>aardvark (5)</li>
<li>bat (200)</li>
</ul>
</body></html>
56
XSLT Extras: sort
XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
XSLT fragment
<xsl:template match="birds | mammals">
<ul>
<xsl:for-each select="*">
<xsl:sort select="@pop" order="descending" data-
type="number" />
<li><xsl:value-of select="name(.)" />
(<xsl:value-of select="@pop"/>)
</li>
</xsl:for-each></ul>
</xsl:template>
57
XSLT Extras: sort
Source XML
<zoo>
<birds>
<albatross pop="4" />
<buzzard pop="2" />
<chickadee pop="12" />
</birds>
<mammals>
<aardvark pop="5" />
<bat pop="200" />
<cheetah pop="2" />
</mammals>
</zoo>
Result HTML
<html><head><title>Zoo</title></head><body>
<ul>
<li>chickadee (12)</li>
<li>albatross (4)</li>
<li>buzzard (2)</li>
</ul>
<ul>
<li>bat (200)</li>
<li>aardvark (5)</li>
<li>cheetah (2)</li>
</ul>
</body></html>
58
XSLT Extras: copy-of
Source XML
<person>
<name first="Neil"
last="Armstrong" />
<quote>...one giant leap for
mankind. </quote>
</person>
XML Output
<quote><name first="Neil"
last="Armstrong"/> <text>…one
giant leap for mankind.</text>
</quote>
Sample XSLT  XML
<xsl:stylesheet version="1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/person">
<quote><xsl:copy-of select="name"
/>
<text><xsl:value-of select="quote"
/></text>
</quote>
</xsl:template>
</xsl:stylesheet>
59
XSLT Extras: more elements
• xsl:text – writes literal text to the output
(useful for controlling whitespace or forcing
exact, unescaped output)
• xsl:processing-instruction – writes a PI like
<?php… ?> or <?xml-stylesheet… ?> to the
output
• xsl:import and xsl:include – used to combine
stylesheets (useful for XSLT libraries)
60
XSLT Extras: more functions
• document(url) – opens an XML document at the
given location, returning its nodes as data that
can be used by the template
Example:
document('zoo.xml')/zoo//*[@pop = 2]
• current() – similar to "." except that it always
refers to the current node, even when used inside
predicates
Example:
//*[@pop = current()/@pop]
61
XSLT Extras: xml-stylesheet
To make an XML document show itself in a
transformed format, add this to the top:
<?xml-stylesheet type="text/xsl"
href="path/to/transform.xslt" ?>
This is particularly useful for XML like RSS
62
Why/When XSLT?
 Web Standard
 XSLT v 1.0 Recommended by W3C almost 10
years ago (it's stable and well understood)
 Dozens of implementations and host
languages (Java, .NET, PHP, C++…)
 Wide tool support (Firefox, IE, Visual Studio,
many text editors, full IDEs…)
 No vendor lock-in
63
Why/When XSLT?
Very good at converting XML to XML,
XHTML/HTML, or plain text
 Makes it easy to keep things well-formed
 Uses XML syntax, so the only real new syntax
is XPath (which is also used elsewhere)
 XPath is far more compact than similar DOM
code in JS/Java/C#/etc.
 Can be interpreted (for quick development)
or compiled (for maximum performance)

Introductionto xslt

  • 1.
  • 2.
    2 Introduction to XSLT Agenda TheX* Ecosystem (XSL, XPath, XQuery...) XML Refresh/Terminology XPath: Addresses for XML documents XSLT Basics: template and value-of XSLT Loops: apply-templates and for-each XSLT Decisions: if and choose XSLT Variables: variable and param XSLT Extras: sort, copy-of, document… Why/When XSLT?
  • 3.
    3 The X* Ecosystem •XSL(T): Extensible Stylesheet Language (Transforms) – Like a giant function with a domain of XML and a range of XML, HTML and Text – XSL-FO (Formatting Objects) is a related, graphics/print-oriented language • XPath: XML Path (addressing) – Like a filesystem path in an XML document – Also like RegEx – a language for navigating in XML documents
  • 4.
    4 XML Refresh/Terminology XML Nodes Processing instruction: <?pi ... ?>  Element: <element /> or <element></element>  Attribute: <element attribute="value" />  Comment: <!-- comment -->  Entity: &amp;  Text node (just plain text)
  • 5.
    5 XML Refresh/Terminology XML SyntaxRules  Escape < > & (turn them into entities &lt; &gt; &amp;)  Every document has exactly one root element  Attribute values are always quoted  Elements are case-sensitive (and are typically lowercase)  You don't have to put an xml processing instruction at the top of your document
  • 6.
    6 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 7.
    7 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 8.
    8 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 9.
    9 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book [@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 10.
    10 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 11.
    11 XPath: Addresses forXML XPath Expressions /library /library/book /library/book/@name /library/book[@name="The Fourth Civilization"] /library/book[1] //book[2] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 12.
    12 XPath: Addresses forXML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
  • 13.
    13 XPath: Addresses forXML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
  • 14.
    14 XPath: Addresses forXML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
  • 15.
    15 XPath: Addresses forXML XPath Node selectors /library/* /library/book[1]/text() /library/node()[1] . <library> <!-- comment --> <book>The Principles of Computer Hardware</book> <book name="The Fourth Civilization" /> </library>
  • 16.
    16 XPath: Addresses forXML XPath Axes /library/child::book (or /library/book for short) /descendent-or-self::book (or //book for short) //book[1]/parent::* (or //book[1]/.. for short) //book[2]/preceding- sibling::book //book[1]/attribute::name (or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 17.
    17 XPath: Addresses forXML XPath Axes /library/child::book (or /library/book for short) /descendent-or- self::book (or //book for short) //book[1]/parent::* (or //book[1]/.. for short) //book[2]/preceding- sibling::book //book[1]/attribute::name (or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 18.
    18 XPath: Addresses forXML XPath Axes /library/child::book (or /library/book for short) /descendent-or-self::book (or //book for short) //book[1]/parent::* (or //book[1]/.. for short) //book[2]/preceding- sibling::book //book[1]/attribute::name (or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 19.
    19 XPath: Addresses forXML XPath Axes /library/child::book (or /library/book for short) /descendent-or-self::book (or //book for short) //book[1]/parent::* (or //book[1]/.. for short) //book[2]/preceding- sibling::book //book[1]/attribute::name (or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 20.
    20 XPath: Addresses forXML XPath Axes /library/child::book (or /library/book for short) /descendent-or-self::book (or //book for short) //book[1]/parent::* (or //book[1]/.. for short) //book[2]/preceding- sibling::book //book[1]/ attribute::name (or //book[1]/@name for short) <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 21.
    21 XPath: Addresses forXML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains( @name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 22.
    22 XPath: Addresses forXML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains( @name, "C++"))] Returns: 2 <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 23.
    23 XPath: Addresses forXML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains( @name, "C++"))] Returns: "library" <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 24.
    24 XPath: Addresses forXML XPath Functions //book[last()] count(//book) name(/*) //book[contains( @name, "C++")] //book[not(contains( @name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 25.
    25 XPath: Addresses forXML XPath Functions //book[last()] count(//book) name(/*) //book[contains(@name, "C++")] //book[not(contains( @name, "C++"))] <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 26.
    26 XPath: Addresses forXML Other Useful XPath Functions position() – provides the position in a list (nice for numbering a sequence of nodes) sum(xpath) – takes a sequence of nodes and adds up their numerical values – see also avg(), min(), max() concat(string, string, …) – exactly what you think string-length(string) – returns the number of characters substring(string, start[, length]) – the first char is at 1 translate(source-string, find-string, replace-string) – looks for individual chars and replaces them Example: translate("ABCD", "BD", "bd")  "AbCd"
  • 27.
    27 XPath: Addresses forXML XPath Operators //book[last() or contains(@name, "C++")] //book[string- length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 28.
    28 XPath: Addresses forXML XPath Operators //book[last() or contains(@name, "C++")] //book[string- length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 29.
    29 XPath: Addresses forXML XPath Operators //book[last() or contains(@name, "C++")] //book[string- length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 30.
    30 XPath: Addresses forXML XPath Operators //book[last() or contains(@name, "C++")] //book[string- length(@name) > 5] //book[1] | //book[2] Other operators: and, =, >, <=, >=, !=, +, -, *, div, mod Don't forget to escape < >! <library> <book name="C++ How to Program" /> <book name="The Fourth Civilization" /> </library>
  • 31.
    31 XSLT Basics • Tryit out – Make an XML file – Make an XSLT file – Run the transform and view the transformed data <xml /> input <xsl:… /> transform <xml /> (or text) output
  • 32.
    • <xsl:template> Element –It details what items from the source document it should handle and uses its content to specify what should be added to the output when it is executed – match attribute is used to associate a template with an XML element and define a template for the entire document. E.g emptyXSL.xsl • <xsl:value-of> Element – used to evaluate an expression and add the result to the output – used to extract the value of an XML element and add it to the output stream of the transformation • <xsl:for-each> Element – used to select every XML element of a specified node-set • <xsl:apply-templates> Element – responsible for deciding which items in the source document should be processed; they are then handled by the appropriate template
  • 33.
    33 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat( name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote" />" </xsl:template> </xsl:stylesheet>
  • 34.
    34 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat( name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote" />" </xsl:template> </xsl:stylesheet>
  • 35.
    35 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind.</quote> </person> Sample Output Neil Armstrong said "...one giant leap for mankind." Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <xsl:template match="/person"> <xsl:value-of select="concat( name/@first, ' ', name/@last)" /> said " <xsl:value-of select="quote" />" </xsl:template> </xsl:stylesheet>
  • 36.
    36 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <html><head><title>Neil Armstrong</title> </head> <body><blockquote>…one giant leap for mankind.</blockquote> </body></html> Sample XSLT  HTML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/person"> <html><head><title> <xsl:value-of select="concat( name/@first, ' ', name/@last)" /> </title></head><body> <blockquote><xsl:value-of select="quote" /></blockquote> </body></html> </xsl:template> </xsl:stylesheet>
  • 37.
    37 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <html><head><title>Neil Armstrong</title> </head> <body><blockquote>…one giant leap for mankind.</blockquote> </body></html> Sample XSLT  HTML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/person"> <html><head><title> <xsl:value-of select="concat( name/@first, ' ', name/@last)" /> </title></head><body> <blockquote><xsl:value-of select="quote" /> </blockquote> </body></html> </xsl:template> </xsl:stylesheet>
  • 38.
    38 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT  XML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote" /></text> </quote> </xsl:template> </xsl:stylesheet>
  • 39.
    39 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT  XML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote" /></text> </quote> </xsl:template> </xsl:stylesheet>
  • 40.
    40 XSLT Basics Sample XML <person> <namefirst="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> Sample Output <quote><speaker firstname="Neil" lastname="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT  XML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><speaker firstname="{name/@first}" lastname="{name/@last}"/> <text><xsl:value-of select="quote" /></text> </quote> </xsl:template> </xsl:stylesheet>
  • 41.
    41 XSLT Loops: for-each SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Sample XSLT  HTML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html><head><title>Zoo</title> </head><body> <xsl:for-each select="*"> <h1> <xsl:value-of select="name(.)" /> </h1> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet>
  • 42.
    42 XSLT Loops: for-each SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title> </head><body> <h1> birds </h1> <h1> mammals </h1> </body></html>
  • 43.
    43 XSLT Loops: for-each SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Sample XSLT  HTML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html><head><title>Zoo</title> </head><body> <xsl:for-each select="*"> <h1><xsl:value-of select="name(.)" /></h1> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop">)</li> </xsl:for-each></ul> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet>
  • 44.
    44 XSLT Loops: for-each SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title> </head><body> <h1>birds</h1> <ul> <li>albatross (4)</li> … </ul> <h1>mammals</h1> <ul> <li>aardvark (5)</li> … </ul> </body></html>
  • 45.
    45 XSLT Loops: apply-templates <xsl:template match="birds| mammals"> <h1><xsl:value-of select="name(.)" /></h1> <ul> <xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop"/>)</li> </xsl:for-each> </ul> </xsl:template> </xsl:stylesheet> Sample XSLT <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/zoo"> <html> <head><title>Zoo</title></head> <body> <xsl:apply-templates select="*" /> </body> </html> </xsl:template>
  • 46.
    46 XSLT Decisions: if XML <zoo> <birds> <albatrosspop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT … <xsl:template match="birds | mammals"> <h1><xsl:value-of select="name(.)" /> </h1> <p>We have more than 2...</p> <xsl:if test="*[@pop &gt; 2]"> <ul> <xsl:for-each select="*[@pop &gt; 2]"> <li><xsl:value-of select="name(.)" /></li> </xsl:for-each> </ul> </xsl:if> </xsl:template> …
  • 47.
    47 XSLT Decisions: if SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <h1>birds</h1> <p>We have more than 2...</p> <ul> <li>albatross</li> <li>chickadee</li> </ul> <h1>mammals</h1> <p>We have more than 2...</p> <ul> <li>aardvark</li> <li>bat</li> </ul> </body></html>
  • 48.
    48 XSLT Decisions: choose XML <zoo> <birds> <albatrosspop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:template match="birds | mammals"> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:choose> <xsl:when test="@pop = 2">a couple</xsl:when> <xsl:when test="@pop &lt;= 5">a few</xsl:when> <xsl:otherwise>many</xsl:otherwise> </xsl:choose>) </li> </xsl:for-each></ul> </xsl:template>
  • 49.
    49 XSLT Decisions: choose SampleXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <ul> <li>albatross (a few)</li> <li>buzzard (a couple)</li> <li>chickadee (many)</li> </ul> <ul> <li>aardvark (a few)</li> <li>bat (many)</li> <li>cheetah (a couple)</li> </ul> </body></html>
  • 50.
    50 XSLT Variables: variable XML <zoo> <birds> <albatrosspop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:template match="birds | mammals"> <xsl:variable name="total-animals" select="sum(*/@pop)" /> <ul><xsl:for-each select="*"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="round(100 * @pop div $total-animals)"/>% of all <xsl:value-of select="name(..)"/>) </li> </xsl:for-each></ul> </xsl:template>
  • 51.
    51 XSLT Variables: variable SourceXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <ul> <li>albatross (22% of all birds)</li> <li>buzzard (11% of all birds)</li> <li>chickadee (67% of all birds)</li> </ul> <ul> <li>aardvark (2% of all mammals)</li> <li>bat (97% of all mammals)</li> <li>cheetah (1% of all mammals)</li> </ul> </body></html>
  • 52.
    52 XSLT Variables: parameter <xsl:templatename="animal"> <xsl:param name="total" /> <li> <xsl:value-of select="name(.)" /> (<xsl:value-of select="round(100 * @pop div $total)"/>%) </li> </xsl:template> XSLT fragments <xsl:template match="birds | mammals"> <xsl:variable name="total- animals" select="sum(*/@pop)" /> <ul><xsl:for-each select="*"> <xsl:call-template name="animal"> <xsl:with-param name="total" value="$total-animals"> </xsl:call-template> </xsl:for-each></ul> </xsl:template>
  • 53.
    53 XSLT Variables: param <xsl:templatename="animal"> <xsl:param name="total" /> <li> <xsl:value-of select="name(.)" /> (<xsl:value-of select="round(100 * @pop div $total)"/>%) </li> </xsl:template> XSLT fragments <xsl:template match="birds | mammals"> <xsl:variable name="total- animals" select="sum(*/@pop)" /> <ul><xsl:for-each select="*"> <xsl:call-template name="animal"> <xsl:with-param name="total" value="$total- animals"> </xsl:call-template> </xsl:for-each></ul> </xsl:template>
  • 54.
    54 XSLT Variables: param XML <zoo> <birds> <albatrosspop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:param name="minimum-population" select="5" /> <xsl:template match="birds | mammals"> <ul> <xsl:for-each select="*[@pop &gt;= $minimum- population]"> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop"/>) </li> </xsl:for-each></ul> </xsl:template>
  • 55.
    55 XSLT Variables: param SourceXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <ul> <li>chickadee (12)</li> </ul> <ul> <li>aardvark (5)</li> <li>bat (200)</li> </ul> </body></html>
  • 56.
    56 XSLT Extras: sort XML <zoo> <birds> <albatrosspop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> XSLT fragment <xsl:template match="birds | mammals"> <ul> <xsl:for-each select="*"> <xsl:sort select="@pop" order="descending" data- type="number" /> <li><xsl:value-of select="name(.)" /> (<xsl:value-of select="@pop"/>) </li> </xsl:for-each></ul> </xsl:template>
  • 57.
    57 XSLT Extras: sort SourceXML <zoo> <birds> <albatross pop="4" /> <buzzard pop="2" /> <chickadee pop="12" /> </birds> <mammals> <aardvark pop="5" /> <bat pop="200" /> <cheetah pop="2" /> </mammals> </zoo> Result HTML <html><head><title>Zoo</title></head><body> <ul> <li>chickadee (12)</li> <li>albatross (4)</li> <li>buzzard (2)</li> </ul> <ul> <li>bat (200)</li> <li>aardvark (5)</li> <li>cheetah (2)</li> </ul> </body></html>
  • 58.
    58 XSLT Extras: copy-of SourceXML <person> <name first="Neil" last="Armstrong" /> <quote>...one giant leap for mankind. </quote> </person> XML Output <quote><name first="Neil" last="Armstrong"/> <text>…one giant leap for mankind.</text> </quote> Sample XSLT  XML <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="/person"> <quote><xsl:copy-of select="name" /> <text><xsl:value-of select="quote" /></text> </quote> </xsl:template> </xsl:stylesheet>
  • 59.
    59 XSLT Extras: moreelements • xsl:text – writes literal text to the output (useful for controlling whitespace or forcing exact, unescaped output) • xsl:processing-instruction – writes a PI like <?php… ?> or <?xml-stylesheet… ?> to the output • xsl:import and xsl:include – used to combine stylesheets (useful for XSLT libraries)
  • 60.
    60 XSLT Extras: morefunctions • document(url) – opens an XML document at the given location, returning its nodes as data that can be used by the template Example: document('zoo.xml')/zoo//*[@pop = 2] • current() – similar to "." except that it always refers to the current node, even when used inside predicates Example: //*[@pop = current()/@pop]
  • 61.
    61 XSLT Extras: xml-stylesheet Tomake an XML document show itself in a transformed format, add this to the top: <?xml-stylesheet type="text/xsl" href="path/to/transform.xslt" ?> This is particularly useful for XML like RSS
  • 62.
    62 Why/When XSLT?  WebStandard  XSLT v 1.0 Recommended by W3C almost 10 years ago (it's stable and well understood)  Dozens of implementations and host languages (Java, .NET, PHP, C++…)  Wide tool support (Firefox, IE, Visual Studio, many text editors, full IDEs…)  No vendor lock-in
  • 63.
    63 Why/When XSLT? Very goodat converting XML to XML, XHTML/HTML, or plain text  Makes it easy to keep things well-formed  Uses XML syntax, so the only real new syntax is XPath (which is also used elsewhere)  XPath is far more compact than similar DOM code in JS/Java/C#/etc.  Can be interpreted (for quick development) or compiled (for maximum performance)