XSL Style Sheets

XML is a great way to describe data in order to exchange it between applications and organizations. However, as part of a business process the data in an XML document will likely need to be represented in a different format before it can be processed or presented. XSL is a language that you can use to transform an XML document into a different format, such as HTML, Wireless Markup Language (WML), or even an alternative XML representation. XSL was originally designed as a way to present XML data as HTML. However, it soon became clear that XML could be transformed to any output format. An enhanced version of XSL known as XSL Transformations (XSLT) has therefore evolved.

This section doesn’t provide an exhaustive guide to XSL syntax, but it gives you enough information to start using XSL style sheets to process XML data. For a complete XSL reference, visit http://www.w3.org/Style/XSL.

XSL Style Sheet Documents

XSL documents define style sheets that you can apply to XML documents. A style sheet contains instructions that tell an XML parser how to generate an output document based on data in an XML document. The XSL style sheet is itself a well-formed XML document that contains XSL commands merged with literal output text.

For the parser to recognize the commands in an XSL document, you must declare a namespace in the root element, usually with the prefix xsl. One of two common namespaces is used in a style sheet: the original XSL namespace (http://www.w3.org/TR/WD-xsl) or the XSLT namespace (http://www.w3.org/1999/XSL/Transform). The Microsoft XML parser version 3.0 (MSXML3) supports both namespaces. However, you need to install MSXML3 in Replace mode by using a tool named Xmlinst.exe to enable support for the XSLT namespace in Internet Explorer 5. x. (Otherwise, Internet Explorer will use MSXML 2.5, which doesn’t support the XSLT namespace.)

The root element in an XSL document is usually a stylesheet element. This element contains one or more template elements that are matched to specific XML data in the XML document being processed, such as the order document shown here:

 <?xml version="1.0"?> <Order OrderNo="1234">     <OrderDate>2001-01-01</OrderDate>     <Customer>Graeme Malcolm</Customer>     <Item>         <Product Product UnitPrice="18">Chai</Product>         <Quantity>2</Quantity>     </Item>     <Item>         <Product Product UnitPrice="19">Chang</Product>         <Quantity>1</Quantity>     </Item> </Order> 

Because an XSL style sheet is an XML document itself, it must obey all the rules for well-formed XML. The following example is a simple XSL style sheet that could be applied to the order document:

 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">     <xsl:template match="/">         <HTML>             <HEAD>                 <TITLE>Northwind Web Page</TITLE>             </HEAD>             <BODY>                 <P>Customer Order</P>             </BODY>         </HTML>     </xsl:template> </xsl:stylesheet> 

This style sheet is based on the XSLT namespace and contains a single template that is applied to the root of an XML document and to all the elements within it. The actual template consists of a series of HTML tags that will appear in the output. This template doesn’t actually do anything very useful; it simply outputs a hard-coded HTML document with none of the XML data from the input document merged into the results. To merge XML data into the template, you need to use some XSL commands.

The value-of Command

XSL defines a number of processing commands that are useful for extracting data from an XML document and merging it into an output document. The most basic of these commands (yet one of the most useful) is the value-of command. The value-of command selects a specific element or attribute value from the XML and merges it with the results. A select attribute is used with value-of to specify the XPath to the XML data you want to extract, so we could enhance the style sheet described earlier to include some data from the XML order document, as shown here:

 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">     <xsl:template match="/">          <HTML>              <HEAD>                  <TITLE>Northwind Web Page</TITLE>              </HEAD>              <BODY>                  <P>Customer Order</P>                  <P>Order No: <xsl:value-of select="Order/@OrderNo"/></P>                  <P>Date: <xsl:value-of select="Order/OrderDate"/></P>                  <P>Customer: <xsl:value-of select="Order/Customer"/></P>              </BODY>          </HTML>      </xsl:template> </xsl:stylesheet> 

This version of the style sheet retrieves the OrderNo attribute and the OrderDate and Customer element values from the Order element by using an XPath location path. Notice that the XPath expressions are relative to the context node identified in the template element’s match parameter (in this case the root element).

Applying the above style sheet to the XML order document we discussed earlier produces the following HTML. I’ll explain how to apply a style sheet to an XML document later in this appendix.

 <HTML>     <HEAD>         <TITLE>Northwind Web Page</TITLE>     </HEAD>     <BODY>         <P>Customer Order</P>         <P>Order No: 1234</P>         <P>Date: 2001-01-01</P>         <P>Customer: Graeme Malcolm</P>     </BODY> </HTML> 

The for-each Command

In an XML document, multiple elements of the same name are commonly used to represent a list of entities. For example, our order document contains two Item elements to represent the two products being ordered. Most programming languages provide a mechanism for iterating, or looping, through a series of data entries. XSL is no exception. You can use the for-each command to loop through a collection of similarly named nodes, using a select attribute to identify the nodes you want to process.

For example, we could further enhance our style sheet to list each item in the order as an entry in a table:

 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">     <xsl:template match="/">         <HTML>             <HEAD>                 <TITLE>Northwind Web Page</TITLE>             </HEAD>             <BODY>                 <P>Customer Order</P>                 <P>Order No: <xsl:value-of select="Order/@OrderNo"/></P>                 <P>Date: <xsl:value-of select="Order/OrderDate"/></P>                 <P>Customer: <xsl:value-of select="Order/Customer"/></P>                 <TABLE Border="0">                     <TR>                         <TD>ProductID</TD>                         <TD>Product Name</TD>                         <TD>Price</TD>                         <TD>Quantity Ordered</TD>                     </TR>                     <xsl:for-each select="Order/Item">                         <TR>                             <TD><xsl:value-of select="Product/@ProductID"/>                             </TD>                             <TD><xsl:value-of select="Product"/></TD>                             <TD><xsl:value-of select="Product/@UnitPrice"/>                             </TD>                             <TD><xsl:value-of select="Quantity"/></TD>                         </TR>                     </xsl:for-each>                 </TABLE>             </BODY>         </HTML>     </xsl:template> </xsl:stylesheet> 

In this version of the style sheet, the parser is told to loop through each Item element and extract the ProductID and UnitPrice attributes of the product element, as well as the values of the Product and Quantity elements, into a table. Notice that the relative XPath expression uses the node identified in the for-each command as the context node. (In this case it’s the Item node.) Indicate the end of the loop by closing the for-each element. The preceding style sheet produces the following HTML when applied to the XML order document discussed earlier:

 <HTML>     <HEAD>         <TITLE>Northwind Web Page</TITLE>     </HEAD>     <BODY>         <P>Customer Order</P>         <P>Order No: 1234</P>         <P>Date: 2001-01-01</P>         <P>Customer: Graeme Malcolm</P>         <TABLE Border="0">             <TR>                 <TD>ProductID</TD>                 <TD>Product Name</TD>                 <TD>Price</TD>                 <TD>Quantity Ordered</TD>             </TR>             <TR>                 <TD>1</TD>                 <TD>Chai</TD>                 <TD>18</TD>                 <TD>2</TD>             </TR>             <TR>                 <TD>2</TD>                 <TD>Chang</TD>                 <TD>19</TD>                 <TD>1</TD>             </TR>         </TABLE>     </BODY> </HTML> 

Generating Attributes with the attribute Command

Sometimes you might want to create an attribute in the output document that contains a value from the XML document being processed. For example, suppose that for each product name, you want to create a hyperlink that passes the ProductID to another Web page where you can display the details of that product. To create a hyperlink in an HTML document, you need to generate an A element containing an href attribute. You can use the attribute command to create an attribute, as shown in the following example:

 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">     <xsl:template match="/">         <HTML>             <HEAD>                 <TITLE>Northwind Web Page</TITLE>             </HEAD>             <BODY>                 <P>Customer Order</P>                 <P>Order No: <xsl:value-of select="Order/@OrderNo"/></P>                 <P>Date: <xsl:value-of select="Order/OrderDate"/></P>                 <P>Customer: <xsl:value-of select="Order/Customer"/></P>                 <TABLE Border="0">                     <TR>                         <TD>ProductID</TD>                         <TD>Product Name</TD>                         <TD>Price</TD>                         <TD>Quantity Ordered</TD>                     </TR>                     <xsl:for-each select="Order/Item">                         <TR>                             <TD><xsl:value-of select="Product/@ProductID"/>                             </TD>                             <TD>                                 <A>                                     <xsl:attribute name="HREF">                                     Products.asp?ProductID=<xsl:value-of                                          select="Product/@ProductID"/>                                     </xsl:attribute>                                     <xsl:value-of select="Product"/>                                 </A>                             </TD>                             <TD><xsl:value-of select="Product/@UnitPrice"/>                             </TD>                             <TD><xsl:value-of select="Quantity"/></TD>                         </TR>                     </xsl:for-each>                 </TABLE>             </BODY>         </HTML>     </xsl:template> </xsl:stylesheet> 

Applying this style sheet to the XML order document results in the following HTML:

 <HTML>     <HEAD>         <TITLE>Northwind Web Page</TITLE> 
     </HEAD>     <BODY>         <P>Customer Order</P>         <P>Order No: 1234</P>         <P>Date: 2001-01-01</P>         <P>Customer: Graeme Malcolm</P>         <TABLE Border="0">             <TR>                 <TD>ProductID</TD>                 <TD>Product Name</TD>                 <TD>Price</TD>                 <TD>Quantity Ordered</TD>             </TR>             <TR>                 <TD>1</TD>                 <TD><A HREF="Products.asp?ProductID=1">Chai</A></TD>                 <TD>18</TD>                 <TD>2</TD>             </TR>             <TR>                 <TD>2</TD>                 <TD><A HREF="Products.asp?ProductID=2">Chang</A></TD>                 <TD>19</TD>                 <TD>1</TD>             </TR>         </TABLE>     </BODY> </HTML> 

Using Multiple Templates in a Style Sheet

So far all the style sheets we’ve seen include a single template that’s applied to the root element of the document. XSL also allows us to use multiple templates in a single style sheet. You might want to do this for two reasons. First, you can easily separate the presentation logic for individual parts of the document, making it easier to debug or change your style sheets. Second, you can use XPath expressions to apply different formatting to XML data depending on the value of the data. When a style sheet contains multiple templates, you incorporate them into the presentation logic by using the apply-templates command. Usually you create a top-level template to process the document as a whole and use the apply-templates command to process elements within the scope of the top-level template. The additional templates can be called at any point, and the top-level template renders any data that isn’t consumed by the additional templates. For example, the following style sheet includes multiple templates: a top-level template that applies to the root of the document, a template for Product elements with a UnitPrice attribute with a value greater than 18, a template for all other Product elements, and a template for Quantity elements:

 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">     <xsl:template match="/">         <HTML>             <HEAD>                 <TITLE>Northwind Web Page</TITLE>             </HEAD>             <BODY>                 <P>Customer Order</P>                 <P>Order No: <xsl:value-of select="Order/@OrderNo"/></P>                 <P>Date: <xsl:value-of select="Order/OrderDate"/></P>                 <P>Customer: <xsl:value-of select="Order/Customer"/></P>                 <TABLE Border="0">                     <TR>                         <TD>ProductID</TD>                         <TD>Product Name</TD>                         <TD>Price</TD>                         <TD>Quantity Ordered</TD>                     </TR>                     <xsl:for-each select="Order/Item">                         <TR>                             <xsl:apply-templates/>                         </TR>                     </xsl:for-each>                 </TABLE>             </BODY>         </HTML>     </xsl:template>     <xsl:template match="Product[@UnitPrice > 18]">         <TD><xsl:value-of select="@ProductID"/></TD>         <TD>             <A>                 <xsl:attribute name="HREF">                 Products.asp?ProductID=<xsl:value-of select="@ProductID"/>                 </xsl:attribute>                 <xsl:value-of select="."/>             </A>         </TD>         <TD>             <FONT color="red">                 <xsl:value-of select="@UnitPrice"/>             </FONT>         </TD>     </xsl:template>     <xsl:template match="Product">         <TD><xsl:value-of select="@ProductID"/></TD>         <TD>             <A>                 <xsl:attribute name="HREF">                 Products.asp?ProductID=<xsl:value-of select="@ProductID"/>                 </xsl:attribute>                 <xsl:value-of select="."/>             </A>         </TD>         <TD><xsl:value-of select="@UnitPrice"/></TD>     </xsl:template>     <xsl:template match="Quantity">         <TD><xsl:value-of select="."/></TD>     </xsl:template>   </xsl:stylesheet> 

Applying this template to the XML order document described earlier results in the following HTML:

 <HTML>     <HEAD>         <TITLE>Northwind Web Page</TITLE>     </HEAD>     <BODY>         <P>Customer Order</P>         <P>Order No: 1234</P>         <P>Date: 2001-01-01</P>         <P>Customer: Graeme Malcolm</P>         <TABLE Border="0">             <TR>                 <TD>ProductID</TD>                 <TD>Product Name</TD>                 <TD>Price</TD>                 <TD>Quantity Ordered</TD>             </TR>             <TR>                 <TD>1</TD>                 <TD><A HREF="Products.asp?ProductID=1">Chai</A></TD>                 <TD>18</TD>                 <TD>2</TD>             </TR>             <TR>                 <TD>2</TD>                 <TD><A HREF="Products.asp?ProductID=2">Chang</A></TD>                 <TD><FONT color="red">19</FONT></TD>                 <TD>1</TD>             </TR>         </TABLE>     </BODY> </HTML> 

Applying Style Sheets

Now that you know how to create a style sheet, you need to understand how to apply a style sheet to an XML document. Applying a style sheet is a function of an XML parser. You can instruct the parser to apply a style sheet either by including a processing instruction in the XML document itself or by using some programmatic logic.

To include a style sheet–processing directive in an XML document, you simply need to add an xml-stylesheet processing instruction, as shown in the following example:

 <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="Order.xsl"?> <Order OrderNo="1234">     <OrderDate>2001-01-01</OrderDate>     <Customer>Graeme Malcolm</Customer>     <Item>         <Product Product UnitPrice="18">Chai</Product>         <Quantity>2</Quantity>     </Item>     <Item>         <Product Product UnitPrice="19">Chang</Product>         <Quantity>1</Quantity>     </Item> </Order> 

When an XML parser reads this document, the xml-stylesheet processing instruction tells the parser to apply the Order.xsl style sheet. The type attribute indicates the kind of style sheet to be applied, such as an XSL style sheet or a cascading style sheet (CSS). The href attribute specifies the absolute or relative path to the style sheet file. Opening a document such as this with an XML-aware browser such as Internet Explorer 5.5 causes the XML parser to load the style sheet and render the XML data accordingly.

The process of applying a style sheet varies programmatically from parser to parser. If you use the Microsoft XML parser, the document is loaded into a Microsoft. XMLDom object and the transformNode method is used to apply a style sheet loaded in another XMLDom object. For example, the following code could be used to apply a style sheet named Order.xsl to an XML document named Order.xml:

 Dim objXML Dim objXSL Dim strResult ‘Load the XML document. Set objXML = CreateObject("Microsoft.XMLDom") objXML.Async = False objXML.Load "c:\Order.xml" ‘Load the XSL style sheet. Set objXSL = CreateObject("Microsoft.XMLDom") objXSL.Async = False objXSL.Load "c:\Order.xsl" ‘Apply the style sheet. strResult = objXML.transformNode(objXSL) 

When this code has completed, strResult contains the output produced by the style sheet.



Programming Microsoft SQL Server 2000 With Xml
Programming Microsoft SQL Server(TM) 2000 with XML (Pro-Developer)
ISBN: 0735613699
EAN: 2147483647
Year: 2005
Pages: 89

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net