using xslt and xpath

154
1 (c) [2001]. Roger L. Costello. All Rights Reserved. Using XSLT and XPath Roger L. Costello (XML Technologies) With changes and additions by Thomas Krichel http://openlib.org/home/kr ichel

Upload: vega

Post on 06-Jan-2016

28 views

Category:

Documents


0 download

DESCRIPTION

Using XSLT and XPath. Roger L. Costello (XML Technologies) With changes and additions by Thomas Krichel http://openlib.org/home/krichel. Roger’s Acknowledgement. I wish to thank David Jacobs for showing me a new way of looking at HTML and XSLT/XPath - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Using XSLT and XPath

1Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using XSLT and XPath

Roger L. Costello (XML Technologies)

With changes and additions by Thomas Krichel http://openlib.org/home/krichel

Page 2: Using XSLT and XPath

2Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Roger’s Acknowledgement

• I wish to thank David Jacobs for showing me a new way of looking at HTML and XSLT/XPath

• Many of the examples that I use in this tutorial come straight from David's excellent paper, Rescuing XSLT from Niche Status (see http://www.xfront.com)

Page 3: Using XSLT and XPath

3Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Thomas acknowledgement

• Roger L. Costello

• Mitre Corp.

Page 4: Using XSLT and XPath

4Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

XSL transforms XML

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

XSL Processor

XSL

XML HTML (or XML or text)

Page 5: Using XSLT and XPath

5Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Doing it using Internet Explorer

• First, download the latest version of Internet Explorer (at this time it is 6.0)

• Write an XSL stylesheet stylish.xsl

• Write an XML file, and refer to the xsl stylesheet with a processing instruction

<?xml-stylesheet type="text/xsl“ href="stylish.xsl"?>

Note: this does not work with other browsers!

Page 6: Using XSLT and XPath

6Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

General stuff

Part 0

Page 7: Using XSLT and XPath

7Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

XML tree

• XSL has a model of XML as a tree.• XSL tree model is similar to the DOM model.• As the processor does its job it looks at elements

of the input tree and transforms them to the output tree.

• The processor only writes the file to the tree at the end.

• End points in the tree are called “nodes”.

Page 8: Using XSLT and XPath

8Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

in the general section

• we examine how XSL looks at an XML document. In fact it builds a tree.

• and then we look at a very simple way to look at what the stylesheet does. After that we have Roger showing us the details.

Page 9: Using XSLT and XPath

9Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Seven types of nodes• root node: contains all the elements in the

document. Not to be confused with the document element of XML.

• element node: contains an element• text node: contain an as-large-as-possible area of

text.• attribute node: contains attribute name and value• comment node: contains a comment• processing instruction (p-i) node• namespace node: each element node has one

namespace node for every namespace declaration

Page 10: Using XSLT and XPath

10Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

properties of nodes: name

• This is empty for the root, text and comment nodes.

• for elments and attribute node, it is the name as it appears in the xml file, expanded by namespace declarations.

• for p-i nodes, it is the target

• for a namespace node, it is the prefix

Page 11: Using XSLT and XPath

11Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

properties of nodes: string value• for text nodes: the text • for comment nodes: the text of the

comment• for p-i nodes: the data part of the p-i.• for an attribute node: the value of the

attribute• for a root node: the concatenation of all the

string values of all element and text children.

• for a namespace node: the URI of the namespace

Page 12: Using XSLT and XPath

12Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

properties of nodes: base URI

• for all nodes: the URI of the XML source document where the node has been found

• Only of interest for elements and p-i nodes

• for the root node: the URI of the document

• for attribute, text and comment nodes: the base URI of its parent node

Page 13: Using XSLT and XPath

13Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

properties of nodes: children

• for element nodes: all the element nodes, text nodes, p-i nodes and comment nodes between its start and end tags.

• for root nodes: all the element nodes, text nodes, p-i nodes and comment nodes that are not children of some other node.

Page 14: Using XSLT and XPath

14Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

parent node

• for all nodes except root nodes: the parent of the node.

• attribute nodes and namespace nodes have an element node as parent node, but are not considered to be its child.

Page 15: Using XSLT and XPath

15Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

property of nodes: attribute

• element: one to many attributes that the element has

• other nodes: empty

Now we look at what XSL does

Page 16: Using XSLT and XPath

16Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Different formats…

• <xsl:output method="xml"> is the default

• <xsl:output method="html>

• <xsl:output method="text"> used for everything else. Final formatting may be up to formatting objects, anyway.

• Your stylesheet processor may have more formats, but they will be vendor-specific.

Page 17: Using XSLT and XPath

17Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

templates set rules

<xsl:template match="expression">

do some stuff

<xsl:template>

