aspnet xml

download aspnet xml

of 59

Transcript of aspnet xml

  • 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