XML - Managing Data Exchange/XSLT and Style Sheets

In previous chapters, we have introduced the basics of using an XSL stylesheet to convert XML documents into HTML. This chapter will briefly review those concepts and introduce many new ones as well. It is a reference for creating stylesheets.
XML Stylesheets.
The eXtensible Stylesheet Language (XSL) provides a means to transform and format the contents of XML document for display. It includes two parts, XSL Transformation (XSLT) for transforming the XML document, and XSLFO (XSL Formatting Objects) for formatting or applying styles to XML documents. The XSL Transformation Language (XSLT) is used to transform XML documents from one form to another, including new XML documents, HTML, XHTML, and text documents. XSL-FO can create PDF documents, as well as other output formats, from XML. With XSLT you can effectively recycle content, redesigning it for use in new documents, or changing it to fit limitless uses. For example, from a single XML source file, you could extract a document ready for print, one for the Web, one for a Unix manual page, and another for an online help system. You can also choose to extract only parts of a document written in a specific language from an XML source that stores text in many languages. The possibilities are endless!
An XSLT stylesheet is an XML document, complete with elements and attributes. It has two kinds of elements, top-level and instruction. Top-level elements fall directly under the codice_1 root element. Instruction elements represent a set of formatting instructions that dictate how the contents of an XML document will be transformed. During the transformation process, XSLT analyzes the XML document, or the source tree, and converts it into a node tree, a hierarchical representation of the entire XML document, also known as the result tree. Each node represents a piece of the XML document, such as an element, attribute or some text content. The XSL stylesheet contains predefined “templates” that contain instructions on what to do with the nodes. XSLT will use the codice_2 attribute to relate XML element nodes to the templates, and transform them into the result document.
Let's review the stylesheet, city.xsl from chapter 2, and examine it in a little more detail:
Exhibit 1: XML stylesheet for city entity
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
Document: city.xsl
&lt;xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="html"/&gt;
 &lt;xsl:template match="/"&gt;
 &lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;Cities&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
 &lt;h2&gt;Cities&lt;/h2&gt;
 &lt;xsl:apply-templates select="cities"/&gt;
 &lt;/body&gt;
 &lt;/html&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="cities"&gt;
 &lt;!-- the for-each element can be used to loop through each node in a specified node set (in this case city) --&gt;
 &lt;xsl:for-each select="city"&gt;
 &lt;xsl:text&gt;City: &lt;/xsl:text&gt;
 &lt;xsl:value-of select="cityName"/&gt;
 &lt;br/&gt;
 &lt;xsl:text&gt;Population: &lt;/xsl:text&gt;
 &lt;xsl:value-of select="cityPop"/&gt;
 &lt;br/&gt;
 &lt;xsl:text&gt;Country: &lt;/xsl:text&gt;
 &lt;xsl:value-of select="cityCountry"/&gt;
 &lt;br/&gt;
 &lt;br/&gt;
 &lt;/xsl:for-each&gt;
 &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
The codice_3 element defines the rules that implement a change. This can be any number of things, including a simple plain-text conversion, the addition or removal of XML elements, or simply a conversion to HTML, when the pattern is matched. The pattern, defined in the element’s codice_2 attribute, contains an abbreviated ../XPath/ location path. This is basically the name of the root element in the doc, in our case, "tourGuide."
When transforming an XML document into HTML, the processor expects that elements in the stylesheet be well-formed, just as with XML. This means that all elements must have an end tag. For example, it is not unusual to see the codice_5 tag alone. The XSLT processor requires that an element with a start-tag must close with an end tag. With the codice_6 element, this means either using codice_7 or codice_8 As mentioned in Chapter 3, the codice_9 element is an empty element. That means it carries no content between tags, but it may have attributes. Although no end tags are output for the HTML output, they still must have end-tags in the stylesheet. For instance, in the stylesheet, you will list: codice_10 or as an empty element codice_11. The HTML output will drop the end-tag so it looks like this: codice_12 On a side note, the processor will recognize html tags no matter what case they are in - BODY, body, Body are all interpreted the same.
Output.
XSLT can be used to transform an XML source into many different types of documents. XHTML is also XML, if it is well formed, so it could also be used as the source or the result. However, transforming plain HTML into XML won't work unless it is first turned into XHTML so that it conforms to the XML 1.0 recommendation.
Here is a list of all the possible type-to-type transformations performed by XSLT:
Exhibit 2: Type-To-Type Transformations
The codice_13 element in the stylesheet determines how to output the result tree. This element is optional, but it allows you to have more control over the output. If you do not include it, the output method will default to XML, or HTML if the first element in the result tree is the codice_14element. Exhibit 3 lists attributes.
Exhibit 3: Element output attributes
XML to XML.
Since we have had a lot of practice transforming an XML document to HTML, we are going to transform city.xml, used in chapter 2, into another XML file, using host.xsd as the schema.
Exhibit 4: XML document for city entity
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 Document: city.xml
&lt;cities xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
 xsi:noNamespaceSchemaLocation='host.xsd'&gt;
