Document

advertisement
XSLT – Extensible Style
Language for Transformation
Presented by:


Igor Borodin
Ilya Brodin
Motivation
Transformation of XML document – Why do we need it?

Store in one format, display in another
Transforming XML to XHTML and displaying in browser, for example

Convert to a more useful format

Make the document more compact
Extracting from XML documents only the data we need
The common: we are interested to get another document that looks like
we specify
Transformation basics


For performing a transformation, we need:

Input document

The specification of the transformation (how to perform it, what is
the input, what is the output)

Transformation processor
XSLT is a language for defining transformations of XML documents
Transformation basics (cont.)

XSLT is a declarative XML-based stylesheet language

XSLT stylesheet is an XML document by itself

It consists of a set of rules that match patterns in input XML
document

The rules declare what output should be produced when a pattern in
the XML document is matched

The order of the definition of rules doesn’t matter
Transformation basics (cont.)

Transformation processor applies the rules on an XML document,
producing the output

The output is a text document that may be an XML document, of
course.
So, XSLT transformation allows us to transform XML in any text
based format.
Simple example

Lets examine a simple example of using XSLT to transform an XML
document into an HTML table:



Input document: people.xml
Stylesheet: people.xsl with the rules of transformation
In order to perform transformation specified by people.xsl, we have
to insert the following processor instruction at the beginning of the
input document:
<?xml-stylesheet type="text/xsl"
href="people.xsl"?>
people.xml:
Note the assignment of
XSLT stylesheet
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="people.xsl"?>
<PEOPLE>
<PERSON>
<NAME>Mark Wilson</NAME>
<ADDRESS>911 Somewhere Circle, Canberra,
Australia</ADDRESS>
<TEL>(++612) 12345</TEL>
<FAX>(++612) 12345</FAX>
<EMAIL>Mark.Wilson@somewhere.com</EMAIL>
</PERSON>
<PERSON>
<NAME>Tracey Wilson</NAME>
<ADDRESS>121 Zootle Road, Cape Town, South
Africa</ADDRESS>
<TEL>(++2721) 531 9090</TEL>
<FAX>(++2721) 531 9090</FAX>
<EMAIL>Tracey.Wilson@somewhere.com</EMAIL>
</PERSON>
<PERSON>
<NAME>Jodie Foster</NAME>
<ADDRESS>30 Animal Road, New York, USA</ADDRESS>
<TEL>(++1) 3000 12345</TEL>
<FAX>(++1) 3000 12345</FAX>
<EMAIL>Jodie.Foster@somewhere.com</EMAIL>
</PERSON>
<PERSON>
<NAME>Lorrin Maughan</NAME>
<ADDRESS>1143 Winners Lane, London, UK</ADDRESS>
<TEL>(++94) 17 12345</TEL>
<FAX>(++94) 17 12345</FAX>
<EMAIL>Lorrin.Maughan@somewhere.com</EMAIL>
</PERSON>
<PERSON>
<NAME>Steve Rachel</NAME>
<ADDRESS>90210 Beverly Hills, California,
USA</ADDRESS>
<TEL>(++1) 2000 12345</TEL>
<FAX>(++1) 2000 12345</FAX>
<EMAIL>Steve.Rachel@somewhere.com</EMAIL></PERSON>
</PEOPLE>
<?xml version="1.0"?>
people.xsl
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML><BODY>
<TABLE BORDER="2">
<TR>
<TD>Name</TD>
<TD>Address</TD>
<TD>Tel</TD>
<TD>Fax</TD>
rule
<TD>Email</TD>
</TR>
<xsl:for-each select="PEOPLE/PERSON">
<TR>
<TD><xsl:value-of select="NAME"/></TD>
<TD><xsl:value-of select="ADDRESS"/></TD>
<TD><xsl:value-of select="TEL"/></TD>
<TD><xsl:value-of select="FAX"/></TD>
<TD><xsl:value-of select="EMAIL"/></TD>
</TR>
</xsl:for-each>
</TABLE></BODY></HTML></xsl:template></xsl:stylesheet>
The result (after transformation in Mozilla browser)
What have we seen?

Stylesheet is an XML document

XSLT has its own set of tags and its own namespace

Rules are being declared using <xsl:template match=”nodeset-expression”> tag

node-set-expression is an XPath expression

The contents of rule definition define the output of the application of
the rule
So, why XSLT?

