too many old people The number of people is:"> too many old people The number of people is:">

Presentation is loading. Please wait.

Presentation is loading. Please wait.

More on XSLT. 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.

Similar presentations


Presentation on theme: "More on XSLT. 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."— Presentation transcript:

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


Download ppt "More on XSLT. 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."

Similar presentations


Ads by Google