&lt;city&gt;
 &lt;cityID&gt;c1&lt;/cityID&gt;
 &lt;cityName&gt;Atlanta&lt;/cityName&gt;
 &lt;cityCountry&gt;USA&lt;/cityCountry&gt;
 &lt;cityPop&gt;4000000&lt;/cityPop&gt;
 &lt;cityHostYr&gt;1996&lt;/cityHostYr&gt; 
&lt;/city&gt;
&lt;city&gt;
 &lt;cityID&gt;c2&lt;/cityID&gt;
 &lt;cityName&gt;Sydney&lt;/cityName&gt;
 &lt;cityCountry&gt;Australia&lt;/cityCountry&gt;
 &lt;cityPop&gt;4000000&lt;/cityPop&gt;
 &lt;cityHostYr&gt;2000&lt;/cityHostYr&gt; 
 &lt;cityPreviousHost&gt;c1&lt;/cityPreviousHost &gt; 
&lt;/city&gt;
&lt;city&gt;
 &lt;cityID&gt;c3&lt;/cityID&gt;
 &lt;cityName&gt;Athens&lt;/cityName&gt;
 &lt;cityCountry&gt;Greece&lt;/cityCountry&gt;
 &lt;cityPop&gt;3500000&lt;/cityPop&gt;
 &lt;cityHostYr&gt;2004&lt;/cityHostYr&gt; 
 &lt;cityPreviousHost&gt;c2&lt;/cityPreviousHost &gt; 
&lt;/city&gt;
&lt;/cities&gt; 
Exhibit 5: XSL document for city entity that list cities by City ID
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"&gt;
 &lt;xsl:output method="html"/&gt; 
 &lt;xsl:template match="/"&gt;
 &lt;xsl:for-each select="//city[count(cityPreviousHost) = 0]"&gt;
 &lt;br/&gt;&lt;xsl:text&gt;City Name: &lt;/xsl:text&gt;&lt;xsl:value-of select="cityName"/&gt;&lt;br/&gt;
 &lt;xsl:text&gt; Rank: &lt;/xsl:text&gt;&lt;xsl:value-of select="cityID"/&gt;&lt;br/&gt;
 &lt;xsl:call-template name="output"&gt;
 &lt;xsl:with-param name="context" select="."/&gt;
 &lt;/xsl:call-template&gt;
 &lt;/xsl:for-each&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template name="output"&gt;
 &lt;xsl:param name="context" select="."/&gt;
 &lt;xsl:for-each select="//city[cityPreviousHost = $context/cityID]"&gt;
 &lt;br/&gt;&lt;xsl:text&gt;City Name: &lt;/xsl:text&gt; &lt;xsl:value-of select="cityName"/&gt;&lt;br/&gt;
 &lt;xsl:text&gt; Rank: &lt;/xsl:text&gt;&lt;xsl:value-of select="cityID"/&gt;&lt;br/&gt;
 &lt;xsl:call-template name="output"&gt;
 &lt;xsl:with-param name="context" select="."/&gt;
 &lt;/xsl:call-template&gt;
 &lt;/xsl:for-each&gt;
 &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
Exhibit 6: XML schema for host city entity
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified"&gt;
&lt;xsd:element name="cities"&gt;
 &lt;xsd:complexType&gt;
 &lt;xsd:sequence&gt;
 &lt;xsd:element name="city" type="cityType" maxOccurs="unbounded"/&gt;
 &lt;/xsd:sequence&gt;
 &lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:complexType name="cityType"&gt;
 &lt;xsd:sequence&gt;
 &lt;xsd:element name="cityID" type="xsd:ID"/&gt;
 &lt;xsd:element name="cityName" type="xsd:string"/&gt;
 &lt;xsd:element name="cityCountry" type="xsd:string"/&gt;
 &lt;xsd:element name="cityPop" type="xsd:integer"/&gt;
 &lt;xsd:element name="cityHostYr" type="xsd:integer"/&gt;
 &lt;xsd:element name="cityPreviousHost" type="xsd:IDREF" minOccurs="0" maxOccurs="1"/&gt;
 &lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
Exhibit 7: XML stylesheet for city entity
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
 Document: city2.xsl
 &lt;xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="xml" encoding="utf-8" indent="yes" /&gt;
 &lt;xsl:attribute-set name="date"&gt;
 &lt;xsl:attribute name="year"&gt;2004&lt;/xsl:attribute&gt;
 &lt;xsl:attribute name="month"&gt;03&lt;/xsl:attribute&gt;
 &lt;xsl:attribute name="day"&gt;19&lt;/xsl:attribute&gt;
 &lt;/xsl:attribute-set&gt;
 &lt;xsl:template match="tourGuide"&gt;
 &lt;xsl:processing-instruction name="xsl-stylesheet"&gt; href="style.css" type="text/css"&lt;br /&gt;
 &lt;/xsl:processing-instruction&gt;
 &lt;xsl:comment&gt;This is a list of the cities we are visiting this week&lt;/xsl:comment&gt;
 &lt;xsl:for-each select="city"&gt;
