Demystifying XML

Web Languages
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

In a recent project, some salespeople told my development team it would be a big help if the salespeople could review the sales histories of their customers online. Management thought it was a good idea, so we got the project. The goal was to present a simple list that our ace road warriors could click to select a customer. We also wanted to give them the ability to sort the list by either customer number or name. How could it be done? Dynamically sorting and formatting Extensible Markup Language (XML) data using JavaScript and Extensible Style Language (XSL) accomplished it. By using this approach, we were able to leverage the XML document that our sales data was stored in and move the sort and presentation formatting workload from the server to the client browser. This article details the XSL and JavaScript that is executed by the client browser to create this interactivity. We began by writing a servlet that returns an XML-described list of customers in a territory like this:






The project source presented here contains five files (Figure 1). When the browser reads salescust.xml, it finds commands that tell it to interpret the data as defined in the schema and to produce its output according to the instructions in the XML stylesheet.

The XML stylesheet contains instructions to load both the cascading style sheet and the global JavaScript functions. These two files provide the visual formatting classes and scripts that are needed to control the output rendering and user input processing.

You can download the complete project from the Midrange Computing Web site at www.midrangecomputing.com/mc. As things stand today, you’ll need Microsoft Internet Explorer Version 5.5 or higher to run it.

The Skeleton


Like any good construction project, XSL needs a structural framework. For this project, that framework looks like Figure 2. You can see that the template exactly mirrors the structure of the XML. It must start with the root node (“/”).

The nonbreaking space character ( ) is not built into XML the way it is in HTML, but it’s still useful. So, I declare it myself, as I’ve done in the example.

Fleshing It Out

The root node contains the document header and the static parts of the body (see Figure 3). It executes one time when the document is loaded. This particular template does little more than build a table with three columns that spans the entire width of the page. The middle column is centered on the page and is 300 pixels in width.

The section contains an instruction to load a file that contains some JavaScript functions that are useful on many different pages (“javascript/globalxml.js”). It also includes a referencing a cascading style sheet to control the appearance of the elements on the page (“stylesheets/styles.css”).

Between the head and body sections, notice the script that requests the sales detail when the user selects a customer from the list. The script itself is enclosed in a CDATA block, a curious construct for including data that should not be parsed. It isn’t strictly necessary to do this to add a script to a style sheet, but it’s a good idea. It keeps the parser from falling over because it thinks the document contains mismatched quotes or brackets. This block also contains a section of code that I haven’t shown. This code protects the JavaScript so nothing can execute until the external global functions are fully loaded. Download the source if you’d like to look at it.

Notice that the tag is now enclosed within (table cell) tags, with an “id” attribute containing the value “listing.” This makes “listing” an area that can be referenced by its “id,” and provides the addressability needed to dynamically update the contents of the page. This is dynamic hypertext markup language (DHTML). Not too scary, is it? The value of “listing” will be whatever is returned when is processed by the parser.

The Dynamic Content

Figure 4 (page 100) contains the rest of the style sheet. The “sales” template now contains

tags around the (See Figure 4, Section A). Notice also contains an attribute named “class,” whose value is “outline.” This is a cascading style sheet class, and it defines the visual attributes of this particular table. It has an outline, and its width is 100 percent of the width of its container (300 pixels). Recall that the entire “sales” template is actually rendered inside of the “listing” table cell. You are working with several levels of nested block elements here.

The “territory” template contains a row that holds the table heading (Figure 4, Section B). It uses the “dialogfont” class to determine its visual characteristics, and it spans two rows (colspan=”2”). It contains the text “Territory” followed by the value of the territory’s “id” and “rep” attributes. A second line (
) within the same table row contains the text “Customer Selection.” By default, the HTML rendering engine will collapse multiple white space characters. Since line breaks in the document source, and tabs and spaces are white space characters, each of these bits of text will be separated by a single space. The style sheet specifies that the

tags in Figure 3 or the entire contents of Figure 4. Voila! The list data is redisplayed in the new order. It’s important to note that the transformNode() function processes everything except the style sheet’s root node, so everything outside the list must be defined in the root (/) template.


This Is Just a Trivial Little Example, But...

I hope it has given you a glimpse of the power that’s available in this new marriage of XML and DHTML. You can use this technology to build robust, full-functioned applications. What I’ve shown you is just the tip of the iceberg. Download the example code from www.midrangecomputing.com/mc and play with it. Explore some of the sites listed in the References and Related Materials list for more ideas and examples. Don’t worry about it being complex. It just seems that way at first. If you can maintain that 2000- line RPG program, this will be a snap. Dive in! The water’s fine.

REFERENCES AND RELATED MATERIALS

