Advanced XSLT II. Iteration in XSLT we sometimes wish to apply the same transform to a set of nodes we iterate through a node set the node set is defined.

Post on 28-Mar-2015

229 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

Transcript

Advanced XSLT II

Iteration in XSLT

• we sometimes wish to apply the same transform to a set of nodes

• we iterate through a node set

• the node set is defined by an XPath expression

• we use a for-each element to control the iteration

<xsl:for-each>

• Applies processing to all nodes in a given node set

• select attribute contains XPath expression defining the node set

<xsl:for-each select=“???”>• the current node changes at each iteration of

for-each– changes the context for transforms of content

example

• we have XML data for a tutorial, divided into sections

• we wish to produce a numbered contents list in HTML

• we use for-each twice to create a numbered heading and a list of sections

• we use the position() function for the numbering

<tutorial> <section>

<title>XML Tutorial</title> <panel> <title>XML and DTDs</title> </panel> <panel> <title>XPath and XSLT</title> </panel>

</section> <section>

<title>XSLT Tutorial</title> <panel> <title>XML and XSLT</title> </panel>

</section><!-- more sections follow – not shown -->

</tutorial>

The Data

<h1>Section 1. XML Tutorial</h1>

<ul>

<li>1. XML and DTDs</li>

<li>2. XPath and XSLT</li>

</ul>

<h1>Section 2. XSLT Tutorial</h1><ul>

<li>1. title>XML and XSLT </li></ul>

… and so on for each section

The Desired Output

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

<xsl:template match = "section"> <h1><xsl:text>Section </xsl:text> <xsl:value-of select = "position()" /> <xsl:text>. </xsl:text> <xsl:value-of select = "title" /></h1><ul> <xsl:apply-templates select="panel"/> </ul> </xsl:template>

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

<xsl:template match = “tutorial”> <xsl:for-each select=“section”> <h1><xsl:text>Section </xsl:text> <xsl:value-of select = “position()” /> <xsl:text>. </xsl:text> <xsl:value-of select = “title” /></h1> <ul>

<xsl:for-each select = “panel”> <li><xsl:value-of select = “position()” /> <xsl:text>. </xsl:text> <xsl:value-of select = “title” /></li></xsl:for-each>

</ul> </xsl:for-each></xsl:template

example - notes

• for-each select=“section” selects all section nodes in the current tutorial– position() will number the sections in

document order

• for-each select=“panel” selects all panel nodes in the current section

• this is just a nested loop!

modes

• Sometimes you may wish to transform the same node in more than one way

• The transform for a node is defined in a template

• A mode attribute is available for template and apply-templates elements

• This allows more than one template to be defined for any node

example

• XML data for a “famous scientists” website

• The data contains a name element for each person featured on the site.

• We use mode to achieve two different presentations of name – table of contents– personal data entry

<?xml version = “1.0”?>

<people>

<person born=“1912” died=“1954”>

<name><first_name>Alan</first-name>

<last_name>Turing</last_name>

</name>

<profession>computer scientist</profession>

<profession>mathematician</profession>

<profession>cryptographer</profession>

</person>

<!-- continued on next page -->

The Data

<!-- continued from previous page -->

<person born=“1918” died=“1988”>

<name><first_name>Richard</first-name>

<middle_initial>P</middle_initial>

<last_name>Feynman</last_name>

</name>

<profession>physicist</profession>

<hobby>playing the bongoes</hobby>

</person>

</people>

The Data

The Desired Output

<ul>

<li>Turing, Alan</li>

<li>Feynman, Richard</li>

</ul>

Name: Alan Turing <br />

Born: 1912 <br />

Died: 1954 <br />

Professions: computer scientist, mathematician, cryptographer <br />

Hobbies: none known

<xsl:template match = "people"> <html><head> <title>Famous Scientists</title></head><body> <ul> <xsl:for-each select = "person"> <li><xsl:value-of select = "name/last_name" />, <xsl:value-of select = "name/first_name" /></li> </xsl:for-each> </ul> <xsl:for-each select = "person"> Name: <xsl:value-of select="name/first_name" />

<xsl:value-of select="name/last_name" /><br/> Born: <xsl:value-of select="@born" /> <br/> Died: <xsl:value-of select="@died" /> <br/> </xsl:for-each> </body></html></xsl:template>

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

<xsl:template match = “people”>

<html><head>

<title>Famous Scientists</title></head><body>

<ul>

<xsl:apply-templates select = “person” mode = “toc” />

</ul>

<xsl:apply-templates select = “person” />

</body></html>

</xsl:template>

<!-- stylesheet continues on next page-->

<!-- specify the template mode for person -->

<xsl:template match = “person” mode = “toc”>

<xsl:apply-templates select=“name” mode=“toc”/>

</xsl:template>

<!--Table of Contents mode template for name-->

<xsl:template match = “name” mode = “toc”>

<li><xsl:value-of select = “last_name” />,