&lt;!-- element name creates a new element where the value of the attribute name sets name of
the new element. Multiple attribute sets can be used in the same element --&gt;
&lt;!-- use-attribute-sets attribute adds all the attributes declared in attribute-set from above --&gt;
 &lt;xsl:element name="cityList" use-attribute-sets="date"&gt;
 &lt;xsl:element name="city"&gt;
 &lt;xsl:attribute name="country"&gt;
 &lt;xsl:apply-templates select="country"/&gt; &lt;/xsl:attribute&gt;
 &lt;xsl:apply-templates select="cityName"/&gt;
 &lt;/xsl:element&gt;
 &lt;xsl:element name="details"&gt;Will write up a one page report of the trip&lt;/xsl:element&gt;
 &lt;/xsl:element&gt;
 &lt;/xsl:for-each&gt;
 &lt;/xsl:template&gt;
 &lt;/xsl:stylesheet&gt; 
The stylesheet produces this result tree:
Exhibit 8: XML result tree for city entity
&lt;?xml version="1.0" encoding="utf-8" standalone="no"?&gt;
 Document: city2.xsl
 &lt;?xsl-stylesheet href="style.css" type="text/css"?&gt;
 &lt;!--This is a list of the cities we are visiting this week--&gt;
 &lt;cityList year="2004" month="03" day="19"&gt;
 &lt;city country="Belize"&gt;Belmopan&lt;/city&gt;
 &lt;details&gt;Will write up a one page report of the trip&lt;/details&gt;
 &lt;/cityList&gt;
 &lt;cityList year="2004" month="03" day="19"&gt;
 &lt;city country="Malaysia"&gt;Kuala Lumpur&lt;/city&gt;
 &lt;details&gt;Will write up a one page report of the trip&lt;/details&gt;
 &lt;/cityList&gt;
 &lt;/stylesheet&gt;
The processor automatically inserts the XML declaration at the top of the result tree. The processing instruction, or PI, is an instruction intended for use by a processing application. In this case, the href points to a local stylesheet that will be applied to the XML document when it is processed. We used codice_22 to create new content in the result tree and added attributes to it.
There are two other instruction elements for inserting nodes into a result tree. These are codice_23 and codice_24. Unlike codice_25, which only copies content of the child node (like the child text node), these elements copy everything. The following code shows how the copy element can be used to copy the city element in city.xml:
Exhibit 9: Copy element
 &lt;xsl:template match="city"&gt;
 &lt;xsl:copy /&gt;
 &lt;/xsl:template&gt;
The result looks like this:
Exhibit 10: Copy element result
 &lt;?xml version="1.0" encoding="utf-8"&gt;
 &lt;city /&gt;
 &lt;city /&gt;
The output isn't very interesting, because copy does not pick up the child nodes, only the current node. In our example, it picks up the two city nodes that are in the city.xml file. The copy element has an optional attribute, use-attribute-sets, which allows you to add attributes to the element. However, it will leave behind any other attributes, except the namespace, if it is present. Here is the result if a namespace is declared in the source document, in this case, the default namespace:
Exhibit 11: Namespace result
 &lt;?xml version="1.0" encoding="utf-8"&gt;
 &lt;city xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
 &lt;city xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
If you want to copy more from the source file than just one node, the codice_24 element includes the current node, and any attribute nodes that are associated with it. This includes any nodes that might be laying around, such as namespace nodes, text nodes, and child element nodes. When we apply the codice_24 element to city.xml, the result is almost an exact replica of city.xml! You can also copy comments and processing instructions using codice_28 and codice_29where codice_30 is the value of the name attribute in the processing instruction you wish to retrieve.
Why would this be useful, you ask? Sometimes you want to just grab nodes and go! For example, if you want to place a copy of city.xml into a SOAP envelope, you can easily do it using codice_24. If you don't already know, Simple Object Access Protocol, or SOAP, is a protocol for packaging XML documents for exchange. This is really useful in a B2B environment because it provides a standard way to package XML messages. You can read more about SOAP at www.w3.org/tr/soap.
Use an XML editor to create the above XML Stylesheets, and experiment with the codice_23 and codice_24 elements.
Templates.
Since templates define the rules for changing nodes, it would make sense to reuse them, either in the same stylesheet or in other stylesheets. This can be accomplished by naming a template, and then calling it with a codice_34 element. Named templates from other stylesheets can also be included. You can quickly see how this is useful in practical applications. Here is an example using named templates:
Exhibit 110: Named templates
&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xsl:output method="xml" /&gt;
 &lt;xsl:template match=" /"&gt;
 &lt;xsl:call-template name="getCity" /&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template name="getCity"&gt;
 &lt;xsl:copy-of select="city" /&gt;
 &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
