October 1999

Do You XML? Then You Need to XSL!

by Bill Pitzer

XML has definitely been the buzz around the Web development world, especially following the release of Internet Explorer 5, with its updated XML parser. But while XML is great for describing structured data, it doesn't actually have a means of displaying the data that it describes. XML was designed this way so that data is kept separate from its presentation. Enter Internet Explorer 5 again, which now supports a subset of the Extensible Stylesheet Language, or XSL. XSL transformations turn XML into a grammar and structure suitable for display in a browser. Internet Explorer 5 supports many different types of XSL transformations. A complete listing can be found in the "XSL Developer's Guide" on Microsoft's site at msdn.microsoft.com/xml/XSLGuide/default.asp

In this article, we'll concentrate on applying XSL style sheets to XML documents. This allows direct browsing of the XML data contained in your page. Although Cascading Style Sheets (CSS) can be used for this purpose, they don't provide the flexibility allowed by XSL.

Mike's House of Music

Mike has a great collection of music he cherishes so much that he's converted the list into XML format so it can be shared with the world. Unfortunately, even though he has diligently set up the XML, he's discovered that this alone won't enable him to display it in other music lovers' browsers. Then Mike discovers that he can use XSL style sheets to display his data. This will be sure to delight Neil Diamond fans around the world. A portion of Mike's collection, displayed using XSL, is shown in Figure A.

Figure A: We'll use XSL to display Mike's music collection.

[ Figure A ]

Defining it with XML

Of course, you'll need an XML document to which you want to apply the XSL style sheet. In Listing A, you'll see the XML describing Mike's music collection. This is a simple example of some well-formed XML. Within the MY-COLLECTION root node, you can see Mike has stored a few pieces of information about each piece of music.

Listing A: Mike's XML music collection


<MY-COLLECTION> 
	<MUSIC>
		<ARTIST>Billy Joel</ARTIST>
		<TITLE>The Entertainer</TITLE>
		<FORMAT>LP</FORMAT>
		<ESTIMATED_WORTH>Priceless</ESTIMATED_WORTH>
	</MUSIC>
	<MUSIC>
		<ARTIST>Weird Al Yankovic</ARTIST>
		<TITLE>I Lost on Jeopardy</TITLE>
		<FORMAT>Tape</FORMAT>
		<ESTIMATED_WORTH>3.40</ESTIMATED_WORTH>
	</MUSIC>
	<MUSIC>
		<ARTIST>Neil Diamond</ARTIST>
		<TITLE>Forever in Blue Jeans</TITLE>
		<FORMAT>CD</FORMAT>
		<ESTIMATED_WORTH>Priceless</ESTIMATED_WORTH>
	</MUSIC>
	<MUSIC>
		<ARTIST>Little River Band</ARTIST>
		<TITLE>Cool Change</TITLE>
		<FORMAT>CD</FORMAT>
		<ESTIMATED_WORTH>5.60</ESTIMATED_WORTH>
	</MUSIC>
	<MUSIC>
		<ARTIST>Englebert Humperdink</ARTIST>
		<TITLE>Please Release Me</TITLE>
		<FORMAT>Wax Cylinder</FORMAT>
		<ESTIMATED_WORTH>1.23</ESTIMATED_WORTH>
	</MUSIC>
</MY-COLLECTION>

Displaying our XML with XLS

Now that we have our XML document, how can we display it? This is where XSL and its transformation capabilities come in. The full listing of the XSL source for displaying Mike's XML can be found in Listing B.

Listing B: XSL source code

<HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  <xsl:for-each select="MY-COLLECTION/MUSIC">
	<DIV>Artist: <xsl:value-of select="ARTIST"/></DIV>
	<DIV>Title: <xsl:value-of select="TITLE"/></DIV>
	<DIV>Format: <xsl:value-of select="FORMAT"/></DIV>
	<DIV>Estimated Worth: <xsl:value-of 
	select="ESTIMATED_WORTH"/></DIV>
	<DIV>----------------------------------------------
	</DIV>    
	</xsl:for-each>
</HTML>
The first line of the XSL code specifies the namespace, hence the ns in the xmlns: in the first tag. We won't concentrate too much on this one. You can read the complete explanation in the working draft at www.w3.org/TR/REC-xml-names

The prefix xsl: in the second line specifies XSL elements to be handled by the XML processor.

The next several lines of code are responsible for displaying our XML fields. Note that the XML code in Listing A contains multiple nodes with the same attributes. You can see that every <MUSIC> node contains exactly the same data elements: artist, title, format, and estimated price. We'd like to display all these data fields in the same format for our example.

The next line of XSL in Listing B,

<xsl:for-each select =
	"MY-COLLECTION/MUSIC"> 
tells the XML processor to apply the same template to every <MUSIC> node within MY-COLLECTION. Note that you must include this ending tag
</xsl:for-each>
to define the range that the opening tag applies to. Now that we've indicated what nodes we'd like to process, we have to indicate to the processor what we'd like to do with the data within them. This is accomplished by specifying the following within the XSL:
<xsl:value-of select="ARTIST"/>
<xsl:value-of select="TITLE"/>
<xsl:value-of select="FORMAT"/>
<xsl:value-of select="ESTIMATED_WORTH"/>
The xsl:value-of statement takes a valid XML pattern and returns the value in the node. In our example, by specifying only the node name in the select attribute, we're simply retrieving that node's value in the current context of the xsl:for-each statement.