This is a rule that says, if you find a node that matches the expression expression, then go ahead and do some stuff. It is called a template. The fact that a rule is written down down does not imply that it is applied.

Page 18: Using XSLT and XPath

18Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

applying templates

• <xsl:apply-templates/>

says: apply all template rules on the current node and on all its child nodes.

Page 19: Using XSLT and XPath

19Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Default, built-in rules for the nodes

• root: <xsl:apply-templates> on all children

• element: <xsl:apply-templates> to the current node and all its children

• attribute: copy the value as text to the output

• text: copy the text to the output

• comment, p-i, namespace: do nothing

Page 20: Using XSLT and XPath

20Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Generating HTML

part I

Page 21: Using XSLT and XPath

21Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 22: Using XSLT and XPath

22Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Enhancing HTML Documents with XML Data

XML Document

HTML Document(with embeddedXSL elements)

XSL element

XML data

XSLProcessor

XML data

Page 23: Using XSLT and XPath

23Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 24: Using XSLT and XPath

24Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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>

FitnessCenter.xsl (see html-example01)

Page 25: Using XSLT and XPath

25Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Note

• The HTML is embedded within an XSL template, which is an XML document. The HTML must be well formed.

• 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.

Page 26: Using XSLT and XPath

26Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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)

Page 27: Using XSLT and XPath

27Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Extracting a Value from & 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."

Page 28: Using XSLT and XPath

28Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Document/

PI<?xml version=“1.0”?>

ElementFitnessCenter

ElementMember

ElementName

ElementPhone

ElementPhone

ElementFavoriteColor

TextJeff

Text555-1234

Text555-4321

Textlightgrey

Page 29: Using XSLT and XPath

29Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Use FavoriteColor 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)

Page 30: Using XSLT and XPath

30Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using an extracted value as attribute

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 attributevalue you must use curly braces: <Body bgcolor="{/FitnessCenter/Member/FavoriteColor}">

Evaluate the expression within the curly braces. Assign the valueto the attribute.

Page 31: Using XSLT and XPath

31Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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)

Page 32: Using XSLT and XPath

32Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

The predicate

In this example we want "the Phone element where the valueof its type attribute equals 'home' ":

<xsl:value-of select="/FitnessCenter/Member/Phone[@type='home']"/>

The expression within […] is called a "predicate". Its purposeis to filter.

Note the use of the single quotes within the double quotes. select=" … ' …' …"

Page 33: Using XSLT and XPath

33Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Review - HTML Table

<table border=“1” width=“100%”>

</table>

<tr>

<tr>

<tr> </tr>

</tr>

</tr><th> </th>

<th> </th>

<th> </th>

<td> </td>

<td> </td>

<td> </td>

<td> </td>

<td> </td>

<td> </td>

This will create a table with 3 rows - the first row contains a headerfor each column. The next two rows contains the table data.

Page 34: Using XSLT and XPath

34Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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

Page 35: Using XSLT and XPath

35Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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.

Page 36: Using XSLT and XPath

36Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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>

(see html-example05)

(leaving out xsl surroundings…)

Page 37: Using XSLT and XPath

37Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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>

Page 38: Using XSLT and XPath

38Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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 treeand 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 thetype attribute)

Do Lab1,Parts 1-3

Page 39: Using XSLT and XPath

39Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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>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>

(see html-example07)

Adding the name

Page 40: Using XSLT and XPath

40Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Getting the Name when accessing the Phone

Member

Phone

555-1234

Phone

555-4321

Name

Jeff

Notice how when in the for-eachloop we need to accessthe Name which is "upand over" with respect to the Phone element

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

Page 41: Using XSLT and XPath

41Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Conditional Processing

• 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".

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

Do Lab1,Part 4

Page 42: Using XSLT and XPath

42Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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: </BODY></HTML>

(see html-example06)

Adding the special offer, leaving phone numbers

Page 43: Using XSLT and XPath

43Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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.

• Let us enlarge our document to contain a couple of more members.

Page 44: Using XSLT and XPath

44Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<?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>

Page 45: Using XSLT and XPath

45Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Access repeated XML elements

<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>

Page 46: Using XSLT and XPath

46Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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>

Access repeated XML elements

Page 47: Using XSLT and XPath

47Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Review - HTML Hyperlinking

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

<A href="#AnnaAndTheKing">Click Here</A>...

This creates an internal hyperlink (the source "anchor" links tothe target anchor).

Page 48: Using XSLT and XPath

48Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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.

Page 49: Using XSLT and XPath

49Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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><TD> <A name="{@id}"> <xsl:value-of select="Phone[@type='home']"/> </A> </TD></TR> </xsl:for-each> </TABLE> Do Lab1,

Parts 5-6

Page 50: Using XSLT and XPath

50Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Numbering

• There is an XSL element that returns a number corresponding to the element's position in the set of selected nodes

