XPath tutorial - basics: Difference between revisions
m (using an external editor) |
m (using an external editor) |
||
Line 1: | Line 1: | ||
{{Incomplete}} | {{Incomplete}} | ||
{{under construction}} | |||
<pageby nominor="false" comments="false"/> | <pageby nominor="false" comments="false"/> | ||
== Introduction == | == Introduction == | ||
Line 43: | Line 44: | ||
* Each time a given XSLT or XQuery instruction needs to address (refer to) parts of an XML document we use XPath expressions. | * Each time a given XSLT or XQuery instruction needs to address (refer to) parts of an XML document we use XPath expressions. | ||
* XPath expressions also can contain functions, simple math and boolean expressions | * XPath expressions also can contain functions, simple math and boolean expressions | ||
With [[XSLT], XPath expressions are typicially used in'' match'' , '' select '' and '' test'' attributes: | |||
[[Image:xml-xpath-2.png]] | [[Image:xml-xpath-2.png]] | ||
== | == The XPath Syntax and the document model == | ||
=== | === Xpath Syntax === | ||
;Primary (relatively simple) XPath expressions: | |||
[[Image:xml-xpath-3.png]] | [[Image:xml-xpath-3.png]] | ||
Line 57: | Line 59: | ||
;Result of an Xpath | |||
* Can be various things, e.g. sets of nodes, a single node, a number, etc .... | * Can be various things, e.g. sets of nodes, a single node, a number, etc .... | ||
Line 63: | Line 65: | ||
;There are two notations for location paths | |||
# abbreviated (less available options) | # abbreviated (less available options) | ||
Line 72: | Line 74: | ||
;The formal specification of an XML Path | |||
** is very complex, i.e. has about 39 clauses and is very difficult to understand | ** is very complex, i.e. has about 39 clauses and is very difficult to understand | ||
** Some expressions shown here are beyound the scope of this class, | ** Some expressions shown here are beyound the scope of this class, don't panic ! | ||
Line 87: | Line 89: | ||
;Nodes that XPath can see: | |||
* root node | * root node | ||
Line 96: | Line 98: | ||
;Nodes XPath can't see: | |||
* XPath looks at the final document, therefore | * XPath looks at the final document, therefore can't see entities and document type declarations.... | ||
;The XML context | |||
* What a given XPath expression means, is always defined by a given XML context, i.e. the current node in the XML tree | * What a given XPath expression means, is always defined by a given XML context, i.e. the current node in the XML tree | ||
Line 108: | Line 110: | ||
;... Advance warning: | |||
The rest of this chapter will be quite boring (and it only covers XPath essentials ....) | The rest of this chapter will be quite boring (and it only covers XPath essentials ....) | ||
Line 173: | Line 175: | ||
;An XML document (file: xpath-jungle.xml used throughout the XPath chapter) | |||
* We only show part of the document | * We only show part of the document | ||
Line 213: | Line 215: | ||
;Task | |||
* We would like to get a simple list of problem titles | * We would like to get a simple list of problem titles | ||
Line 221: | Line 223: | ||
;(1) XSLT template for project XML root element (file: xpath-jungle-1.xsl) | |||
<xsl:template match="'' /project'' "> | <xsl:template match="'' /project'' "> | ||
Line 251: | Line 253: | ||
;(2) XSLT template for the problem element | |||
<xsl:template match='' "'' '' problems/problem'' '' "'' > | <xsl:template match='' "'' '' problems/problem'' '' "'' > | ||
Line 263: | Line 265: | ||
;(3) Result HTML | |||
<html> | <html> | ||
Line 321: | Line 323: | ||
;XML fragment | |||
<participants> | <participants> | ||
Line 361: | Line 363: | ||
;Task | |||
* Display a list of First Names plus their food preferences | * Display a list of First Names plus their food preferences | ||
Line 367: | Line 369: | ||
;XSLT (File xpath-jungle-2.xsl) | |||
* The first rule will just select all participants and create the list container (ul) | * The first rule will just select all participants and create the list container (ul) | ||
Line 423: | Line 425: | ||
;Parts of the result: | |||
<h1>What do we know about our participants ?</h1> | <h1>What do we know about our participants ?</h1> | ||
Line 480: | Line 482: | ||
;FYI: The system built-in (default) rules rely on wildcards | |||
This rule applies to the document root and all other elements (see [xml-xpath.html#23299 2.8 ���%G�₁��%@���Union of XPaths���%G�₁��%@ [25]]) | This rule applies to the document root and all other elements (see [xml-xpath.html#23299 2.8 ���%G�₁��%@���Union of XPaths���%G�₁��%@ [25]]) | ||
Line 534: | Line 536: | ||
;Mathematical expressions | |||
* Use the standard operators, except '' div'' instead of'' /'' ") | * Use the standard operators, except '' div'' instead of'' /'' ") | ||
Line 546: | Line 548: | ||
;Boolean operators (comparison, and, or) | |||
* List of operators (according to precedence) | * List of operators (according to precedence) | ||
Line 560: | Line 562: | ||
;Examples | |||
* Return all exercise titles with a grade bigger than 5. | * Return all exercise titles with a grade bigger than 5. | ||
Line 568: | Line 570: | ||
* Find elements that have a given attribute with a given value | * Find elements that have a given attribute with a given value | ||
'' XML_element_name [ @attribute_name = | '' XML_element_name [ @attribute_name = 'value']'' | ||
//solutions/item''[@val="low"]'' | //solutions/item''[@val="low"]'' | ||
Line 576: | Line 578: | ||
* Example XSLT template that will match all item elements with val="low". | * Example XSLT template that will match all item elements with val="low". | ||
<xsl:template match="'' //item[@val= | <xsl:template match="'' //item[@val='low']'' "> | ||
<xsl:value-of select="." /> | <xsl:value-of select="." /> | ||
Line 584: | Line 586: | ||
;Note: Usually expression also contain functions (see [xml-xpath.html#21068 2.7 ���%G�₁��%@���XPath functions���%G�₁��%@ [21]]) | |||
* Return last five elements of a list | * Return last five elements of a list | ||
Line 600: | Line 602: | ||
;The XSLT stylesheet (file xpath-jungle-3.xsl) | |||
<xsl:template match="/"> | <xsl:template match="/"> | ||
Line 652: | Line 654: | ||
;HTML result | |||
<html> | <html> | ||
Line 732: | Line 734: | ||
returns TRUE if the second string is part of the first and starts off the first | returns TRUE if the second string is part of the first and starts off the first | ||
//Participant[starts-with(Firstname, | //Participant[starts-with(Firstname,'Berna')]" | ||
Line 740: | Line 742: | ||
returns TRUE if the second string is part of the first | returns TRUE if the second string is part of the first | ||
//Participant[contains(FirstName, | //Participant[contains(FirstName,'nat')] | ||
Line 778: | Line 780: | ||
==== Example 2-4: Computation of an average ==== | ==== Example 2-4: Computation of an average ==== | ||
* We would like to compute the average of | * We would like to compute the average of participant's qualifications | ||
<participant><FirstName>Daniel</FirstName> | <participant><FirstName>Daniel</FirstName> | ||
Line 787: | Line 789: | ||
;The XSLT stylesheet (file xpath-jungle-4.xsl) | |||
* We compute the sum of a node-set and then divide by the number of nodes | * We compute the sum of a node-set and then divide by the number of nodes | ||
Line 815: | Line 817: | ||
;HTML result | |||
<html> | <html> | ||
Line 833: | Line 835: | ||
==== Example 2-5: Find first names containing | ==== Example 2-5: Find first names containing 'nat' ==== | ||
;The XSLT stylesheet (file xpath-jungle-5.xsl) | |||
<xsl:template match="/"> | <xsl:template match="/"> | ||
Line 1,019: | Line 1,021: | ||
|- | |- | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
@attr= | @attr='value' | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
value of attribute | value of attribute | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
list[@type= | list[@type='ol'] | ||
| rowspan="1" colspan="1" | | | rowspan="1" colspan="1" | | ||
'' <list type="ol"> ...... </list>'' | '' <list type="ol"> ...... </list>'' | ||
Line 1,053: | Line 1,055: | ||
* In most situations, writing simple XSLT rules will do | * In most situations, writing simple XSLT rules will do | ||
* Do not attempt to use looping constructs etc. when you | * Do not attempt to use looping constructs etc. when you don't have to | ||
* There is no special "magic" for dealing with images, links, stylesheets etc. Simply: | * There is no special "magic" for dealing with images, links, stylesheets etc. Simply: | ||
** look at your XML | ** look at your XML | ||
Line 1,064: | Line 1,066: | ||
;XML file with picture file names (file images.xml) | |||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
Line 1,100: | Line 1,102: | ||
;XSLT stylesheet (file images.xsl) | |||
<xsl:template match="list"> | <xsl:template match="list"> | ||
Line 1,148: | Line 1,150: | ||
;Parts of the XML file (file douglas-recipes.xml) | |||
<list> | <list> | ||
Line 1,192: | Line 1,194: | ||
;XSLT fragment (file douglas-recipes.xsl) | |||
<xsl:template match="list"> | <xsl:template match="list"> | ||
Line 1,246: | Line 1,248: | ||
;HTML result | |||
<?xml version="1.0" encoding="iso-8859-1"?> | <?xml version="1.0" encoding="iso-8859-1"?> | ||
Line 1,325: | Line 1,327: | ||
;XML (file ingredient-list.xml) | |||
<?xml version="1.0" encoding="ISO-8859-1" ?> | <?xml version="1.0" encoding="ISO-8859-1" ?> | ||
Line 1,341: | Line 1,343: | ||
;XSL (file ingredient-list.xsl) | |||
<xsl:template match="/ingredients"> | <xsl:template match="/ingredients"> | ||
Line 1,396: | Line 1,398: | ||
;HTML results | |||
<html xmlns="http://www.w3.org/1999/xhtml"> | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
Line 1,437: | Line 1,439: | ||
;Same logic would apply e.g. to building references | |||
<xsl:template match="reference"> | <xsl:template match="reference"> | ||
Line 1,489: | Line 1,491: | ||
;XML (file animals.xml) | |||
<example> | <example> | ||
Line 1,513: | Line 1,515: | ||
;XSLT template for animal (file animals:xsl) | |||
<xsl:template match="animal"> | <xsl:template match="animal"> | ||
Line 1,554: | Line 1,556: | ||
;HTML (some) | |||
<li><p style="color:black;font-weight:bold;">Panther</p> </li> | <li><p style="color:black;font-weight:bold;">Panther</p> </li> | ||
Line 1,581: | Line 1,583: | ||
;XML (file rowset.xml) | |||
* Typical database query output may look like this | * Typical database query output may look like this | ||
Line 1,613: | Line 1,615: | ||
;XSLT (file rowset.xsl) | |||
<xsl:template match="ROWSET"> | <xsl:template match="ROWSET"> | ||
Line 1,677: | Line 1,679: | ||
;XML fragment (file: participants.xml) | |||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
Line 1,711: | Line 1,713: | ||
;Part of XSLT (file: participants.xsl) | |||
�� | �� | ||
Line 1,769: | Line 1,771: | ||
;XML (file: ingredient-list2.xml) | |||
<ingredients> <item>3 taco shells</item><item>1 pkg hamburger 100g</item> | <ingredients> <item>3 taco shells</item><item>1 pkg hamburger 100g</item> | ||
Line 1,779: | Line 1,781: | ||
;XSLT (file ingredient-list2.xsl) | |||
<xsl:template match="/ingredients"> | <xsl:template match="/ingredients"> | ||
Line 1,892: | Line 1,894: | ||
;Module 7 | |||
* XML Schema | * XML Schema | ||
Line 1,908: | Line 1,910: | ||
;Create an XSLT transformation to (X)HTML. | |||
* Create a DTD and a valid XML example file | * Create a DTD and a valid XML example file | ||
Line 1,924: | Line 1,926: | ||
;Minimal requirement: | |||
{| border="1" | {| border="1" | ||
Line 1,945: | Line 1,947: | ||
;You will get extra points for | |||
{| border="1" | {| border="1" | ||
Line 1,994: | Line 1,996: | ||
** Alternatively: Create a really difficult XSLT and a good report | ** Alternatively: Create a really difficult XSLT and a good report | ||
;Submission format | |||
I require a double submission: | I require a double submission: | ||
Line 2,006: | Line 2,008: | ||
your_name.{doc|pdf|html} Chose the format you like (optional) | your_name.{doc|pdf|html} Chose the format you like (optional) | ||
== links == | == links == |
Revision as of 16:29, 25 November 2007
This article or section is currently under construction
In principle, someone is working on it and there should be a better version in a not so distant future.
If you want to modify this page, please discuss it with the person working on it (see the "history")
<pageby nominor="false" comments="false"/>
Introduction
Prerequisites
- Editing XML (being able to use a simple DTD)
- Introductory XSLT (xsl:template, xsl:apply-templates and xsl:value-of)
- Know about the role of XPath with respect to XSLT
Objectives
- Better understand XPath expressions
- Learn some XSLT programming constructions (conditions and loops)
- Being able to cope with most XML to HTML transformations
Disclaimer
- There may be typos (sorry) and mistakes (sorry again)
- Please also consult a textbook !
Introduction to XML Path Language
Definition and history
- XPath is a language for addressing parts of an XML document
- In support of this primary purpose, it also provides basic facilities for manipulation of strings, numbers and booleans.
- XPath uses a compact non-XML syntax (to facilitate use of XPath within URIs and XML attribute values).
- XPath gets its name from its use of a path notation as in URLs for navigating through the hierarchical structure of an XML document.
- XPath was defined at the same time as XSLT (nov 1999)
- Initally, it was developped to support XSLT and XPointer (XML Pointer Language used for XLink, XInclude, etc.)
- Specifications
- XPath 1.0 http://www.w3.org/TR/xpath (nov 1999)
- Used by XSLT 1.0
- XPath 2.0 http://www.w3.org/TR/xpath20/ (Jan 2007)
- XPath 2.0 Functions and Operators http://www.w3.org/TR/xquery-operators/
- XPath 2.0 is a superset of XPath 1.0
- Used by XSLT 2.0 and XQuery ... and other specifications
XSLT, XQuery and XPath
- Each time a given XSLT or XQuery instruction needs to address (refer to) parts of an XML document we use XPath expressions.
- XPath expressions also can contain functions, simple math and boolean expressions
With [[XSLT], XPath expressions are typicially used in match , select and test attributes:
The XPath Syntax and the document model
Xpath Syntax
- Primary (relatively simple) XPath expressions
- Result of an Xpath
- Can be various things, e.g. sets of nodes, a single node, a number, etc ....
- There are two notations for location paths
- abbreviated (less available options)
- e.g. para is identical to child::para
- unabbreviated (not presented in these slides !!)
- e.g. " child::para " would define the para element children of the current context node.
- The formal specification of an XML Path
- is very complex, i.e. has about 39 clauses and is very difficult to understand
- Some expressions shown here are beyound the scope of this class, don't panic !
2.2 The document model of XPath
- XPath sees an XML document as a tree structure
- Each information (XML elements, attributes, text, etc.) is called a node
- this is fairly similar to the W3C DOM model an XML or XSLT processor would use
- Nodes that XPath can see
- root node
- ATTENTION: The root is not necessarily the XML root element. E.g. processing instructions like a stylesheet declaration are also nodes.
- Elements and attributes
- Special nodes like comments, processing instructions, namespace declarations.
- Nodes XPath can't see
- XPath looks at the final document, therefore can't see entities and document type declarations....
- The XML context
- What a given XPath expression means, is always defined by a given XML context, i.e. the current node in the XML tree
- ... Advance warning
The rest of this chapter will be quite boring (and it only covers XPath essentials ....)
2.3 Element Location Paths
- We present a few expressions for locating nodes
- This page is not complete and uses abbreviated syntax
Document root node: returns the document root (which is not necessarily the XML root!)
/
Direct child element:
XML_element_name
Direct child of the root node:
/XML_element_name
Child of a child:
XML_element_name/XML_element_name
Descendant of the root:
//XML_element_name
Descendant of a node:
XML_element_name//XML_element_name
Parent of a node:
../
Un far cousin of a node:
../../XML_element_name/XML_element_name/XML_element_name
Example 2-1: Extracting titles from an XML file
- An XML document (file
- xpath-jungle.xml used throughout the XPath chapter)
- We only show part of the document
!-- XML fragment -->
< project >
<title>The Xpath project</title>
......
<problems>
<problem>
<title> Initial problem </title>
<description>We have to learn something about Location Path</description>
<difficulty level="5">This problem should not be too hard</difficulty>
</problem>
<problem>
<title> Next problem </title>
<description>We have to learn something about predicates</description>
<difficulty level="6">This problem is a bit more difficult</difficulty>
</problem>
</problems>
</project>
- Task
- We would like to get a simple list of problem titles
(XSLT Templates on next slide)
- (1) XSLT template for project XML root element (file
- xpath-jungle-1.xsl)
<xsl:template match=" /project ">
<html>
<body bgcolor="#FFFFFF">
<h1><xsl:value-of select="title" /></h1>
Here are the titles of our problems:
<ul>
<xsl:apply-templates select=" problems/problem " />
</ul>
</body>
</html>
</xsl:template>
- The XPath of the "match" means: applies to project element node, descendant of root node
- Execution context of this template is therefore the element " project "
- xsl:apply-templates will select a rule for descendant " problem ".
- (2) XSLT template for the problem element
<xsl:template match= " problems/problem " >
<li><xsl:value-of select=" title " /></li>
</xsl:template>
- This second rule will be triggered by the first rule, because problems/problem is indeed a descendant of the project element
- (3) Result HTML
<html>
<body bgcolor="#FFFFFF">
<h1>The Xpath project</h1>
Here are the titles of our problems:
<ul>
<li>Initial problem</li>
<li>Next problem</li>
</ul>
</body>
</html>
2.4 Attribute Location Paths
Find an attribute of a child element of the current context
@attribute_name
Example:
@val
Find attributes of an element in a longer location path starting from root
/element_name/element_name/@attribute_name
Example:
/project/problems/solutions/item/@val
Find attributes in the whole document
//@attribute_name
Example 2-2: Make an html img link from an attribute
- XML fragment
<participants>
<participant>
<FirstName>Daniel</FirstName>
<qualification>8</qualification>
<description>Daniel will be the tutor</description>
<FoodPref picture="dolores_001.jpg">Sea Food</FoodPref>
</participant>
<participant>
<FirstName>Jonathan</FirstName>
<qualification>5</qualification>
<FoodPref picture="dolores_002.jpg">Asian</FoodPref>
</participant>
<participant>
<FirstName>Bernadette</FirstName>
<qualification>8</qualification>
<description>Bernadette is an arts major</description>
</participant>
.......
- Task
- Display a list of First Names plus their food preferences
- XSLT (File xpath-jungle-2.xsl)
- The first rule will just select all participants and create the list container (ul)
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>What do we know about our participants ?</h1>
Here are some food preferences:
<ul>
<xsl:apply-templates select=".//participant" />
</ul>
</body>
</html>
</xsl:template>
- The second rule will display names of participants and launch a template for FoodPref
- Note: Not all participants have a FoodPref element. If it is absent it will just be ignored.
<xsl:template match="participant">
<li><xsl:value-of select="FirstName "/>
<xsl:apply-templates select="FoodPref "/>
</li>
</xsl:template>
- This rule displays the text (contents) of FoodPref and then makes an HTML img tag
<xsl:template match="FoodPref">
prefers <xsl:value-of select="." />.
<img src="{@picture} "/> <br clear="all"/>
</xsl:template>
- Parts of the result
<h1>What do we know about our participants ?</h1>
Here are some food preferences:
<ul>
<li>Daniel prefers Sea Food.
<img src="dolores_001.jpg"><br clear="all"></li>
<li>Jonathan
prefers Asian.
<img src="dolores_002.jpg"><br clear="all"></li>
<li>Bernadette</li>
<li>Nathalie</li>
</ul>
2.5 Location wildcards
- Sometimes (but not often!), it is useful to work with wildcards
- You have to understand that only one rule will be applied/element. Rules with wildcards have less priority and this is why "your rules" are applied before the system defaults.
Find all child nodes of type XML element
*
Find all child nodes (including comments, etc.)
node()
Find all element attributes
@*
Find all text nodes
text()
- FYI
- The system built-in (default) rules rely on wildcards
This rule applies to the document root and all other elements (see [xml-xpath.html#23299 2.8 ���%G�₁��%@���Union of XPaths���%G�₁��%@ [25]])
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Text and attribute values are just copied (see
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
2.6 XPaths with predicates
- A predicate is an expression that can be true or false
- It is appended within [...] to a given location path and will refine results
- More than one predicate can be appended to and within (!) a location path
- Expressions can contain mathematical or boolean operators
Find element number N in a list
XML_element_name [ N ]
/project/participants/participant[2]
/project/participants/participant[2] /FirstName
Find elements that have a given attribute
XML_element_name [ @attribute_name ]
Find elements that have a given element as child
XML_element_name [ XML_element_name ]
//participant[FoodPref]
- Mathematical expressions
- Use the standard operators, except div instead of / ")
- * div mod
- mod is interesting if you want to display a long list in table format
5 mod 2 returns 1, "7 mod 2" and "3 mod 2" too
- Boolean operators (comparison, and, or)
- List of operators (according to precedence)
<=, <, >=, >
=, !=
and
or
- Examples
- Return all exercise titles with a grade bigger than 5.
//exercise[note>5]/title
- Find elements that have a given attribute with a given value
XML_element_name [ @attribute_name = 'value']
//solutions/item[@val="low"]
- Example XSLT template that will match all item elements with val="low".
<xsl:template match=" //item[@val='low'] ">
<xsl:value-of select="." />
</xsl:template>
- Note
- Usually expression also contain functions (see [xml-xpath.html#21068 2.7 ���%G�₁��%@���XPath functions���%G�₁��%@ [21]])
- Return last five elements of a list
author [(last() - 4) <= position()) and (position() <= last())]
- Return all Participant nodes with a contents of FirstName bigger than 7 characters:
"//Participant[string-length(FirstName)>=8]"
Example 2-3: Retrieve selected elements
- The XSLT stylesheet (file xpath-jungle-3.xsl)
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Retrieve selected elements</h1>
Here is the name of participant two:
<ul><li><xsl:value-of select=".//participant[2]/FirstName "/></li></ul>
Here are all participant's firstnames that have a food preference:
<ul><xsl:apply-templates select=".//participant[FoodPref] "/></ul>
Here are all items that have a value of "high"
<ul><xsl:apply-templates select=".//item[@val='high'] "/></ul>
</body>
</html>
</xsl:template>
��
<xsl:template match="participant">
<li><xsl:value-of select="FirstName"/></li>
</xsl:template>
��
<xsl:template match="item">
<li><xsl:value-of select="."/></li>
</xsl:template>
��
- HTML result
<html>
<body bgcolor="#FFFFFF">
<h1>Retrieve selected elements</h1>
Here is the name of participant two:
<ul>
<li>Jonathan</li>
</ul>
Here are all participant's firstnames that have a food preference:
<ul>
<li>Daniel</li>
<li>Jonathan</li>
</ul>
Here are all items that have a value of "high"
<ul>
<li>Register for a XSLT course and do exercices</li>
<li>Register for a XPath course and do exercices</li>
</ul>
</body>
</html>
2.7 XPath functions
- XPath defines a certain number of functions
- You can recognize a function because it has "()".
- Functions are programming constructs that will return various kinds of informations, e.g.
- true / false
- a number
- a string
- a list of nodes
- It is not obvious to understand these ....
- There are restrictions on how you can use functions (stick to examples or the reference)
last()
last() gives the number or nodes within a context
position()
position() returns the position of an element with respect to other children for a parent
count(node-set)
count gives the number of nodes in a node set (usually found with an XPath).
starts-with(string, string)
returns TRUE if the second string is part of the first and starts off the first
//Participant[starts-with(Firstname,'Berna')]"
contains(string, string)
returns TRUE if the second string is part of the first
//Participant[contains(FirstName,'nat')]
string-length(string)
returns the length of a string
number(string)
transforms a string into a number
sum(node-set)
computes the sum of a given set of nodes.
If necessary, does string conversion with number()
round(number)
round a number, e.g. 1.4 becomes 1 and 1.7 becomes 2
translate(string1, string2, string3)
translates string1 by substituting string2 elements with string3 elements
(See next slides for examples ....)
Example 2-4: Computation of an average
- We would like to compute the average of participant's qualifications
<participant><FirstName>Daniel</FirstName>
<qualification>8</qualification> </participant>
- The XSLT stylesheet (file xpath-jungle-4.xsl)
- We compute the sum of a node-set and then divide by the number of nodes
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Qualification level of participants</h1>
Average is
<xsl:value-of select= "sum(.//participant/qualification) div
count(.//participant/qualification)" />
</body>
</html>
</xsl:template>
- HTML result
<html>
<body bgcolor="#FFFFFF">
<h1>Qualification level of participants</h1>
Average is
5.75
</body>
</html>
Example 2-5: Find first names containing 'nat'
- The XSLT stylesheet (file xpath-jungle-5.xsl)
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Do we have a "nat" ?</h1>
First Names that contain "nat":
<ul>
<xsl:apply-templates select=".//participant[contains(FirstName,'nat') ]"/>
</ul>
First Names that contain "nat" and "Nat":
<ul>
<xsl:apply-templates select=".//participant[contains
(translate(FirstName,'N','n'),'nat')] "/>
</ul>
</body>
</html>
</xsl:template>
��
<xsl:template match="participant">
<li><xsl:value-of select="FirstName"/></li>
</xsl:template>
2.8 Union of XPaths
- Union Xpaths combine more than one XPath (and all the resulting nodes are returned).
- A typical example is the default rule which means that the template matches either the root element (i.e. "/" or just any element),
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
- Often this is used to simplify apply-templates or even templates themselves. E.g. the following rules applies to both "description" and "para" elements.
<xsl:template match="para|description">
<p><xsl:apply-templates/></p>
</xsl:template>
2.9 List of commonly used XPath expressions
Syntax |
(Type of path) |
Example path |
Example matches |
---|---|---|---|
name |
child element name |
project |
<project> ...... </project> |
/ |
child / child |
project/title |
<project> <title> ... </title> |
/ |
(root element) | ||
// |
descendant |
project//title |
<project><problem> <title>....</title> |
//title |
<root>... <title>..</title> (any place) | ||
* |
"wildcard" |
*/title |
<bla> <title>..</title> and <bli> <title>...</title> |
| |
"or operator |
title|head |
<title>...</title> or <head> ...</head> |
*|/|@* |
All elements: root, children and attributes | ||
. |
current element |
. |
|
../ |
parent element |
../problem |
<project> |
@attr |
attribute name |
@id |
<xyz id="test">...</xyz> |
element/@attr |
attribute of child |
project/@id |
<project id="test" ...> ... </project> |
@attr='value' |
value of attribute |
list[@type='ol'] |
<list type="ol"> ...... </list> |
position() |
position of element |
position() |
|
last() |
number of elements within a context |
last() position()!=last() |
3. XSLT reminder
- In most situations, writing simple XSLT rules will do
- Do not attempt to use looping constructs etc. when you don't have to
- There is no special "magic" for dealing with images, links, stylesheets etc. Simply:
- look at your XML
- figure out how to translate into equivalent HTML (or whatever you are translating into)
Example 3-1: Dealing with pictures
- XML file with picture file names (file images.xml)
<?xml version="1.0"?>
<?xml-stylesheet href="images.xsl" type="text/xsl"?>
<page>
<title>Hello Here are my images</title>
<list>
<image> dolores_001.jpg</image>
<image>dolores_002.jpg</image>
<image>dolores_002.jpg</image>
<image2>scrolls.jpg </image2>
<image2>scrolls.jpg </image2>
<image3 source="dolores_002.jpg">Recipe image</image3>
</list>
<comment>Written by DKS.</comment>
</page>
��
- XSLT stylesheet (file images.xsl)
<xsl:template match="list">
Apply templates for image elements:
<xsl:apply-templates select="image "/>
This will only insert the first "image2" element contents it finds:
<p> <img src="{image2}"/> </p>
And another template for a tag image3 element (with an attribute)
<xsl:apply-templates select="image3 "/>
</xsl:template>
- This rule will insert the content of the image element into the value of src="".
<xsl:template match="image">
<p> <img src="{.} "/> </p>
</xsl:template>
- This rule will insert the value of the source attribute into the value of src and also insert the contents of the the image3 element.
<xsl:template match="image3">
<p> <img src="{@source} "/><xsl:value-of select="."/> </p>
</xsl:template>
4. Multiple templates for one element
- XSLT allows to define multiple rules for the same XPath by using the "mode" attribute
- This construct is frequently used to produce table of contents
- Parts of the XML file (file douglas-recipes.xml)
<list>
<recipe id="r1">
<recipe_name>TACOS</recipe_name>
<meal>Dinner</meal>
<ingredients>
<item>3 taco shells</item>
<item>1 pkg hamburger 100g</item>
........
</ingredients>
��
<directions>
<bullet>Oven on at 180 degrees.</bullet>
......
<bullet>Cut up lettuce.</bullet>
</directions>
</recipe>
��
<recipe id="r2">
....
</list>
- XSLT fragment (file douglas-recipes.xsl)
<xsl:template match="list">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> <title>Recipes</title> </head>
<body bgcolor="#ffffff">
<h1>Recipes</h1>
<h2>Contents</h2>
<p> <xsl:apply-templates select="recipe" mode="toc"/ > </p>
<xsl:apply-templates select="recipe "/>
</body> </html>
</xsl:template>
- We define 2 rules for "recipe": One will have a mode="toc"
- The next rule will create the table of contents.
- It will use the recipe_name as link
- It will use the id attribute to create an internal href link
<xsl:template match="recipe" mode="toc" >
<p><a href="#{@id} "><xsl:value-of select="recipe_name "/></a></p>
</xsl:template>
- This rule is almost "normal", except that we insert a name anchor
<xsl:template match="recipe" >
<h1><a name="{@id} "><xsl:value-of select="recipe_name"/></a> </h1>
<xsl:apply-templates select="meal"/>
<xsl:apply-templates select="ingredients"/>
<xsl:apply-templates select="directions"/> </xsl:template>
- HTML result
<?xml version="1.0" encoding="iso-8859-1"?>
��
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Recipes</title>
</head>
<body bgcolor="#ffffff">
<h1>Recipes</h1>
<h2>Contents</h2>
<p>
<p> <a href="#r1">TACOS</a> </p>
<p> <a href="#r2">VOL AU VENT (one person)</a> </p>
</p>
<hr/>
<h1>
<a name="r1">TACOS</a>
</h1>
<p> Type: Dinner</p>
5. Conditional XSLT and whitespaces
- Although many conditionals can be expressed with XPath and according selection rules, XSLT provides 2 typical programming constructs to handle "if" and "if-then-else" situations.
- When you use XPath functions like position(), you have to be very careful about whitespaces
5.1 Simple if
Syntax for xsl:if:
<xsl:if test = "boolean_expression">
<!-- Content or xsl instructions here -->
</xsl:if>
Example 5-1: Display lists, the last element differently with xsl:if
- Warning: This only works in standards compliant browsers if you either eliminate whitespaces from your XML file or if you add the following XSL instruction at the beginning:
<xsl:strip-space elements="element_name element_name ...."/>
<xsl:strip-space elements="ingredients"/>
- XML (file ingredient-list.xml)
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="ingredient-list.xsl" type="text/xsl"?>
<ingredients>
<item>3 taco shells</item>
<item>1 pkg hamburger 100g</item>
<item>Taco mix</item><item>Lettuce</item></ingredients>
- XSL (file ingredient-list.xsl)
<xsl:template match="/ingredients">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> <title>Ingrediant list</title> </head>
<body bgcolor="#ffffff">
Here is a list of recipe ingrediants:
<p> <xsl:apply-templates select="item"/>. </p>
Here is a list of recipe ingrediants, this time numbered:
<p> <xsl:apply-templates select="item" mode="numb"/>. </p>
</body>
</html>
</xsl:template>
��
<xsl:template match="item">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()" > <xsl:text>, </xsl:text> </xsl:if>
</xsl:template>
��
<xsl:template match="item" mode="numb">
(<xsl:value-of select="position() "/>)
<xsl:value-of select="."/>
<xsl:if test="position()!=last()" > <xsl:text>, </xsl:text> </xsl:if>
</xsl:template>
��
</xsl:stylesheet>
- HTML results
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ingrediant list</title>
</head>
<body bgcolor="#ffffff">
Here is a list of recipe ingrediants:
<p>3 taco shells, 1 pkg hamburger 100g, Taco mix, Lettuce. </p>
Here is a list of recipe ingrediants, this time numbered:
<p>
(1) 3 taco shells,
(2) 1 pkg hamburger 100g,
(3) Taco mix,
(4) Lettuce. </p>
</body>
</html>
- Same logic would apply e.g. to building references
<xsl:template match="reference">
<xsl:apply-templates
select="author|ref|title|edition|publisher|pubPlace|publicationYear"/>.
</xsl:template>
��
<xsl:template match="author|edition|publisher|pubPlace|publicationYear">
<xsl:apply-templates/>
<xsl:if test="position() !=last()">, </xsl:if>
</xsl:template>
5.2 If-then-else
Syntax:
<xsl:choose>
<!-- Content: (xsl:when , xsl:otherwise?) -->
</xsl:choose>
<xsl:when test = "boolean-expression">
<!-- Content: template -->
</xsl:when>
<xsl:otherwise>
<!-- Content: template -->
</xsl:otherwise>
Example 5-2: Animal colors with xsl:choose
- XML (file animals.xml)
<example>
<title>Animals with colors</title>
<list>
<animal color="black">Panther</animal>
<animal color="complicated with spots">Panther</animal>
<animal color="white">Polar bear</animal>
<animal color="green">Frog</animal>
<animal>Cow</animal>
</list>
</example>
- XSLT template for animal (file animals
- xsl)
<xsl:template match="animal">
<li>
<xsl:choose>
<xsl:when test="@color='black'" >
<p style="color:black;font-weight:bold;"> <xsl:value-of select="."/> </p>
</xsl:when>
��
<xsl:when test="@color='green'" >
<p style="color:green;font-weight:bold;"> <xsl:value-of select="."/> </p>
</xsl:when>
��
<xsl:otherwise >
<p style="color:cyan"> <xsl:value-of select="."/> </p>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:template>
- HTML (some)
<li><p style="color:black;font-weight:bold;">Panther</p> </li>
<li><p style="color:cyan">Panther</p></li>
<li><p style="color:cyan">Polar bear</p></li>
<li><p style="color:green;font-weight:bold;">Frog</p></li>
<li><p style="color:cyan">Cow</p></li>
6. Looping
- Most of the time you do "looping" with templates (as in all previous examples)
- There is a xsl:for-each looping construct. It is useful to write more compact code, to use it with sorting and functional programming constructs (not explained here).
xsl:for-each select="XPath"
Example 6-1: Translating database query output into an HTML table
- XML (file rowset.xml)
- Typical database query output may look like this
- E.g. survey data will present as a series of rows of the same length
- We would like to translate each ROW into a table row and each child as a table cell
��
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="rowset.xsl" type="text/xsl"?>
<page>
<ROWSET>
<ROW><id>1</id><login>test</login><fullname>Joe Test </fullname>
<food>3</food><work>4</work><love>5</love><leisure>2</leisure></ROW>
<ROW><id>2</id><login>test2</login><fullname>Janine Test </fullname>
<food>3</food><work>4</work><love>6</love><leisure>2</leisure></ROW>
.......
</ROWSET>
</page>
- XSLT (file rowset.xsl)
<xsl:template match="ROWSET">
<table border="2" cellspacing="1" cellpadding="6">
<tr><th>id</th>
<th>Login</th>
<th>Full Name</th>
<th>food</th><th>work</th><th>love</th><th>leisure</th>
</tr>
<xsl:for-each select="ROW">
<tr>
<td><xsl:value-of select="id"/></td>
<td><xsl:value-of select="login"/></td>
<td><xsl:value-of select="fullname"/></td>
<td><xsl:value-of select="food"/></td>
<td><xsl:value-of select="work"/></td>
<td><xsl:value-of select="love"/></td>
<td><xsl:value-of select="leisure"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
6.1 Looping with a sort
- xsl:sort can sort a list according to several criteria, can be used more than once
<xsl:sort
select = "Xpath"
data-type = { "text" | "number" }
order = { "ascending" | "descending" }
case-order = { "upper-first" | "lower-first" } />
Example 6-2: Sort a participants list according to qualification
- XML fragment (file
- participants.xml)
<?xml version="1.0"?>
<?xml-stylesheet href="participants.xsl" type="text/xsl"?>
<participants>
<participant>
<FirstName>Daniel</FirstName>
<qualification>8</qualification>
<description>Daniel will be the tutor</description>
<FoodPref picture="dolores_001.jpg">Sea Food</FoodPref>
</participant>
<participant>
<FirstName>Jonathan</FirstName>
<qualification>5</qualification>
<FoodPref picture="dolores_002.jpg">Asian</FoodPref>
......
</participant>
- Part of XSLT (file
- participants.xsl)
��
<xsl:template match="participants">
<table border="2" cellspacing="1" cellpadding="6">
<tr><th>Qualification</th>
<th>First Name</th>
<th>Description</th>
<th>Food Picture</th>
</tr>
<xsl:for-each select="participant" >
<xsl:sort select="qualification" />
<tr>
<td><xsl:value-of select="qualification"/></td>
<td><xsl:value-of select="FirstName"/></td>
<td><xsl:value-of select="description"/></td>
<td><xsl:if test="FoodPref/@picture">
<img src="{FoodPref/@picture}"/></xsl:if></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
7. Moving on
- XSLT is a full programming language, but further XSLT constructs are out of scope for this class......
- Just for your information, I present a small example that demonstrates function calls.
Example 7-1: Display ingredients with increasing fonts
- XML (file
- ingredient-list2.xml)
<ingredients> <item>3 taco shells</item><item>1 pkg hamburger 100g</item>
<item>Taco mix</item> <item>50 g of cheese</item> <item>1 tomato</item>
<item>1 carot</item> <item>Lettuce</item></ingredients>
- XSLT (file ingredient-list2.xsl)
<xsl:template match="/ingredients">
<html>
<head> <title>Ingrediant list</title> </head>
<body bgcolor="#ffffff">
Here is a list of recipe ingrediants:
<xsl:for-each select="item">
<xsl:call-template name="display_item ">
<xsl:with-param name="position " select="position()"/>
</xsl:call-template>
</xsl:for-each>
</body>
</html>
</xsl:template>
<!-- you can change the value of these 2 parameters -->
<xsl:param name="initial_size " select="5"/>
<xsl:param name="multiplier " select="3"/>
��
<xsl:template name ="display_item ">
<xsl:param name="position "/>
<xsl:variable name="font_size"
select="$initial_size $position * $multiplier"/>
<xsl:variable name="color">
<xsl:choose>
<xsl:when test="$position mod 3 = 0">
<xsl:text>yellow</xsl:text></xsl:when>
<xsl:when test="$position mod 3 = 1">
<xsl:text>red</xsl:text> </xsl:when>
<xsl:when test="$position mod 3 = 2">
<xsl:text>blue</xsl:text> </xsl:when>
<xsl:otherwise><xsl:text>green</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable >
<p style="color:{$color}; font-size: {$font_size}pt;">
<xsl:value-of select="."/><br />
[Pos = <xsl:value-of select="$position"/>,
Multip. = <xsl:value-of select="$multiplier"/>,
Font size = <xsl:value-of select="$font_size"/>] </p>
</xsl:template>
��
8. Next steps
8.1 Reading
Carey (pp. 297-317, 317-335)
Optional: 1 or 2 case problems
8.2 Next modules
- Module 7
- XML Schema
9. Homework: mini-project 6
Due: Monday Feb. 19 16:00h
9.1 Task
- Create an XSLT transformation to (X)HTML.
- Create a DTD and a valid XML example file
- Translate the XML document to somewhat valid HTML or XHTML
- Write some user documentation (i.e. make sure others could use your DTD and stylesheet)
- Make use of some more advanced XPath and XSLT constructs (but be reasonable !!!)
- Take into account critique for homework 5
- You may reuse materials from previous homework
- I strongly suggest to base this project on homework 5 (XSLT)
9.2 Approximate evaluation grid
- Minimal requirement
Features |
Expect a |
---|---|
Valid XML (DTD) and well-formed XSLT style sheet that does a translation |
D |
An XML contents that displays as (X)HTML in a web browser of your choice |
C |
- You will get extra points for
Extra features |
Extra points ( /- quality) |
---|---|
Inserted comments <!-- ... --> in the various files (XML, XSLT or CSS) |
|
XML data organization that is appropriate for your domain |
|
Complexity of style sheet (kinds of transformations) |
... |
Ergonomic and nice presentation (style and function) |
... |
Your result document is valid HTML or XHTML |
|
A 1-2 page user manual that explains a user how to use your DTD and stylesheet |
... |
A 1 page report that discusses your implementation |
... |
- To get a B: Produce a useful (X)HTML document from valid XML
- To get an A:
- Create a useful DTD, an ergonomic XSLT, a useful manual and a report
- Alternatively: Create a really difficult XSLT and a good report
- Submission format
I require a double submission:
- Paper copies to be turned in a start of Monday lesson
- Electronic copies to be uploaded to the server in folder homework/project_6 !!!
Please make sure to name these documents according to the following rules:
your_name.xml or your_name.html or your_name.xhtml (mandatory)
your_name.dtd (optional)
your_name.{doc|pdf|html} Chose the format you like (optional)
links
Introductory tutorials
- Xpath (Wikipedia)
- Zvon tutorial (lots of examples)
Other
- XPath Visualizer A windows program you can install to train. Alternatively, just use a XML editor with Xpath support.
- Liquid XML has an XPath builder