[Accessibility conventions are described at the bottom of the page]
*** This is a free preview excerpt of a commercial publication. ***
2. Getting started with XSLT and XPath
[> 3.][< 1.2.7][^^^]
2.0 Getting started
[> 2.1][> 3.][< 2.][^^][^^^]
A few simple transformations:
[[1] - using Saxon
[[2] - Saxon 6.5.5 (and later) support XSLT 1.0
[2] - Saxon 9 (and later) support XSLT 2.0 and XQuery 1.0
][1] - using Internet Explorer 5 or greater
[[2] - for IE5, the updated MSXML processor (at least the third Web Release of March 2000) is needed to support the W3C XSLT 1.0
Recommendation
[2] - the IE6 production release supports the W3C XSLT 1.0 Recommendation
]]
Dissect example transforms
[[1] - identify transform components as an introduction to basic concepts covered in more detail in the later chapters
]
This material has a number of handy references harvested from the specification documents:
[[1] - [XSLT 1.0 element summary - Section C.1.1]
[1] - [XPath 1.0 and XSLT 1.0 function summary - Section C.1.2]
[1] - [XPath 1.0 grammar productions - Section C.1.3]
[1] - [XSLT 1.0 grammar productions - Section C.1.4]
[1] - [XSLT 2.0 element summary - Section C.2.1]
[1] - [XPath 2.0 and XSLT 2.0 function summary - Section C.2.2]
[1] - [XPath 2.0 grammar productions - Section C.2.3]
[1] - [XSLT 2.0 grammar productions - Section C.2.4]
]
2.1 Transform examples
[> 2.2][< 2.0][^^][^^^]
2.1.1 Some simple examples
[> 2.2][> 3.][< 2.0][^^][^^^]
[Example 2-1:
The first sample instance in XML 1.0 (modified)
Consider the following XML file hello.xml obtained from the XML 1.0 Recommendation and modified to declare an associated stylesheet:
01 <?xml version="1.0"?>
02 <?xml-stylesheet type="text/xsl" href="hello.xsl"?>
03 <greeting>Hello world.</greeting>
]
This is the complete logical tree of the entire instance:
[Figure 2.1: The nodes of the stylesheet tree
A tree of nodes is shown with the root node at the top with two children. The first is a processing-instruction node with
the name "xml-stylesheet" and the value "type="text/xsl" href="hello.xsl"". The second is an element node named "greeting" in no namespace. Attached to the element node is a namespace node with the name "xml" and the value "http://www.w3.org/XML/1998/namespace". A child of the element is a text node with the value "Hello world.".
]
Note that there is no node in the tree created by the XML Declaration
[[1] - the XML Declaration is a syntactic signal in an XML instance regarding the encoding and version of XML being used
[1] - it is consumed by the XML processor as part of the parsing process and is not delivered to an application
]
[Example 2-2:
An implicitly-declared simple stylesheet
Consider the following XSLT file hellohtm.xsl to produce HTML, noting how much it looks like an HTML document yet contains XSLT instructions:
01 <?xml version="1.0"?>
02 <!--hellohtm.xsl-->
03 <!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
04 <html xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
05 xsl:version="1.0">
06 <head><title>Greeting</title></head>
07 <body><p>Words of greeting:<br/>
08 <b><i><u><xsl:value-of select="greeting"/></u></i></b>
09 </p>
10 </body>
11 </html>
12
]
[Example 2-3: Explicit invocation of [Example 2-2]
Using an MSDOS command line invocation to execute the stand-alone processor explicitly with a supplied stylesheet, we see
the following result:
01 C:\ptux\samp>java -jar ../prog/saxon.jar hello.xml hellohtm.xsl
02 <html>
03 <head>
04 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
05 <title>Greeting</title>
06 </head>
07 <body>
08 <p>Words of greeting:<br><b><i><u>Hello world.</u></i></b></p>
09 </body>
10 </html>
11 C:\ptux\samp>
]
Note how the end result contains a mixture of the stylesheet markup and the source instance content, without any use of the
XSLT vocabulary. The processor has recognized the use of HTML by the type of the document element and has engaged SGML markup
conventions.
The <meta> element on line 4 added by Saxon is ensuring the character set of the web page is properly recognized by conforming user
agents.
[Example 2-4:
An explicitly-declared simple stylesheet
Consider next the following XSLT file hello.xsl to produce XML output using the HTML vocabulary, where the output is serialized as XML:
01 <?xml version="1.0"?><!--hello.xsl-->
02 <!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
03
04 <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
05 version="1.0">
06
07 <xsl:output method="xml" omit-xml-declaration="yes"/>
08
09 <xsl:template match="/">
10 <b><i><u><xsl:value-of select="greeting"/></u></i></b>
11 </xsl:template>
12
13 </xsl:transform>
]
Remember that the syntax of the transform does not represent the syntax of the result, only the nodes of the result; the following
is the node tree (not showing attribute and namespace nodes) of the stylesheet:
[Figure 2.2: The nodes of the XSLT stylesheet tree
A tree of element nodes is shown with the node with the local name "transform" at the top, with two child nodes: "output"
and "template". The "template" child has one child node named "b", that has a child node named "i", that has a child node
named "u" that has a child node named "value-of". The namespace of the "b", "i" and "u" nodes is the empty string. The namespace
of the instructions is "http://www.w3.org/1999/XSL/Transform". Root, attribute and namespace nodes are not shown. The "output",
"template" and "value-of" nodes are crossed to indicate they are instruction elements. The "b", "i" and "u" elements are double-circled
to indicate they are literal result elements.
]
The node tree constructed using the [stylesheet] ([Figure 2.2]) on the [source] ([Figure 2.1]) is:
[Figure 2.3: The nodes of the result tree
A tree of only four nodes is shown with the node with the local name "b", that has a child node named "i", that has a child
node named "u" that has a child text node named with the text "Hello world.". The namespace of the "b", "i" and "u" nodes
is the empty string. Root and namespace nodes are not shown. The element nodes are double-ringed circles, indicating they
come from the operation tree. The text node is a single-ringed circle, indicating it is calculated from the source node tree
information.
]
[[1] - note from the drawing conventions how the element nodes come from the operation node tree and the text node is calculated
from the source node tree information
]
[Example 2-5: Explicit request to use association that invokes [Example 2-4]
Using an MSDOS invocation to execute XSLT with the Saxon processor (with -o for the output file and -a to respect stylesheet association) we see the following tree serialization:
01 C:\ptux\samp>java -jar ../prog/saxon.jar -o hello.htm -a hello.xml
02
03 C:\ptux\samp>type hello.htm
04 <b><i><u>Hello world.</u></i></b>
05 C:\ptux\samp>
]
The result hello.htm file serialization of the constructed node tree can be viewed with a browser to see the results using the menu selection
View/Source to examine the content:
[Figure 2.4: A non-XML-aware browser viewing the source of a document
A screen shot of Netscape 3 showing the View/Source menu option behavior as a separate mini window revealing the HTML markup
of the "Hello world" HTML page.
]
Two ways of working with the Microsoft XSLT processor:
Using the msxml.bat invocation batch file (documented in detail in free download preview of on-line tutorial material) at an MSDOS command line
to execute the MSXML processor:
[Example 2-6:
Example invocation of the MSXML processor for [Example 2-4]01 C:\ptux\samp>..\prog\msxml hello.xml hello.xsl hello-ms.htm
02 Invoking MSXML....
03
04 C:\ptux\samp>type hello-ms.htm
05 <b><i><u>Hello world.</u></i></b>
06 C:\ptux\samp>
]
Using IE to directly view the file will show the interpreted result on the browser canvas, in such a way that the menu function
View/Source reveals the untouched XML:
[Figure 2.5: An XML-aware browser viewing the source of a document
A screen shot of IE6 showing the View/Source menu option behavior as a separate notepad window revealing the XML markup of
the "Hello world" XML file.
]
Other browsers support on-the-fly XSLT transformation
[[1] - not all browsers have XML processors that support all of the syntax features of XML
[[2] - e.g. lack of support for XML entities
]]
2.2 Syntax basics
[> 2.3][< 2.1.1][^^][^^^]
2.2.1 XSLT stylesheet requirements
[> 2.2.2][> 2.3][> 3.][< 2.1.1][^^][^^^]
An XSLT stylesheet:
[[1] - must identify the namespace prefix with which to recognize the XSLT vocabulary
[[2] - a typical namespace declaration attribute declares a particular URI for a given prefix:
[[3] - xmlns:prefix="http://www.w3.org/1999/XSL/Transform"
[3] - as a common practice the prefix "xsl" is used to identify the XSLT vocabulary, though this is not mandatory
[[4] - historically this is because XSLT was first published as one chapter of the XSL specification
[4] - all of the examples for XSL were written with "xsl:" and remained after XSLT was spun off as its own specification
][3] - the default namespace should not be used to identify the XSLT vocabulary
[[4] - technically possible for elements of the vocabulary, but doing so prevents XSLT vocabulary attributes to be used wherever
possible
[4] - not an issue for small stylesheets, but a maintenance headache if a large stylesheet needs to begin using XSLT attributes
]][2] - extensions beyond the XSLT recommendation are outside the scope of the XSLT vocabulary so must use another URI for such constructs
][1] - must also indicate the version of XSLT required by the stylesheet
[[2] - this dictates the data model rules for building of the source tree based on XPath 1 or XPath 2
[2] - also engages the incompatible version-specific behavior of the processor for certain instructions
[2] - [T2.0]using "1.0" for XSLT 2.0 either engages backwards-compatible behavior or signals an error and does not execute the transformation
[2] - in the start tag of an a element in the XSLT namespace
[[3] - version="version-number"
[3] - attributes not in any namespace that are attached to an element in the XSLT namespace are regarded as being in the XSLT namespace
][2] - in the start tag of an element not in the XSLT namespace
[[3] - prefix:version="version-number"
]]]
2.2.2 XSLT instructions and literal result elements
[> 2.2.3][> 2.3][> 3.][< 2.2.1][^][^^][^^^]
An XSLT instruction:
[[1] - is detected in the stylesheet tree only
[[2] - not recognized if used in the source tree
[2] - instruction defined by the XSLT recommendation and specified using the prefix associated with the XSLT URI
][1] - may be a control construct
[[2] - the wrapper and top-level elements
[2] - procedural and process-control instructions
[2] - logical and physical stylesheet maintenance facilities
][1] - may be a construction construct
[[2] - synthesis of result tree nodes
[2] - copying of nodes from a source node tree
][1] - may be a text value placeholder
[[2] - any calculated value using <[xsl:value-of]> is replaced in situ
[2] - <xsl:value-of select="greeting"/>
[2] - this example instruction calculates the concatenation of all text portions of all descendents of the first of the selected
points in the source tree
[2] - the select= attribute is an expression specifying the point in the source tree or, more generally, the outcome of an arbitrary expression
evaluation which in this case is a node set
[2] - the value "greeting" indicates the name of a direct element child node of the current source tree focus, which at the time of execution in this
example is the root of the document (hence <greeting> must be the document element)
][1] - may be a custom extension
[[2] - a non-standardized instruction implemented by the XSLT processor
[2] - implements extensibility
[[3] - standardized fallback features allow any conforming XSLT processor to still interpret a stylesheet that is using extensions
][2] - specified using a namespace prefix associated with a URI known to the processor
]]
A literal result element:
[[1] - any element not recognized to be an instruction
[[2] - used in stylesheet file
[2] - any vocabulary that isn't a declared instruction vocabulary
][1] - represents a result-tree node
[[2] - element and its associated attributes are to be added to the result
]]
2.2.3 XSLT templates and template rules
[> 2.2.4][> 2.3][> 3.][< 2.2.2][^][^^][^^^]
An XSLT template (a.k.a. "sequence constructor" in XSLT 2.0):
[[1] - specifies a fragment for constructing the result tree as a tree of nodes
[[2] - see the nodes in [Figure 2.2]
][1] - expressed in syntax as a well-formed package of markup
[[2] - may or may not include XSLT instructions
][Example 2-7: Simple template in [Example 2-4]01 <b><i><u><xsl:value-of select="greeting"/></u></i></b>
]
[1] - a representation of the desired nodes to add to the result tree
[1] - the XSLT processor recognizes any constructs therein from the XSLT vocabulary as XSLT instructions and acts on them
[[2] - regards all other constructs not from the XSLT vocabulary as literal result elements that comprise a representation of a tree
fragment to add to the result tree
]]
An XSLT template rule:
[[1] - a result tree construction rule associated with source tree nodes
[[2] - specifies the template to add to the result tree when processing a source tree node
[2] - a "matching pattern" describes the nodes of the source tree
[2] - see [Figure 1.4]
][Example 2-8:
Simple template rule using the simple example template01 <xsl:template match="/">
02 <b><i><u><xsl:value-of select="greeting"/></u></i></b>
03 </xsl:template>
]
[1] - prepares the XSLT processor for building a portion of the result tree whenever the stylesheet asks the processor to visit
the given source tree node
[1] - uses the match= attribute as a "pattern" describing the characteristics of the source tree node associated with the given template
[[2] - the pattern value "/" indicates the root of the source document (distinct from and the hierarchical parent of the document element of the source
document, therefore, the very top of the hierarchy)
][1] - a traditional stylesheet must declare all the stylesheet writer's template rules to be used by the XSLT processor
[1] - a simplified stylesheet defines in its entirety the one and only template rule for the stylesheet, that being for the root
node
]
XSLT processor first visits the source tree root node:
[[1] - the root node template rule begins the construction of the result tree
[1] - all subsequent construction is controlled by the stylesheet
]
[T2.0]Can begin processing at a specified named template or mode at invocation
[[1] - source tree is optional when starting at an arbitrary rule
]
2.2.4 XSLT stylesheet components
[> 2.3][> 3.][< 2.2.3][^][^^][^^^]
A "simplified" XSLT stylesheet:
[[1] - can be declared inside an arbitrary XML document (e.g. an XHTML document) by using namespace declarations for XSLT constructs
found within
[1] - the entire stylesheet file is a template for the entire result tree
[[2] - regarded as the template rule for the root node
][1] - identifiable components of this implicitly declared XSLT script:
]
[Figure 2.6: Components of a Simplified Stylesheet
The following file is depicted as lines of text:
<?xml version="1.0"?><!--hellohtm.xsl-->
<!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xsl:version="1.0">
<head><title>Greeting</title></head>
<body>Words of greeting:<br/>
<b><i><u><xsl:value-of select="greeting"/></u></i></b>
</body>
</html>
Various bubbles point to portions of the file. The top line is the XML declaration the remainder of the lines make up the
result tree template. Elements prefixed with "xsl:" are instructions while other elements are "literal result elements". The namespace declaration for XSLT and the version
attribute are highlighted with a bubble as well.
]
A more traditional stylesheet:
[[1] - can be written as an entire XML document (or embedded fragment in an XML document) by using a stylesheet document element
as the explicit container
[1] - traditional stylesheets can be utilized by other explicitly declared stylesheets
[1] - identifiable components of this traditional XSLT script:
]
[Figure 2.7: Components of a Traditional Stylesheet
The following file is depicted as lines of text:
<?xml version="1.0"?><!--hello-full.xsl-->
<!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<b><i><u><xsl:value-of select="greeting"/></u></i></b>
</xsl:template>
</xsl:transform>
Various bubbles point to portions of the file. The top line is the XML Declaration. The xsl:transform element is the document element. Children of the document element are labeled as "top-level elements". The xsl:template is labeled as a "template rule". The markup inside the template rule is labeled as a "result tree template". The same namespace
declaration, version, literal result elements and instructions are labeled as in the prior diagram.
]
2.3 Approaches to transform design
[> 2.4][< 2.2.4][^^][^^^]
2.3.1 Pull and push constructs
[> 2.4][> 3.][< 2.2.4][^^][^^^]
Consider for illustration an XML file containing sale and purchase information maintained chronologically, thus in an arbitrary
order:
<chrono-info>
<purchase>...</purchase>
<sale>...</sale>
<sale>...</sale>
<purchase>...</purchase>
<sale>...</sale>
<purchase>...</purchase>
</chrono-info>
How one approaches accessing the information to create the result tree varies
[[1] - one can pull the information out of the source node tree
[1] - one can push the information from the source node tree at the stylesheet
]
Pulling the input data and repositioning in the tree
[[1] - the hierarchy of the source file is known by the transform writer
[1] - at the point of building "the next" part of the result tree
]
The transform "pulls" information as and when needed:
[[1] - from known locations in the source node tree
[1] - for extraction or calculation using the lexical value
[[2] - <xsl:value-of select="string(XPath-expression)"/>
][1] - for extraction or calculation using the schema-qualified value
[[2] - <xsl:value-of select="XPath-expression"/>
][1] - for wholesale copying of source tree nodes
[[2] - <xsl:copy-of select="XPath-expression"/>
][1] - for repositioning over a sequence of arbitrary locations or values of any data type
[[2] - <xsl:for-each select="XPath-node-set-expression">
...template...
</xsl:for-each>
[2] - [T2.0] <xsl:for-each select="XPath-sequence-expression">
...template...
</xsl:for-each>
]]
Transform-determined result order implements direct document construction
[[1] - the result tree is built by the transform obtaining each result component from the source, in result order, and framing each
component as required with literal markup from the transform
[1] - if the result can be described as a single template using only the "pull" instructions, the transform can be simply declared
as a single result template
]
Pull example
[[1] - to process all of the sales records together, followed by all of the purchase records together, they are pulled from the source
tree one set before the others:
[[2] - <xsl:template match="chrono-info">
<sale-purchase-summary>
<xsl:for-each select="sale">
...template for the sale...
</xsl:for-each>
<xsl:for-each select="purchase">
...template for the purchase...
</xsl:for-each>
</sale-purchase-summary>
</xsl:template>
][1] - each address "sale" and "purchase" will respectively find all <sale> and <purchase> child elements of <chrono-info>
[1] - the order of the two instructions will construct the result tree by adding one template for each of the sale elements until
all sale elements have been addressed, followed then by adding one template for each of the purchase elements until all purchase
elements have been addressed:
[[2] - <sale-purchase-summary>
...result construction for sale...
...result construction for sale...
...result construction for sale...
...result construction for purchase...
...result construction for purchase...
...result construction for purchase...
</sale-purchase-summary>
]]
Recall the input elements shown on [Pull and push constructs - Section 2.3.1 Pull and push constructs]
Pushing the input data and repositioning in the tree
[[1] - arbitrary or unexpected source structure
[[2] - the structure of the source file is not in either an expected or explicit order
[2] - source file order must be accommodated by transformation
][1] - to process all of the records in the order they appear in the document, they are pushed through the transform logic while
specifying the union of all such nodes
]
XSLT stylesheets:
[[1] - the stylesheet "pushes" nodes of information at the template rules:
[[2] - visits known (using names) or unknown (using a wild card) source tree nodes
[2] - <xsl:apply-templates select="XPath-node-expression">
][1] - template rules respond to node visitations by constructing the result tree:
[[2] - <xsl:template match="XPath-pattern">
]]
Source-determined result order implements indirect tree construction
[[1] - the <xsl:apply-templates> instruction is the event generators
[[2] - selects the source information the processor is to visit
][1] - the <xsl:template> template rule is the event handler
[[2] - the type of event described as a qualification of the source information in the match= attribute
]]
Note it is not necessary to exclusively use one approach or the other
[[1] - transforms alternately push some of the input data through the processor (data driven) and pull the same or other input data
where required (transform driven)
[1] - the pulling of data that is relative to the data being pushed can be done in the template catching the data being pushed
]
Push example
[[1] - using XSLT:
[[2] - <xsl:template match="chrono-info">
<sale-purchase-summary>
<xsl:apply-templates select="sale | purchase"/>
</sale-purchase-summary>
<xsl:template>
][1] - where each construct being pushed must somehow be handled by the stylesheet:
[[2] - <xsl:template match="sale">...template...</xsl:template>
<xsl:template match="purchase">...template...</xsl:template>
][1] - each address "sale" and "purchase" will respectively find all <sale> and all <purchase> elements in the source tree, but the union operator "|" will return the set of all those nodes in document order which may very well be interleaved
[1] - the order of the two result expressions is irrelevant because each result expression will be triggered only by the kind of
node being matched
[1] - this will construct the result tree by adding one template for each of the sale elements and purchase elements in the document
order encountered in the source tree:
[[2] - <sale-purchase-summary>
...result construction for purchase...
...result construction for sale...
...result construction for sale...
...result construction for purchase...
...result construction for sale...
...result construction for purchase...
</sale-purchase-summary>
]]
Recall the input elements shown on [Pull and push constructs - Section 2.3.1 Pull and push constructs]
Contrast the result with that of the pull approach on [Pull and push constructs - Section 2.3.1 Pull and push constructs]
2.4 More transform examples
[> 3.][< 2.3.1][^^][^^^]
2.4.1 Processing XML with many transforms
[> 3.][< 2.3.1][^^][^^^]
[Example 2-9: Sample product sales source information
Consider the data file prod.xml containing some sales data information:
01 <?xml version="1.0"?><!--prod.xml-->
02 <!DOCTYPE sales [
03 <!ELEMENT sales ( products, record )> <!--sales information-->
04 <!ELEMENT products ( product+ )> <!--product record-->
05 <!ELEMENT product ( #PCDATA )> <!--product information-->
06 <!ATTLIST product id ID #REQUIRED>
07 <!ELEMENT record ( cust+ )> <!--sales record-->
08 <!ELEMENT cust ( prodsale+ )> <!--customer sales record-->
09 <!ATTLIST cust num CDATA #REQUIRED> <!--customer number-->
10 <!ELEMENT prodsale ( #PCDATA )> <!--product sale record-->
11 <!ATTLIST prodsale idref IDREF #REQUIRED>
12 ]>
13 <sales>
14 <products><product id="p1">Packing Boxes</product>
15 <product id="p2">Packing Tape</product></products>
16 <record><cust num="C1001">
17 <prodsale idref="p1">100</prodsale>
18 <prodsale idref="p2">200</prodsale></cust>
19 <cust num="C1002">
20 <prodsale idref="p2">50</prodsale></cust>
21 <cust num="C1003">
22 <prodsale idref="p1">75</prodsale>
23 <prodsale idref="p2">15</prodsale></cust></record>
24 </sales>
]
Of note:
[[1] - each product is identified with id= declared to be of type ID
[[2] - permits the element to be addressed with a unique identifier
][1] - there is no total information, only information about each product sale
[1] - the product names are not duplicated
[[2] - the product information is referenced using idref= from the product sale
]]
The equivalent set of document constraints on the logical hierarchy expressed using W3C Schema could be in prod.xsd:
[Example 2-10: A schema expression for product information01 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
02 <xsd:element name="sales">
03 <xsd:complexType>
04 <xsd:sequence>
05 <xsd:element name="products">
06 <xsd:complexType>
07 <xsd:sequence>
08 <xsd:element name="product" maxOccurs="unbounded">
09 <xsd:complexType mixed="true">
10 <xsd:attribute name="id" type="xsd:ID"/>
11 </xsd:complexType>
12 </xsd:element>
13 </xsd:sequence>
14 </xsd:complexType>
15 </xsd:element>
16 <xsd:element name="record">
17 <xsd:complexType>
18 <xsd:sequence>
19 <xsd:element name="cust" maxOccurs="unbounded">
20 <xsd:complexType>
21 <xsd:sequence>
22 <xsd:element name="prodsale" maxOccurs="unbounded">
23 <xsd:complexType>
24 <xsd:simpleContent>
25 <xsd:extension base="xsd:integer">
26 <xsd:attribute name="idref" type="xsd:IDREF"/>
27 </xsd:extension>
28 </xsd:simpleContent>
29 </xsd:complexType>
30 </xsd:element>
31 </xsd:sequence>
32 <xsd:attribute name="num" type="xsd:string"/>
33 </xsd:complexType>
34 </xsd:element>
35 </xsd:sequence>
36 </xsd:complexType>
37 </xsd:element>
38 </xsd:sequence>
39 </xsd:complexType>
40 </xsd:element>
41 </xsd:schema>
]
[[1] - note the declaration of prodsale is an integer value
[1] - note the ID/IDREF relationships expressed between id= and idref=
]
The hint that a particular W3C Schema applies to a document is given via reserved attributes
[[1] - a processor is not obliged to use the hints
]
The following document has a self-referential consistency error that will not be detected unless schema validation is turned
on:
[[1] - note how customer C1003 has a product sale pointing to a non-existent product
]
In addition, the ID/IDREF relationships are not recognized unless schema validation is turned on:
[[1] - any built-in facilities for supporting ID-typed attributes are not engaged
]
[Example 2-11: A document in error01 <?xml version="1.0"?><!--prod-bad.xml-->
02 <sales xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
03 xsi:noNamespaceSchemaLocation="prod.xsd">
04 <products><product id="p1">Packing Boxes</product>
05 <product id="p2">Packing Tape</product></products>
06 <record><cust num="C1001">
07 <prodsale idref="p1">100</prodsale>
08 <prodsale idref="p2">200</prodsale></cust>
09 <cust num="C1002">
10 <prodsale idref="p2">50</prodsale></cust>
11 <cust num="C1003">
12 <prodsale idref="p1">75</prodsale>
13 <prodsale idref="p3">15</prodsale></cust></record>
14 </sales>
]
Recall the sample data on [Example 2-9]
[[1] - very dissimilar reports could be generated for the one data file by using different transforms:
]
[Figure 2.8: Different HTML results from the same XML source
Two Netscape screens are shown. The one on the left shows a table of the customer information (left most column is customer
number, then one column for each of the products "Packing Boxes" and "Packing Tape". A "Totals" row shows the sum of each
product.
The one on the right shows the same information as a list instead of a table. Customer numbers and product names are duplicated
as required to show a total of 5 lines, one for each of the sales.
]
Of note:
[[1] - items are rearranged from one authored order to two different presentation orders
[1] - transformation includes calculation of sum of marked up values
]
Recall the sample data on [Example 2-9]
[[1] - any result vocabulary can be used; for example, WML rendered on a mobile device:
]
[Figure 2.9: A WML result from the XML source
Four images of a WAP phone are shown, each with a portion of the content. The top left shows a menu of the three customers.
The other panes show the sales summary of each customer, with a total of the number of items and amount of product.
]
[Example 2-12:
Tabular presentation of the sample product sales source information
The simplified stylesheet prod-pull.xsl for the table ([Figure 2.8]) for the XML ([Example 2-9]):
01 <?xml version="1.0"?><!--prod-pull.xsl-->
02 <!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
03 <html xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
04 xsl:version="1.0">
05 <head><title>Product Sales Summary</title></head>
06 <body><h2>Product Sales Summary</h2>
07 <table summary="Product Sales Summary" border="1">
08 <!--list products-->
09 <tr align="center"><th/>
10 <xsl:for-each select="//product">
11 <th><b><xsl:value-of select="."/></b></th>
12 </xsl:for-each></tr>
13 <!--list customers-->
14 <xsl:for-each select="/sales/record/cust">
15 <xsl:variable name="customer" select="."/>
16 <tr align="right">
17 <td><xsl:value-of select="@num"/></td>
18 <xsl:for-each select="//product"> <!--each product-->
19 <td><xsl:value-of select="$customer/prodsale
20 [@idref=current()/@id]"/>
21 </td></xsl:for-each>
22 </tr></xsl:for-each>
23 <!--summarize-->
24 <tr align="right"><td><b>Totals:</b></td>
25 <xsl:for-each select="//product">
26 <xsl:variable name="pid" select="@id"/>
27 <td><i><xsl:value-of
28 select="sum(//prodsale[@idref=$pid])"/></i>
29 </td></xsl:for-each></tr>
30 </table>
31 </body></html>
]
Information added from the stylesheet and pulled from the source document:
[[1] - the header and body title are hardwired content from stylesheet
[1] - the table's header row comes from each product name in source
[1] - the customer information is visited to produce rows (note use of variable)
[[2] - sale information produces columns
][1] - total information is generated by stylesheet using sum() built-in function (no custom node-traversal programming needed)
]
[Example 2-13: List-oriented presentation of the sample product sales source information
The traditional stylesheet prod-push.xsl for the list ([Figure 2.8]) for the XML ([Example 2-9]):
01 <?xml version="1.0"?><!--prod-push.xsl-->
02 <!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
03 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
04 version="1.0">
05
06 <xsl:template match="record"> <!--processing for each record-->
07 <ul><xsl:apply-templates/></ul></xsl:template>
08
09 <xsl:template match="prodsale"> <!--processing for each sale-->
10 <li><xsl:value-of select="../@num"/> <!--use parent's attr-->
11 <xsl:text> - </xsl:text>
12 <xsl:value-of select="id(@idref)"/> <!--go indirect-->
13 <xsl:text> - </xsl:text>
14 <xsl:value-of select="."/></li></xsl:template>
15
16 <xsl:template match="/"> <!--root rule-->
17 <html><head><title>Record of Sales</title></head>
18 <body><h2>Record of Sales</h2>
19 <xsl:apply-templates select="/sales/record"/>
20 </body></html></xsl:template>
21
22 </xsl:stylesheet>
]
Source document is pushed through the stylesheet:
[[1] - the order of the template rules is irrelevant
[[2] - only one node is being pushed at the stylesheet, so only one template responds
][1] - the header and body title are hardwired content from stylesheet
[1] - the root rule pushes all sales records through the stylesheet
[1] - each record produces the <ul> unordered list wrapper for list items and pushes child elements through the stylesheet
[1] - each child element pushed through produces a list item that pulls information from the parent and from an arbitrary place
of the source
]
An importing stylesheet can exploit the template rule fragmentation
[[1] - another stylesheet can import this stylesheet and specialize the behavior of any top-level construct
[1] - an overriding definition of any template rule will take precedence over that rule in the above transformation
]
[Example 2-14: Card-oriented presentation of the sample product sales source information
The traditional stylesheet prod-wml.xsl for the WML ([Figure 2.9]) and XML ([Example 2-9]):
01 <?xml version="1.0"?><!--prod-wml.xsl-->
02 <!--XSLT 1.0 - http://www.CraneSoftwrights.com/training -->
03 <xsl:stylesheet version="1.0"
04 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
05 <xsl:output doctype-system="http://CRANE/wml13.dtd"/>
06
07 <xsl:template match="/"> <!--root rule-->
08 <wml><card title="Record of Sales"> <!--index card-->
09 <p><em>Record of Sales</em></p>
10 <p><select name="cards">
11 <xsl:apply-templates mode="head"
12 select="/sales/record/cust"/>
13 </select></p></card>
14 <xsl:apply-templates select="/sales/record/cust"/>
15 </wml></xsl:template>
16
17 <xsl:template match="cust" mode="head"><!--index entry-->
18 <option onpick="#{@num}">
19 <xsl:text/>Customer <xsl:value-of select="@num"/>
20 </option></xsl:template>
21
22 <xsl:template match="cust"><!--customer's card in deck-->
23 <card id="{@num}" title="Customer {@num}">
24 <p><em><xsl:value-of select="@num"/></em></p>
25 <p>Items: <xsl:value-of select="count(prodsale)"/></p>
26 <p>Total: <xsl:value-of select="sum(prodsale)"/></p>
27 <xsl:apply-templates/></card></xsl:template>
28
29 <xsl:template match="prodsale"><!--proc for each sale-->
30 <p><xsl:value-of select="id(@idref)"/> <!--indirect-->
31 <xsl:text> - </xsl:text>
32 <xsl:value-of select="."/></p></xsl:template>
33
34 </xsl:stylesheet>
]
Source document is pushed through the stylesheet:
[[1] - the same source is visited twice using different template rules for processing to produce different results
]
An importing stylesheet can exploit the template rule fragmentation
[[1] - another stylesheet can import this stylesheet and specialize the behavior of any top-level construct
[1] - an overriding definition of any template rule will take precedence over that rule in the above transformation
]
*** This is a free preview excerpt of a commercial publication. ***
This is an accessible version of Crane's commercial training material.
The content has been specifically designed to assist screen reader software
in viewing the entire textual content. Figures are replaced with text
narratives.
Navigation hints are in square brackets:
[Tx.x] and [Fx.x] are textual representations of the applicability icons;
[digit] indicates list depth for nested lists;
[link [URL]] indicates the URL of a hyperlink if different than link;
[EXAMPLE] indicates an example listing of code;
[FIGURE] indicates the presence of a figure replaced by its description;
[>] jumps forward;
[<] jumps backward;
[^] jumps to start of the section;
[^^] jumps to the start of the chapter;
[^^^] jumps to the table of contents.
Suggestions for improvement are welcome:
[info@CraneSoftwrights.com]
Book sales: [http://www.CraneSoftwrights.com/links/trn-acc.htm]
Information: [http://www.CraneSoftwrights.com/links/info-acc.htm]
This content is protected by copyright and, as there are no means to protect
this accessible version from plagiarism, please do not make any
commercial edition available to others.
+//ISBN 978-1-894049::CSL::Courses::PTUX//DOCUMENT Practical Transformation Using XSLT and XPath 2011-02-11 21:00UTC//EN
Practical Transformation Using XSLT and XPath
Fourteenth Edition - 2011-02-11
ISBN 978-1-894049-24-5
Copyright © Crane Softwrights Ltd.