You are on page 1of 106

<?xml version=1.

0> <course startdate=February 06, 2006> <title> eXtensible Markup Language </title> <lecturer>Phan Vo Minh Thang</lecturer> </course>

eXtensible Markup Language


Using XSLT and XPath to Enhance HTML Documents
Thanks to Roger L. Costello

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

History

XSL
(low-precision graphics, e.g.,HTML, text, XML) XQuery XLink/ XPointer (high-precision graphics, e.g., PDF)

XSLT

XSL

XML Schemas

XPath

XSLT

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Note
For brevity, instead of using the term XSLT/XPath, I will simply call it XSL.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Multiple Output Formats


XSL may be used to generate either HTML, XML, or text

XSL

XML

XSL Processor

HTML (or XML or text)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xalan/xt/saxon
xalan: A free XSL processor, implemented in Java, from Apache (http://www.apache.org/) xt: A free XSL processor, implemented in Java, from James Clark (http://www.jclark.com/) saxon: A free XSL processor, implemented in Java, from Michael Kay (http://users.iclway.co.uk/mhkay/saxon

XML

XSL

xalan/xt/saxon

HTML (or XML or text) Invoking from a DOS command line:


run-xalan FitnessCenter.xml FitnessCenter.xsl FitnessCenter.html run-xt FitnessCenter.xml FitnessCenter.xsl FitnessCenter.html eXtensible Markup Language run-saxon FitnessCenter.xml FitnessCenter.xsl FitnessCenter.htmlVo Minh Thang MSc. Lecturer: Phan

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Styling XML Documents using IE6 or Netscape7


Put a stylesheet PI at the top of your XML document. Now you can simply drop the XML document into the browser and the XML will be automatically styled using the stylesheet referenced in the stylesheet PI.

<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="FitnessCenter.xsl"?> <FitnessCenter> <Member level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> </FitnessCenter>

Add this stylesheet PI to the top of your XML document

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

HTML Generation
We will first use XSL to generate HTML documents When generating HTML, XSL should be viewed as a tool to enhance HTML documents. That is, the HTML documents may be enhanced by extracting data out of XML documents XSL provides elements (tags) for extracting the XML data, thus allowing us to enhance HTML documents with data from an XML document

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Enhancing HTML Documents with XML Data

XML Document

XML data

XSL Processor

XSL element

HTML Document
(with embedded XSL elements)

XML data

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Enhancing HTML Documents with the Following XML Data

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="FitnessCenter.xsl"?>

<FitnessCenter> <Member level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> </FitnessCenter> FitnessCenter.xml
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Embed HTML Document in an XSL Template

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY> Welcome! </BODY> </HTML> </xsl:template> </xsl:stylesheet>

Note how we have the HTML document embedded within an XSL template

FitnessCenter.xsl (see html-example01)


eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Note
The HTML is embedded within an XSL template, which is an XML document Consequently, the HTML must be well formed, i.e., every start tag must have an end tag Because the HTML is embedded within an XSL template, we are able to add XSL elements to the HTML, allowing us to extract data out of XML documents Let's customize the HTML welcome page by putting in the member's name. This is achieved by extracting the name from the XML document. We use an XSL element to do this.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Extracting the Member Name


<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! </BODY> </HTML> </xsl:template> </xsl:stylesheet>

(see html-example02)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Note
Notice how we have enhanced the HTML document by using data from the XML document!

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Extracting a Value from an XML Document, Navigating the XML Document


Extracting values: use the <xsl:value-of select=""/> XSL element Navigating: The slash ("/") indicates parent/child relationship A slash at the beginning of the path indicates that it is an absolute path, starting from the top of the XML document
/FitnessCenter/Member/Name
"Start from the top of the XML document, go to the FitnessCenter element, from there go to the Member element, and from there go to the Name element."
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Document /

PI <?xml version=1.0?>

Element FitnessCenter

Element Member

Element Name

Element Phone

Element Phone

Element FavoriteColor

Text Jeff

Text 555-1234

Text 555-4321

Text lightgrey

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Extract the FavoriteColor and use it as the bgcolor


<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY bgcolor="{/FitnessCenter/Member/FavoriteColor}"> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! </BODY> </HTML> </xsl:template> </xsl:stylesheet>

(see html-example03)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Note

Attribute values cannot contain "<" nor ">" - Consequently, the following is NOT valid:
<Body bgcolor="<xsl:value-of select='/FitnessCenter/Member/FavoriteColor'/>">

To extract the value of an XML element and use it as an attribute value you must use curly braces:
<Body bgcolor="{/FitnessCenter/Member/FavoriteColor}">

Evaluate the expression within the curly braces. Assign the value to the attribute.
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Extract the Home Phone Number


<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY bgcolor="{/FitnessCenter/Member/FavoriteColor}"> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! <BR/> Your home phone number is: <xsl:value-of select="/FitnessCenter/Member/Phone[@type='home']"/> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

(see html-example04)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Note

In this example we want "the Phone element where the value of its type attribute equals 'home' ":
<xsl:value-of select="/FitnessCenter/Member/Phone[@type='home']"/>

The expression within [] is called a "predicate". Its purpose is to filter. Note the use of the single quotes within the double quotes.
select=" ' ' "

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Review - HTML Table


<table border=1 width=100%> <th> <th> <th> </tr> <tr> </th> </th> </th> <td> <td> <td> </tr> <tr> </td> </td> </td> <td> <td> <tr> <td> </tr> </td> </td> </td> </table> This will create a table with 3 rows - the first row contains a header for each column. The next two rows contains the table data.
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<table border=1 width=75%> <tr> <th>Fruit</th> <th>Color</th> </tr> <tr> <td>Papaya</td> <td>Red</td> </tr> <tr> <td>Banana</td> <td>Yellow</td> </tr> </table>

Fruit Color Papaya Red Banana Yellow

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Create a Table of Phone Numbers


Suppose that a Member has an arbitrary number of phone numbers (home, work, cell, etc). Create an HTML table comprised of the phone numbers. On each row of the table put the type (home, work, cell, etc) in one column and the actual phone number in the next column.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY bgcolor="{/FitnessCenter/Member/FavoriteColor}"> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! <BR/> Your phone numbers are: <TABLE border="1" width="25%"> <TR><TH>Type</TH><TH>Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member/Phone"> <TR> <TD><xsl:value-of select="@type"/></TD> <TD><xsl:value-of select="."/></TD> </TR> </xsl:for-each> </TABLE> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

(see html-example05)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Iterating through XML Elements

<xsl:for-each select="/FitnessCenter/Member/Phone"> <!- - Within here we are at one of the Phone elements. Thus, in <xsl:value-of select="path", the value for path is relative to where we are in the XML document. The "." refers to the Phone element that we are currently positioned at. - -> </xsl:for-each>

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Absolute Path versus Relative Path

<xsl:value-of select="/FitnessCenter/Member/Phone[@type='home']"/> This is an absolute xPath expression (we start from the top of the XML tree and navigate down the tree) <xsl:value-of select="@type"/> This is a relative xPath expression (relative to where we currently are located, give me the value of the type attribute)

Do Lab1, Parts 1-3

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Special Offer to Platinum Members


Let's further enhance our example to provide a special offer to "platinum" members. We need to check to see if the "level" attribute on the Member element equals "platinum".

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY bgcolor="{/FitnessCenter/Member/FavoriteColor}"> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! <BR/> <xsl:if test="/FitnessCenter/Member/@level='platinum'"> Our special offer to platinum members today is ... <BR/> </xsl:if> Your phone numbers are: <TABLE border="1" width="25%"> <TR><TH>Type</TH><TH>Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member/Phone"> <TR> <TD><xsl:value-of select="@type"/></TD> <TD><xsl:value-of select="."/></TD> </TR> </xsl:for-each> </TABLE> </BODY> </HTML>

(see html-example06)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Conditional Processing
Use the <xsl:if test=""/> element to perform conditional processing.

Do Lab1, Part 4

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Accessing Multiple Parts of the XML Document


Let's enhance the table to contain three columns - the name of the Member, the type of the phone (home, work, cell, etc), and the actual phone number.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY bgcolor="{/FitnessCenter/Member/FavoriteColor}"> Welcome <xsl:value-of select="/FitnessCenter/Member/Name"/>! <BR/> <xsl:if test="/FitnessCenter/Member/@level='platinum'"> Our special offer to platinum members today is ... <BR/> </xsl:if> Your phone numbers are: <TABLE border="1" width="25%"> <TR><TH>Name</TH><TH>Type</TH><TH>Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member/Phone"> <TR> <TD><xsl:value-of select="../Name"/></TD> <TD><xsl:value-of select="@type"/></TD> <TD><xsl:value-of select="."/></TD> </TR> </xsl:for-each> </TABLE> </BODY> </HTML> eXtensible Markup Language

(see html-example07)

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Getting the Name when accessing the Phone


Member

Notice how when in the for-each loop we need to access the Name which is "up and over" with respect to the Phone element

Name

Phone

Phone

Jeff

555-1234

555-4321

Bottom line: we can access elements in other parts of the XML tree via the ../ operator.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Other ways to Access the XML Data


Note: Assume that there are multiple Members <xsl:value-of select="/FitnessCenter/Member[1]/Name"/> "Select the Name of the first Member" <xsl:value-of select="/FitnessCenter/Member[position()=1]/Name"/> "Select the Name of the first Member" <xsl:value-of select="/FitnessCenter/Member[last()]/Name"/> "Select the Name of the last Member" <xsl:for-each select="/FitnessCenter/Member[not(position()=last())]"> <!- - Process all Members but the last - -> </xsl:for-each>
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Other ways to Access the XML Data (cont.)

<xsl:for-each select="/FitnessCenter/Member[position() != last())]"> <!- - Process all Members but the last - -> </xsl:for-each> <xsl:for-each select="/FitnessCenter/Member[position() &gt;1]"> <!- - Process all Members but the first - -> </xsl:for-each> <xsl:for-each select="/FitnessCenter//Name"> <!- - Process all Name elements which have FitnessCenter as an ancestor - -> </xsl:for-each>
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Other ways to Access the XML Data (cont.)


<!- - Iterate through a list of Member nodes - -> <xsl:for-each select="/FitnessCenter/Member"> <!- - Output the Name of the "current" Member - -> <xsl:value-of select="./Name"/> </xsl:for-each> <!- - Since a specific Member is not specified, all Member nodes - -> <!- - all selected. That is, the Name node within each Member - -> <!-- node is selected. --> <xsl:for-each select="/FitnessCenter/Member/Name"> <xsl:value-of select="."/> </xsl:for-each>
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Nodelist

This xPath expression: /FitnessCenter/Member selects a list of nodes (a list of Member nodes). This list of nodes is called a "nodelist".

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Enhanced XML Document


<?xml version="1.0"?> <FitnessCenter> <Member id="1" level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> <Member id="2" level="gold"> <Name>David</Name> <Phone type="home">383-1234</Phone> <Phone type="work">383-4321</Phone> <FavoriteColor>lightblue</FavoriteColor> </Member> <Member id="3" level="platinum"> <Name>Roger</Name> <Phone type="home">888-1234</Phone> <Phone type="work">888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> </Member> </FitnessCenter>

Note that each Member now has a unique id (the id attribute)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Review - HTML Hyperlinking

<A name="AnnaAndTheKing"></A>

<A href="#AnnaAndTheKing">Click Here</A> ... This creates an internal hyperlink (the source "anchor" links to the target anchor).
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Hyperlink Name to Home Phone


Problem: create an HTML document that has two tables a Member Name table, and a Member home Phone number table. Hyperlink the Member's Name to his/her Phone.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<TABLE border="1" width="25%"> <TR><TH>Name</TH></TR> <xsl:for-each select="/FitnessCenter/Member"> <TR> <TD> <A href="#{@id}"> <xsl:value-of select="Name"/> </A> </TD> </TR> </xsl:for-each> </TABLE> <BR/><BR/><BR/><BR/><BR/> <TABLE border="1" width="25%"> <TR><TH>Home Phone Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member"> <TR> (see html-example08) <TD> <A name="{@id}"> <xsl:value-of select="Phone[@type='home']"/> Do Lab1, </A> Parts 5-6 </TD> </TR> </xsl:for-each> eXtensible Markup Language </TABLE> Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Numbering
There is an XSL element that returns a number corresponding to the element's position in the set of selected nodes <xsl:for-each select="/FitnessCenter/Member"> <xsl:number value="position()" format="1"/> <xsl:text>. </xsl:text> <xsl:value-of select="Name"/> <BR/> </xsl:for-each> (see html-example09)

Output: 1. Jeff 2. David 3. Roger

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Start Numbering from 0


How would you start the numbering from zero, rather than one?

<xsl:number value="position() - 1" format="1">

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

format attribute of xsl:number


In the previous example we saw how to generate numbers, and we saw that the generated numbers were 1, 2, 3, etc. With the format attribute we can specify the format of the generated number, i.e., 1, 2, 3 or I, II, III, or A, B, C, or format=1 generates the sequence: 1, 2, 3, format=01 generates: 01, 02, 03, format=A generates: A, B, C, format=a generates: a, b, c, format=I generates: I, II, III, format=i generates: i, ii, iii, ...
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

format attribute of xsl:number

<xsl:for-each select="/FitnessCenter/Member"> <xsl:number value="position()" format="A"/> <xsl:text>. </xsl:text> <xsl:value-of select="Name"/> <BR/> </xsl:for-each> Output: A. Jeff B. David C. Roger
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Sorting
There is an XSL element that sorts the elements that you extract from the XML document

<xsl:for-each select="/FitnessCenter/Member"> <xsl:sort select="Name" order="ascending"/> <xsl:value-of select="Name"/> <BR/> </xsl:for-each>

(see html-example10) "For each Member, sort the Name elements"

Output: David Jeff Roger

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Sorting

<xsl:for-each select="/FitnessCenter/Member"> <xsl:sort select="Name" order="ascending"/> <xsl:value-of select="Name"/> <BR/> </xsl:for-each>

The set of Member elements selected by xsl:for-each is sorted using the Name child element. This occurs prior to the first iteration of the loop. After the set of Member elements are sorted then the looping begins.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

concat() function
concat(destination string, string to add) Note: if you want to concatenate more than one string to the destination string then simply add more arguments

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<xsl:for-each select="/FitnessCenter/Member"> <xsl:value-of select="concat('Welcome ', Name, '!')"/> <BR/> </xsl:for-each> Output: Welcome Jeff! Welcome David! Welcome Roger!

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xsl:variable
This XSL element allows you to create a variable to hold a value (which could be a string or a subtree of the XML document). The variable is referenced by $variable-name

<xsl:variable name=hello select='Hello World'/>


This creates a variable called hello, that has a value which is the literal string, Hello World. We could use this variable as follows: Value = <xsl:value-of select=$hello/> This will output: Value = Hello World

hello
Hello World

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Member's Phone Numbers: <TABLE border="1" width="25%"> <TR><TH>Name</TH><TH>Type</TH><TH>Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member"> <xsl:variable name="name" select="Name"/> <xsl:for-each select="Phone"> <TR> <TD><xsl:value-of select="$name"/></TD> <TD><xsl:value-of select="@type"/></TD> <TD><xsl:value-of select="."/></TD> </TR> </xsl:for-each> </xsl:for-each> </TABLE>

(see html-example12)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xsl:variable

<xsl:variable name=member select=Member[1]/>

This creates a variable called member, that has a value which is a subtree. We could use this variable as follows:
Member

Name = <xsl:value-of select=$member/Name/> Home Phone = <xsl:value-of select=$member/Phone[@type='home']/>


Name Phone Phone ...

This will result in generating: Name = Jeff Home Phone = 555-1234


Jeff 555-1234 555-4321

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xsl:variable
A variable is write once, read many.
That is, you can assign a variable a value only once, but then you can retrieve the value of the variable many times.

A variable has a scope limited to the XSL element that it is nested within. Its scope starts where it is defined and extends to the end of the XSL element that it is nested within.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Member's Phone Numbers: <TABLE border="1" width="25%"> <TR><TD>Name</TD><TD>Type</TD><TD>Number</TD></TR> <xsl:for-each select="/FitnessCenter/Member"> <xsl:variable name="name" select="Name"/> <xsl:for-each select="Phone"> <TR> <TD><xsl:value-of select="$name"/></TD> <TD><xsl:value-of select="@type"/></TD> <TD><xsl:value-of select="."/></TD> </TR> </xsl:for-each> </xsl:for-each> </TABLE>

The name variable's life ends here

Do Lab2, Part 1

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Global Variables
You can create a variable outside of <xsl:template match="/">. Then, the variable is global.
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:variable name="pi" select="'3.142857142857'"/> <xsl:template match="/" > <HTML> <HEAD> <TITLE>Value of Pi</TITLE> </HEAD> <BODY> The value of pi = <xsl:value-of select="$pi"/> </BODY> </HTML> </xsl:template>

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Problem
Suppose that we want to create a variable, names, and we want this variable to contain a list of the Member Names, with each name separated by a slash. How would you create such a variable?

Heres what you might attempt to do:

Member's Names: <xsl:variable name="names" select="/FitnessCenter/Member[1]/Name"/> <xsl:for-each select="/FitnessCenter/Member[position() &gt; 1]"> <xsl:variable name="names" select="concat($names, '/')"/> <xsl:variable name="names" select="concat($names, Name)"/> </xsl:for-each> <xsl:value-of select="$names"/>
Output: Jeff

(see html-example13)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Lets add some statements to trace this example


<xsl:variable name="names" select="/FitnessCenter/Member[1]/Name"/> <xsl:value-of select="$names"/> <BR/> <xsl:for-each select="/FitnessCenter/Member[position() &gt; 1]"> <xsl:variable name="names" select="concat($names, '/')"/> <xsl:value-of select="$names"/> <BR/> <xsl:variable name="names" select="concat($names, Name)"/> <xsl:value-of select="$names"/> <BR/> </xsl:for-each> <xsl:value-of select="$names"/>
Output:

(see html-example14)

Jeff Jeff/ Jeff/David Jeff/ <--- Why did we loose the previous Name? That name went out of scope. Jeff/Roger Jeff

Obviously, this approach doesnt work. So how do we do it?

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Heres what we would like to do

names

Open up the names box Jeff / David / Roger

Iterate through each name, adding into the open box

<xsl:for-each select="/FitnessCenter/Member"> Add this iterations Name and a slash to the open names box </xsl:for-each>

names Close the box Jeff/David/Roger

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Problem - Solution

In all previous examples of creating a variable we declared the name of the variable and then had a select attribute which gave the variable its value. We can omit the select attribute: <xsl:variable name=names> - Do stuff in here. All output will go into the names box. </xsl:variable>

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Problem - Solution

Member's Names: <xsl:variable name="names"> <xsl:value-of select="/FitnessCenter/Member[1]/Name"/> <xsl:for-each select="/FitnessCenter/Member[position() &gt; 1]"> <xsl:text>/</xsl:text> <xsl:value-of select="Name"/> </xsl:for-each> </xsl:variable> <xsl:value-of select="$names"/>

(see html-example15) Output: Member's Names: Jeff/David/Roger


eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

contains() function
contains(string to be tested, test string) returns true if string to be tested contains test string

<xsl:if test=contains($greeting, welcome)> $greeting contains welcome </xsl:if>

Do Lab2, Part 2

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xsl:choose
xsl:choose allows you to elegantly express multiple conditional tests. Heres the structure:

<xsl:choose> <xsl:when test='something> [action] </xsl:when> <xsl:when test='something'> [action] </xsl:when> <xsl:otherwise> [action] </xsl:otherwise> </xsl:choose>

The first xsl:when statement that evaluates to true is executed. If none evaluates to true then the xsl:otherwise statement is executed. eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Implementing an if-then-else
There is no if-then-else element in XSL. However, there is an elegant way to do it:
<xsl:choose> <xsl:when test="contains($member-list, 'Jeff')"> <xsl:text>Jeff is a member</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>No member by the name Jeff</xsl:text> </xsl:otherwise> </xsl:choose>

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

substring-before() String Function


Heres the form of this string function: substring-before(string, pattern) Example: <xsl:variable name="phone" select="Phone"/> <xsl:value-of select="substring-before($phone, '-')"/> Get the contents of Phone and put it into the variable called phone. Then extract from the content of phone the string before the '-' (i.e., the telephone exchange).
phone 555-1234
substring-before($phone, -)

555
eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

substring-after() String Function


Heres the form of this string function: substring-after(string, pattern) Example: <xsl:variable name="phone" select="Phone"/> <xsl:value-of select="substring-after($phone, '-')"/> Get the contents of Phone and put it into the variable called phone. Then extract from the content of phone the string after the '-'.
phone 555-1234
substring-after($phone, -)

1234
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

starts-with() String Function

Heres the form of this string function: starts-with(string, pattern) Example: <xsl:if test="starts-with(Phone, '555')"> [action] </xsl:if> If the Phone starts with the string, 555 then do [action].
eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

substring() function
substring(string, i, len?) returns the substring of string that starts at the ith position and has length, len. The length argument (len) is optional. If not present then this function returns the substring starting at the ith position all the way to the end of the string. Note: the first character is at position 1 (not 0 as with some languages)

substring(1234567890, 2, 5) returns 23456

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

string-length() function
string-length(string) returns the length of the string

string-length(1234567890) returns 10

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

translate() function
translate(string, from-pattern, to-pattern) Example. translate(Hello, ABCDEFGHIJKLMNOPQRSTUVWXYZ, abcdefghijklmnopqrstuvwxyz); this will convert Hello to hello (i.e., convert to lower case) A better approach to the above problem is: <xsl:variable name="upperCaseChars" select=" 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' "/> <xsl:variable name="lowerCaseChars" select=" 'abcdefghijklmnopqrstuvwxyz' "/> translate(Hello, $upperCaseChars, $lowerCaseChars)
Do Lab2, Part 3

Note: need to put the string within (single) quotes, otherwise the XSL Processor will try to interpret it as an XML element.
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Boolean and Relational Operators


Boolean operators: not, and, or Relational operators: <, >, =, <=, >=, != The less than and greater than signs are reserved symbols, so they need to be escaped when you use them. Thus, the relational operators will appear in your XSL code like this:

Want this: < > = <= >= != Use this: &lt; &gt; = &lt;= &gt;= !=

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Arithmetic
The arithmetic operators available: +, -, *, div, mod (remainder from doing a division)
Note: recall that an XML element can have a dash in the name. So, if you want to indicate subtraction, be sure to surround - with blank spaces.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Arithmetic functions

sum(node set) this function sums up all the values in the set of nodes floor(number) returns the largest integer that is not greater than number Example. floor(2.5) returns 2 ceiling(number) returns the smallest integer that is not less than number Example. Ceiling(2.5) returns 3 round(number) returns the integer closest to number Example. round(2.3) returns 2

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Enhanced XML Document


<?xml version="1.0"?> <FitnessCenter> <Member id="1" level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> <MembershipFee>340</MembershipFee> </Member> <Member id="2" level="gold"> <Name>David</Name> <Phone type="home">383-1234</Phone> <Phone type="work">383-4321</Phone> <FavoriteColor>lightblue</FavoriteColor> <MembershipFee>500</MembershipFee> </Member> <Member id="3" level="platinum"> <Name>Roger</Name> <Phone type="home">888-1234</Phone> <Phone type="work">888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> <MembershipFee>340</MembershipFee> </Member> </FitnessCenter>

Note that each Member now has MembershipFee element

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Compute Membership Revenue

Membership Fee Revenue: <xsl:value-of select="sum(//MembershipFee)"/>

(see html-example16)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

xsl:attribute
This XSL element is used by nesting it within an output element. It enables you to create an attribute for the output element

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Coloring alternate rows

Member Names: <TABLE border="1" width="25%"> <xsl:for-each select="/FitnessCenter/Member"> <TR> <xsl:if test="position() mod 2 = 0"> <xsl:attribute name="bgcolor">yellow</xsl:attribute> </xsl:if> <TD><xsl:value-of select="Name"/></TD> </TR> </xsl:for-each> </TABLE>

(see html-example17) For each even row of the table, the TR value will be: <TR bgcolor="yellow">

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

count() function

count(set of node) returns an integer representing the number of nodes (i.e., XML elements) in the set. Example. Number of members = <xsl:value-of select="count(//Member)"/> Output: Number of members = 5

Do Lab2, Part 4

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Selecting all Elements/Attributes

<xsl:for-each select="/FitnessCenter/Member"> <xsl:for-each select="@*"> ... </xsl:for-each> <xsl:for-each select="*"> ... </xsl:for-each> </xsl:for-each>

For each attribute do ...

For each child element do ...

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Getting the Name of the Element/Attribute using the name() Function

<xsl:for-each select="/FitnessCenter/Member"> <xsl:for-each select="@*"> Attribute = <xsl:value-of select="name(.)"/> </xsl:for-each> <xsl:for-each select="*"> Element = <xsl:value-of select="name(.)"/> </xsl:for-each> </xsl:for-each> (see html-example19) name(node) returns the name of "node"
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

When to use Curly Braces?


When I assign an attribute a value, when do I use curly braces and when do I not use them?

Use curly braces for these attributes: - the attribute of a literal result element (where you literally type what should be output) Example: <a href=#{@id}> - the name attribute of xsl:attribute Example: <xsl:attribute name ={@value}> - the name attribute of xsl:pi Example: <xsl:pi name ={@value}> - the name attribute of xsl:element Example: <xsl:element name ={@value}> - the optional attributes of xsl:sort: Example: <xsl:sort order ={@value}> lang ={@value}> data-type ={@value}> case-order ={@value}>
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

document( ) Function
This function enables you to access other XML documents (besides the XML document that you specify when you invoke the XSL Processor). The format for using the document() function is: document(url), where url is a URL to another XML document

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Fitness Centers Merger


Another fitness center has just merged with us. They have an xml document (FitnessCenter2.xml) containing their Members. You are to create an XSL-enhanced HTML document that creates a single table comprised of all the Members from both fitness clubs.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<TABLE border="1" width="75%"> <TR><TH>Name</TH><TH>Phone(home)</TH>...</TR> <xsl:for-each select="/FitnessCenter/Member"> <TR> <TD><xsl:value-of select="Name"/></TD> <TD><xsl:value-of select="Phone[@type='home']"/></TD> <TD><xsl:value-of select="Phone[@type='work']"/></TD> <TD><xsl:value-of select="FavoriteColor"/></TD> </TR> </xsl:for-each> <xsl:variable name="fitnessCenter2" select="document('file://localhost/xml-course/.../FitnessCenter2.xml')"/> <xsl:for-each select="$fitnessCenter2/FitnessCenter/Member"> <TR> <TD><xsl:value-of select="Name"/></TD> <TD><xsl:value-of select="Phone[@type='home']"/></TD> <TD><xsl:value-of select="Phone[@type='work']"/></TD> <TD><xsl:value-of select="FavoriteColor"/></TD> </TR> </xsl:for-each> Do Lab3, </TABLE>
Part 1

(see html-example20)

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Parameterized Processing
You can create a subroutine (called a named template), and you can pass to it parameters.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<xsl:template match="/"> <HTML> <HEAD> <TITLE>Fitness Center</TITLE> </HEAD> <BODY> <xsl:call-template name="displayNameWithFont"> <xsl:with-param name="fontFace" select="'Impact'"/> <xsl:with-param name="name" select="/FitnessCenter/Member[1]/Name"/> </xsl:call-template> <BR/> ... </BODY> </HTML> </xsl:template> <xsl:template name="displayNameWithFont"> <xsl:param name="fontFace" select="'Braggadocio'"/> <!-- default font --> <xsl:param name="name"/> <FONT face="{$fontFace}"> <xsl:value-of select="$name"/> </FONT> </xsl:template> eXtensible Markup Language (see html-example21)

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Call by Reference
How do we create a named template that returns a value? Example: create a named template which, when passed a number, it returns the number div 2.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<xsl:template match="/"> <HTML> <HEAD> <TITLE>Fitness Center</TITLE> </HEAD> <BODY> 16 / 2 = <xsl:variable name="result"> <xsl:call-template name="NumDiv2"> <xsl:with-param name="N" select="16"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$result"/> </BODY> </HTML> </xsl:template> <xsl:template name="NumDiv2"> <xsl:param name="N"/> <xsl:value-of select="$N div 2"/> </xsl:template>
eXtensible Markup Language (see html-example22) Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

Problem: Determine if all <Number> values are <= 100

<section id=06> XSLT </section> </material>

<?xml version="1.0"?> <NumberList> <Number>23</Number> <Number>41</Number> <Number>70</Number> <Number>103</Number> <Number>99</Number> <Number>6</Number> </NumberList> (see html-example22-1)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes <xsl:template match="/"> <xsl:text>All numbers in the list are less than or equal to 100: </xsl:text> <xsl:variable name="result"> <xsl:call-template name="AllLessThan100"> <xsl:with-param name="numberList" select="NumberList/Number"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$result"/> </xsl:template>

<section id=06> XSLT </section> </material>

Pass to the named template a list of <Number> nodes, i.e., a nodelist. This is a recursive routine If the nodelist is empty then return true Check the first node on the list. If it's greater than 100, then return false (and we're done). Otherwise, recurse over the remaining nodes.

