1
Introduction to XSLTOrion Ifland / 2008-11-04
2
Introduction to XSLTAgenda
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
4
The X* Ecosystem XQuery / XPath 2.0 / XSLT 2.0
Kind of jumbled together XQuery looks more like a mix of XSLT, SQL,
and Javascript (including lots of XPath) XMLNS (XML Namespaces)
Like programming language namespaces, distinguishes between elements/attributes with the same name
Used by XSLT and many other XML dialects
5
XML Refresh/Terminology XML Nodes
Processing instruction: <?pi ... ?> Element: <element /> or
<element></element> Attribute: <element attribute="value" /> Comment: <!-- comment --> Entity: & Text node (just plain text)
6
XML Refresh/Terminology XML Syntax Rules
Escape < > & (turn them into entities < > &)
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
7
XML Namespaces Reason
Gives context to the meaning of elements Disambiguates between elements with the
same name Challenges
Easy to forget to specify namespaces Non-forgiving
8
XML Namespaces Syntax
Default namespace, e.g. xmlns="http://www.w3.org/xhtml/1999"<html />
Prefixed namespace, e.g. xmlns:dc="http://purl.org/dc/elements/1.1/"<dc:title />
9
XML Namespaces Example: XHTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<p> </p>
</body>
</html>
10
XML Namespaces Example: XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="/*">
<html> … </html>
</xsl:template>
</xsl:stylesheet>
11
XPath: Addresses for XMLXPath 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 XMLXPath 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>
13
XPath: Addresses for XMLXPath 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>
14
XPath: Addresses for XMLXPath 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>Predicate
15
XPath: Addresses for XMLXPath 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>
16
XPath: Addresses for XMLXPath 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>
17
XPath: Addresses for XMLXPath 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>
18
XPath: Addresses for XMLXPath 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>
19
XPath: Addresses for XMLXPath 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>
20
XPath: Addresses for XMLXPath 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>
Selects the "current" node
21
XPath: Addresses for XMLXPath 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>
22
XPath: Addresses for XMLXPath 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>
23
XPath: Addresses for XMLXPath 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>
24
XPath: Addresses for XMLXPath 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>
25
XPath: Addresses for XMLXPath 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>
26
XPath: Addresses for XMLXPath 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>
27
XPath: Addresses for XMLXPath 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>
28
XPath: Addresses for XMLXPath 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>
29
XPath: Addresses for XMLXPath 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>
30
XPath: Addresses for XMLXPath 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>
31
XPath: Addresses for XMLOther Useful XPath Functionsposition() – 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 themExample: translate("ABCD", "BD", "bd") "AbCd"
32
XPath: Addresses for XMLXPath 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>
33
XPath: Addresses for XMLXPath 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>
34
XPath: Addresses for XMLXPath 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>
35
XPath: Addresses for XMLXPath 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>
36
XPath: Addresses for XMLNamespacesxmlns:y="http://x"
/y:library
/y:library/y:book
/y:library/y:book/@name
Namespaces must be declared in the XSLT document – prefixes aren't "imported" from the source document
<x:library xmlns:x="http://x">
<x:book name="C++ How to Program" />
<x:book name="The Fourth Civilization" />
</x:library>
37
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
38
XSLT BasicsSample XML<person>
<name first="Neil" last="Armstrong" /><quote>...one giant leap for mankind.</quote>
</person>
Sample OutputNeil 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>
39
XSLT BasicsSample XML<person>
<name first="Neil" last="Armstrong" /><quote>...one giant leap for mankind.</quote>
</person>
Sample OutputNeil 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>
40
XSLT BasicsSample XML<person>
<name first="Neil" last="Armstrong" /><quote>...one giant leap for mankind.</quote>
</person>
Sample OutputNeil 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>
41
XSLT BasicsSample 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>
All well-formed
42
XSLT BasicsSample 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>
43
XSLT BasicsSample 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>
44
XSLT BasicsSample 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>
45
XSLT BasicsSample 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>
46
XSLT Loops: for-eachSample 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>
47
XSLT Loops: for-eachSample 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>
48
XSLT Loops: for-eachSample 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>
49
XSLT Loops: for-eachSample 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>
50
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>
51
XSLT Decisions: ifXML<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 > 2]">
<ul><xsl:for-each select="*[@pop > 2]">
<li><xsl:value-of select="name(.)" /></li>
</xsl:for-each></ul>
</xsl:if></xsl:template>…
52
XSLT Decisions: ifSample 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>
53
XSLT Decisions: chooseXML<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 <= 5">a few</xsl:when>
<xsl:otherwise>many</xsl:otherwise></xsl:choose>)
</li></xsl:for-each></ul>
</xsl:template>
54
XSLT Decisions: chooseSample 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>
55
XSLT Variables: variableXML<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>
56
XSLT Variables: variableSource 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>
57
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>
58
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>
59
XSLT Variables: paramXML<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 >= $minimum-population]"><li><xsl:value-of select="name(.)" />
(<xsl:value-of select="@pop"/>)
</li></xsl:for-each></ul>
</xsl:template>
60
XSLT Variables: paramSource 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>
61
XSLT Extras: sortXML<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>
62
XSLT Extras: sortSource 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>
63
XSLT Extras: copy-ofSource 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>
64
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)
65
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 templateExample: document('zoo.xml')/zoo//*[@pop = 2]
current() – similar to "." except that it always refers to the current node, even when used inside predicatesExample://*[@pop = current()/@pop]
66
XSLT Extras: xml-stylesheetTo 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
67
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
68
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)
69
Introduction to XSLTQuestions, demos…