Last time, I showed you how XML and Extensible Style Language (XSL) can elegantly solve the age-old problem of browser incompatibility. However, I ended the discussion just short of the crucial point: How do you build such a solution in practice?

Suppose you're in precisely the situation I described in the last issue--that is, you have

  • An XML schema that fully describes all the pages on your Web site
  • All the XSL views you need (e.g., one each for Microsoft Internet Explorer—IE—5.0, IE 4.0, Netscape Navigator, and a Wireless Application Protocol—WAP—device)

You can create one (or a few, depending on your project and preferences) Active Server Pages (ASP) page that redirects users to the correct XML page and identifies the proper XSL according to the browser's capabilities. You can make links and forms to point to this redirector page, such as Redir.asp, in which a command-line parameter adds enough information for the actual content. For example, in the code

the ASP page extracts the XML name (or the information that allows a successful retrieval) and loads it. You also can store all the XML code in a database table. This solution is useful because you can rely on the database server for transaction handling, security, and concurrent access. In this case, Redir.asp doesn't necessarily need the file name, but it does require other information that you must define and code.

When the ASP page obtains the XML source code (whether it comes from a disk file or a database field), it can't easily convert that code into HTML. So, your next step is to determine the XSL associated with the browser that issued the request. Because both XML and XSL source code is available, you can easily convert the text to HTML.

An XSL set of rules acts on XML in the same way that a compiler does. XSL translates XML input into HTML output. XSL is an XML document, so you need an XML parser that supports XSL, such as Microsoft's MSXML parser. Here's the script code necessary to produce HTML code from XML:

Set xml = Server.CreateObject("Microsoft.XmlDom")
xml.async = False
xml.loadXML xmlSourceCode
Set xsl = Server.CreateObject("Microsoft.XmlDom")
xsl.async = False
xsl.loadXML xslSourceCode
html = xml.transformNode(xsl.documentElement)
Response.Write html

You need two distinct instances of MSXML parser: one to manage the XML document object model, and one for the XSL counterpart. Then you simply use the XML transformNode method on the root node of the XSL document object model. The final output is the HTML code the browser receives. (Be sure to set the Async property to False to ensure a synchronous creation of the XML document object model.)

Although this discussion focuses on Microsoft tools, such as ASP and the MSXML parser, this pattern is universal. The actors are an XML parser, a server-side application (Java Server Page, Common Gateway Interface—CGI), and a Web server that supports both. The only special requirement is that the XML parser support XSL.

If you need a client-side tool that compiles XML into HTML using an offline batch method, the code snippet above is already half the job. Just remove or replace the calls to the ASP's Server and Response objects, and you're done! Want an example? Here's a VBScript program that takes on the command line of XML, XSL, and HTML file names and creates a new HTML file:

fileXML = WScript.Arguments.Item(0)
fileXSL = WScript.Arguments.Item(1)
fileHTM = WScript.Arguments.Item(2)

set xml = CreateObject("Microsoft.XMLDOM")
xml.Async = False
xml.load(fileXML)
set xsl = CreateObject("Microsoft.XMLDOM")
xsl.Async = False
xsl.load(fileXSL)

set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.CreateTextFile(fileHTM)
f.Write xml.transformNode(xsl.documentElement)
f.Close