<xsl:template name="AllLessThan100"> <xsl:param name="numberList"/> <xsl:choose> <xsl:when test="not($numberList)"> <xsl:text>true</xsl:text> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test="$numberList[1] &gt; 100"> <xsl:text>false</xsl:text> </xsl:when> <xsl:otherwise> <xsl:call-template name="AllLessThan100"> <xsl:with-param name="numberList" select="$numberList[position() &gt; 1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template>

eXtensible Markup Language Part 2

Do Lab3,

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

generate-id()
Use this function to generate a unique string for a node

Example. generate-id(/FitnessCenter/Member[1]) will return a unique id for the first Member

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

Using generate-id() to Uniquely Identify Elements

<section id=06> XSLT </section> </material>

In html-example08 we created two tables - a table containing the Members Names, and a separate table containing home Phone numbers. Each Name was hyperlinked to his/her home Phone. We used the id attribute on each Member element to link the two tables together. Suppose there is no id attribute. We can use generate-id() to create a unique identifier.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

<TABLE border="1" width="25%"> <TR><TH>Name</TH></TR> <xsl:for-each select="/FitnessCenter/Member"> <TR> <TD> <A href="#{generate-id(.)}"> <xsl:value-of select="Name"/> </A> </TD> </TR> </xsl:for-each> </TABLE> <BR/><BR/><BR/><BR/><BR/> <TABLE border="1" width="25%"> <TR><TH>Home Phone Number</TH></TR> <xsl:for-each select="/FitnessCenter/Member"> <TR> <TD> <A name="{generate-id(.)}"> <xsl:value-of select="Phone[@type='home']"/> (see html-example23) </A> </TD> </TR> </xsl:for-each> eXtensible Markup Language </TABLE> Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Same (XML) Data, Multiple Views