After returning all the data elements, we close our xsl:for-each tag. Some extra labels and a divider have also been added so the output is more readable. These are processed just like text in an HTML page.

The XSL patterns assigned to each select attribute can contain different expressions that affect what data you return. A full discussion of the XSL pattern syntax can be found at msdn.microsoft.com/xml/xslguide/patterns-overview.asp

XML and XSL meet HTML

We now have our XML code and our XSL code, each contained in separate files. Now let's bring these data elements into our HTML page. In Listing C you'll see the HTML code you need.

Listing C: HTML containing XML

<HTML>
<HEAD>
<TITLE>Mike's Collection of Music</TITLE>

<!Script goes here

</HEAD>
<!-- Here are the XML tags to define the external -->
<!-- XML and XSL source files -->
<XML id="myXML" SRC="mike_data.xml"></XML>
<XML id="myStyle" src="xsl_source.xsl"></XML>
<BODY LANGUAGE=javascript onload="return window_onload()">
<P><FONT face="Rockwell Extra Bold" size=5>
<STRONG>Mike's Collection of Music</STRONG></FONT></P>
<DIV id="xmlContent"></DIV>
</BODY>
</HTML>

The XML/HTML connection

Let's first look at getting the XML data into our HTML page for display. The HTML code we'll use is in Listing C. Since our XML is in a separate file, rather than embedding it right in the page, we can create a data island in the HTML code that provides a connection to this external XML file. By surrounding an XML block with <XML> tags in our HTML code, we tell the browser to expect XML code within those tags. We can then access an external XML source file by setting the src attribute of the <XML> tag to the name of our XML file. Assuming the file is called mike_data.xml, we do that with the statement:

<XML id="myXML" src="mike_data.xml">
</XML>
Using this method, the XML document is completely separate from the HTML page surrounding it. Therefore, you can use any method you wish to populate the XML page without having to change the HTML every time. This includes creating the page manually in XML Notepad, or writing an application to construct well-formed XML from another data source.

Those zany guys in the "Extreme XML" column at Microsoft featured an example of building such a structure from an Access database at msdn.microsoft.com/xml/articles/xml030998.asp

Since you probably work with data from relational databases already, this could prove to be a very useful technique.

XSL gets included, too

Much like the data island we created previously, we need to include the XSL file in our HTML code like this:

<XML id="myStyle" src="xsl_source.xsl">
</XML>
Note that we use the same src attribute we used for the XML document to point to the XSL document. Using the transformation capability of the XSL, we're able to convert our XML data island into HTML code that the browser can display. How the HTML is formed depends on the XSL style sheet applied to it.

Transforming XML to HTML

The code in Listing C sets up the data islands for us, but we still have to transform their contents into HTML so the data will display in the browser. The script we need to add to our HTML code appears in Listing D.

Listing D: Script for transforming XML to HTML

<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>
<!--
function window_onload() {
	xmlContent.innerHTML = 
	=>myXML.transformNode(myStyle.XMLDocument);
}
//-->
</SCRIPT>
In the window_onload function, we actually perform the transformation from XML to HTML like this:
xmlContent.innerHTML = myXML.
=>transformNode(myStyle.XMLDocument);
This HTML page produces the output you saw in Figure A. The transformNode method on the XML data island we've defined returns the contents in HTML for us. Its only parameter is the node we would like to transform. This data is then assigned to the xmlContent DIV tag contained in the BODY of the page. Once you've defined your XML and XSL files, this one line is all it takes. Since we're using an external XML file, any changes to the data will automatically appear on the screen.

Don't stop there

So now you know how to display a simple XML file in your HTML page. Once you've defined your XML data island, you can manipulate it like any other XML structure. In the July 1999 issue of Microsoft Web Builder, we showed you how to traverse your XML nodes. In that example, we populated the XML document utilizing script. In this case, utilizing the ID assigned to our XML tags, you can perform the methods needed to navigate the nodes. A reference to the XMLDocument would look like this:

var xml_document = myXML.XMLDocument;
Microsoft's XML DOM reference can be found on their site at msdn.microsoft.com/xml/reference/xmldom/start.asp

The beginning of a great thing

This simple example barely scratches the surface of what can be done with XML. The language is a very powerful tool for manipulating data. Look more closely at the XSL reference and you'll see how easy it is to change the look of your output. Using this article as a starting point, take our structure and try to tweak it. Some things you could try: sort the records, filter them on certain field criteria, or actually change the data in a node before outputting it. XML's strength will become more apparent as you become more familiar with the language and its application. And, keep in mind that the transformation method we use in this article is a subset of the entire XSL language working draft. Microsoft intends to support XSL in its entirety, based on the final W3C recommendations. You can view the current working draft of XSL at www.w3.org/TR/1998/WD-xsl-19981216.html

Copyright © 1999, ZD Inc. All rights reserved. ZD Journals and the ZD Journals logo are trademarks of ZD Inc. Reproduction in whole or in part in any form or medium without express written permission of ZD Inc. is prohibited. All other product names and logos are trademarks or registered trademarks of their respective owners.