Simple syntax

Easy to write

Easy to read and understand

Reusable

+ all the advantages of being the XML based language
The stylesheet as XML
document

XSLT stylesheet is an XML document, so:
 The whole stylesheet should be well-formed, the following
rule is invalid:
<xsl:template match="/">
<trifle>
<piffle>
<flim>
</piffle>
</trifle>
</xsl:template>

Like any XML document, contains XML declaration at the top
The stylesheet as XML
document

Its document element is <xsl:stylesheet> which contains all
the template rules

The XSLT namespace has the URI
http://www.w3.org/1999/XSL/Transform
 The xsl prefix is used by the transformation processor to
determine which elements are part of the stylesheet
infrastructure and which are part of the output
Tree representation of an XML
document

It is convenient to think about transformation process and output
producing as about traveling on the input tree and building the
output tree piece-by-piece

Traveling starts from the root of the tree, and proceeds down

So, we will represent XML document as a tree

The same representation we met before in this course
Tree representation of an XML
document

Moreover, as we saw in example, XSLT uses XPath to access or
refer to parts of an XML document
 <xsl:for-each select="PEOPLE/PERSON">

For understanding and writing XPATH expressions, it is convenient
to think of an XML document as a tree

So, let’s briefly recall what the tree representation of an XML
document is:
Tree representation of an XML
document

There are 7 kinds of nodes:







Element: may contain another elements
Attribute: leaf node
Text: leaf node. One element can have several text child nodes
Comment
Processing instruction
Namespace
Root: an abstract point above the document element
Tree representation of an XML
document
The following document contains all these types of nodes:
<?xml version="1.0"?>
<!-- Dee-licious! -->
<sandwich xmlns="http://www.food.org/ns">
<ingredient type="grape">jelly</ingredient>
<ingredient>
<?knife spread thickly?>
peanut-butter
</ingredient>
<ingredient>
bread
<!-- white bread, preferably -->
</ingredient>
</sandwich>
Tree representation of an XML
document
Here is its tree representation:
Expressing Structure with
Templates

The rule in the transformation is an XML element called
<xsl:template> whose contents are the elements and data that
will form the result subtree.
Here is an example of template rule:
<xsl:template match="/">
<html>
<head>
<title>My first template rule</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
</xsl:template>
Expressing Structure with
Templates

The output is an HTML document:
<html>
<head>
<title>My first template rule</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>

But we can consider the output as a tree. This tree was actually built
by the rule, node by node
Expressing Structure with
Templates

Notice the match attribute in the <xsl:template> element. This
attribute selects the appropriate level of a source tree. In the
example, the attribute selects the root node. This is where traveling
on the input tree (transformation) starts, and therefore, our example
rule will be the first rule executed

Since the rule doesn't allow processing to continue past the root
node (there are no references to the children of this node), it
effectively blocks all other rules. The transformation not only
begins with this rule, but ends here as well
Expressing Structure with
Templates

There are special elements that transmit the processing to another
levels of the input tree, i.e. another rules will continue the
constructing of the result tree. In the example we saw some of them:


<xsl:for-each select=“node-set-expression”>
<xsl:value-of select=“node-set-expression”>

There are more, will be described later
Selecting nodes

XSLT needs to be able to move through the document tree, to select
nodes or data, to describe the location of a node or a group of nodes
somewhere in a document

These skills are provided by XPath

XPath calls the description of the location a location path

The structure of a location path:
 Axis – describes the direction to travel
 Node test – specifies what kinds of nodes are applicable
 Set of optional Boolean predicates – winnowing down the
candidates even further
XPath- node axes
XPath- node tests
XPath- location path examples
XPath- predicate examples
XPath- location path shortcuts
Match patterns

Location paths most often used in match attributes of
<xsl:template> elements (we will call them match patterns)

But there is a little difference from the generic case:
 Only descending or self-referential axes may be used
 Axes like parent and preceding make things way too
complicated and could possibly set up infinite loops
Match patterns - examples

<xsl:template match="aphorism"> . . . </xsl:template>


<xsl:template match=“quote | aphorism”> . . .
</xsl:template>


Will be called each time element <aphorism> is found
Will be called each time elements <aphorism> or <quote> are found
<xsl:template match=“category/quote”> . . .
</xsl:template>