In html-example24 I show how to create an HTML document that allows a client to view an XML document in different forms. Look at html-example24. With the buttons on the left side of the screen we can select which view is desired.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Multiple Stylesheets to provide the different views

FitnessCenter.xml

ShowMembers.xsl ShowPlatinumMembers.xsl ShowGoldMembers.xsl

ShowAll.xsl

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

FitnessCenter.html - comprised of two frames

ShowMembers

ShowPlatinumMembers

ShowGoldMembers

ShowAll

RawXML

Controls.html

Body.html

FitnessCenter.html
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

FitnessCenter.html

<HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <FRAMESET cols="20%,80%"> <FRAME src="controls.html" name="controlsFrame"> <FRAME src="body.html" name="bodyFrame"> </FRAMESET> </HTML>

Two columns. The first column is 20% of the width of the screen. The second column is 80% of the width of the screen.

FitnessCenter.html NOTE: do NOT have a <BODY> element (it won't work if you do)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Body.html
<HTML> <HEAD> <TITLE>Fitness Center</TITLE> </HEAD> <BODY> </BODY> </HTML> Body.html This document is very simple - it's empty! The body will be filled in with the HTML that is generated by styling the XML document
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Controls.html
(tracing through the actions that occur when a user selects "ShowGoldMembers")

Press Show Gold Members button


Invoke the Javascript function, ShowGoldMembers()

Load ShowGoldMembers.xsl

Transform (the previously loaded) FitnessCenter.xml using ShowGoldMembers.xsl

Set the body of Body.html to the generated html

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Controls.html
(code to ShowGoldMembers)
<FORM name="controlForm"> <INPUT type="button" value="Show Gold Members" onclick="ShowGoldMembers </FORM>

This is preloading the XML document

<SCRIPT language="JScript" defer="true"> var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); xml.async = false; xml.load("FitnessCenter.xml"); function ShowGoldMembers() { var xsl = new ActiveXObject("Msxml2.DOMDocument.3.0"); xsl.async = false; xsl.load("ShowGoldMembers.xsl"); parent.bodyFrame.document.body.innerHTML = xml.transformNode(xsl); } </SCRIPT>