<xsl:value-of select = “first_name” /></li>

</xsl:template>

<!-- default mode template for person-->

<xsl:template match = “person”>

Name: <xsl:value-of select=“first-name” />&nbsp;

<xsl:value-of select=“last-name” /><br/>

Born: <xsl:value-of select=“@born” /> <br/>

Died: <xsl:value-of select=“@died” /> <br/>

<!-- complete the rest as an exercise -->

</xsl:template>

<!-- end of stylesheet -->

</xsl:stylesheet>

attribute value templates

• allows attribute values derived from the source to be set in the output

• example<xsl:template match = “name”><name first = “{first_name}”

initial = “{middle_initial}” last = “{last_name}” />

</xsl:template>

<xsl:call-template>

• specifies a particular template to be invoked

• perhaps not related directly to a node-set– e.g. to add boilerplate start_html markup

• template must have a name attribute

• <xsl:call-template> calls the template by name

<xsl:template name = “createMasthead”>

<!—Interesting stuff that generates the masthead

goes in here -->

</xsl:template>

<xsl:template match = “/”>

<html>

<head><title>some-title</title></head>

<body>

<xsl:call-template name = “createMasthead” />

<xsl:param>, <xsl:with-param>

• <xsl:param> defines parameters for templates• parameters can be passed to templates from either

call-template or apply-template elements containing <xsl:with-param> elements

• name attribute names the parameter• select attribute (or content) defines the value of the

parameter

<apply-templates><call-template><with-param>

<template><param>

XSLT

processing flow

reference to

template and parameter passed

return to XSLT processing flow

<xsl:template name = “addTableCell”>

<xsl:param name = “bgcolor” select = “’blue’” />

<xsl:param name = “width”>

<xsl:text>150</xsl:text>

</xsl:param>

<td width = “$width” bgcolor = “$bgcolor”>

<!-- cell content goes here -->

</td>

</xsl:template>

<xsl:call-template name = “addTableCell”>

<xsl:with-param name = “width” select = “./@width” />

</xsl:call-template>

<xsl:variable>

• allows values to be stored to assist with processing flow logic

• name attribute names the variable

• select attribute (or content) defines the value of the variable

• value can also be defined from element content

<xsl:variable name = “x” />

<!– variable $x defined, value is the empty string -->

<xsl:variable name = “color” value = “’blue’” />

<!-- variable $color has as value the string “blue” -->

<xsl:variable name = “y”>

<xsl:choose>

<xsl:when test = “$x &gt; 7”>

<xsl:text>13</xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:text>15</xsl:text>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<!-- essentially, if $x > 7, $y = 13 else $y = 15 -->

<xsl:sort>

• appears inside <xsl:apply-templates> or inside <xsl:for-each>

• sorts a node-set according to some criterion

• successive sort elements impose sub-orders

• select attribute defines the sorting criterion

• data-type defines the type of sort– text (the default)– number

<xsl:for-each select = “addressbook/address”>

<xsl:sort select = “name/last-name” />

<xsl:sort select = “name/first-name” />

<xsl:apply-templates select = “.” />

</xsl:for-each>

<!-- sorts addresses by last then first name -->

<xsl:for-each select = “number-list/number”>

<xsl:sort select = “.” data-type = “number” />

<xsl:value-of select = “.” />

</xsl:for-each>

<!-- sorts numbers in numerical order -->

<xsl:sort>

more sort attributes

• order– ascending (default)– descending

• case-order– upper-first– lower-first

document ( )

• converts a parameter into a URI– relative to current document– second parameter gives an alternative base URI

• returns a node-set associated with the URI

• allows content to be extracted from multiple XML documents

• without parameter defaults to current document

multiple XML files

XSLTdocument

XSLTprocessor

outputdocument

set oftemplate rules

match elements and replace using template rules

XMLsource

XMLsource

XMLsource

XMLsource

XMLsource

XMLsource

masterdocument

document()

<report>

<title>Fridge Contents</title>

<fml file = “fridge1.xml” />

<fml file = “fridge2.xml” />

<fml file = “fridge3.xml” />

</report>

<xsl:template match = “/”>

<xsl:for-each select = “/report/fml”>

<xsl:apply-templates select=“document(@file)”/>

</xsl:for-each>

</xsl:template>

<!--followed by templates for fridge elements-->

XML

XSLT

XSLT extensions• extension elements are passed to external

code (extension functions) for processing– Java, Perl, C# etc.

• extends power of XSLT to arbitrary transformations

• implementation varies between XSLT processors– Xalan, Saxon, XT all allow extensions, but in

different ways

Useful websites• Standards:

– www.w3.org/Style/XSL/- administrates xsl std• www.w3.org/TR/xslt

• Tutorials/Forums– www.w3schools.com/xsl– www.learn-xslt-tutorial.com/– www.xml.com– www.tizag.com/xmlTutorial/xslttutorial.php

top related