aspnet xml
TRANSCRIPT
-
7/30/2019 aspnet xml
1/59
CHAPTER
7Transforming XML with XSLTand ASP.NET
IN THIS CHAPTER
What Is XSLT? 234
The Transformation Process 235
Getting Your Feet Wet with XSLT 237
The XSLT Language 242
XSLT Functions 267
.NET Classes Involved in Transforming XML 272
Creating a Reusable XSLT Class 287
-
7/30/2019 aspnet xml
2/59
XML for ASP.NET Developers234
What Is XSLT?During the development of the XML specification, the W3C working group realized that for
XML to reach its full potential, a method of transforming XML documents into different for-
mats needed to exist. At some time or another, an application that has the capability to work
with XML documents will need to display or structure the data in a different format than speci-
fied in the document. If the only method for accomplishing this task necessitates programmati-
cally transforming the XML document into the appropriate format by using an XML parser
paired with a programming language, the power of having a cross-platform and language-
independent XML language would be lost. Some method of transforming XML documentsinto different formats such as HTML, flat files, Wireless Markup Language (WML), and even
other forms of XML needed to be devised so that it could be used on any platform and with
any language.
To accommodate this transformation process, Extensible Stylesheet Language Transformations
(XSLT) was created. Version 1.0 of the XSLT specification reached recommended status at the
W3C in November of 1999 (http://www.w3.org/TR/1999/REC-xslt-19991116) and many
XML parsers now provide full XSLT support. The .NET framework provides 100% compli-
ance with the XSLT version 1.0 specification.
What exactly is XSLT useful for and why would you, as an ASP.NET developer, want to learnabout it? The answer boils down to the capability of XSLT to transform XML documents into
different formats that can be consumed by a variety of devices, including browsers, Personal
Digital Assistants (PDAs), Web-enabled phones, and other devices that will appear in the near
future.
Transformations can also be useful in situations where an XML documents structure does not
match up well with an application that will accept the data within the document. An XML doc-
ument may contain the appropriate data to be imported into a database, for example, but may
not be structured in a way that the application performing the import expects. For example, the
application may be better prepared to handle element-based XML documents rather than oneswith a lot of attributes, as shown in the following document:
Using XSLT, this document can be transformed into a structure that the application is better
suited to work with:
-
7/30/2019 aspnet xml
3/59
1
Dan
Wahlin
2
Heedy
Wahlin
3
Danny
Wahlin
4
Jeffery
Wahlin
This chapter teaches you how to perform this type of transformationas well as many
othersby covering the following topics:
The transformation process
The XSLT language
.NET classes involved in transforming XML
The Transformation Process
The process of transforming an XML document into another format, such as HTML or WML,relies on two types of processing engines. First, a parser capable of loading an XML document
must be present to load the source document into a DOM tree structure (for more information
about the DOM, refer to Chapter 6, Programming the Document Object Model (DOM) with
ASP.NET. Next, the XSLT document must be loaded and a tree structure will be created for it,
as well. This tree structure will normally be optimized to accommodate XSLT processing and
is specific to the processor being used. An XSLT processor is then needed to take the XML
document structure, match up nodes within the document against templates found in the
XSLT document, and then output the resulting document. The third tree structure (the resulting
document) is dynamically created based on information contained in the XSLT document. A
simple diagram of this transformation process is shown in Figure 7.1.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
235
-
7/30/2019 aspnet xml
4/59
XML for ASP.NET Developers236
XSLT Processor
XMLHTMLPDFWMLETC.
XML
XSLT
FIGURE 7.1The XSLT transformation process.
XSLT TemplatesBefore looking more closely at how to build XSLT documents, its important that you under-
stand what the building blocks of these documents are. Although XSLT stands for Extensible
Stylesheet Language Transformations, an alternative name for it could potentially be
Extensible Template Language Transformations. Why? The answer is because of its reliance on
templates to process and create a particular output structure. The W3C provides the following
statement about templates:
A stylesheet contains a set of template rules. A template rule has two parts: a pattern which is
matched against nodes in the source tree and a template which can be instantiated to form part
of the result tree. This allows a stylesheet to be applicable to a wide class of documents that
have similar source tree structures.
If you have ever used templates in Excel, Word, or PowerPoint, you know that they provide a
basic structure that can be reused for specific purposes. For example, every time you submit an
expense report, you may be accustomed to filling out a template in Word that is designed for
this purpose. The template likely has specific form fields built in so that every expense report
being submitted looks the same. There may be other templates that are used for purchaseorders. The point is that the templates are geared to match up with a specific task, such as cre-
ating an expense report, a purchase order, or some other activity.
Templates in XSLT function in much the same way, except that they are geared to match up
with nodes in an XML document. XSLT templates provide a way to process and structure data
contained within elements and attributes in the source XML document. Their basic purpose is
to provide a template structure that can be processed when a particular node in the source
XML document is discovered.
So how do templates work? The XSLT processor described earlier is provided with two tree
structures to walk through. The first is the structure for the source XML document and the
-
7/30/2019 aspnet xml
5/59
second is the XSLT document itself. After these two structures are provided, the XSLT proces-
sor attempts to match element or attribute names found in the XML document with templates
contained in the XSLT tree structure. This matching process uses XPath expressions that are
embedded within the XSLT document. When a node found within the XML document matches
a template in the XSLT document, that template is processed.
Processing of templates found within an XSLT document normally starts with a template that
matches the root node of the XML document and proceeds down to its children. When a tem-
plate is processed, the output is added to the third tree structure mentioned earlier that is used
in building the output document.
Templates offer an efficient way to process a variety of XML document structures and are very
efficient in cases where an XML document contains repetitive items. Each time an element,
attribute, text node, and so on is found, it is matched up with the appropriate template via
XPath expressions. If a given node does not have a matching template, no processing will
occur on it, and the next section of the XML document is processed. In cases where a match-
ing node is found, the template takes care of generating the proper output structure based on
data/nodes contained within the node.
So that you can see templates in action, the next section introduces you to a simple XSLT doc-
ument. The sections that follow describe in greater detail how to use templates and other parts
of the XSLT language.
Getting Your Feet Wet with XSLTIn this section well examine a simple XSLT document that transforms XML into HTML for
display in a browser. The sections that follow show how XSLT can transform XML into many
formats other than HTML. This example represents a common task that you will likely use
when developing ASP.NET applications that require the presentation of XML data within a
browser. Listing 7.1 shows an XML document that contains information about different
golfers.
LISTING 7.1 Golfers XML Document
1:
2:
3:
4:
5: Heedy
6: Wahlin
7:
8:
9:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
237
-
7/30/2019 aspnet xml
6/59
LISTING 7.1 continued
10:
11:
12:
13:
14:
15:
16: Dan
17: Wahlin
18:
19: 20:
21:
22:
23:
24:
25:
Listing 7.2 presents an XSLT document that can be used to transform the XML just shown into
HTML. The different elements used in this document are discussed later.
LISTING 7.2 Golfers XSLT Document
1:
2:
4:
5:
6:
7:
8:
9: .blackText {font-family:arial;color:#000000;}
10: .largeYellowText {font-family:arial;font-size:18pt;
11: color:#ffff00;}
12: .largeBlackText {font-family:arial;font-size:14pt;
13: color:#000000;}
14: .borders {border-left:1px solid #000000;
15: border-right:1px solid #000000;
16: border-top:1px solid #000000;
17: border-bottom:1px solid #000000;}
18:
19:
20:
21: Golfers:
XML for ASP.NET Developers238
-
7/30/2019 aspnet xml
7/59
LISTING 7.2 continued
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
33:
34:
35: Skill:
36:
37:
38:
39: Handicap:
40:
41:
42:
43: Clubs:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53: Favorite Courses
54: 55:
56:
57: City:
58: State:
59: Course:
60:
61:
62:
63:
64:
65:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
239
-
7/30/2019 aspnet xml
8/59
LISTING 7.2 continued
66:
67:
68:
69:
70:
71:
72:
73:
74:
75: 76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
To transform the XML document shown in Listing 7.1 using the XSLT document shown in
Listing 7.2, the code shown in Listing 7.3 can be used:
LISTING 7.3 Using the XslTransform Class
1:
2:
3:
4:
5: public void Page_Load(Object sender, EventArgs E) {
6: string xmlPath = Server.MapPath(listing7.1.xml);
7: string xslPath = Server.MapPath(listing7.2.xsl);
8:
9: //Instantiate the XPathDocument Class
10: XPathDocument doc = new XPathDocument(xmlPath);
11:
12: //Instantiate the XslTransform Class
13: XslTransform transform = new XslTransform();
14: transform.Load(xslPath);
XML for ASP.NET Developers240
-
7/30/2019 aspnet xml
9/59
LISTING 7.3 continued
15:
16: //Custom format the indenting of the output document
17: //by using an XmlTextWriter
18: XmlTextWriter writer = new XmlTextWriter(Response.Output);
19: writer.Formatting = Formatting.Indented;
20: writer.Indentation=4;
21: transform.Transform(doc, null, writer);
22: }
23:
On executing the code in Listing 7.3, the XML document will magically be transformed into
HTML that can be rendered in a browser. The result of this transformation is shown in
Figure 7.2.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
241
FIGURE 7.2Transforming an XML document into HTML.
The code shown in Listings 7.2 and 7.3 may look quite foreign to you at this point. Don t let
that worry you, though, because each portion of the code will be broken down to show how the
different pieces work together. In addition to covering the XSLT language, the examples that
follow also demonstrate XPath expressions as a point of review. For a detailed explanation of
XPath, refer to Chapter 3, XPath, XPointer, and XLink. Before examining the .NET classes
involved in transforming XML to other structures, lets first examine what pieces are involved
in constructing an XSLT document.
-
7/30/2019 aspnet xml
10/59
The XSLT LanguageNow that youve seen the transformation process and have been introduced to what an XSLT
document looks like, lets break the different parts used in the document into individual pieces.
First up: the XSLT document root element.
The XSLT Document Root ElementLooking back at Listing 7.2, youll notice that the document follows all the rules specified in
the XML specification described in Chapter 2, XML for ASP.NET Basics. The case of each
opening tag matches the case of the closing tag, all attributes are quoted, all tags are closed,and so on. XSLT documents are, in fact, well-formed XML documents. As a result, the first
line of each document should contain the XML declaration. Although this line is optional, its
essential that you get into the practice of using it, especially because new versions of the XML
specification will certainly be coming in the future.
Following the XML declaration, one of two elements specific to the XSLT language can be
used for the documents root node. These elements are the following:
Although you can use either element as the root of an XSLT document, the samples that follow
throughout this chapter use the xsl:stylesheet element. You can certainly substitute the
xsl:transform element instead if you feel more comfortable using it.
Two different items must also be included for an XSLT document to follow the guidelines
found in the XSLT specification. These are a local namespace declaration as well as an
attribute named version. The inclusion of the xsl:stylesheet element, the namespace decla-
ration, and the version attribute are shown next:
The namespace URI (http://www.w3.org/1999/XSL/Transform) must be listed exactly as
shown, and the version attribute must have a value of1.0 for the document to be conformant
with the November 1999 XSLT specification. As different versions of the specification are
released, this version number can be changed, depending on what features the XSLT document
XML for ASP.NET Developers242
-
7/30/2019 aspnet xml
11/59
uses. Failure to list these parts correctly will result in an error being returned by the XSLT
processor.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
243
XSLT ElementsIf youve had the opportunity to work with HTML in the past, youre already aware of how
elements are used to perform specific tasks. For example, the element can be used
along with the and elements to construct a table for display in a browser. The
element can be used when an image needs to be displayed, and the element can be
used as a container for different form elements such as text boxes and radio buttons. Each of
these elements have a specific purpose and when appropriate, can contain supporting child
elements.
The XSLT version 1.0 specification lists several elements that can be used to transform XMLdocuments. These elements can be used in a variety of ways, including determining the output
format, performing if/then type logic, looping, and writing out data within a node contained in
the XML document to the result tree structure. An XSLT element is distinguished from other
elements that may be within an XSLT document by its association with a namespace that
defines a URI ofhttp://www.w3.org/1999/XSL/Transform. Declaring this namespace on the
XSLT root element (xsl:stylesheet or xsl:transform) was shown in the previous section.
Table 7.1 contains a listing of all potential elements in version 1.0 of the XSLT specification.
Notice that each element is prefixed by the xsl namespace.
TABLE 7.1 XSLT Elements
XSLT Element Description
xsl:apply-imports Used in conjunction with imported style sheets to over-
ride templates within the source style sheet. Calls to
xsl:apply-imports cause an imported template with
lower precedence to be invoked instead of the source
style sheet template with higher precedence.
xsl:apply-templates When xsl:apply-templates is used, the XSLT proces-
sor finds the appropriate template to apply, based on the
type and context of each selected node.
XSLT version 1.1 was in Working Draft at the time this section was written. XSLT style
sheets that use new features found in this version will need to let the XSLT processor
know by changing the version attribute to 1.1.
NOTE
-
7/30/2019 aspnet xml
12/59
TABLE 7.1 continued
XSLT Element Description
xsl:attribute Creates an attribute node that is attached to an element
that appears in the output structure.
xsl:attribute-set Used when a commonly defined set of attributes will be
applied to different elements in the style sheet. This is
similar to named styles in CSS.
xsl:call-template Used when processing is directed to a specific template.
The template is identified by name.
xsl:choose Used along with the xsl:otherwise and xsl:when ele-
ments to provide conditional testing. Similar to using a
switch statement in C# or Select Case statement in
VB.NET.
xsl:comment Writes a comment to the output structure.
xsl:copy Copies the current node from the source document to
the result tree. The current nodes children are not
copied.
xsl:copy-of Used to copy a result-tree fragment or node-set into the
result tree. This performs a deep copy, meaning thatall descendants of the current node are copied to the
result tree.
xsl:decimal-format Declares a decimal-format that is used when converting
numbers into strings with the format-number() function.
xsl:element Creates an element with the specified name in the output
structure.
xsl:fallback Provides an alternative (or fallback) template when spe-
cific functionality is not supported by the XSLT proces-
sor being used for the transformation. This element
provides greater flexibility during transformations asnew XSLT versions come out in the future.
xsl:for-each Iterates over nodes in a selected node-set and applies a
template repeatedly.
xsl:if Used to wrap a template body that will be used only
when the if statement test returns a true value.
xsl:import Allows an external XSLT style sheet to be imported into
the current style sheet. The XSLT processor will give a
lower precedence to imported templates as compared to
templates in the original XSLT style sheet.
XML for ASP.NET Developers244
-
7/30/2019 aspnet xml
13/59
TABLE 7.1 continued
XSLT Element Description
xsl:include Allows for the inclusion of another XSLT style sheet
into the current style sheet. The XSLT processor gives
the same precedence to the included templates as tem-
plates in the original XSLT style sheet.
xsl:key Declares a named key and is used in conjunction with
the key() function in XPath expressions.
xsl:message Used to output a text message and optionally terminate
style sheet execution.
xsl:namespace-alias Used to map a prefix associated with a given namespace
to another prefix. This can be useful when a style sheet
generates another style sheet.
xsl:number Used to format a number before adding it to the result
tree or to provide a sequential number to the current
node.
xsl:otherwise Used with the xsl:choose and xsl:when elements to
perform conditional testing. Similar to using default in a
switch statement.
xsl:output Specifies options for use in serializing the result tree.
xsl:param Used to declare a parameter with a local or global
scope. Local parameters are scoped to the template in
which they are declared.
xsl:preserve-space Preserves whitespace in a document. Works in conjunc-
tion with the xsl:strip-space element.
xsl:processing-instruction Writes a processing instruction to the result tree.
xsl:sort Used with xsl:for-each or xsl:apply-templates to
specify sort criteria for selected node lists.
xsl:strip-space Causes whitespace to be stripped from a document.
Works in conjunction with the xsl:preserve-space
element.
xsl:stylesheet This element must be the outermost element in an XSLT
document and must contain a namespace associated
with the XSLT specification and a version attribute.
xsl:template Defines a reusable template for producing output for
nodes that match a particular pattern.
xsl:text Writes out the specified text to the result tree.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7 TRANSFORMING
XMLWITHXSLT
ANDASP.NET
245
-
7/30/2019 aspnet xml
14/59
TABLE 7.1 continued
XSLT Element Description
xsl:transform Used in the same manner as the xsl:stylesheet
element.
xsl:value-of Writes out the value of the selected node to the result
tree.
xsl:variable Used to declare and assign variable values that can be
either local or global in scope.
xsl:when Used as a child element ofxsl:choose to perform mul-tiple conditional testing. Similar to using case in a
switch or Select statement.
xsl:with-param Used in passing a parameter to a template that is called
via xsl:call-template.
Although not every element listed in Table 7.1 is discussed in this section, you will be exposed
to the more common elements and see how they can be used to transform XML into formats
such as HTML, WML, and even EDI.
XML for ASP.NET Developers246
The HTML generated by an XSLT document must conform to the rules outlined in the
XML specification. All elements must be closed, including , , and all the
other elements that normally do not need to be closed in HTML. Attributes used on
elements must be quoted, a beginning and ending element tags case must match,
and so on. Keep in mind that the XSLT processor knows how to work only with well-
formed XML and knows nothing about the tags used in HTML, WML, and so on. As a
result, everything within the XSLT document must follow the XML rules.
NOTE
Transforming to HTML Using XSLT ElementsOne of the best ways to learn about the different XSLT elements is to see them in action.
Listing 7.4 repeats the XSLT style sheet shown earlier in Listing 7.2 but adds additional func-
tionality. After looking through the code, youll see a step-by-step explanation of what the code
is doing.
LISTING 7.4 Golfers XSLT Document
1:
2:
-
7/30/2019 aspnet xml
15/59
LISTING 7.4 continued
3: version=1.0>
4:
5:
6:
7:
8:
9: .blackText {font-family:arial;color:#000000;}
10: .largeYellowText {font-family:arial;
11: font-size:18pt;color:#ffff00;}
12: .largeBlackText {font-family:arial;13: font-size:14pt;color:#000000;}
14: .borders {border-left:1px solid #000000;
15: border-right:1px solid #000000;
16: border-top:1px solid #000000;
17: border-bottom:1px solid #000000;}
18:
19:
20:
21:
22: List of
23: 0>
24: 25:
26:
27: Golfers
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
40:
41:
42:
43: Skill:
44:
45:
46:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
247
-
7/30/2019 aspnet xml
16/59
LISTING 7.4 continued
47:
48:
49: color:#ff0000;font-weight:bold;
50:
51:
52: color:#005300;
53:
54:
55: color:#000000;
56: 57:
58: color:#ffffff;
59:
60:
61:
62:
63:
64:
65: Handicap:
66:
67:
68: 69:
70:
71: Clubs:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82: Favorite Courses
83:
84:
85:
86:
87: City:
88:
89:
90: State:
91:
XML for ASP.NET Developers248
-
7/30/2019 aspnet xml
17/59
LISTING 7.4 continued
92:
93: Course:
94:
95:
96:
97:
98:
99:
100:
101: 102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113: 114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126: List Course Information
127:
128:
The following explanation walks through each element used in Listing 7.4.
Line 1:
1:
The XML declaration is used because this is a valid XML document.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
249
-
7/30/2019 aspnet xml
18/59
Lines 23:
2:
This line contains the first XSLT element used in the document: xsl:stylesheet. As shown
earlier, this element has an associated namespace declaration and version attribute. The
xsl:transform element could also be used here. One of these two elements will always be the
root node of the XSLT document.
Line 4:
4:
The xsl:output element is used to specify what type of format will be created in the result
tree. The method attribute can contain values ofxml, html, or text. This element is a top-level
element, meaning that it must be a child of the xsl:stylesheet element to be used properly.
The different attributes that can be used to describe this element are the following: method,
version, encoding, omit-xml-declaration, standalone, doctype-public, doctype-system,
cdata-section-elements, indent, media-type. This element includes the indent attribute,
which will indent the result tree to show its hierarchical structure. XSLT processors do not
have to honor the indentation request. If the processor does support indentation, the manner in
which the indentation is implemented is up to the processor.
Lines 533:
5:
6:
7:
8:
9: .blackText {font-family:arial;color:#000000;}
10: .largeYellowText {font-family:arial;
11: font-size:18pt;color:#ffff00;}
12: .largeBlackText {font-family:arial;
13: font-size:14pt;color:#000000;}
14: .borders {border-left:1px solid #000000;
15: border-right:1px solid #000000;
16: border-top:1px solid #000000;
17: border-bottom:1px solid #000000;}
18:
19:
20:
21:
22: List of
23: 0>
24:
25:
XML for ASP.NET Developers250
-
7/30/2019 aspnet xml
19/59
26:
27: Golfers
28:
29:
30:
31:
32:
33:
Heres an example of the first template definition specified in the XSLT document. Templates
contain structured information that will be processed and output to the result tree. They are
processed when the XPath pattern found in the match attribute matches a node found in thesource XML document.
This template has a match attribute with a value of/. The value (/) represents a pattern that
matches the XML document (think of it as the position directly above the root XML element).
The purpose of a pattern is to identify which nodes a template applies to. You can think of pat-
terns as valid XPath statements, although the XSLT definition does define them separately.
If the pattern specified in the match attribute matches a node in the source XML document, the
information located within the template will be processed and written out to the result tree. In
this case, when the XML document is matched, the basic elements used to start an HTML doc-
ument are added to the result tree.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
251
Its worth repeating that that the and elements contained within the
template are simply standard XML elements to the XSLT processor. It knows nothing
about HTML elements and simply cares that the elements follow the XML rules. Only
when processing has completed and the result tree is rendered in an application that
understands HTML tags, will the and elements have any presentation
purpose.
NOTE
The xsl:template element can have the attributes shown in Table 7.2.
TABLE 7.2 xsl:template Attributes
Attribute Name Description
match The match attributes value is a pattern defined by an XPath statement
that states which nodes in the source XML document should be
processed by the template it is associated with. Although optional, if this
attribute is not included, the name attribute shown next must be included.
-
7/30/2019 aspnet xml
20/59
TABLE 7.2 continued
Attribute Name Description
name Applies a name to a template. This attribute is used by xsl:call-
template. Although optional, if this attribute is not included, the match
attribute shown next must be included.
priority The value must be a number that says the priority of the template. The
priority attributes value will be taken into consideration if several tem-
plates match the same node.
mode Applies a mode to a template. The mode is simply a name that can be
used by the xsl:apply-templates element to hit a template that does aspecific form of transformation. For example, if you need a node named
chapter within an XML document to be processed differently, depend-
ing on its position within the document, you can create different tem-
plates that all match the chapter node. To differentiate the templates
from each other (because they have the same match attribute value) a
mode can be applied to each one. A call can then be made to the specific
template that needs to be processed by using the xsl:apply-templates
element and then specifying the template that has the desired mode.
Lines 2326:
23: 0>
24:
25:
26:
This portion of the XSLT document shows how the xsl:if element can be used to test a par-
ticular condition. In this case, an XSLT function named count() is used. This function takes
an XPath statement as input and returns the number of nodes as output. Youll learn more
about XSLT functions in the next section.
The xsl:if element must have an attribute named test, which converts a valid XPath state-ment to a Boolean. In this case, the test checks to see whether the number of golfer nodes
exceeds the value of 0. If the test returns true, the content (referred to as the template body)
between the xsl:if start and end tags is processed.
Line 25 contains the xsl:value-of element, which is used frequently in XSLT documents
to write out the value of a particular node to the result tree. This element must contain an
attribute named select. The value of the attribute must contain a valid XPath expression. The
node (or nodes) returned by the expression is converted to a string. In this case, the number of
golfer nodes within the XML document is returned and placed in the result tree structure.
XML for ASP.NET Developers252
-
7/30/2019 aspnet xml
21/59
The xsl:value-of element may optionally include an attribute named disable-output-
escaping that is useful when characters such as < or > need to be output without being escaped
by using < or >. The attribute accepts a value ofyes or no. Using it is especially useful
when an XML element contains HTML tags that need to be written to the result tree structure
without escaping the brackets.
Line 30:
30:
The xsl:apply-templates element provides a way to call templates that may match with
other items contained in the source XML document. Before explaining what this element doesin more detail, its appropriate to introduce a term called the context node. The context node is
defined as the source document node currently being processed by the XSLT processor as
specified by a template. Because we are processing the document node in the current template,
that node is considered the context node. Obviously, many other elements are below this node,
including golfers and golfer, that may also have templates associated with them. By using
xsl:apply-templates the XSLT code is saying (in more human terms), Find all templates
that match with child elements of the current node (the context node) and go out and process
them. The first child node that will be found is the root node of the source document
(golfers). The template that matches up with it is described next.
Lines 3436:
34:
35:
36:
The golfers node in the source XML document matches up with the template defined in these
lines of the XSLT document. As the XSLT processor is attempting to match templates with
nodes in the XML document, any node with a name ofgolfers will automatically be
processed by this template. Within the template, youll notice that the content is very sparse,
except for the inclusion of an xsl:apply-templates element. With the context node now
being the golfers node, calling xsl:apply-templates will send the processor looking fortemplates that match up with child nodes of the golfers node.
Youll notice that line 30 includes an attribute named select that applies to the xsl:apply-
templates element. This attribute accepts a valid XPath expression as a value. In this case, it
selects a template that matches up with a node named golfer. Because the golfers node con-
tains golfer nodes only as children, including this attribute is unnecessary and is shown only
to exemplify its use. If, however, the golfers node contained child nodes other than the
golfer node and we wanted the golfer node template to be processed first, the inclusion of
the select attribute would be more appropriate. This will become more clear as the next tem-
plate is discussed.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
253
-
7/30/2019 aspnet xml
22/59
Lines 3799:
37:
38:
40:
41:
42:
43: Skill:
44:
45:
46:
47:
48:
49: color:#ff0000;font-weight:bold;
50:
51:
52: color:#005300;
53:
54:
55: color:#000000;
56:
57:
58: color:#000000;59:
60:
61:
62:
63:
64:
65: Handicap:
66:
67:
68:
69:
70: 71: Clubs:
72:
73:
74:
75:
76:
77:
78:
79:
80:
XML for ASP.NET Developers254
-
7/30/2019 aspnet xml
23/59
81:
82: Favorite Courses
83:
84:
85:
86:
87: City:
88:
89:
90: State:
91:
92: 93: Course:
94:
95:
96:
97:
98:
99:
This template does the bulk of the work in Listing 7.4 by matching up with all golfer nodes in
the source XML document. When the template is processed, the shell structure for an HTML
table is written out. This table will be used to present all the information about a specific golfer.
Line 40 uses the xsl:apply-templatesand provides a pattern for the template that should be
called by using the select attribute. By providing a pattern equal to name, only a template that
matches up with the pattern will be processed. Why didnt we simply call xsl:apply-templates
and not worry about which of the context node s child node templates were called? The answer
is that we want to ensure that the template with a pattern matching the name child node is
processed before any other children of the context node (golfer, in this case).
After the template matching the name node is called, processing will be done on that template
and then return to the golfers template. Specifically, the XSLT processor will jump back to
the next statement in the golfer template that immediately follows the call to .
Lines 4674 exhibit several of the XSLT elements shown earlier in Table 7.1. To start things
off, line 46 contains an xsl:attribute element named style. This XSLT element adds a style
attribute to the tag in line 45. The value of the attribute is dynamically assigned based on
a series of conditional tests. To accomplish the tests, the xsl:choose, xsl:when, and xsl:
otherwise elements are used. These elements function in a manner similar to the switch,
case, and default keywords used when coding a switch statement in C#.
The conditional test starts with the xsl:choose element. It can be followed by as many
xsl:when elements, as needed. The xsl:when element must contain a mandatory attribute
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
255
-
7/30/2019 aspnet xml
24/59
named test that contains the expression to test. If the test returns true, the content between
the xsl:when starting and ending tags will be assigned to the value of the style attribute. The
test performed in line 48 checks to see whether an attribute of the context node (remember that
the context node is golfer at this point) named skill has a value equal to excellent. If it
does, the style attribute will have a value ofcolor:#ff0000;font-weight:bold;. Assuming
the skill attribute does have a value ofexcellent, the actual structure added on completion of
the xsl:choose block testing will be the following:
If the first xsl:when returns false, testing will continue down the line. If no xsl:when tests
return true, the xsl:otherwise block will be hit and the style attribute will be assigned a
value ofcolor:#000000; (lines 5759).
After the style attribute has been added to the tag, processing continues with line 62,
which adds the value of the skill attribute to the table column by using the xsl:value-of ele-
ment discussed earlier. Lines 6494 continue to add additional columns to the table and write
out the value of attributes found on the context node (the golfer node).
When processing in the golfers template completes, the xsl:apply-templates element is
again used along with a select attribute that points to a template pattern offavoriteCourses
(line 96). This template will be discussed later.
Lines 100107:
100:
101:
102:
103:
104:
105:
106:
107:
The template declaration shown in line 100 matches up with all name nodes found within theXML document. This template is called from within the golfer template discussed earlier (see
line 40). Processing of the template is limited to writing out a new row in the table (line 101)
followed by a column containing the values of the firstName and lastName elements. These
values are written to the result tree by using the xsl:value-of element(lines 103 and 104).
Lines 108127:
108:
109:
110:
111:
XML for ASP.NET Developers256
-
7/30/2019 aspnet xml
25/59
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123: 124:
125:
126: List Course Information
127:
The template matching favoriteCourses contains no functionality other than to call xsl:
apply-templates. This is because it contains no attributes and acts only as a parent container
element. Because the favoriteCourses node contains only child nodes named course, calling
xsl:apply-templates will result in only one template match.
Processing within the template that matches the course nodes is limited to adding a new row
(line 113) with columns containing the values for attributes named city, state, and name.
Each course node found within the source XML document will be matched with this template
and the appropriate attribute values will be written out.
Line 112 introduces a new XSLT element that hasnt been covered to this point. The
xsl:call-template element can be used to call a template in a similar manner as calling a
function within C# or VB.NET. Calling a template in XSLT is accomplished by identifying the
name of the template to call via a name attribute. The template that is called must, in turn, have
a matching name attribute as shown in line 125.
Calling templates can be useful when a template doesnt match up with a given node in an
XML document but needs to be accessible to process commonly used features or perform cal-
culations. For example, if your XSLT code needs to walk through a list of pipe-delimited
strings, a template can be called recursively until each piece of data within the string has been
processed. Youll see a concrete example of using the xsl:call-template element in conjunc-
tion with the xsl:with-param and xsl:param elements toward the end of this chapter.
Line 128:
128:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
257
-
7/30/2019 aspnet xml
26/59
The XSLT language follows all the rules outlined in the XML specification. As such, the
xsl:stylesheet element must be closed.
This example has shown how you can use some of the main elements found in the XSLT spec-
ification. For more information on some of the other elements not covered in the previous
example, refer to the XSLT version 1.0 specification (http://www.w3.org/TR/1999/REC-
xslt-19991116) or pick up a copy of a book titledXSLT Programmers Reference
(ISBN 1-861003-12-9).
Transforming XML into Another Form of XML Using XSLT Elements
HTML isnt the only structure that can be created by an XSLT document. Many cases may
occur in which other formats, such as a comma-delimited, WML, or even another form of
XML, need to be generated to integrate with an application. In this section well take a look at
a simple example of transforming from XML to XML and show how a few of the XSLT ele-
ments can make this process easier. XML-to-XML transformations are useful when an XML
documents structure needs to be changed before sending it off to a vendor or to another appli-
cation that expects a different format.
Listing 7.5 shows the XML document that needs to be transformed, Listing 7.6 shows the
result of the transformation, and Listing 7.7 shows the XSLT document used in processing the
transformation.
LISTING 7.5 The Source XML Document
1:
2:
3:
4: 1
5:
6: Dan
7: Wahlin
8:
9: 10: 1234 Anywhere St.
11: AnyTown
12: 85789
13:
14:
15: 1234 LottaWork Ave.
16: AnyTown
17: 85786
18:
19:
20:
XML for ASP.NET Developers258
-
7/30/2019 aspnet xml
27/59
LISTING 7.5 continued
21: 2
22:
23: Elaine
24: Wahlin
25:
26:
27: 1234 Anywhere St.
28: AnyTown
29: 85789
30:
31:
32: 1233 Books Way
33: AnyTown
34: 85784
35:
36:
37:
LISTING 7.6 The Result of Transforming the XML Document in Listing 7.5
1: 2:
3:
4:
5: 1234 Anywhere St.
6: AnyTown
7: 85789
8:
9:
10: 1234 LottaWork Ave.
11: AnyTown
12: 85786
14: 15:
16:
17:
18: 1234 Anywhere St.
19: AnyTown
20: 85789
21:
22:
23: 1233 Books Way
24: AnyTown
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
259
-
7/30/2019 aspnet xml
28/59
LISTING 7.6 continued
25: 85784
26:
27:
28:
LISTING 7.7 The XSLT Document
1:
2:
4:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26: 27:
Breaking the XSLT document down into individual pieces reveals a few new things not seen in
previous examples. First, Line 4 uses the xsl:output element to specify an output format of
xml. It also specifies that the XML declaration should be included. This is done by setting the
omit-xml-declaration attribute to no. Because this is the attributes default value, it could
have been left out altogether.
Lines 610 take care of setting the starting template (the one that matches the document node)
needed in the XSLT document. This template simply adds a node named root to the result tree
XML for ASP.NET Developers260
-
7/30/2019 aspnet xml
29/59
and then triggers the process of looking for other templates that match up with nodes in the
source XML document.
The template matching the row element node writes a row element to the result tree. The bulk
of the transformation process occurs in lines 1324. To start, three different attributes are
added to the row element by using the xsl:attribute element. The value of these attributes is
obtained by using the xsl:value-of element to access the appropriate elements in the source
XML document.
After the attributes are added, the xsl:for-each element is used to loop through all address
elements. This element simply takes the name of the node-set to loop through as the value of
the select attribute. Because the address elements (and their children) remain unchanged
from the source to the result tree, the xsl:copy-of element is used to simply copy over the
address element (and all its children) to the result tree. Had we wanted only to copy the
address element itself and not the children, we could have used the xsl:copy element instead.
However, utilizing the xsl:copy-of element prevents us from having to create each element
(address, street, city, zip) dynamically by using the xsl:element or xsl:copy elements.
Now that youve had an opportunity to see some of the most common XSLT elements in
action, lets take a look at a few more that can help make your XSLT documents more dynamic
and flexible.
Using Variables and Parameters: The xsl:variable andxsl:param ElementsAs programmers, we all take for granted the capability to use variables and pass parameters to
functions. In fact, its hard to imagine programming without variables and parameters. Most
programmers would be hard pressed to eliminate them from their applications. Fortunately,
theres no need to worry about variables or parameters being eliminated from C#, VB.NET, or
even from languages such as XSLT. The XSLT specification includes the capability to use a
variable or pass a parameter to a template. In this section, you are provided with a general
overview of how variables and parameters can be used to make your XSLT documents more
flexible. Lets first take a look at how variables can be used.
Variables in XSLT
XSLT variables are used to avoid calculating the same result multiple t imes. Although very
similar to variables used in C# or any other programming language, XSLT variables can be set
once but cannot be updated after they are set. The value assigned to a variable is retained until
the variable goes out of scope. What, you say! XSLT variables can be set only once? Doesnt
this make them the equivalent of a constant?
Theres a method to the madness that makes perfect sense when analyzed. Because XSLT
relies on templates that can be called randomly, depending on the structure of the source XML
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
261
-
7/30/2019 aspnet xml
30/59
document, the capability to update a particular global variable could introduce problems. These
types of problems are referred to as side effects, and the XSLT specification eliminates the
problem by allowing for no side effects. If youve ever stepped into a project that you didnt
originally code that had bugs cropping up because of overuse of global variables, youll appre-
ciate this concept.
To illustrate the concept of side effects more, lets take a look at a simple example. If a tem-
plate named template1 relies on another template named template2 to update the value of a
global variable, what happens iftemplate2 doesnt ever get processed? The rather obvious
answer is that the global variable will never be updated and therefore can cause potential prob-
lems to template1 when it is processed. By not allowing variables in XSLT style sheets to beupdated, this problem is avoided.
XML for ASP.NET Developers262
Its important to realize that XSLT documents can be written without the use of variables.However, variables can aid in cleaning up the code and can also result in more efficient XSLT
style sheets. The following example uses a portion of the code shown earlier in Listing 7.4 to
demonstrate how a variable declared globally (as a child element of the xsl:stylesheet ele-
ment) can be used in XSLT:
golfers have lower handicaps
Some XSLT processors do allow for variables to be updated by using extension func-
tions. These functions are specific to the XSLT processor and are not part of the XSLT
specification.
NOTE
-
7/30/2019 aspnet xml
31/59
The xsl:variable element can have a name and a select attribute. The name attribute is
required and serves the obvious purpose of assigning a name that can be used to reference
the variable. The select attribute is optional but when listed, must contain a valid XPath
expression.
So what have we gained by using a variable in this template? The code has actually been made
much more efficient as compared to writing the same code without using the variable. Instead
of having to calculate the count of all the golfers in the XML document with handicaps less
than 11 each time a golfer node template is matched, the variable obtains this value and stores
it when the XSLT style sheet is first loaded. The variable can then be referenced in several
places by adding the $ character to the beginning of the variable name ($count in this case).Doing this cuts out unnecessary processing during the transformation process.
At times, the value of an attribute may need to be dynamically generated and used in several
places. In many cases, using a variable can make this process easier:
#ff0000
#ffff00
#ffffff
Although the value of the color attribute found on the font tag could be added by using thexsl:attribute element multiple times, by defining the value once in the variable, the code is
kept cleaner and the processing is more efficient.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
263
The previous example shows a shortcut that can be used to embed data directly into
attributes that will be written out to the result tree. By wrapping a variable (or other
item) with the { and } brackets, it will dynamically be added to the result tree. This is
TIP
continues
-
7/30/2019 aspnet xml
32/59
Variables can also be useful for storing values returned by calling a template. This process will
be shown a little later after youre introduced to the xsl:param element.
Parameters in XSLT
Parameters are useful in a variety of programming languages, with XSLT being no exception.
Parameters can be used in XSLT documents in two basic ways. First, parameter values can be
passed in from an ASP.NET application. This allows data not found within the XML document
or XSLT style sheet to be part of the transformation process. Second, parameter values can be
passed between XSLT templates in much the same way that parameters can be passed between
functions in C# or VB.NET. Youll see how parameters can be used in both ways later in the
chapter.
Declaring a parameter is similar to declaring a variable. Simply name the parameter and add an
optional select attribute:
As with variables, parameters can be children of the xsl:stylesheet or xsl:transform ele-
ments and can also be children of the xsl:template element. So when would you want to use
a parameter? Lets assume that the golfers XSLT document shown in Listing 7.4 needs to show
a specific golfer based on user input in a Web form. To accomplish this task, the ASP.NET
application can pass in the value entered by the user to a parameter within the XSLT docu-
ment. This value can then be used to display the proper golfers information. A simplified
document that uses a parameter named golferNum is shown next:
XML for ASP.NET Developers264
in contrast to adding the attribute name and value to a tag by using the
xsl:attribute element. As another example, if you had an attribute named width in
an XML document, you could write it out to a table tag by doing the following:
. This is similar to doing something such as in ASP.NET.
-
7/30/2019 aspnet xml
33/59
Having this parameter in the XSLT style sheet will cause a specific golfers information to be
transformed. Any other golfers in the XML document will simply be ignored. How is this
accomplished? A small change was made to the xsl:apply-templates element in the golfers
template. Instead of processing all golfer nodes in the XML document, the XPath expression
in the select attribute specifies the specific golfer node to process:
Although this example hard-codes a value for the golferName parameter, an ASP.NET page
would normally pass the value in using specific classes in the System.Xml assembly. Youll be
introduced to these classes later in the chapter. If the value passed into the golferName para-
meter from the ASP.NET page does not match up with an existing golfer node in the XML
document, no error will be raised.
Parameters can also be used in conjunction with the xsl:call-template element. Fortunately,
from working with other programming languages, you already have a good understanding of
how this works. Imagine calling a method named GetOrders() that accepts a single parameter
as an argument. The method call would look something like the following:GetOrders(ALFKI);
Now imagine that GetOrders is the name of an XSLT template used to transform an XML
document containing customers and orders. Calling the template and passing the parameter can
be accomplished by doing the following:
This example shows the use of the xsl:call-template and xsl:with-param elements to initi-
ate the template call. The xsl:call-template element has a single attribute that provides the
name of the template to call. The xsl:with-param element has two attributes. One is used to
name the parameter that data will be passed to and the other provides the value that is to be
passed. The select attribute can contain any valid XPath expression. The xsl:with-param
element can only be a child of the xsl:call-template or xsl:apply-templates element.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
265
-
7/30/2019 aspnet xml
34/59
The xsl:param element in the template being called is updated by using the xsl:with-param
element shown previously. It has two potential attributes, including name and select, as
described earlier. In the previous example, the parameter named CustomerID is assigned a
default value ofALFKI. This value will be overridden when the GetOrders template is called
and a parameter value is passed to it using the xsl:with-param element.
Because variables cannot be updated in XSLT, parameters play a large role in allowing values
to be passed between templates. A global parameter (declared as a child of the xsl:stylesheet
or xsl:transform elements) can receive input from an ASP.NET page, but it cannot be
updated more than once after processing of the XSLT document begins. However, the capabil-
ity to place parameters within the scope of a specific template body offers the capability to call
templates recursively. This is possible because a single template can call i tself and pass a para-meter value (or more than one value, in the case of multiple parameters within the template)
that can then be processed as appropriate.
Although the inability to update variables and parameters may seem somewhat restrictive, the
authors of the XSLT specification knew that it was necessary because XML documents can
contain many different structures. You cant depend on one template being processed before
another, especially in the case where one XSLT document is used to transform a variety of
XML documentsall with different structures.
Accessing Return Values of XSLT Templates
You may have noticed that although a template can act somewhat like a method, it has no way
to return a responseor does it? By wrapping the xsl:variable element around a template
call made using the xsl:call-template element, the output normally written to the result tree
can instead be captured by the variable. This process is shown next:
XML for ASP.NET Developers266
The xsl:param element named CustomerID (shown earlier) has a parameter value of
ALFKI with single quotes around it because it is a string value rather than an XPath
expression. Had the single quotes been omitted, the XSLT processor would try to find
a node namedALFKI (which doesnt exist, of course). Although this seems fairly obvi-
ous, its an easy mistake to make.
TIP
-
7/30/2019 aspnet xml
35/59
Customer
ID:
The variable named Orders will be filled with a node-set generated by a call to the GetNames
template. Doing this offers a powerful means for building more dynamic and efficient XSLT
documents.
Now that youre familiar with several of the main elements used in creating XSLT style sheets,
its time to examine XSLT functions.
XSLT FunctionsIn Chapter 3, XPath, XPointer, and XLink, you were introduced to several functions built in
to the XPath language. Because XSLT relies on XPath for creating expressions that locate
nodes in an XML document, these functions are available for use in your XSLT documents. In
addition to these functions, the XSLT language adds a few more. Table 7.3 shows these func-
tions and provides a description and example of using them in XSLT documents.
TABLE 7.3 XSLT Functions
Function Description
current() Returns a node set that contains the current node as its only
member. This function exists to help identify the current
node when it is different from the context node. In previousexamples you have seen that the context node can be repre-
sented by the . character. For example, to write out the
value of the context node being processed by a template,
you can do the following:
This code will provide the same result:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
267
-
7/30/2019 aspnet xml
36/59
TABLE 7.3 continued
Function Description
current() (continued) At this point in the template, the current node is the same
as the context node. When used within the square brackets
of a predicate ([ and ]), however, the current node is often
different from the context node. An example of this is
shown next:
Other Comparable Golfers:
The predicate statement ([./@skill = current()/
@skill]) will compare the value of the context nodes
skill attribute (in this case, the golfer node being looped
through) to the golfer node being handled by the template
(the current node). This is an example of how the context
node changes during a loop. However, the current node is
associated with the node being handled by the template and
stays the same during the looping process.
document(object,node-set?) Although XSLT makes it easy to transform a single XML
document into other structures, what happens if the result
tree needs to be created from more than just one XML
document? Using the document() function, other XML
documents can be pulled into an XSLT document for pro-cessing. This can be useful in many situations, including
when one XML document contains a presentation structure
and another contains the data to be plugged into that struc-
ture. Using the document() function, these types of activi-
ties can be accomplished relatively easily. An example of
using the document() function is shown next:
XML for ASP.NET Developers268
-
7/30/2019 aspnet xml
37/59
TABLE 7.3 continued
Function Description
This will load data.xml into the variable named xmlDoc.
Referencing elements within the external document can be
accomplished in the following manner:
Although the preceding document() function example tar-
gets an external document, this function can also be used to
target a node-set within the main XML document. This can
be useful when you want to work with a lookup tablestructure embedded in the XML document.
Aside from providing a string URI value, a node-set can be
passed to access the remote document, as shown next:
For the XML document:
The following XSLT document creates a result tree con-
taining the handicap nodes from the referenced documents:
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
269
-
7/30/2019 aspnet xml
38/59
TABLE 7.3 continued
Function Description
element-available(string) This function is useful if you are writing an XSLT docu-
ment that may be processed using different XSLT proces-
sors. Before using elements that you know may not be
supported, a check can be made to see if the processor does
indeed support the element in question. This is helpful
when testing for XSLT elements found in a later version of
XSLT or in checking for vendor specific elements. The
function will return a Boolean value:
HI!
format-number(number, This function converts numbers to a string using a format
string,string?) pattern supplied in the second parameter. Here are some
examples of using this function:
The following function call returns 5,351:
format-number(5351,#,###)
The following function call returns 5351.00:format-number(5351, #.00)
The following function call returns 53.5100:
format-number(53.51, #.0000)
The following function call returns 0053.5100:
format-number(53.51, 0000.0000)
The following function call returns 0053.51:
format-number(53.51, 0000.####)
The following function call returns 53.6:
format-number(53.56, 0.0)
function-available(string) Similar to element-available, although this function checks
whether specific functions are supported by the XSLT
processor.
generate-id(node-set?) This function generates a string that is guaranteed to
uniquely identify a node. The same string will always be
returned for the same node. The string that is generated
will vary from processor to processor and will start with an
alphabetic character.
XML for ASP.NET Developers270
-
7/30/2019 aspnet xml
39/59
TABLE 7.3 continued
Function Description
key(string,object) This function is used in conjunction with the xsl:key ele-
ment to return a node-set that has a specific name and
value defined by the xsl:key statement. For example, the
following code shows how the xsl:key element can define
a key:
This key can then be accessed by using the key() function:
...
system-property(string) This function returns the value of the system property iden-
tified by the name passed as the argument. Three different
system properties must be supported by a compliant XSLTprocessor, including xsl:version, xsl:vendor, and
xsl:vendor-url. An example of using this function
follows:
unparsed-entity-uri() This function returns declarations of unparsed entities in
the DTD of the source XML document.
Given the entity declaration:
http://www.lottaclubs.com/clubs.txt>
The following code:
Would return a value of
http://www.lottaclubs.com/clubs.txt.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
271
-
7/30/2019 aspnet xml
40/59
.NET Classes Involved in Transforming XMLNow that youve seen the different XSLT elements and functions that are at your disposal, its
time to learn about what classes in the .NET framework can be used in your ASP.NET applica-
tions when XSL transformations are necessary. After all, XSLT is simply a text-based language
that is of li ttle utility without an XSLT processor.
Several classes built in to the System.Xml assembly can be used when transforming XML into
other structures via XSLT. Back in Listing 7.3, a preview of a few of these classes interacting
with each other was given that demonstrated how to transform an XML document into HTML.
In this section youll learn more about these classes and a few others so that you are fully
armed with everything you need to know to use XSLT in your ASP.NET applications. Figure
7.3 presents an overview of the main classes used in XSL transformations.
XML for ASP.NET Developers272
XmlDocument
XmlReader
System.IO.Stream System.IO.Textwriter
XmlWriter
Implement XPathNavigator and IXPathNavigable
XmlDataDocument
XslTransform
XPathDocument
DOM Fast XSLTDOM DataSet
XSL/T
XML Stores
XPath
FIGURE 7.3.NET Classes involved in XSL transformations.
Table 7.4 provides a description of each of these classes.
TABLE 7.4 .NET Classes Used in XSL Transformations
Class Description
XmlDocument The XmlDocument class implements the IXPathNavigable interface
and extends the XmlNode class, which provides the capability to create
nodes within a DOM structure. This class was discussed in Chapter 6.
Because the XmlDocument class provides node-creation capabilities, it
will not provide the fastest throughput in XSL transformations.
However, in cases where a DOM structure must be edited first before
being transformed, this class can be used.
-
7/30/2019 aspnet xml
41/59
TABLE 7.4 continued
Class Description
XmlDataDocument The XmlDataDocument class extends the XmlDocument class. The
XmlDataDocument class can be used when working with DataSets in
ADO.NET. Chapter 8, Leveraging ADO.NETs XML Features
Using ASP.NET, covers this class in more depth.
XPathDocument The XPathDocument class implements the IXPathNavigable interface
like the XmlDocument class does. However, the XPathDocument class
does not extend the XmlNode class (as the XmlDocument class does)
and therefore provides the fastest option for transforming XML via
XSLT. Youll see this class used in the examples that follow.
Because the XPathDocument class implements the IXPathNavigable
interface, it is able to leverage features built in to the abstract
XPathNavigator class (which, in turn, uses the XPathNodeIterator
abstract class for iteration over node-sets) to provide cursor-style
access to XML data, resulting in fast and efficient XSL transforma-
tions.
XslTransform The XslTransform class is used to transform XML data into other
structures. Using the XslTransform class involves instantiating it,
loading the proper style sheet with the Load() method, and then pass-
ing specific parameters to its Transform() method. This process willbe detailed in the next few sections.
XsltArgumentList The XsltArgumentList class is used to provide parameter values to
xsl:param elements defined in an XSLT style sheet. It can be passed
as an argument to the XslTransform classs Transform() method.
The XPathDocument ClassBefore looking at the XslTransform class, you need to familiarize yourself with the
XPathDocument class. To use this class you must reference the System.Xml.XPath namespacein your ASP.NET applications. As mentioned in Table 7.4, this class provides the most efficient
way to transform an XML document using XSLT because it provides a read-only representa-
tion of a DOM structure. The XPathDocument class is very simple to use because it has only
one XML-related method named CreateNavigator() that can be used to create an instance of
the XPathNavigator class. However, it does have several constructors that are worth mention-
ing. Table 7.5 shows the different constructors.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
273
-
7/30/2019 aspnet xml
42/59
TABLE 7.5 XPathDocument Constructors
Constructor Description
Public XPathDocument(XmlReader, Accepts an XmlReader as well as an
XmlSpace) XmlSpace enumeration.
Public XPathDocument(XmlReader) Accepts an XmlReader.
Public XPathDocument(TextReader) Accepts a TextReader.
Public XPathDocument(Stream) Accepts a Stream.
Public XPathDocument(string,XmlSpace) Accepts the string value of the path to
an XML document and an XmlSpace
enumeration.
Public XPathDocument(string) Accepts the string value of the path to an
XML document.
Listing 7.3 used the last constructor shown in Table 7.5 that accepts the path to the XML docu-
ment to transform. You could also load the XPathDocument with XML data contained in a
Stream (a FileStream for instance), an XmlReader, or a TextReader. Having these different
constructors offers you complete control over how transformations will be carried out in your
ASP.NET applications. Which one you use will depend on how you choose to access your
applications XML documents. Listing 7.8 instantiates an XPathDocument class by passing inan XmlTextReader object.
LISTING 7.8 Instantiating an XPathDocument Class
public void Page_Load(Object sender, EventArgs E) {
string xmlPath = Server.MapPath(listing7.1.xml);
string xslPath = Server.MapPath(listing7.2.xsl);
FileStream fs = new FileStream(xmlPath,FileMode.Open,
FileAccess.Read);
StreamReader reader = new StreamReader(fs,Encoding.UTF8);
XmlTextReader xmlReader = new XmlTextReader(reader);
//Instantiate the XPathDocument Class
XPathDocument doc = new XPathDocument(xmlReader);
Response.Write(XPathDocument successfully created!);
XML for ASP.NET Developers274
-
7/30/2019 aspnet xml
43/59
LISTING 7.8 continued
//Close Readers
reader.Close();
xmlReader.Close();
}
Running the code shown in Listing 7.5 will write out XPathDocument successfully created!
to the browser. Youll certainly agree that because it has simply readied the XML document for
transformation, this code doesnt buy you much. To actually transform the XML document
using XSLT, youll need to use another class named XslTranform.
The XslTransform ClassThe XslTransform class is found in the System.Xml.Xsl namespace. Using it is as easy as
instantiating it, loading the XSLT document, and then calling its Transform() method. Tables
7.6 and 7.7 show the different properties and methods found in the XslTransform class.
TABLE 7.6 XslTransform Class Properties
Property Description
XmlResolver The XmlResolver property can be used to specify a resolver class usedto resolve external resources. For example, it can be used to resolve
resources identified in xsl:include elements. If this property is not
set, the XslTransform class will use the relative path of the supplied
XSLT style sheet to resolve any included style sheets.
Chapter 5 showed an example of using the XmlUrlResolver class to
access authenticated documents.
TABLE 7.7 XslTransform Class Methods
Method Description
Load() Loads an XSLT document. This method can accept an XmlReader, a
document URL, or a variety of other objects.
Transform() The Transform() method is overloaded and can therefore accept a
variety of parameters. The most common form of the method that
youll likely use in your ASP.NET applications is shown next (check
the .NET SDK for the other overloaded versions of the method):
xsl.Transform(XpathDocument,XsltArgumentList,Stream)
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
275
-
7/30/2019 aspnet xml
44/59
-
7/30/2019 aspnet xml
45/59
XsltArgumentList class and add parameter name/value pairs to it. It can also be used withextension objects. Table 7.8 shows the different methods available on the XsltArgumentList
class (it has no properties).
TABLE 7.8 XsltArgumentList Methods
Method Description
AddExtensionObject(namespaceURI, Allows an extension object to be added to the
object) collection of extension objects. The namespace
URI can be used to remove or retrieve an
object from the collection using either
GetExtensionObject() or RemoveExtension
Object(). Similar to the addObject() method
found on the IXslProcessor interface in
MSXML3.
AddParam(name,namespaceURI,value) Allows a parameter name/value pair to be added
to the collection of parameters. If you do not want
to assign a namespaceURI, the URI can be empty
strings. It is similar to the addParameter()
method found on the IXslProcessor interface in
MSXML3.
GetExtensionObject(namespaceURI) Allows an extension object to be retrieved from
the collection of extension objects based on the
namespaceURI assigned to the object in the
AddExtensionObject() method.
GetParam(name,namespaceURI) Allows a parameter name/value pair to be
retrieved from the collection of parameters based
on a name and namespaceURI combination. If a
parameter name has no assigned namespaceURI,
the URI can be empty strings.
RemoveExtensionObject Allows an extension object to be removed from
(namespaceURI) the collection of extension objects based on thenamespaceURI assigned to the object in the
AddExtensionObject() method.
RemoveParam(name,namespaceURI) Allows a parameter name/value pair to be
removed from the collection of parameters based
on a name and namespaceURI combination. If a
parameter name has no assigned namespaceURI,
the URI can be empty strings.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
277
-
7/30/2019 aspnet xml
46/59
The method that youll use most frequently among those listed in Table 7.8 is theAddParam()method. This method accepts the name of the parameter, a namespace URI (optional), and the
value of the parameter. The following example shows how to add a parameter named
golferName to the XsltArgumentList collection:
XSLT Code:
ASP.NET Code:
XsltArgumentList args = new XsltArgumentList();
args.AddParam(golferName,,Dan);
This code allows the XSLT parameter named golferName to be assigned a value ofDan.
Although the value ofDan was hard-coded into theAddParam() method, it could just as easily
be dynamically pulled from a text box or drop-down box, as youll see in the next example.
Because the XsltArgumentList class relies on the HashTable class behind the scenes, multiple
parameter name/value pairs can be added and stored.
After an XsltArgumentList class has been instantiated and filled with the proper name/value
pairs, how do the parameters in the XSLT style sheet get updated with the proper values? The
answer is to pass the XsltArgumentList into the XslTransform classs Transform() method,
as shown next:
//Create the XPathDocument object
XPathDocument doc = new XPathDocument(Server.MapPath(Listing7.1.xml));
//Create the XslTransform object
XslTransform xslDoc = new XslTransform();
xslDoc.Load(Server.MapPath(Listing 7.4.xsl));
//Create the XsltArgumentList object
XsltArgumentList args = new XsltArgumentList();
args.AddParam(golferName,,Dan);
//Perform the transformation - pass in the parameters in the XsltArgumentList
xslDoc.Transform(doc,args,Response.Output);
In the next section youll be presented with an ASP.NET application that does this task.
Putting It All TogetherYouve now seen the main XSLT classes built in to the .NET framework. In this section youll
see how these can be used to build a simple ASP.NET application that allows a user to select a
specific golfers information from an XML document. After the golfer is chosen, XSLT will be
XML for ASP.NET Developers278
-
7/30/2019 aspnet xml
47/59
used along with the XPathDocument, XslTransform, and XsltArgumentList classes to displaythe golfers information. Figures 7.4 and 7.5 show screen shots of the two pages involved in
the sample XSLT application.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
279
FIGURE 7.4The golfer selection form.
FIGURE 7.5The XSLT-generated results of the golfer selection.
To build this application, code-behind techniques were used in the ASP.NET page. If youre
not familiar with this mechanism in ASP.NET coding, it allows the actual program code to be
stored separately from the visual portion (the HTML) found in the ASP.NET page. The tech-
nique of placing all the code (programming code and HTML) into one ASP.NET page shown
in many places throughout the book was used simply to make listings easier to read and follow.
-
7/30/2019 aspnet xml
48/59
In practice, however, its highly recommended that you leverage code-behind techniques tokeep your ASP.NET code more maintainable.
For this example, a file named xsltGolfer.aspx.cs contains all the programming code for the
listings that follow, and xsltGolfer.aspx contains the HTML. The XSLT style sheet used for
the application is named xsltGolfer.xsl. Lets start by examining what code is executed
when the ASP.NET page first loads (the Page_Load event). As youll see in Listing 7.10, this
code takes care of loading all the firstName element values found in the XML document into
a drop-down box.
LISTING 7.10 The Page_Load Event and FillDropDown() Method (xsltGolfer.aspx.cs)
1: private void Page_Load(object sender, System.EventArgs e) {
2: if (!Page.IsPostBack) {
3: FillDropDown(firstName);
4: }
5: }
6:
7: private void FillDropDown(string element) {
8: string name = ;
9: this.ddGolferName.Items.Clear();
10: XmlTextReader reader = new XmlTextReader(xmlPath);
11: object firstNameObj = reader.NameTable.Add(firstName);
12: while (reader.Read()) {
13: if (reader.Name.Equals(firstNameObj)) {
14: name = reader.ReadString();
15: ListItem item = new ListItem(name,name);
16: this.ddGolferName.Items.Add(item);
17: }
18: }
19: reader.Close();
20: }
You can see that the XmlTextReader and XmlNameTable classes are used to efficiently parse the
XML data and add it to the drop-down box (ddGolferName). Both classes were discussed in
Chapter 5, Using the XmlTextReader and XmlTextWriter Classes in ASP.NET.
After the user selects a specific golfer from the drop-down box and clicks the button, the
btnSubmit_Click event is fired. The code within this event takes care of getting the selected
golfer name value from the drop-down box and passes it into the XSLT style sheet by using the
XsltArgumentList class. The style sheet then takes care of transforming the selected golfers
XML data into HTML, as shown earlier in Figure 7.5. Listing 7.11 shows the code involved in
this process.
XML for ASP.NET Developers280
-
7/30/2019 aspnet xml
49/59
LISTING 7.11 Transforming XML to HTML Using XSLT (xsltGolfer.aspx.cs)1: protected void btnSubmit_Click(object sender, System.EventArgs e) {
2: string xslPath = Server.MapPath(xsltGolfer.xsl);
3: XmlTextReader xmlReader = null;
4: StringBuilder sb = new StringBuilder();
5: StringWriter sw = new StringWriter(sb);
6:
7: try {
8: xmlReader = new XmlTextReader(xmlPath);
9: //Instantiate the XPathDocument Class
10: XPathDocument doc = new XPathDocument(xmlReader);
11:12: //Instantiate the XslTransform Classes
13: XslTransform transform = new XslTransform();
14: transform.Load(xslPath);
15:
16: //Add Parameters
17: XsltArgumentList args = new XsltArgumentList();
18: args.AddParam(golferName,,
19: this.ddGolferName.SelectedItem.Value);
20:
21: //Call Transform() method
22: transform.Transform(doc, args, sw);
23:24: //Hide-Show ASP.NET Panels in xsltGolfer.aspx
25: this.pnlSelectGolfer.Visible = false;
26: this.pnlTransformation.Visible = true;
27: this.divTransformation.InnerHtml = sb.ToString();
28: }
29: catch (Exception excp) {
30: Response.Write(excp.ToString());
31: }
32: finally {
33: xmlReader.Close();
34: sw.Close();
35: }
36: }
Although this doesnt show much in the way of new classes, it does show how the different
classes discussed in earlier sections can be tied together to create an ASP.NET application that
leverages XML and XSLT.
Transforming XML with XSLT and ASP.NET
CHAPTER 7
7TRANSFORMING
XMLWITHXSLT
ANDASP.NET
281
XML f ASP NET D l
-
7/30/2019 aspnet xml
50/59
Using Extension Objects with XSLTWhile looking through the methods exposed by the XsltArgumentList class back in Table 7.8,
you may have wondered how the extension object methods could be used to enhance XSLT/
ASP.NET applications. Using these methods is surprisingly easy and can provide your XSLT
style sheets with even more power and flexibility. Keep in mind that by using extension objects
in XSLT, you may render your XSLT unusable on other platforms or by other languages sim-
ply because extensions are not a part of the XSLT 1.0 specification (the XSLT 1.1 working
draft does include extension elements and functions, however). If your application will be the
only one that uses a particular XSLT style sheet and you need additional functionality not in
the XSLT 1.0 specification, extension objects may be the answer. Some other benefits of using
extension objects include:
Methods on classes within other namespaces (other than System namespaces) can be
called.
Extension functions allow better encapsulation and reuse of classes.
Style sheets can be kept smaller and more maintainable.
What exactly is an extension object? Think of it as an external class that can be referenced and
used within an XSLT style sheet. By using extension objects, you can get the current date and
time, query a database to do a lookup based on a value found in the XML source document, hit
a Web service, or trigger another application to begin running. All of this and much more canbe done from within an XSLT style sheet.
To see how this works in practice, the next code sample shown in Listing 7.12 builds on the
previous one shown in Listing 7.11 to add the capability to write out the current date/time of
the server from a specific location within the style sheet. Lets first look at the class that will
be instantiated and used as an extension object.
LISTING 7.12 The Date/Time Extension Class (xsltDateObject.cs)
1: namespace XsltTransformation.ExternalObjects {
2: using System;3:
4: public class XsltDateTime {
5: DateTime _date;
6: public XsltDateTime() {
7: _date = DateTime.Now;
8: }
9: public DateTime GetDateTime() {
10: return _date;
11: }
12: }
13: }
XML for ASP.NET Developers282
Transforming XML with XSLT and ASP NET
-
7/30/2019 aspnet xml
51/59
This class (named XsltDateTime) does nothing more than return the current system date andtime. It must be instantiated within an ASP.NET page and then added to the external object
collection of the XsltArgumentList class.
You may be wondering if it would be easier to pass the date and time into the style sheet using
a regular XSLT parameter. The answer is yes; it would be easier because no exter