Load the XSL document Transform the XML document using the stylesheet, and assign the body of Body.html to the generated html.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Using SAXON in a Browser


(rather the XSL Processor built into IE)

The last example utilized the XSL Processor built into IE (msxml) to do the transformations. Suppose the you would like to use a different XSL Processor, e.g., SAXON?
Why would you want to do this? Answer: SAXON has several capabilities that msxml does not have.

SAXON comes with a Java applet that you can use to do XSL processing within a browser. See html-example-24-a for details on how to use SAXON's Java applet to implement the multi-button example. See html-example-24-b for an example of how to use SAXON as the XSL Processor within a browser.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Inserting spaces into HTML output

<xsl:text disable-output-escaping="yes"><![CDATA[&#160;&#160;&#160;&#160;]]></xsl:text>

Put one character references for each space required

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

Debugging your Stylesheets using xsl:message

<section id=06> XSLT </section> </material>

xsl:message is used to display a message, and (optionally) terminate execution of the stylesheet. The message is sent to the screen, not to the output file. This provides a very nice way to monitor the flow of your stylesheet, without impacting the output file.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Example using xsl:message

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <BODY> <xsl:for-each select="FitnessCenter/Member"> <xsl:if test="MembershipFee &lt; 0"> <xsl:message terminate="yes"> <xsl:text>Invalid MembershipFee</xsl:text> </xsl:message> </xsl:if> </xsl:for-each> <xsl:text>All the MembershipFee elements are valid</xsl:text> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

See html-example26

Two possible values for terminate - yes, or no. terminate="yes" means that you want the message output to the screen and then the program stopped. terminate="no" means that you want the message output to the screen and the program to eXtensible Markup Language Lecturer: Phan Vo Minh Thang MSc. continue executing.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

system-property() function
The system-property(property name) function enables you to obtain information about the XSL Processor that you are using:
xsl:vendor - if you specify this as the value for property name then it will return the name of the XSL Processor vendor xsl:vendor - this provides the URL to the vendor's web site xsl:version - this indicates what version of the XSL spec is implemented.

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Recommended Practice

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:message> XSLT Processor: <xsl:value-of select="system-property('xsl:vendor')"/> </xsl:message> <HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY> Welcome! </BODY> </HTML> </xsl:template> </xsl:stylesheet>

It is very good practice to add this to the start of every stylesheet. This will give you a message indicating which XSL Processor you are using. When might you be uncertain which XSL Processor is being used? Java comes bundled with xalan. Suppose that you want to write a Java program which uses Saxon instead. You will definitely want to use the above to ensure that you are invoking Saxon and not the built-in xalan. (I know. I have made the mistake of thinking that I was using Saxon when in fact I was using xalan.)
Lecturer: Phan Vo Minh Thang MSc.

See html-example27

eXtensible Markup Language

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Embedded Stylesheets
You can embed a stylesheet within an XML document.

<?xml version="1.0"?> <!DOCTYPE FitnessCenter [ <!ATTLIST xsl:stylesheet id ID #REQUIRED> ]> <?xml-stylesheet type="text/xml" href="#embed"?> <FitnessCenter> <Member level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> ... <xsl:stylesheet id="embed" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> ... </xsl:stylesheet> </FitnessCenter>

Stylesheet embedded within the XML document

eXtensible Markup Language

Lecturer: Phan Vo Minh Thang MSc.

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Embedded Stylesheets

You must indicate that the id attribute is of type ID.

<?xml version="1.0"?> <!DOCTYPE FitnessCenter [ <!ATTLIST xsl:stylesheet id ID #REQUIRED> ]> <?xml-stylesheet type="text/xml" href="#embed"?> <FitnessCenter> <Member level="platinum"> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> ... <xsl:stylesheet id="embed" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> ... </xsl:stylesheet> </FitnessCenter>

The stylesheet PI references the embeded stylesheet (as indicated by the"#" sign)

Add an id attribute to the xsl:stylesheet element.

Lecturer: Phan Vo See html-example28 (Note: not all XSL Processors support embedded stylesheets)Minh Thang MSc.

eXtensible Markup Language

<?xml version=1.0> <material> XML Lectures Notes

<section id=06> XSLT </section> </material>

Info

Course name:

Special Selected Topic in Information System


Section: XSLT Number of slides: 106 Updated date: 12/02/2006 Contact: Mr.Phan Vo Minh Thang
(minhthangpv@hcmuaf.edu.vn)
eXtensible Markup Language
Lecturer: Phan Vo Minh Thang MSc.

You might also like