Templates also have a mode attribute. This allows you to process a node more than once, producing a different result each time, depending on the template. Let's create a stylesheet to practice modes.
Exhibit 12: XML template modes
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 Document: cityModes.xsl
&lt;xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xsl:output method="html" /&gt;
 &lt;xsl:template match="tourGuide"&gt;
 &lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;City - Using Modes&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
 &lt;xsl:for-each select="city"&gt;
 &lt;xsl:apply-templates select="cityName" mode="title" /&gt;
 &lt;xsl:apply-templates select="cityName" mode="url" /&gt;
 &lt;br /&gt;
 &lt;/xsl:for-each&gt;
 &lt;/body&gt;
 &lt;/html&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="cityName" mode="title"&gt;
 &lt;h2&gt;&lt;xsl:value-of select="current()"/&gt;&lt;/h2&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="cityName" mode="message"&gt;
 &lt;p&gt;Come visit &lt;b&gt;&lt;xsl:value-of select="current()" /&gt;&lt;/b&gt;!&lt;/p&gt;
 &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
The result isn't very flattering since we didn't do much with the file, but it gets the point across.
Exhibit 13: Result from above stylesheet
&lt;h2&gt;Belmopan&lt;/h2&gt;
Come visit &lt;b&gt;Belmopan&lt;/b&gt;!
&lt;h2&gt;Kuala Lumpur&lt;/h2&gt;
Come visit &lt;b&gt;Kuala Lumpur&lt;/b&gt;!
By default, XSLT processors have built-in template rules. If you apply a stylesheet without any matching rules, and it fails to match a pattern, the default rules are automatically applied. The default rules output the content of all the elements.
Sorting.
Writing “well formed” code XML is vital. At times, however, simply displaying information (the most elementary level of data management) is not all that is necessary to properly identify a project. As information technology specialists, it is necessary to fully understand that order is vital for interpretation. Order can be attained by putting data in a format that is quickly readable. Such information then becomes quickly usable. Using a comparative model or simply looking for a specific name or item becomes very easy. Finding a specific musical artist, title, or musical type becomes very easy. As an Information Specialist, you must fully be aware that it often becomes necessary to sort information.
The basis of sorting in XMLT is the xsl:sort command. The xsl:sort element exemplifies a sort key component. A sort key component identifies how a sort key value is to be identified for each item in the order of information being sorted.
A Sort Key Value is defined as “the value computed for an item by using the Nth sort key component”
The significance of a sort key component is realized either by its select attribute, or by the contained sequence constructor. A Sequence Constructor is defined as a “sequence of zero or more sibling nodes in the stylesheet that can be evaluated to return a sequence of nodes and atomic values”. There are instances when neither is present. Under these circumstances, the default is select=".", which has the effect of sorting on the actual value of the item if it is an atomic value, or on the typed-value of the item if it is a node. If a select attribute is present, its value must be an Xpath expression.
The following is how the &lt;xsl:sort&gt; element is used to sort the output.
Sort Information is held as Follows:
Sorting output in XML is quite easy and is done by adding the &lt;xsl:sort&gt; element after the &lt;xsl:for-each&gt; element in the XSL file.
Exhibit 14: Stylesheet with sort function
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xsl:template match="/"&gt;
 &lt;html&gt;
 &lt;body&gt;
 &lt;h2&gt;TourGuide Example&lt;/h2&gt;
 &lt;xsl:apply-templates select="cities"/&gt;
 &lt;/body&gt;
 &lt;/html&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="cities"&gt;
 &lt;xsl:for-each select="city"&gt;
 &lt;xsl:sort select="cityName"/&gt;
 &lt;xsl:value-of select="cityName"/&gt;
 &lt;xsl:value-of select="cityCountry"/&gt;
 &lt;/xsl:for-each&gt;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
This example will sort the file alphabetically by artist name.
Note: The select attribute indicates what XML element to sort on. Information can be SELECTED and SORTED by “title” or “artist”. These are categories that the XML document will display within the body of the file.
We have used the codice_39 function to sort the results of an codice_40 statement before. The sort element has many other uses as well. Essentially, it instructs the processor to sort nodes based on certain criteria, which is known as the sort key. It defaults to sorting the elements in ascending order. Here is a short list of the different attributes that sort takes:
Exhibit 15: Sort attributes
The sort element can be used in either the codice_25 or the codice_42 elements. It can also be used multiple times within a template, or in several templates, to create sub-ordering levels.
Numbering.
The codice_43 instruction element allows you to insert numbers into your results. Combined with a sort element, you can easily create numbered lists. When this simple stylesheet, hotelNumbering.xsl, is applied to city_hotel.xml, we get the result listed below:
Exhibit 16: Sorting and numbering lists
 &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
 Document: hotelNumbering.xsl
 &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="text" omit-xml-declaration="yes"/&gt;
 &lt;xsl:template match="/"&gt;
 &lt;xsl:apply-templates select="tourGuide/city/hotel"&gt;
 &lt;xsl:sort/&gt;
 &lt;/xsl:apply-templates&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="hotel"&gt;
 &lt;xsl:number value="position()" format="&amp;#xa; 0. "/&gt;
 &lt;xsl:value-of select="hotelName"/&gt;
 &lt;/xsl:template&gt;
 &lt;/xsl:stylesheet&gt;