Will be called each time element <quote> that live inside
<category> is found
Match patterns - examples

<xsl:template match=“quote[@id = ‘4’]"> . . .
</xsl:template>


<xsl:template match=“@type”> . . . </xsl:template>


Will be called each time <quote> having attribute id with value 4
is found
Will be called each time attribute node type is found
<xsl:template match=“quote[source/text(‘Greg
Travis’)]”> . . . </xsl:template>

Will be called each time element <quote> whose source is
Greg Travis is found
Resolving conflicts among rules

It's possible for more than one rule to match a node
 XSLT processor selects the best match

Here are the rules of precedence:

If the pattern contains multiple alternatives separated by | , each
alternative is treated with equal importance, as though there
were a separate rule for each

A specific pattern has higher priority than a pattern that contains
general information. For example, the pattern
quotelist/quote/body is more specific than body, and
takes precedence
Resolving conflicts among rules

The rules of precedence (continued):

A pattern that relies on a wildcard is more general and therefore
has lower priority than a specific pattern. The pattern
stuff/cruft defeats the wildcard pattern stuff/*

A pattern with a successful test expression in square brackets ([])
overrides a pattern with no test expression but that is otherwise
identical. So bobo[@role="clown"] is better than bobo

Other information, such as position in the stylesheet, may be
used to pare down the set if there is still more than one rule
remaining
Resolving conflicts among rules

The <xsl:template> element has an optional priority attribute
that can be set to give it precedence over other rules and override
the process of determination

The value must be a real number (i.e., it must have a decimal
point) between 1.0 and -1.0, with a default of 0

A larger number overrides a smaller number
Transformation process

Transformation starts at the root of the document, “/” in XPath

It maintains the stack of rules

For each node it meets, it calls the template rule that match this
node
 What to do if there is no rule defined?
Next slide answers…

The rule produces the output that it specifies. It can call another
template, putting it at the top of the stack

If the stack becomes empty, transformation stops!
 We have seen the example of such situation
Default rules

What happens if transformation process finds a node in the tree and
there is no rule defined that match that node?

There are default (built-in) template rules to allow recursive
processing to continue in the absence of a successful pattern match
by an explicit template rule in the stylesheet

Each node type has a built-in rule that matches it

So, there is always rule for any node

Default rules have the lowest priority, thus defined rules override
them
Default rules

Root or any element:
 <xsl:template match="*|/"> <xsl:applytemplates/> </xsl:template>



<xsl:apply-templates/> instruction calls the templates
that match immediate children of the current node (puts them
on stack)
We found a problem – it doesn’t calls the templates of
attribute child nodes
Text and attribute nodes:
 <xsl:template match="text()|@*"> <xsl:value-of
select="."/> </xsl:template>

<xsl:value-of select="."/> instruction copies the
value of the matched node to the output (text in this case).
Formal definition of value – in next slides.
Default rules

Processing instruction or comment:
 <xsl:template match="processinginstruction()|comment()"/>


Takes no action – filters that nodes out
Namespace nodes:

The built-in template rule for namespace nodes is also to do
nothing

There is no pattern that can match a namespace node

So, the built-in template rule is the only template rule that is
applied for namespace nodes
Boolean conditions

What if we interested to produce the output under some conditions?

There are several ways to do so, each relies on the result of certain
XPath expression

First, XPath expression can evaluate to the following types of
values:





Boolean (true or false)
Node set
Number
String
Result tree fragment (a mixture of nodes in a tree structure that
aren't well-formed XML)
Boolean conditions

Each of the returned types can be converted to a Boolean value
according to the following rules:
Boolean conditions

So, lets return to our question: what if we interested to produce the
output under some conditions?

One way: we can write several rules, each one will be called when
our condition is satisfied

For example:
<xsl:template match="category[@type=‘humor’]">
. . . </xsl:template>
<xsl:template match="category[@type=‘philosophy’]">
. . .
</xsl:template>
Boolean conditions

Another way – to use XSLT special elements for conditional
processing

<xsl:if
test = “boolean-expression”>
. . .
</xsl:if>
<xsl:template match="category">
<xsl:if test="@type='humor'">
For example:
. . .
</xsl:if> </xsl:template>

<xsl:template
match="*">
<xsl:if
test="child::*">
I have children.
</xsl:if>
</xsl:template>
<xsl:if test="@type='philosophy'">
. . .
</xsl:if>
</xsl:template>
Boolean conditions
<xsl:template
match="category[@type=‘humor’]">
Hello, world!
</xsl:template>
<xsl:template match="category">
<xsl:if test="@type='humor'">
Hello, world!
</xsl:if> </xsl:template>

Let’s define stylesheet with one of these rules only. Will the output
be the same? (the . . . is the same text)
No! Can you explain why?
Boolean conditions

Another useful element is <xsl:choose>

Each <xsl:when> is
evaluated sequentially.
The first node that
matches is the one
whose content is used

If nothing matches,
the content of
<xsl:otherwise>
is used
<xsl:template match="*">
<xsl:choose>
<xsl:when test="self::chapter">
I am a chapter.
</xsl:when>
<xsl:when
test="self::appendix">
I am an appendix.
</xsl:when>
<xsl:otherwise>
I don't know what I am.
</xsl:otherwise>
</xsl:choose>
</xsl:template>
XPath node set functions


XSLT uses XPath expressions not only for matching, but for
manipulating nodes too
We can use all the node set function of XPath
XPath node set functions

There are also some functions that create node sets
Numeric expressions

A number in XSLT is defined to be a 64-bit floating point number,
whether it has a decimal point or no

Any expression type can be converted into Number:
Numeric expressions

XSLT provides a number of functions and operators to manipulate
numeric values (actually, XPath functions)
String expressions

Any expression can be converted into a string using the string()
function
String expressions

Creating strings:
String expressions

Operating on strings:
Fine-tuning templates

We have seen the basics of template rules and selection

Now we will look on some ways of customizing the process

outputting values

node creation

generating numbers and text

sorting

looping through node sets
Outputting Node Values with
<xsl:value-of>

<xsl:value-of> is the tool for calculating and returning values

May output text or numbers, for example:
 <xsl:value-of select=“count(//source)"/>

May work on nodes, for example:
 <xsl:value-of select="."/>

What is the value of a node?

Let’s see how the value of a node is defined in XSLT:
The values for each node type

Root
 The root node inherits the value of the document element

Element
 All the parsed character data in the element, together with the
values of its descendants of type text and element only

Attribute
 The value of the attribute with entities resolved, and leading and
trailing whitespace removed
The values for each node type

Text
 All the text in the node

Processing instruction
 Everything inside the processing instruction delimiters except the
name

Comment
 The text inside the comment delimiters

Namespace
 The namespace's URI
Outputting Node Values with
<xsl:value-of> (continued)

If <xsl:value-of> is applied to a set of nodes, only the first
node's value is used

May be confusing

For processing a set of nodes, XSLT provides <xsl:for-each>
element
Looping with <xsl:for-each>

<xsl:for-each> sets up a new context node set internally

The following rule generates a table of contents:
<xsl:template match="book">
<xsl:for-each select="chapter">
<xsl:value-of select="position()"/>.
<xsl:value-of select="title"/>.
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>

This rule uses <xsl:for-each> to create a numbered list of
chapter titles before processing each chapter with the
<xsl:apply-templates> directive
Creating nodes

In order to create nodes, we can simply type them out in template
rules

Sometimes, the values of the nodes can be determined only in “runtime”, or through a complex process

XSLT supply us additional tools for node creation
Creating attributes
<xsl:template match="entry">
<p>See the
<a>
<xsl:attribute name="href">
http://www.phone.com/<xsl:value-of select="@id"/>
</xsl:attribute>
catalog page
</a> for more information.
</p>
</xsl:template>

<xsl:attribute> created children attribute node for <a>
 We couldn’t create such href attribute by simply including it
inside <a> element.
Creating other nodes

In addition to <xsl:attribute>, there is a directive for creating
any type of nodes

<xsl:element name=“expression”>
<xsl:text>
<xsl:comment>

…


<xsl:template match="thing">
<xsl:element name="{@type}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
Creating other nodes
<thing type="circle">radius: 3</thing>
<thing type="square">side: 7</thing>
Transformation from previous slide
<circle>radius: 3</circle>
<square>side: 7</square>
Creating text nodes

<xsl:text>


Better control over white space
Outputting forbidden characters like < and &
 disable-output-escaping attribute
<xsl:template match="codelisting">
<h3>Code Example</h3>
<pre>
<xsl:text disable-output-escaping="yes">
cout << "How to output strings in C++";
</xsl:text>
</pre>
</xsl:template>
Outputting numbers

<xsl:number value=“expression” format=“format
string”>


<xsl:value-of> offers a limited formatting: decimal numeric
<xsl:number> offers more flexibility
Sorting
Imagine we
have a telephone
book document:

<telephone-book>
...
<entry id="44456">
<surname>Mentary</surname>
<firstname>Rudy</firstname>
<town>Simpleton</town>
<street>123 Bushwack Ln</street>
<phone>555-1234</phone>
</entry>
<entry id="44457">
<surname>Chains</surname>
<firstname>Allison</firstname>
<town>Simpleton</town>
<street>999 Leafy Rd</street>
<phone>555-4321</phone>
</entry>
...
</telephone-book>
Sorting

We want it to be displayed sorted by three keys: last name, first
name and town

By default, transformation will process the document in document
order
 The entry with id=‘44456’ will be output before id=‘44457’

How can we sort?
Sorting - <xsl:sort>

Here is the solution:
<xsl:template match="telephone-book">
<xsl:apply-templates>
<xsl:sort select="town"/>
<xsl:sort select="surname"/>
<xsl:sort select="firstname"/>
</xsl:apply-templates>
</xsl:template>

There are three sorting axes here. First, all the results are sorted by
town. Next, the entries are sorted by surname. Finally, the entries
are sorted by first name
Example: Checkbook
<?xml version="1.0"?>
<!DOCTYPE checkbook SYSTEM "checkbook.dtd">
<checkbook>
<deposit type="direct-deposit">
<payor>Bob's Bolts</payor>
<amount>987.32</amount>
<date>21-6-00</date>
<description category="income">Paycheck</description>
</deposit>
<payment type="check" number="980">
<payee>Kimora's Sports Equipment</payee>
<amount>132.77</amount>
<date>23-6-00</date>
<description category="entertainment">kendo equipment</description>
</payment>
<payment type="atm">
<amount>40.00</amount>
<date>24-6-00</date>
<description category="cash">pocket money</description>
</payment>
……
</checkbook>
Example: Checkbook (cont’d)
 The output format is HTML, so it can be viewed in any web
browser.
 The first template rule sets up the HTML page's structure and
necessary tags:
<xsl:template match="checkbook">
<html>
<head/>
<body>
<!-- page content goes here -->
</body>
</html>
</xsl:template>
Example: Checkbook (cont’d)
 Let’s start with adding dates interval when payments were made.
<xsl:template match="checkbook">
<html>
<head/>
<body>
<!-- income information -->
<h3>
<xsl:text>Income from </xsl:text>
<xsl:value-of select="child::*[1]/date"/>
<xsl:text> until </xsl:text>
<xsl:value-of select="child::*[last()]/date"/>
<xsl:text>:</xsl:text>
</h3>
<xsl:apply-templates select="deposit"/>
</body>
</html>
</xsl:template>
 <xsl:apply-templates select="deposit"/> - will output
income transactions in the order they appear in the document.
Example: Checkbook (cont’d)
 Now let's add a section to describe the deductions from the
checking account, sorted by amount.
<xsl:template match="checkbook">
<html>
<head/>
<body>
<!-- income information -->
<h3>
………………
</h3>
<xsl:apply-templates select="deposit"/>
<!-- payment information -->
<h3>
<xsl:text>Expenditures from </xsl:text>
<xsl:value-of select="child::*[1]/date"/>
<xsl:text> until </xsl:text>
<xsl:value-of select="child::*[last()]/date"/>
<xsl:text>, ranked from highest to lowest:</xsl:text>
</h3>
<xsl:apply-templates select="payment">
<xsl:sort data-type="number" order="descending"
select="amount"/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
Example: Checkbook (cont’d)

Finally, let's display the account balance. We'll use <xsl:number>
to calculate the sum of the transactions.

Two sum() terms are necessary: one for the payment total and one
for the income total. Then we'll subtract the total payment from the
total income.

To make it clear whether the user is in debt or not, we'll color-code
the calculated result and print a warning if it's negative.
Example: Checkbook (cont’d)
<h3>Balance</h3>
<p>
<xsl:text>Your balance as of </xsl:text>
<xsl:value-of select="child::*[last()]/date"/>
<xsl:text> is </xsl:text>
<tt><b>
<xsl:choose>
<xsl:when test="sum(payment/amount)>sum(deposit/amount)">
<font color="red">
<xsl:text>$</xsl:text>
<xsl:value-of select="sum( deposit/amount )
- sum( payment/amount )"/>
</font>
</xsl:when>
<xsl:otherwise>
<font color="blue">
<xsl:text>$</xsl:text>
<xsl:value-of select="sum( deposit/amount )
- sum( payment/amount )"/>
</font>
</xsl:otherwise>
</xsl:choose>
</b></tt>
</p>
Example: Checkbook (cont’d)
<xsl:if test="sum( payment/amount ) > sum( deposit/amount )">
<p>
<font color="red">
<xsl:text>DANGER! Deposit money quick!</xsl:text>
</font>
</p>
</xsl:if>
Example: Checkbook (cont’d)

Let’s add some formatting to payment details output:
 Formulate nicely
 Add numbering
<xsl:template match="payment"><p>
<xsl:value-of select="position()"/>
<xsl:text>. On </xsl:text>
<xsl:value-of select="date"/>
<xsl:text>, you paid </xsl:text>
<tt><b> <xsl:text>$</xsl:text>
<xsl:value-of select="amount"/></b></tt>
<xsl:text> to </xsl:text>
<i>
<xsl:value-of select="payee"/>
</i>
<xsl:text> for </xsl:text>
<xsl:value-of select="description"/>
<xsl:text>.</xsl:text>
</p></xsl:template>
Example: Checkbook (cont’d)

Previous template is not good when type="atm“. Let's make a
special rule just for this case:
<xsl:template match="payment[@type='atm']">
<p>
<xsl:value-of select="position()"/>
<xsl:text>. On </xsl:text>
<xsl:value-of select="date"/>
<xsl:text>, you withdrew </xsl:text>
<tt><b>
<xsl:text>$</xsl:text>
<xsl:value-of select="amount"/>
</b></tt>
<xsl:text> from an ATM for </xsl:text>
<xsl:value-of select="description"/>
<xsl:text>.</xsl:text>
</p>
</xsl:template>
Example: Checkbook (cont’d)

Finally, let’s perform the same kind of formatting for deposits:
<xsl:template match="deposit">
<p>
<xsl:value-of select="position()"/>
<xsl:text>. On </xsl:text>
<xsl:value-of select="date"/>
<xsl:text>, </xsl:text>
<tt><b>
<xsl:text>$</xsl:text>
<xsl:value-of select="amount"/>
</b></tt>
<xsl:text> was deposited into your account by </xsl:text>
<i>
<xsl:value-of select="payor"/>
</i>
<xsl:text>.</xsl:text>
</p>
</xsl:template>
Example: Checkbook (cont’d)

Resulting HTML:
<html><body>
<h3>Income from 21-6-00 until 31-6-00:</h3>
<p>1. On 21-6-00, <tt><b>$987.32</b></tt> was deposited into your
account by <i>Bob's Bolts</i>.</p>
<h3>Expenditures from 21-6-00 until 31-6-00, ranked from highest to
lowest:</h3>
<p>1. On 31-6-00, you paid <tt><b>$800.00</b></tt> to <i>Old Man
Ferguson</i> for a 3-legged antique credenza that once belonged to
Alfred Hitchcock.</p>
<p>2. On 23-6-00, you paid <tt><b>$132.77</b></tt> to <i>Kimora's
Sports Equipment</i> for kendo equipment.</p>
<p>3. On 30-6-00, you paid <tt><b>$58.79</b></tt> to <i>Barnes and
Noble</i> for O'Reilly Books.</p>
<p>4. On 29-6-00, you paid <tt><b>$47.28</b></tt> to <i>Wild Oats
Market</i> for groceries.</p>
<p>5. On 24-6-00, you withdrew <tt><b>$40.00</b></tt> from an ATM for
pocket money.</p>
<p>6. On 26-6-00, you paid <tt><b>$36.86</b></tt> to <i>Lone Star
Cafe</i> for lunch with Greg.</p>
<h3>Balance</h3>
<p>Your balance as of 31-6-00 is <tt><b><font
color="red">$-128.38</font></b></tt>
</p><p>
<font color="red">DANGER! Deposit money quick!</font>
</p>
</body></html>
Example: Checkbook (cont’d)
Modes

Sometimes we want to treat nodes differently depending on where
they are used in the document. ( For example, we may want
footnotes in tables to be alphabetized instead of numbered. )

To set up a mode, simply add a mode attribute set to a particular
label to the affected <xsl:template> and template-calling
elements.

The mode label can be anything you want as long as it's unique
among mode labels.
Modes (example)
<!– General template -->
<xsl:template match="footnote">
<xsl:variable name="fnum"
select="count(preceding::footnote[ancestor::chapter//.])+1"/>
<a><xsl:attribute name="href">
<xsl:text>#FOOTNOTE-</xsl:text>
<xsl:number value="$fnum" format="1"/>
</xsl:attribute>
<xsl:text>[</xsl:text>
<xsl:number value="$fnum"/>
<xsl:text>]</xsl:text></a>
</xsl:template>
<!– Specific template -->
<xsl:template match="footnote" mode="tabular">
<xsl:variable name="fnum"
select="count(preceding::footnote[ancestor::chapter//.])+1"/>
<a><xsl:attribute name="href">
<xsl:text>#FOOTNOTE-</xsl:text>
<xsl:number value="$fnum" format="1"/>
</xsl:attribute>
<xsl:text>[</xsl:text>
<xsl:number value="$fnum" format="a"/>
<xsl:text>]</xsl:text></a>
</xsl:template>
Modes (example cont’d)

Usage:
<xsl:template match="table-entry">
<xsl:apply-templates mode="tabular"/>
</xsl:template>
Named templates

Instead of match attribute in template definition, you can specify
name attribute

We can call template explicitly by its name, using <xsl:calltemplate name=“..."/>

Like function call in programming languages

Can be defined and called with parameters
Named templates - example
<xsl:template name="navbar">
<a href="index.htm">Home</a> |
<a href="help.htm">Help</a> |
<a href="toc.htm">Contents</a>
</xsl:template>
<xsl:template match="mainblock">
<body>
<xsl:call-template name="navbar"/>
<xsl:apply-templates/>
<xsl:call-template name="navbar"/>
</body>
</xsl:template>
<xsl:template name="navbar">
<xsl:param name="title"></xsl:param>
<xsl:value-of select="$title"/>
Default value can
<a href="index.htm">Home</a> |
be put here
<a href="help.htm">Help</a> |
<a href="toc.htm">Contents</a>
</xsl:template>
<xsl:template match="mainblock">
<xsl:call-template name="navbar"/>
<xsl:with-param name="title">
Navigate from this page
</xsl:with-param>
<xsl:apply-templates/>
<xsl:call-template name="navbar"/>
<xsl:with-param name="title">
Navigate from this page
</xsl:with-param>
</xsl:template>
Variables

Declared using <xsl:variable name=“name”
select=“expression”>

But, despite the name, can hold only constant initial value. Just like
#define in C

Declaration:
<xsl:variable name="fnum“
select="count(preceding::footnote[ancestor::chapte
r//.])+1"/>

Usage:
<xsl:number value=“$fnum”/>
XSLT tools – development and
debugging

Altova XMLSPY
 Excellent support for creating, running and debugging XSLT,
friendly and comfortable environment
 Many other features

Altova Stylevision
 Visual stylesheet editor
 Many other features

MarrowSoft <Xcelerator>:
 Editor
 Debugger
 Many other features
XSLT tools for Web - client-side
XSLT transformation

Internet Explorer 5.0 was the first browser to support XSLT
 Internet Explorer 6.0 provides full support of XSLT (according to
what Microsoft says), using Microsoft XML (MSXML) 3.0 parser

Opera does not, and, as it seems now, will not support XSLT
transformations in browser

Mozilla supports, using TransforMiiX processor
As expected, many problems start:



Different HTML support and presentation
Different whitespace handling
Different syntax support…
XSLT tools for Web - server-side
XSLT transformation

As we noticed, client-side transformations may be problematic



There are browsers that do not support XSLT
Different browsers may display differently the result
The transformation can be performed on the server’s side


Altova offers free XSLT command line parser, which uses exactly
the same engine that XMLSPY uses
Microsoft offers MSXML parser for download
Useful XSLT resources

http://www.w3.org/TR/xslt


Official XSLT specification
http://www.topxml.com/xsl/tutorials/intro/default.asp

Excellent XSLT tutorial
The end!
Questions?
Download