(see html-example09)

<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>

Output:1. Jeff2. David3. Roger

Page 51: Using XSLT and XPath

51Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Start Numbering from 0

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

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

Page 52: Using XSLT and XPath

52Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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, ...

Page 53: Using XSLT and XPath

53Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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. JeffB. DavidC. Roger

Page 54: Using XSLT and XPath

54Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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>

"For each Member, sort the Name elements"

Output:DavidJeffRoger

(see html-example10)

Page 55: Using XSLT and XPath

55Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

xsl:sort

<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 issorted using the Name child element. This occurs priorto the first iteration of the loop. After the set of Memberelements are sorted then the looping begins.

Page 56: Using XSLT and XPath

56Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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 a literal string.We could use this variable as follows: Value = <xsl:value-of select=“$hello”/>This will output:Value = Hello World

Page 57: Using XSLT and XPath

57Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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)

Page 58: Using XSLT and XPath

58Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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: Name = <xsl:value-of select=“$member/Name”/>Home Phone = <xsl:value-of select=“$member/Phone[@type='home']”/>This will result in generating: Name = Jeff Home Phone = 555-1234

Member

Phone

555-1234

Phone

555-4321

Name

Jeff

Page 59: Using XSLT and XPath

59Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

concat() functionconcat(destination_string, string_to_add)

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

<xsl:value-of select="concat('Welcome ', Name, '!')"/>

<BR/>

</xsl:for-each>

Output:

Welcome Jeff!

Welcome David!

Welcome Roger!

Page 60: Using XSLT and XPath

60Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Scope of xsl:variable

• A variable is “write once, read many time”.

• 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.

Page 61: Using XSLT and XPath

61Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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 hereDo Lab2,

Part 1

Page 62: Using XSLT and XPath

62Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Global Variables<?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></xsl:stylesheet>

Page 63: Using XSLT and XPath

63Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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?

Here’s 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)

Page 64: Using XSLT and XPath

64Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Let’s 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"/>

(see html-example14)

Page 65: Using XSLT and XPath

65Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Output of the previous example

Jeff

Jeff/

Jeff/David

Jeff/ The previous name went out of scope.

Jeff/Roger

Jeff

Page 66: Using XSLT and XPath

66Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Here’s what we would like to do

names

Open up thenames box

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

Iterate througheach name, adding intothe open box

Jeff/David/RogerClose the box

names

Jeff … / … David … / … Roger

Page 67: Using XSLT and XPath

67Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Output to a variableIn 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>

Page 68: Using XSLT and XPath

68Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Example for output to a variable

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

Page 69: Using XSLT and XPath

69Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

xsl:choosexsl:choose allows you to elegantly express multiple

conditional tests. Here’s 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.

Page 70: Using XSLT and XPath

70Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 71: Using XSLT and XPath

71Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

substring-after() works too

substring-before(string, pattern)

returns the part of the string string before the occurrence of the pattern pattern. Example:

“Get the contents of Phone and put it into the variable called ‘phone’. Then extract from the content of ‘phone’ the stringbefore the '-' (i.e., the telephone exchange)”.

<xsl:variable name="phone" select="Phone"/><xsl:value-of select="substring-before($phone, '-')"/>

substring-before()

Page 72: Using XSLT and XPath

72Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

starts-with() string functionHere’s the form of this string function:

starts-with(string, pattern)

It tests if the string string starts with the pattern pattern. It returns a Boolean (i.e. true or false). Example:

<xsl:if test="starts-with(Phone, '555')"> action</xsl:if>

“If the Phone starts with the string, ‘555’ then do action”.

Page 73: Using XSLT and XPath

73Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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).

Example:

substring(‘1234567890’, 2, 5) returns ‘23456’

Page 74: Using XSLT and XPath

74Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

string-length() function

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

Example:

string-length(‘1234567890’) returns 10

Page 75: Using XSLT and XPath

75Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

translate() functiontranslate(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)

Note: need to put the string within (single) quotes, otherwisethe XSL Processor will try to interpret it as an XML element.

Do Lab2,Part 3

Page 76: Using XSLT and XPath

76Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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.

< > = <= >= !=&lt; &gt; = &lt;= &gt;= !=

Want this:Use this:

Page 77: Using XSLT and XPath

77Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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.

Page 78: Using XSLT and XPath

78Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 79: Using XSLT and XPath

79Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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 Membernow has MembershipFeeelement

Page 80: Using XSLT and XPath

80Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Compute Membership Revenue

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

(see html-example16)

Page 81: Using XSLT and XPath

81Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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">

Page 82: Using XSLT and XPath

82Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

count() function

count(set of node) returns an integer representing the numberof 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

Page 83: Using XSLT and XPath

83Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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 elementdo ...

Page 84: Using XSLT and XPath

84Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Namecalling with 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

Page 85: Using XSLT and XPath

85Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Use Curly Braces if

• the attribute is 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}”>

Page 86: Using XSLT and XPath

86Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 87: Using XSLT and XPath

87Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Fitness Center 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.

Page 88: Using XSLT and XPath

88Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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></TABLE>

(see html-example20)

Do Lab3,Part 1

Page 89: Using XSLT and XPath

89Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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>

(see html-example21)

Page 90: Using XSLT and XPath

90Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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>

(see html-example22)Do Lab3,

Part 2

Page 91: Using XSLT and XPath

91Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

Page 92: Using XSLT and XPath

92Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using generate-id() to Uniquely Identify Elements

• 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.

Page 93: Using XSLT and XPath

93Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<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']"/> </A> </TD></TR> </xsl:for-each> </TABLE> (see html-example23)

Page 94: Using XSLT and XPath

94Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using XSLT and XPath to Transform XML Documents

Part II

Page 95: Using XSLT and XPath

95Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Transformation Language

• XSL may be used as a transformation language --> it may be used to transform an XML document into another XML document (perhaps the new one is the same, minus company sensitive data)

Transformation Engine(XSL Processor)

XSL

XML XML

Page 96: Using XSLT and XPath

96Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Example: Filter Gold Members<?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>

<?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="3" level="platinum"> <Name>Roger</Name> <Phone type="home">888-1234</Phone> <Phone type="work">888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> </Member></FitnessCenter>

Page 97: Using XSLT and XPath

97Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

XML Transformations - all about (Template) “Rules”

• “Hey xsl processor, when you encounter the root element (e.g., FitnessCenter) do [action1]”

• “Hey xsl processor, when you encounter the Member element do [action2]”

• And so forth

Page 98: Using XSLT and XPath

98Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

XML Transformations - all about (Template) “Rules”

• Each template rule has two parts:– A pattern or matching part, that identifies the

XML node in the source document to which the action part is to be applied. Matching information is contained in an attribute.

– An action part that details the transformation of the node

Page 99: Using XSLT and XPath

99Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

XSL Document Structure<?xml version=“1.0”?><xsl:stylesheet> <xsl:template match=“/”> [action] </xsl:template> <xsl:template match=“FitnessCenter”> [action] </xsl:template> <xsl:template match=“Member”> [action] </xsl:template> ...</xsl:stylesheet>

Page 100: Using XSLT and XPath

100Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Template Rules

Template rules take the following general form:

<xsl:template match=“pattern”> [action]

</xsl:template>

Page 101: Using XSLT and XPath

101Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Template Rules (Example)

<xsl:template match=“Member”> <xsl:apply-templates/></xsl:template>

“Hey XSL processor, as you parse through the XML documentand you get to a <Member> element use this template rule.”

<xsl:template match=“Member”>

“Go to each of my children (the Member children) and apply the template rules to them.”

<xsl:apply-templates/>

Page 102: Using XSLT and XPath

102Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

TerminologyIn FitnessCenter.xml we have (snippet):

<FitnessCenter> <Member> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> ...</FitnessCenter>

“Member is a child element of the FitnessCenter element. Name, Phone,Phone, and FavoriteColor are children elements of the Member element.Member is a parent of Name. FitnessCenter and Member are ancestors of Name.”

Page 103: Using XSLT and XPath

103Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

xsl:element

• Suppose that you are writing a stylesheet to generate an XML document. Obviously, you will need your stylesheet to output elements.– xsl:element is used to create elements

<xsl:element name=“element-name”> [contents of the new element]</xsl:element>

<element-name> [contents of the new element] </element-name>

creates

Page 104: Using XSLT and XPath

104Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Identity Transformation

• For our first example, lets create a stylesheet which simply creates an XML document that is a copy of the input XML document

Page 105: Using XSLT and XPath

105Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Document/

PI<?xml version=“1.0”?>

ElementFitnessCenter

ElementMember

ElementMember

ElementMember

ElementName

ElementPhone

ElementPhone

ElementFavoriteColor

... ...

TextJeff

Text555-1234

Text555-4321

Textlightgrey

...

Page 106: Using XSLT and XPath

106Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:template match="/"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="FitnessCenter"> <xsl:element name="FitnessCenter"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="Member"> <xsl:element name="Member"> <xsl:apply-templates/> </xsl:element> </xsl:template>

Cont. -->

Page 107: Using XSLT and XPath

107Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:template match="Name"> <xsl:element name="Name"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="Phone"> <xsl:element name="Phone"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="FavoriteColor"> <xsl:element name="FavoriteColor"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="text()"><xsl:value-of select="."/>

</xsl:template>

</xsl:stylesheet>

(see xml-example01)

Page 108: Using XSLT and XPath

108Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0" encoding="UTF-8"?><FitnessCenter> <Member> <Name>Jeff</Name> <Phone>555-1234</Phone> <Phone>555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> <Member> <Name>David</Name> <Phone>383-1234</Phone> <Phone>383-4321</Phone> <FavoriteColor>lightblue</FavoriteColor> </Member> <Member> <Name>Roger</Name> <Phone>888-1234</Phone> <Phone>888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> </Member></FitnessCenter>

Note that we've lost the attribute on the Member element

Page 109: Using XSLT and XPath

109Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:template match="Member"> <xsl:element name="Member"> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element> </xsl:template>

For each attribute Add an attribute to the element being output. The name of the attribute is the name of the current attribute being processed. The value of the attribute is the value of the current attribute being processed.

Getting Member’s Attribute:

(see xml-example02)

Page 110: Using XSLT and XPath

110Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0" encoding="UTF-8"?><FitnessCenter> <Member level=“platinum”> <Name>Jeff</Name> <Phone type="home">555-1234</Phone> <Phone type="work">555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> <Member level=“gold”> <Name>David</Name> <Phone type="home">383-1234</Phone> <Phone type="work">383-4321</Phone> <FavoriteColor>lightblue</FavoriteColor> </Member> <Member level=“platinum”> <Name>Roger</Name> <Phone type="home">888-1234</Phone> <Phone type="work">888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> </Member></FitnessCenter>

Page 111: Using XSLT and XPath

111Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Generalize

• Our identity stylesheet will only work for FitnessCenter XML documents. We can make a stylesheet which does an identity transformation on any XML document.

Page 112: Using XSLT and XPath

112Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. <?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="/"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="*"> <xsl:element name="{name(.)}"> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="text()"><xsl:value-of select="."/>

</xsl:template>

</xsl:stylesheet> (see xml-example03)

Page 113: Using XSLT and XPath

113Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Default Template Rules

• Every xsl document has two default template rules

• These rules are applied when the XSL Processor cannot find a template rule to use in your stylesheet

• Here are the two default template rules:

<xsl:template match=“/ | *”><xsl:apply-templates/>

</xsl:template>

<xsl:template match=“text()”><xsl:value-of select=“.”/>

</xsl:template>

“Match on the document orany element. The action is to goto the children and execute theirtemplate rules.”

“Match on a text node. The actionis to output the value of the textnode.”

Page 114: Using XSLT and XPath

114Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Multiple Applicable Rules

Suppose that the XSL Processor is processing FitnessCenterand it gets to the <Member> element. Why does it use: <xsl:template match=“Member”>...and not the default template rule: <xsl:template match=“/ | *”>...??? After all, both apply.

Answer: given two rules that apply, the more specific rule wins.--> Clearly, “*” is much more general than “Member”. “*” matches on any element. “Member” just matches

on the Member element.

Page 115: Using XSLT and XPath

115Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/> <xsl:template match="*"> <xsl:element name="{name(.)}"> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element> </xsl:template></xsl:stylesheet>

(see xml-example04)

Now that we know about the default template rules, we can further reduce the size of the stylesheet.

Page 116: Using XSLT and XPath

116Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:apply-templates select=“pattern”>

• The xsl:apply-templates element (without the select attribute) tells the XSL Processor to apply the template rules to all children (in document order)

• The xsl: apply-templates element can have a select attribute that tells the XSL Processor to process only the child element that matches “pattern”. – Thus, the select attribute rule enables us to specify the order in

which the children are processed

Page 117: Using XSLT and XPath

117Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:apply-templates select=“pattern”>

<xsl:template match="Member"> <xsl:apply-templates select="Name"/> <xsl:apply-templates select="Phone[@type='work']"/></xsl:template>"Go to the template rule for my Name child element. Thengo to the template rule for the work Phone child element."

<xsl:template match="Member"> <xsl:apply-templates select="*"/></xsl:template>"Go to all the child element nodes (not to any child text nodes)."

Do Lab4,Part 1-4

Page 118: Using XSLT and XPath

118Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

mode Attribute

• Allows you to create multiple template rules for the same element. Each template rule can process the element differently.

• So, you can have multiple template rules for the same element. Just give each template rule a different mode

<xsl:template match="Name" mode="Normal">

<xsl:template match="Name" mode="footnote">

Page 119: Using XSLT and XPath

119Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Problem

• Identity transform the FitnessCenter.xml document. However, after you have copied all the Members, follow up with a (new) GoldMembers section, containing the name of each gold member (within stars)

• The next slide shows what the output XML file should look like

Page 120: Using XSLT and XPath

120Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. <?xml version="1.0" encoding="UTF-8"?><FitnessCenter> <Member level="platinum"> <Name>Jeff</Name> <Phone>555-1234</Phone> <Phone>555-4321</Phone> <FavoriteColor>lightgrey</FavoriteColor> </Member> <Member level="gold"> <Name>David</Name> <Phone>383-1234</Phone> <Phone>383-4321</Phone> <FavoriteColor>lightblue</FavoriteColor> </Member> <Member level="platinum"> <Name>Roger</Name> <Phone>888-1234</Phone> <Phone>888-4321</Phone> <FavoriteColor>lightyellow</FavoriteColor> </Member> <GoldMembers> <Name>***David***</Name> </GoldMembers></FitnessCenter>

(see xml-example05)

Note that thenames hereare processeddifferentlythan the namein the GoldMemberssection

Page 121: Using XSLT and XPath

121Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. <?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/>

<xsl:template match="/"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="FitnessCenter"> <xsl:element name="FitnessCenter"> <xsl:apply-templates/> <xsl:element name="GoldMembers"> <xsl:for-each select="Member[@level='gold']"> <xsl:apply-templates select="Name" mode="footnote"/> </xsl:for-each> </xsl:element> </xsl:element> </xsl:template>

<xsl:template match="Member"> <xsl:element name="Member"> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates mode="Normal"/> </xsl:element> </xsl:template>

Page 122: Using XSLT and XPath

122Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:template match="Name" mode="Normal"> <xsl:element name="Name"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="Name" mode="footnote"> <xsl:element name="Name"> <xsl:text>***</xsl:text> <xsl:apply-templates/> <xsl:text>***</xsl:text> </xsl:element> </xsl:template>

<xsl:template match="Phone" mode="Normal"> <xsl:element name="Phone"> <xsl:apply-templates/> </xsl:element> </xsl:template>

<xsl:template match="FavoriteColor" mode="Normal"> <xsl:element name="FavoriteColor"> <xsl:apply-templates/> </xsl:element> </xsl:template>

</xsl:stylesheet>

Do Lab5,Part 1

Page 123: Using XSLT and XPath

123Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Stylesheet Reuse via xsl:include and xsl:import

• The elements xsl:include and xsl:import enable you to reuse other stylesheets.

• These elements are “top-level elements”. This means that they must be immediate children of the xsl:stylesheet element (i.e., they cannot be within a template rule)

• The xsl:include element is basically a macro substitution - the element is replaced by the contents of stylesheet it references

Page 124: Using XSLT and XPath

124Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:variable name="lcase" select="'abcdefghijklmnopqrstuvwxyz'"/><xsl:variable name="ucase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

<xsl:template match="*"> <xsl:apply-templates select="@* | * | text() | comment() | processing-instruction()"/></xsl:template>

<xsl:template match="@*"> <xsl:value-of select="translate(.,$lcase, $ucase)"/></xsl:template>

<xsl:template match="text()"> <xsl:value-of select="translate(.,$lcase, $ucase)"/></xsl:template>

</xsl:stylesheet>

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

<xsl:include href="file://localhost/xml-course/new-xsl/toUpperCase.xsl"/>

<xsl:template match="FitnessCenter"> ... </xsl:template> ...</xsl:stylesheet>

Replace the xsl:includeelement with the contentsof the referenced stylesheet(i.e., all the children ofxsl:stylesheet)

toUpperCase.xsl

Page 125: Using XSLT and XPath

125Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

xsl:import

• xsl:import acts just like xsl:include - the stylesheet that it references is macro-substituted. However, there is a difference:

– With xsl:include the stuff that is macro-substituted into the stylesheet has the same precedence as the rest of the stylesheet. It is as though you had one stylesheet.

– With xsl:import the stuff that is macro-substituted into the stylesheet has lower precedence than the rest of the stylesheet. Also, all xsl:import elements must come first in the stylesheet.

Page 126: Using XSLT and XPath

126Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using Long Names for Xpath Expressions

Part III

Page 127: Using XSLT and XPath

127Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Problem: iterate through ancestors

• Suppose that in your stylesheet you are at an arbitrary node in the XML tree. How would you output the name of all of its ancestor nodes?

Will this work: <xsl:value-of select="name(..)"/> <xsl:value-of select="name(../..)"/> <xsl:value-of select="name(../../..)"/>How many of these should we do? We don't know since we are at an arbitrary node!

Page 128: Using XSLT and XPath

128Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Problem: get the previous sibling and following sibling

• Suppose that in your stylesheet you are at an arbitrary node in the XML tree. How would you output the name of its previous sibling and following sibling?

Page 129: Using XSLT and XPath

129Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Long Notation

• Thus far we have used the abbreviated notation for expressing a path to a node. As we see there are some things for which the abbreviated notation is inadequate

• The long notation gives you the ability to express things that can't be expressed using the short notation