Exhibit 17: Result hotelNumbering.xsl
 1. Bull Frog Inn
 2. Mandarin Oriental Kuala Lumpur
 3. Pan Pacific Kuala Lumpur
 4. Pook's Hill Lodge
The expression in codice_44 is evaluated and the value for codice_45 is based on the sorted node list. To improve the looks we are adding the format attribute with a linefeed character reference (&amp;#xa;), a zero digit to indicate that the number will be
a zero digit to indicate that the number will be an integer type, and a period and space to make it look nicer. The format list can be based on the following sequences:
Exhibit 17: Numbering formats
 codice_46 – Uppercase letters
 codice_47 – Lowercase letters
 codice_48 – Uppercase Roman numerals
 codice_49 – Lowercase Roman numerals
 codice_50 – Numeral prefix
 codice_51 – Integer prefix/ hyphen prefix
To specify different levels of numbering, such as sections and subsections of the source document, the codice_52 attribute is used, which tells the processor the levels of the source tree that should be considered. By default, it is set to codice_53, as seen in the example above. It also can take values of codice_54 and codice_55. The codice_56 attribute is a pattern that tells the processor which nodes to count (for numbering purposes). If it is not specified, it defaults to a pattern matching the same node type as the current node. The codice_57 attribute can also be used to specify the node where the counting should start.
When level is set to codice_53, the processor searches for nodes that match the value of codice_56, and if it is not present, it matches the current node. When it finds the match, it creates a node-list and counts all the matching nodes of that type. If the codice_57 attribute is listed, it tells the processor where to start counting from, rather than counting all nodes
When the level is codice_54, it doesn't just count a list of one node type, it creates a list of all the nodes that are ancestors of the current node, in the actual order from the source document. After this list is created, it selects all the nodes that match the nodes represented in count. It then maps the number of preceding siblings for each node that matches count. In effect, codice_54 remembers all the nodes separately. This is where codice_55 is different. It will number all the elements sequentially, instead of counting them in multiple levels. As with the other two values, you can use the codice_57 attribute to tell the processor where to start counting from, which in effect will separate it into levels.
This is a modification of the example above using the codice_65:
Exhibit 18: Sorting and numbering lists
 Document: hotelNumbering2.xsl
 &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="text" omit-xml-declaration="yes"/&gt;
 &lt;xsl:template match="/"&gt;
 &lt;xsl:apply-templates select="tourGuide//hotelName"/&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="hotel"&gt;
 &lt;xsl:number level="multiple"
 count="city|hotel" format="&amp;#xa; 1.1 "/&gt;
 &lt;xsl:apply-templates /&gt;
 &lt;/xsl:template&gt;
 &lt;/xsl:stylesheet&gt;
Exhibit 19: Result – hotelNumbering2.xsl
 1.1 Bull Frog Inn
 1.2 Pook's Hill Lodge
 2.1 Pan Pacific Kuala Lumpur
 2.2 Mandarin Oriental Kuala Lumpur
The first template matches the root node and then selects all codice_66 nodes that have codice_67 as an ancestor, creating a node-list. The next template recursively processes the codice_68 element, and gives it a number for each instance of codice_68 based on the number of elements in the attribute. This is figured out by counting the number of preceding siblings, plus 1.
Formatting.
Formatting numbers is a simple process so this section will be a brief overview of what can be done. Placed within the XML stylesheet, functions can be used to manipulate data during the transformation. In order to make numbers a little easier to read, we need to be able to separate the digits into groups, or add commas or decimals. To do this we use the codice_70 function. The purpose of this function is to convert a numeric value into a string using specified patterns that control the number of leading zeroes, separator between thousands, etc. The basic syntax of this function is as follows: codice_71
The following are the characters and their meanings used to represent the number format when using the format-number function within a stylesheet:
Exhibit 20: Format-number function
 Symbol Meaning
 0 A digit.
 # A digit, zero shows as absent.
 . (period) Placeholder for decimal separator.
 , Placeholder for grouping separator.
 ; Separate formats.
 - Default prefix for negative.
 % Multiply by 100 and show as a percentage.
 X Any other characters can be used in the prefix or suffix.
 ‘ Used to quote special characters in a prefix or suffix.
Conditional Processing.
There are times when it is necessary to display output based on a condition. There are two instruction elements that let you conditionally determine which template will be used based on certain tests. These are the codice_40 and codice_75 elements.
The test condition for an codice_40 statement must be contained within the codice_77 attribute of the codice_78 element. Expressions that are testing greater than and less than operators must represent them by “&amp;gt;” and “&amp;lt;” respectively in order for the appropriate transformation to take place. The codice_79 function from XPath is a Boolean function and evaluates to true if its argument is false, and vice versa. The codice_80 and codice_81 conditions can be used to combine multiple tests, but an codice_40 statement can, at most, test only one expression. It can also only instantiate the use of one template.
The codice_83 element, is similar to the codice_84 statement in Java. By using the codice_83 element, the codice_75 element can offer a many alternative expressions. A choose element must contain at least one when statement, but it can have as many as it needs. The choose element can also contain one instance of the otherwise element, which works like the final else in a Java program. It contains the template if none of the other expressions are true.
The codice_42 element is another conditional processing element. We have used it in previous chapter exercises, so this will be a quick review. The codice_42 element is an instruction element, which means it must be children of template elements. codice_42 evaluates to a node-set, based on the value of the select attribute, or expression, and processes through each node in document order, or sorted order.
Parameters and Variables.
XSLT offers two similar elements, codice_90 and codice_91. Both have a required codice_30 attribute, and an optional codice_93 attribute, and you declare them like this:
Exhibit 21: Variable and parameter declaration
 &lt;xsl:variable name=""var1" select=""/&gt;
 &lt;xsl:param name=""par1" select=""/&gt;
The above declarations have bound to an empty string, which is the same effect as if you had left off the select attribute. With parameters, this value is considered only a default, or initial value to be changed either from the command line, or from another template using the codice_94 element. However, with the variable, as a general rule, the value is set and can't be changed dynamically except under special circumstances. When making declarations, remember that variables can be declared anywhere within a template, but a parameter must be declared at the beginning of the template.
Both elements can also have global and local scope, depending on where they are
defined. If they are defined at the top-level under the &lt;stylesheet&gt; elements, they are global in scope and can be used anywhere in the stylesheet. If they are defined in a template, they are local and can only be used in that template. Variables and parameters declared in templates are visible only to the template they are declared in, and to templates underneath them. They have a cascading effect: they can spill down from the top-level into a template, down into a template within that one, etc, but they cannot go back up!
We are going to hard-code a value for the parameter in it's declaration element using the codice_93 attribute.
Exhibit 22: HTML results
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
 Document: countryParam.xsl
 &lt;xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="text"/&gt;
 &lt;xsl:param name="country" select="'Belize'"/&gt;
 &lt;xsl:param name="code" /&gt;
 &lt;xsl:template match="/"&gt;
 &lt;xsl:apply-templates select="country-codes" /&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="country-codes"&gt;
 &lt;xsl:apply-templates select="code" /&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="code"&gt;
 &lt;xsl:choose&gt;
 &lt;xsl:when test="countryName[. = $country]"&gt;
 The country code for
 &lt;xsl:value-of select="countryName"/&gt; is
 &lt;xsl:value-of select="countryCode"/&gt;.
 &lt;/xsl:when&gt;
 &lt;xsl:when test="countryCode[. = $code]"&gt;
 The country for the code
 &lt;xsl:value-of select="countryCode"/&gt; is
 &lt;xsl:value-of select="countryName"/&gt;.
 &lt;/xsl:when&gt;
 &lt;xsl:otherwise&gt;
 Sorry. No matching country name or country code.
 &lt;/xsl:otherwise&gt;
 &lt;/xsl:choose&gt;
 &lt;/xsl:template&gt;
 &lt;/xsl:stylesheet&gt;
The value that you pass in does not have to be enclosed in quotes, unless you are passing a value with more than one word. For example, we could have passed
either country="United States" or country=Belize without getting an error.
The value of a variable can also be used to set an attribute value. Here is an example setting the countryName element with an attribute of countryCode equal to the value in thecodice_96 variable:
Exhibit 23: Attribute of countryCode 
 codice_97
This is known as an attribute value template. Notice the use of braces around the parameter. This tells the processor to evaluate the content as an expression, which then converts the result to a string in the result tree. There are attributes which cannot be set with an attribute value template: 
Parameters, though not variables, can be passed between templates using the codice_94 element. This element has two attributes, codice_30, which is required, and codice_93, which is optional. This next example uses with-param as a child of the codice_34 element, although it can also be used as a child of codice_25.
Exhibit 24: XSL With-Param
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
 Document: withParam.xsl
 &lt;xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 &lt;xsl:output method="text"/&gt;
 &lt;xsl:template match="/"&gt;
 &lt;xsl:apply-templates select="tourGuide/city"/&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template match="city"&gt;
 &lt;xsl:call-template name="countHotels"&gt;
 &lt;xsl:with-param name="num" select="count(hotel)"/&gt;
 &lt;/xsl:call-template&gt;
 &lt;/xsl:template&gt;
 &lt;xsl:template name="countHotels"&gt;
 &lt;xsl:param name="num" select=""" /&gt;
 &lt;xsl:text&gt;City Name: &lt;/xsl:text&gt;
 &lt;xsl:value-of select="cityName" /&gt;
 &lt;xsl:text&gt;&amp;#xa;&lt;/xsl:text&gt;
 &lt;xsl:text&gt;Number of hotels: &lt;/xsl:text&gt;
 &lt;xsl:value-of select="$num" /&gt;
 &lt;xsl:text&gt;&amp;#xa;&amp;#xa;&lt;/xsl:text&gt;
 &lt;/xsl:template&gt;
 &lt;/xsl:stylesheet&gt;
Exhibit 25: Text results – withParam.xsl
 City Name: Belmopan
 Number of hotels: 2
 City Name: Kuala Lumpur
 Number of hotels: 2
The Muenchian Method.
The Muenchian Method is a method developed by Steve Muench for performing
 functions using keys. Keys work by assigning a key value to a
 node and giving you access to that node through the key value. If there are lots
 of nodes that have the same key value, then all those nodes are retrieved when you use
 that key value. Effectively this means that if you want to group a set of nodes
 according to a particular property of the node, then you can use keys to group them
 together. One of the more common uses for the Muenchian method is grouping items and counting the number of
occurrences in that group, such as number of occurrences of a city
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
 &lt;xsl:output method="html"/&gt; 
 &lt;xsl:key name="Count" match="*/city" use="cityName" /&gt; 
 &lt;xsl:template match="cities"&gt; 
 &lt;xsl:for-each 
 select="//city[generate-id()=generate-id(key('Count', cityName)[1])]"&gt; 
 &lt;br/&gt;&lt;xsl:text&gt;City Name:&lt;/xsl:text&gt;&lt;xsl:value-of select="cityName"/&gt;&lt;br/&gt;
 &lt;xsl:text&gt;Number of Occurences:&lt;/xsl:text&gt;
 &lt;xsl:value-of select="count(key('Count', cityName))"/&gt;
 &lt;br/&gt;
 &lt;/xsl:for-each&gt; 
 &lt;/xsl:template&gt; 
&lt;/xsl:stylesheet&gt;
Text Results – muenchianMethod.xsl
 City Name: Atlanta
 Number of Occurrences: 1
 City Name: Athens
 Number of Occurrences: 1
 City Name: Sydney
 Number of Occurrences: 1
Datatypes.
There are five different datatypes in XSLT: Node-set, String, Number, Boolean, and Result tree fragment. Variables and parameters can be bound to each of these, but the last type is specific to them.
Node-sets are returned everywhere in XSLT. We've seen them returned from codice_25 and codice_119 elements, and variables. Now we will see how a variable can be bound to a node-set. Examine the following code:
Exhibit 26: Variable bound to a node-set
&lt;xsl:variable name="cityNode" select="city" /&gt;
&lt;xsl:template match="/"&gt;
 &lt;xsl:apply-templates select="$cityNode/cityName" /&gt;
&lt;/xsl:template&gt; 
Here, we are setting the value of the variable codice_120 to the node-set codice_108 from the source tree. The codice_122 element is a child of city, so the output generated by apply-templates is the text node of codice_122. Remember, you can use variable references in expressions but not patterns. This means we cannot use the reference codice_124 as the value of a codice_2 attribute.
String types are useful if you are interested only in the text of nodes, rather than in the whole node-set. String types use XPath functions, most notably, codice_126. This is just a simple example:
Exhibit 27: String types
&lt;xsl:variable name="cityName" select="string('Belmopan')" /&gt;
This is in fact, a longer way of saying:
Exhibit 28: Shorter version of above
&lt;xsl:variable name="cityName" select="' Belmopan'" /&gt;
It is also possible to declare a variable that has a number value. You do this by using the XPath function codice_127.
Exhibit 29: Declaration of variable with number value
&lt;xsl:variable name="population" select="number(11100)" /&gt;
You can use numeric operators such as + - * / to perform mathematic operations on numbers, as well as some built in XPath functions such as codice_128 and codice_129.
The Boolean type has only two possible values, true or false. As an example, we are going to use a Boolean variable to test to see if a parameter has been passed into the stylesheet. 
Exhibit 30: Boolean variable to test
&lt;xsl:param name="isOk" select=""" /&gt;
&lt;xsl:template match="city" /&gt;
 &lt;xsl:choose&gt;
 &lt;xsl:when test="boolean($isOk)"&gt;
 …logic here…
 &lt;/xsl:when&gt;
 &lt;xsl:otherwise&gt;
 Error: must use parameter isOk with any value to apply template
 &lt;/xsl:otherwise&gt;
 &lt;/xsl:choose&gt;
&lt;/xsl:template&gt; 
We start with an empty-string declaration for the parameter codice_130. In the codice_77 attribute of codice_83, the codice_133 function tests the value of codice_130. If the value is an empty string, as we defined by default, codice_133 evaluates to codice_136, and the template is not instantiated. If it does have a value, and it can be any value at all, codice_133 evaluates to codice_138.
The final datatype is the result tree fragment. Essentially it is a chunk of text (a string) that can contain markup. Let's look at an example before we dive into the details:
Exhibit 31: Result tree fragment datatype
 &lt;xsl:variable name="fragment"&gt; 
 &lt;description&gt;Belmopan is the capital of Belize&lt;/description&gt; 
 &lt;/xsl:variable&gt;
Notice we didn't use the select attribute to define the variable. We aren't selecting a node and getting its value, rather we are creating arbitrary text. Instead, we declared it as the content of the element. The text in between the opening and closing variable tags is the actual fragment of the result tree. In general, if you use the select attribute as we did earlier, and don't specify content when declaring variables, the elements are empty elements. If you don't use select and you do specify content, the content is a result tree. You can perform operations on it as if it were a string, but unlike a node set, you can't use operators such as / or // to get to the nodes. The way you retrieve the content from the variable and get it into the result tree is by using the copy-of element. Let's see how we would do this:
Exhibit 32: Retrieve and place into result tree 
 &lt;xsl:template match="city" 
 &lt;xsl:copy-of select="cityName" /&gt; 
 &lt;xsl:copy-of select="$fragment" /&gt; 
 &lt;/xsl:template&gt; 
The result tree would now contain two elements: a copy of the city element and the added element, description.
EXSLT.
EXSLT is a set of community developed extensions to XSLT. The modules include facilities to handle dates and times, math, and strings.
Multiple Stylesheets.
In previous chapters, we have imported and used multiple XML and schema documents. It is also possible to use multiple stylesheets using the codice_139 and codice_140 elements, which should be familiar. It is also possible to process multiple XML documents at a time, in one stylesheet, by using the XSLT function codice_141.
Including an external stylesheet is very similar to what we have done in earlier chapters with schemas. The codice_140 element only has one attribute, which is codice_143. It is required and always contains a URI (Uniform Resource Identifier) reference to the location of the file, which can be local (in the same local directory) or remote. You can include as many stylesheets as you need, as long as they are at the top level. They can be scattered all over the stylesheet if you want, as long as they are children of the codice_144 element. When the processor encounters an instance of include, it replaces the instance with all the elements from the included document, including template rules and top-level elements, but not the root codice_144 element. All the items just become part of the stylesheet tree itself, and the processor treats them all the same. Here are declarations for including a local and remote stylesheet:
Exhibit 33: Declarations for local and remote stylesheet
&lt;xsl:include href="city.xsl" /&gt;
&lt;xsl:include href="http://www.somelocation.com/city.xsl"/&gt;
Since codice_140 returns all the elements in the included stylesheet, you need to make sure that the stylesheet you are including does not include your own stylesheet. For example, city.xsl cannot include city_hotel.xsl, if city_hotel.xsl has an include element which includes city.xsl. When including multiple files, you need to make sure that you are not including another stylesheet multiple times. If city_hotel.xsl includes amenity.xsl, and country.xsl includes amenity.xsl, and city.xsl includes both city_hotel.xsl and country.xsl, it has indirectly included amenity.xsl twice. This could cause template rule duplication and errors. These are some confusing rules, but they are easy to avoid if you carefully examine the stylesheets before they are included.
The difference between importing stylesheets and including them is that the template rules imported each have a different import precedence, while included stylesheet templates are merged into one tree and processed normally. Imported templates form an import tree, complete with the root codice_144 element so the processor can track the order in which they were imported. Just like include, import has one attribute, href, which is required and should contain the URI reference for the document. It is also a top-level element and can be used as many times as need. However, it must be the immediate child for the codice_144 element, otherwise there will be errors. This code demonstrates importing a local stylesheet:
Exhibit 34: Importing local stylesheet
&lt;xsl:import href="city.xsl" /&gt;
The order of the codice_139 elements dictates the precedence that matching templates will have over one another. Templates that are imported last have higher priority than those that are imported first. However, the codice_3 element also has a codice_151 attribute that can affect its priority. The higher the number in the codice_151 attribute, the higher the precedence. Import priority only comes into effect when templates collide, otherwise importing stylesheets is not that much different from including them. Another way to handle colliding templates is to use the codice_153 element. If a template in the imported document collides with a template in the importing document, apply-templates will override the rule and cause the imported template to be invoked.
The codice_141 function allows you to process additional XML documents
and their nodes. The function is called from any attribute that uses an expression, such as the codice_93 attribute. For example:
Exhibit 35: Document() function
&lt;xsl:template match="hotel"&gt;
 &lt;xsl:element name="amenityList"&gt;
 &lt;xsl:copy-of select="document('amenity.xml')" /&gt;
 &lt;/xsl:element&gt;
&lt;/xsl:template&gt;
When applied to an xml document that only contains an empty hotel element, such as codice_156the result tree will add a new element called amenityList, and place all the content from amenity.xml (except the XML declaration) in it. The document function can take many other parameters such as a remote URI, and a node-set, just to name a few. For more information on using codice_141, visit http://www.w3.org/TR/xslt#document
XSL-FO.
XSL-FO stands for Extensible Stylesheet Language Formatting Objects and is a language for formatting XML data. When it was created, XSL was originally split into two parts, XSL and XSL-FO. Both parts are now formally named XSL. XSL-FO documents define a number of rectangular areas for displaying output. XSL-FO is used for the formatting of XML data for output to screen, paper or other media, such as PDF format. For more information, visit http://www.w3schools.com/xslfo/default.asp
Reference Section.
Exhibit 36: XSL Elements 
Exhibit 37: XSLT Functions 
Exhibit 38: Inherited XPath Functions 
"Node Set Functions"
"String Functions"
"Number Functions"
" Boolean Functions"
Exercises.
In order to learn more about XSL and stylesheets, exercises are provided.
Answers.
In order to learn more about XSL and stylesheets, answers are provided.