• Microsoft BizTalk: www.microsoft.com/biztalk/

• Microsoft Windows Script Technologies: http://msdn.microsoft.com/scripting/default.htm

• Microsoft XML SDK 2.5: http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/xmlsdk/xmls6g53.htm

• Web Developer’s Virtual Library: www.wdvl.com/ Authoring/Languages/

• xmlpitstop.com Web site: www.xmlpitstop.com

• xmlTree Directory of Content Web site: www.xmltree.com

salescust.xml The data Is the file that the browser requests. Double click it to see what the result looks like.

salescust.xsl XML Stylesheet Contains the run-time logic that tells the XML processor how to display the data.

schemas/sales.xml XML Schema Defines XML element relationships and data types found in the salescust application.

stylesheets/styles.css Cascading Style Defines classes that tell the

Sheet browser how to display specific types of HTML elements. This will give all of the pages in the application a consistent look and feel.

javascript/globalxml.js External script Contains general script functions functions that are useful in many different XML stylesheets

Figure 1: The downloadable code contains five files. This figure documents their usage.




]>

http://www.w3.org/TR/WD-xsl">


Figure 2: The skeleton XSL template exactly mirrors the structure of the XML.


element’s text should be centered so both lines will be centered within the width of the table.

The two column header buttons (Figure 4, Section C) make the output look like a spreadsheet or grid control. Each table cell specifies three class names “button enabled link”. Each of these is a style sheet class, and “button” does just what you would expect. It makes the cell look like a button. The “enabled” class name specifies that the cell should inherit its color attributes from elsewhere. The “link” class name sets the text color to blue and makes the “hand” cursor display when the mouse passes over the element. The


JavaScript events defined for each button complete the effect. When the mouse passes over the button or when it receives a mouse click, the text color changes as expected. The mouseOver, mouseOut, and mouseDown functions are defined in globalxml.js. They’re all very similar. Here’s the mouseOver function:

function mouseOver(obj) {
obj.style.color=’#FF0000’;
}

It sends the “this” pointer, an object reference to the

element, to the mouseOver function, which changes the text color of whatever object is passed to it.

In Figure 4, Section D, you get to the really neat stuff! Here an attribute named “order-by” is specified on the tag. Everything between and is a loop that is executed for each customer (select=”customer”) row within the current context (the territory). It’s an alternative to .

Within each loop, a table row is constructed consisting of a customer ID button and a customer name. The XSL processor sorts the data as specified (initially by the customer’s “id” attribute).

When the user clicks a customer ID button, the onClick event fires, and the event handler passes a reference to its container (the table cell or

element) to the loadPage function in Figure 3. Then loadPage opens a new window (a new instance of the browser), specifies that its contents will be provided by “salesdtl.asp” and appends a query string consisting of “cust=” and the contents of the table cell (its innerHTML property), which is the customer ID. Of course, “salesdtl.asp” is a script or servlet that can retrieve the sales information for a single customer.

Sorting the List

What happens when the user clicks one of the column headers? I’m glad you asked. Going back to Figure 4, Section C, when the onClick event fires, onClick=”sort (‘@custname’);” or onClick=”sort(‘@id’);” passes the literal value “@custname” or “@id” to the sort function in globalxml.js. It looks like this:

stylesheet = document.XSLDocument;
source = document.XMLDocument;
sortField = document.XSLDocument.selectSingle
Node(“//@order-by”);

function sort(field) {
sortField.value = field;
listing.innerHTML = source.documentElement.transformNode(stylesheet);
}

The first three lines are really executed when the global functions are loaded. They’re not part of the function itself. They retrieve object references for the XSL style sheet, the XML document, and the attribute named “order-by” that was declared in Figure 4, Section D.

The sort function takes the literal value (“@custname” or “@id”) and assigns it to the value of the “order-by” attribute of the element. Then it tells the XML parser to reparse the document, replacing the contents of listing.innerHTML, which is everything between the

and





 


 

Figure 3: The root node is the static part of the page.





Territory



Customer Selection


onClick=”sort(‘@id’);”
onMouseOver=”mouseOver(this);”
onMouseOut=”mouseOut(this);”
onMouseDown=”mouseDown(this);”>
Cust

onClick=”sort(‘@custname’);”
onMouseOver=”mouseOver(this);”
onMouseOut=”mouseOut(this);”
onMouseDown=”mouseDown(this);”>
Name



onClick=”loadPage(this);”
onMouseOver=”mouseOver(this);”
onMouseOut=”mouseOut(this);”
onMouseDown=”mouseDown(this);”>





A

B

C

D

Figure 4: The balance of the style sheet defines the dynamic content.


BLOG COMMENTS POWERED BY DISQUS