Page 130: Using XSLT and XPath

130Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. Document

/

PI<?xml version=“1.0”?>

ElementFitnessCenter

ElementMember

ElementName

ElementPhone

ElementPhone

ElementFavoriteColor

TextJeff

Text555-1234

Text555-4321

Textlightgrey

ancestors

precedingsibling

followingsiblings

If we are currently at the Member's first phone element then: we can select all ancestors by: all preceding siblings by: all following siblings by: ancestor::* preceding-sibling::* following-sibling::* Which yields: Which yields: Which yields: Member Name Phone FitnessCenter FavoriteColor

Page 131: Using XSLT and XPath

131Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. Document

/

PI<?xml version=“1.0”?>

ElementFitnessCenter

ElementMember

ElementName

ElementPhone

ElementPhone

ElementFavoriteColor

TextJeff

Text555-1234

Text555-4321

Textlightgrey

(the other Member elements)

descendants

If we are currently at the FitnessCenter element then: we can select all descendants by: descendant::* Which yields: Member Name Phone, etc

(see axis-example01)

Page 132: Using XSLT and XPath

132Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Axis

• ancestor, preceding-sibling, following-sibling, and descendent each provide a different way of navigating the XML tree.

• They are each called an axis

• On the next slide, we have a list of axis

Page 133: Using XSLT and XPath

133Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

• ancestor: selects all ancestors

• ancestor-or-self: selects the current node plus all its ancestors

• attribute: selects all the attributes

• child: selects all the children

• descendant: selects all the descendants

• descendant-or-self: selects the current node plus all its descendants

• following: selects everything in the document that follows the current node

• following-sibling: selects the siblings that follow

• namespace: selects all the namespaces that are in scope

• parent: selects the parent

• preceding: selects everything in the document that precedes the current node

• preceding-sibling: selects the siblings that precede

• self: selects the current node (see axis-example02)

Page 134: Using XSLT and XPath

134Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<xsl:template match="Member">  Member is the starting node   <br/>  <br />   Its ancestors are:   <br/> <xsl:for-each select="ancestor::*">  <xsl:value-of select="name(.)" />   <br/> </xsl:for-each><br />   Its preceding siblings are:   <br/> <xsl:for-each select="preceding-sibling::*">  <xsl:value-of select="name(.)" />   <br/> </xsl:for-each> <br/>   Its following siblings are:   <br/> <xsl:for-each select="following-sibling::*">   <xsl:value-of select="name(.)" />   <br/> </xsl:for-each>  <br/>   </xsl:template>

Example

Page 135: Using XSLT and XPath

135Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Using XSLT and XPath to Transform XML Documents that

contain Namespaces

Part IV

Page 136: Using XSLT and XPath

136Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

ProblemSuppose that the document that we are processing is using namespaces:

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

Note that we have a default namespace declaration. Thus, FitnessCenter, Member, Name, Phone, and FavoriteColor all belong to the http://www.gym.com namespace.

Page 137: Using XSLT and XPath

137Copyright (c) [2001]. Roger L. Costello. All Rights Reserved. <?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:apply-templates/> </BODY></HTML> </xsl:template>

<xsl:template match="*"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="Member"> Your name is: <xsl:value-of select="Name/text()"/> </xsl:template>

<xsl:template match="text()"> </xsl:template>

</xsl:stylesheet> (see namespaces-example01)

Output:-- empty --

Page 138: Using XSLT and XPath

138Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Why is the output empty?

<xsl:template match="Member"> Your name is: <xsl:value-of select="Name/text()"/></xsl:template>

This template does not match any element in the instance document!This template matches on a Member element in no namespace.However, in our instance document the Member element is in thehttp://www.gym.org namespace, i.e.,

