too many old people The number of people is:"> too many old people The number of people is:">
Download presentation
Presentation is loading. Please wait.
Published byAmie Carpenter Modified over 9 years ago
1
More on XSLT
2
More on XSLT variables Earlier we saw two ways to associate a value with a variable A variable whose value is the empty string, for example A variable whose value is specified by the select attribute Examples But there is a third way, which allow greater flexibility –It involves using a non-empty xsl:variable element –The content specifies the value of the variable –We can use the full range of XSLT elements to compute the value
3
Computing a contingent value for an xsl:variable 21]) > 1"> too many old people The number of people is:
4
Computing a cumulative value for an xsl:variable The ages of the people are:
5
Computing a complex cumulative value for an xsl:variable : The ages of the people are:
6
Aside: the position() function When a sequence of items is being processed, this function return the position of the current item within the sequence This is true whether the sequence of items is being processed by –a for-each element, or –an apply-templates element
7
Terminating a cumulative value for an xsl:variable This program does not append a comma to the last item in the sequence, The ages of the people are:
8
Aside: the last() function When a sequence of items is being processed, this function return the position of the last item within the sequence This is true whether the sequence of items is being processed by –a for-each element, or –an apply-templates element
9
Terminating a cumulative value for an xsl:variable, version 2 This program uses last() to avoid placing a comma after last item in sequence, The ages of the people are:
10
Aside: templates can be used when computing values for variables We can use the full range of XSLT elements to compute the value This includes using the apply-templates element
11
Using apply-templates to compute the value for a variable 21]"/> The ages of the people over 21 are,
12
Aside: More on sorting We have seen that sort elements can be used inside for- each elements They can also be used inside apply-template elements
13
Sorting inside an apply-templates element The ages of the sorted people are,
14
The xsl:copy-of element The xsl:value-of element returns the string value of the selected node (set) The xsl:copy-of element returns a copy of the XML Fragments for the selected node (set) This difference is usually not visible when we use client-side XSLT processing –because browsers do not render XML tags that they have generated themselves
15
The difference between xsl:copy-of and xsl:value-of is (usually) invisible when XSLT is applied on the client-side
16
The difference between xsl:copy-of and xsl:value-of is also invisible when a browser renders result of server-side HTML generation
17
But the difference between xsl:copy-of and xsl:value-of is visible when a browser shows source code from server-side HTML generation
18
Now, consider XML generation on the server-side
19
Difference between xsl:copy-of and xsl:value-of is visible when a browser renders result of server-side XML generation
20
Difference between xsl:copy-of and xsl:value-of (contd.) Remember that, when a node set is converted to a string, only the string value of the first node in the set is returned This means that, when a browser renders the result, more text is visible when xsl:copy-of is used to process a node-set than when xsl:value-of is used –that is, some difference, at least, is visible in the browser –even though the XML tags returned by xsl:copy-of are ignored by the browser We will see this on the next slide
21
When a node set is selected, more text is visible from xsl:copy-of than from xsl:value-of, even in client-side processing
22
Common usage of xsl:copy-of One common usage of xsl:copy-of is –generating another XML document from an existing one An extension of this is –generating multiple alternative XML document(s) from an existing one These operations could be done using client- side processing But it makes more sense to use server-side processing –because XML generated on the client-side is not given the default tree-based rendering by the browser
23
Generating two alternative XML document(s) from an existing one, depending on the query-string in the request
24
Creating XML with the xsl:element element The stylesheets on the previous slides used literal tags, like this... Instead of using literal tags, we can use the xsl:element element, like this... That is, two stylesheets below produce the same result
25
Combining input from multiple XML documents We have seen how a PHP program can use different XSLT stylesheets to extract different pieces of information from one XML document that is, an XML document can be split into multiple other documents XSLT provides a function which we can use to do the reverse - to combine multiple XML documents into one output document the document() function can be used to access nodes in an external XML document If the final document is to be in HTML, we can use this function in client-side processing But, if the final document is to be in XML, it makes more sense to use the function in server-side processing We will consider some examples on the next few slide
26
The two XML documents that we will combine One document contains the ages of some people The other document contains the names of these people The two documents can be cross-referenced because each person is identified by an ID
27
Combining two XML documents into HTML, using the document() function in client-side XSLT processing Name Age
28
Combining two XML documents into XML, using the document() function in server-side XSLT processing
29
Creating processing instructions using the element Syntax of this element: Example usage: type="text/xsl" href="someSheet.xsl" creates
30
Server-side combination of XML documents into XML that is processed by XSLT on the client-side type="text/xsl" href="people.xsl"
31
XML Fragments
32
Consider, again, this XSLT element The select attribute identifies a set of nodes in a parse tree But the xsl:copy-of element does NOT return a copy of the selected nodes Instead, it returns an XML Fragment for the selected node set This distinction - between a node set and an XML Fragment - is very important But, first, let's see some more about XML Fragments –because, as we shall see later, the fact that XSLT can create XML Fragments gives us great power
33
XML Fragments An XML Fragment is a portion of an XML document An XML Fragment may not be well-formed For example, it may not have a single root document, as in this fragment car bike Usually, however, an XML Fragment is well-balanced. Informally, this means that, if the fragment includes any part of the markup of any construct, it contains all of the markup of that construct For example, if a well-balanced fragment contains part of an element, it contains all of the start tag and all of the end tag for the element For more detail on XML Fragments, see http://www.w3.org/TR/xml-fragment
34
Fragments versus nodes: errors in XPath expressions The number of people is This program causes an error because the value given to the variable $thePeople is Fred 21 Tom 22 Dick 23 This is an XML fragment It is a piece of unparsed text, But, in this place, XPath requires a set of parse tree nodes
35
Fragments versus nodes: errors in XPath expressions (contd.) Later, we shall see the how useful it would be to be able to do something like this... So the problem caused by an XML Fragment appearing where a node-set is expected is something we need to overcome We can do this using the XSLT extension mechanism
36
XSLT extension mechanism The W3C specification for XSLT 1.0 is at http://www.w3.org/TR/xslt It defined a mechanism for adding new instruction elements and functions to the language. This mechanism is specified at http://www.w3.org/TR/xslt#extension
37
XSLT extension mechanism (contd.) Many sets of extension elements and functions have been developed Using a set of extensions developed by somebody else is easy We simply make the stylesheet refer to the namespace for the set of extensions, and use the prefix we associated with the namespace each time that we use an extension element/function <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:somePrefix="someNamespace" >......
38
XSLT extension mechanism (contd.) Various s/w developers produced different proprietary sets of extension elements and functions This caused problems because stylesheets which used these proprietary extensions were not portable To address this portability problem, a group was formed to identify a set of extensions that a large number of people thought were needed The identified set of extensions is called EXSLT and is defined at http://www.exslt.org/ Because this set of extensions was widely accepted, several developers of XSLT processors claim to have implemented them
39
EXSLT The EXSLT extensions are divided into a group of modules, each of which has its own namespace –Common EXSLT, http://exslt.org/common –Math EXSLT, http://exslt.org/math –Sets EXSLT, http://exslt.org/sets –Date and Times EXSLT, http://exslt.org/dates-and-times –Strings EXSLT, http://exslt.org/strings –Regular Expressions EXSLT, http://exslt.org/regular-expressions –Dynamic EXSLT, http://exslt.org/dynamic –Random EXSLT, http://exslt.org/random –Functions EXSLT, http://exslt.org/functionshttp://exslt.org/functions (allow users to define their own functions for use in expressions and patterns in XSLT) Unfortunately, not every XSLT processor which claims to support EXSLT supports all of the above –Luckily, however, all/most of them support the extension function which we need when we want to use XML fragments in XPath expressions
40
The node-set() function in EXSLT One of the extension functions included in the Common EXSLT module is called node-set() It takes a well-balanced XML fragment as input, parses it, and returns a set of nodes We can use it in an improved version of our last stylesheet
41
The EXSLT node-set() extension function <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" > The number of people is The node-set() function computes a parse tree from an XML fragment We can then use this parse tree in XPath, just as we would use any sub- tree of the parse tree for the XML document being processed by the stylesheet
42
Not all browsers support EXSLT The EXSLT node-set() function is implemented by several Firefox, Chrome, Safari and Opera, but not by MSIE In the last screenshot below, MSIE claims that there are no functions in the namespace http://exslt.org/common
43
Although MSIE does not support EXSLT node-set(), it provides an equivalent function of the same name, in a different namespace <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" > The number of people is The namespace for XSLT extensions in MSIE is urn:schemas-microsoft-com:xslt
44
Output generated by stylesheet refers to the XSLT extension namespace When the server receives a request for our document, demo12.xml, its response contains XML But, our stylesheet, demo12.xsl, is also generating XML –the and tags are not in the HTML namespace Each browser takes its own approach to rendering the resultant XML Most browsers take the standard approach of just rendering the string value of the resultant XML But the Opera browser complains that the resultant XML has no style information and renders the actual resultant XML fragment –we see something interesting - the resultant XML refers to the namespace for the XSLT extension function
45
Preventing namespace references in generated XML output The XSLT extension mechanism includes a tool to prevent the generation of references to extension namespaces This is an attribute called extension-element-prefixes which should be used in the root element of the stylesheet the attribute's value is a list of prefixes for the spaces which should not be referenced When we use it, Opera shows that the EXSLT Common namespace is not cited (although it still complains that there is no XSLT stylesheet) <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl" > The number of people is
46
Of course, if we generate HTML on the client-side, we get no warning, even from Opera, about the lack of an XSLT stylesheet <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl" > The number of people is
47
XSLT extension functions as a motivation for server-side processing We have seen that MSIE does not support EXSLT (although it supports something which is probably functionally equivalent) It is also the case that even those browsers which do support EXSLT do not support all of EXSLT –for example, Firefox does not support all of the Math extension functions defined in EXSLT Consequently, some website developers prefer to achieve browser compatibility by using server-side processing
48
EXSLT support in PHP We have seen that we can perform XSLT processing on the server with PHP PHP5 supports EXSLT, although some systems administrators do not turn it on But, the XSLT module in PHP5 provides a function for checking if EXSLT support has been turned on hasExsltSupport() ) { die('EXSLT support not available'); } // use EXSLT here if the program has not died above... ?> If we are sure that XSLT support has been turned on we don't need to use the hasExsltSupport() function we just have to use PHP module for XSLT processing as before the only reference to EXSLT is in the XSLT stylesheet
49
Server-side usage of node-set function from EXSLT The XSLT generates HTML4, –so the PHP program does not set an XML header The XSLT uses node- set() from EXSLT to process an XML fragment in an XPath expression Because EXSLT is used on the server, the approach is compatible with all HTML4-compliant browsers –see next slide
50
Server-side usage of EXSLT on previous slide is compatible with all HTML4-compliant browsers
51
The power of using XML fragments in XSLT
52
We have seen that EXSLT means we can use XML Fragments in XSLT This enables us to simplify many XSLT processing tasks that, otherwise, would be quite complicated For example, if we need to process an XML document that has several layers of cross-referencing, we can "flatten" the XML before we do the required processing
53
Using node-set() means that we can apply the full power of XSLT processing to the content of XML Fragments Applying node-set() to an XML fragment constructs a parse tree for the fragment In effect, the XML fragment becomes a "mini-document" which we can process using the full power of XSLT Suppose, for example, we bind $someVariable to an XML fragment We can, for example, do any of the following ...
54
Applying for-each to content of an XML fragment This stylesheet has one template, which matches the root node It binds the variable $thePeople to an XML fragment Then it uses node-set() to compute a parse tree from this XML fragment and...... uses a for-each element to process each person node within this tree
55
Applying templates to content of an XML fragment This stylesheet has two templates The template which matches the root node binds the variable $thePeople to an XML fragment Then it uses node-set() to compute a parse tree from this XML fragment and...... uses the second template to process each person node within this tree
56
Interpretation of / while processing fragment parse trees The interpretation of absolute XPath expressions changes during the processing of parse trees for XML fragments While XSLT is processing the parse tree of an XML fragment, –the fragment is treated, almost, like an XML document in its own right Specifically, the parse tree for the fragment becomes the context for the processing This means that, while the parse tree for the fragment is being processed, absolute XPath expressions refer to this parse tree, rather than to the parse tree for the overall XML document That is, the meta-character / at the start of an XPath expression refers to the root of the parse tree for the fragment On the next few slides, we will see several examples of this, involving for-each and apply-templates Later, when we use XML fragments to process complex documents, we will see the importance of using / with care
57
Example 1 (using for-each), version 1 This stylesheet binds $theFirstnames to an XML fragment for the element It then uses node-set() to compute a parse tree from this XML fragment and tries to output the age of each person whose firstname is in the fragment No age is output because, in the XPath expression /info/ages/age[..] the root node is actually the root node of the parse tree for $theFirstnames –which contains no age elements
58
Example 1 (using for-each), version 2 As before the stylesheet binds $theFirstnames to an XML fragment for the element and uses node-set() to compute a parse tree from this XML fragment Before it uses for-each on each firstname in this parse tree, it stores a copy of the tree for the overall document in $mainDocument Ages are output this time because, in the XPath expression $mainDocument/info/ages/age[..] the root node is the root node of the parse tree for the overall document - which does contain age elements
59
Showing that the interpretation of / changes As before, this stylesheet binds $theFirstnames to an XML fragment for the element and uses node-set() to compute a parse tree from this XML fragment Before it uses for-each on each firstname in this parse tree, it prints the tagname of the root element for the overall document Inside the for-each statement, it prints the tagname of the current root element We can see they are different This is because, inside the for- each, the root element is the root element of exsl:node-set($theFirstnames)
60
Example 2 (using apply-templates), version 1 There are two templates The first one binds $fred to an XML fragment for the element whose pid=1 and uses apply-templates to process the root element in the parse tree for $fred The second template tries to output the age of the person cited in this element But no age is output because, in the XPath expression /info/ages/age[..] the root node is actually the root node of the parse tree for $fred –which contains no age elements
61
Example 2 (using apply-templates), version 2 Again, there are two templates As before, the first one binds $fred to an XML fragment for the element whose pid=1 and uses apply-templates to process the root element in the parse tree for $fred The second template does output the age of the person cited in this element An age is output because, in the XPath expression $mainDocument/info/ages/age[..] $mainDocument contains the parse tree for the main document - which does contain age elements
62
A note on variable scope In the program on the last slide, the value of $mainDocument is used only in the second template But $mainDocument could not be set inside this template because, there, the meta character / refers to the root note of $fred And $mainDocument could not be set in the first template, because it would not be visible in the second template So, $mainDocument had to be set outside any template - in the transform element Note that when a variable is set at the level of the transform element its ordering, relative to the templates, is not important
63
Applying XSLT processing to XML fragments Being able to apply XSLT processing to XML fragments gives us a lot of power It means that, if we have a complicated XML document, we can compute a simpler abstract from the given document Then, if necessary, we can compute an even simpler abstract from the first abstract And so on,... ... until, after possibly several levels of abstraction,... ... we have an XML fragment that is simple to process
64
To put it another way, … Being able to assign a variable to an XML fragment means that, in effect, we can have XSLT variables whose values are – data structures, rather than … –… just scalar values, like numbers and strings
65
Repeated abstraction - an example Consider this XML document Suppose we want a stylesheet which will identify and display the name of the oldest person born in the city in which most people were born This person's name is Bob The task of computing this can be simplified by using XML fragments to perform repeated abstraction
66
Example of repeated abstraction (contd.) We will use server-side processing The PHP program is below We just need to write the stylesheet
67
Example of repeated abstraction (contd.) Task: identify name of oldest person born in city in which most people were born Steps –Compute numbers of people born in each city –Identify city in which most people were born –Get IDs of people who were born in this city –Get ages of these people –Identify highest age among these ages –Using the pid of this age get the name of this person
68
Example of repeated abstraction (contd.) Step 1: Compute numbers of people born in each city and put in $cityBirths
69
Example of repeated abstraction (contd.) Step 2: From $cityBirths, compute $IdOfCityWithMostBirths
70
Example of repeated abstraction (contd.) Step 3: From $IdOfCityWithMostBirths, compute $IdsOfPeopleBornInCityWithMostBirths
71
Example of repeated abstraction (contd.) Step 4: From $IdsOfPeopleBornInCityWithMostBirths, compute $ agesOfPeopleBornInCityWithMostBirths Note the need to remember the primary document in a variable <xsl:for-each select="exsl:nodeset($IdsOfPeopleBornInCityWithMostBirths)/personIds/personId">
72
Example of repeated abstraction (contd.) Step 5: From $agesOfPeopleBornInCityWithMostBirths compute $IdOfOldestPersonBornInCityWithMostBirths List these ages in descending order, but output only the pid attribute of the first member of the sorted set <xsl:for-each select="exsl:node-set($agesOfPeopleBornInCityWithMostBirths)/list/item">
73
Example of repeated abstraction (contd.) Step 6: From $IdOfOldestPersonBornInCityWithMostBirths compute the name of the person with this pid The name of the oldest person born in the city with most births is <xsl:value-of select="/info/firstnames/firstname[@pid = exsl:node-set( $IdOfOldestPersonBornInCityWithMostBirths )]"/>
74
Complete stylesheet, part 1 <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" > Oldest person in most populous city
75
Complete stylesheet, part 2
76
Complete stylesheet, part 3
77
Complete stylesheet, part 4 The name of the oldest person born in the city with most births is
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.