{http://www.gym.com}Member

Page 139: Using XSLT and XPath

139Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Namespace Terminology

{http://www.gym.com}Member

Expanded name = The combination of the namespace URI and the local name

Local name

Namespace URI

Page 140: Using XSLT and XPath

140Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Namespace Terminology (cont.)

<gym:FitnessCenter xmlns:gym="http://www.gym.com"> <gym:Member> …</gym:FitnessCenter>

<gym:Member>

prefix

Page 141: Using XSLT and XPath

141Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

local-name()

• This is a built-in function which returns a string, corresponding to the local name of the element.

<xsl:template match="*"> Local name = <xsl:value-of select="local-name(.)"/> <xsl:apply-templates/></xsl:template>

Output:Local name = FitnessCenterLocal name = MemberLocal name = NameLocal name = PhoneLocal name = PhoneLocal name = FavoriteColor

(see namespaces-example02)

Page 142: Using XSLT and XPath

142Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

<?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:apply-templates/> </BODY></HTML> </xsl:template> <xsl:template match="*"> <xsl:apply-templates/> </xsl:template>

<xsl:template match="*[local-name()='Member']"> Your name is: <xsl:value-of select="*[local-name(.)='Name']/text()"/> </xsl:template>

<xsl:template match="text()"> </xsl:template>

</xsl:stylesheet>

Output:Your name is: Jeff

(see namespaces-example03)

Page 143: Using XSLT and XPath

143Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Alternatively<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gym="http://www.gym.com" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"><HTML><BODY><xsl:apply-templates/> </BODY></HTML> </xsl:template> <xsl:template match="*"><xsl:apply-templates/></xsl:template>

<xsl:template match="gym:Member"> Your name is: <xsl:value-of select="gym:Name"/> </xsl:template>

<xsl:template match="text()"> <!-- Do nothing --> </xsl:template>

</xsl:stylesheet>

Declare the gym namespace

Match on the Member elementin the gym namespace

Select the Name element inthe gym namespace

(see namespaces-example04)

Page 144: Using XSLT and XPath

144Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

namespace-uri()• This is a built-in function which returns a string

corresponding to the namespace URI of the node.

<xsl:template match="*"> Local name = <xsl:value-of select="local-name(.)"/> Namespace URI = <xsl:value-of select="namespace-uri(.)"/> <xsl:apply-templates/></xsl:template>

Output:Local name = FitnessCenterNamespace URI = http://www.gym.comLocal name = MemberNamespace URI = http://www.gym.comLocal name = NameNamespace URI = http://www.gym.comLocal name = PhoneNamespace URI = http://www.gym.com... (see namespaces-example05)

Page 145: Using XSLT and XPath

145Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

name() Revisited

• We have seen the name() function before. It returns the name of the node. But what name does it return if the node is in a namespace?– Answer: it returns the element name and its

prefix (this is called the QName, for Qualified Name)

Page 146: Using XSLT and XPath

146Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:template match="*"> Local name = <xsl:value-of select="local-name(.)"/> Namespace URI = <xsl:value-of select="namespace-uri(.)"/> Name = <xsl:value-of select="name(.)"/> <xsl:apply-templates/></xsl:template>

Page 147: Using XSLT and XPath

147Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Output:Local name = FitnessCenterNamespace URI = http://www.gym.comName = gym:FitnessCenterLocal name = MemberNamespace URI = http://www.gym.comName = gym:MemberLocal name = NameNamespace URI = http://www.gym.comName = gym:NameLocal name = PhoneNamespace URI = http://www.gym.comName = gym:PhoneLocal name = PhoneNamespace URI = http://www.gym.comName = gym:PhoneLocal name = FavoriteColorNamespace URI = http://www.gym.comName = gym:FavoriteColor

(see namespaces-example06)

Page 148: Using XSLT and XPath

148Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Identity transform - copying namespace declarations

• Recall our identity transform stylesheet:<xsl:template match="*"> <xsl:element name="{name(.)}"> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element></xsl:template>

Iterate through eachattribute and add themas attributes onto the element.

Page 149: Using XSLT and XPath

149Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

@* does not select namespace declarations!

• The @* will only select non-namespace declaration attributes. It will not select namespace declaration attributes

<Library xmlns="http://www.library.org" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" id="Boston Public Library">

This will be selected by @*

These will not be selected by @*

Page 150: Using XSLT and XPath

150Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

Identity transformation for XML documents containing namespaces?

• So how do we create a stylesheet that can copy over namespace declarations, along with the other attributes?– Answer: use the <xsl:copy/> element

• This element will copy the current element and all namespace declarations to the output file.

Page 151: Using XSLT and XPath

151Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:template match="* | @*"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template>

</xsl:stylesheet>

(see namespaces-example07)

The problem with this identity transform stylesheet is that it's not set upto allow us to make changes to elements/attributes.

Page 152: Using XSLT and XPath

152Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:template match="*"> <xsl:element name="{name(.)}"> <xsl:copy-of select="namespace::*" /> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each>

<xsl:apply-templates/>

</xsl:element> </xsl:template>

</xsl:stylesheet>

Error! Attemptingto create anelement in anamespace, butthe namespacehas not beendeclared yet!

Page 153: Using XSLT and XPath

153Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

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

<xsl:template match="*"> <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:copy-of select="namespace::*" /> <xsl:for-each select="@*"> <xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each>

<xsl:apply-templates/>

</xsl:element> </xsl:template>

</xsl:stylesheet>

Simultaneouslydeclare theelement and its namespace

Simultaneouslydeclare theattribute and its namespace

(see namespaces-example08)

Page 154: Using XSLT and XPath

154Copyright (c) [2001]. Roger L. Costello. All Rights Reserved.

The End

Thanks for your attention!