When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
Related Web Technologies
User Tips!
Coding Tips

Sample Chapters
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
XML Info
Author an Article
Print this page.
Published: Wednesday, June 20, 2001

Creating an XML and XSL Class

By Richard Chisholm

More on Classes and XML
This article examines how to use VBScript classes to transform XML documents for use in a Web application. Before tackling this article, readers should have a solid understanding of classes and XML. To learn more about either of these subjects, be sure to check out the following links:

As you have no doubt read here on 4Guys, using VBScript classes can simplify your ASP code by hiding the complexities of certain tasks. An added benefit to this is that the presentation portion of the page, which likely includes a mixture of VBScript and HTML, can also be made simpler and easier to read. This article will highlight a Class that transforms XML documents for use in Web applications. The class is very straight forward, and is designed to be used as an include utility file. More specifically, it can return either HTML or XML data, as well as access and modify the XML or XSL document on the server, sending the results to main ASP code. Thus, you can easily tailor your code for a specific browser. I developed this on Windows 2000 Pro, with the MSXML3 parser installed. Any MS operating system should be fine, just as long as you have MSXML3 and VBScript 5.0. (To learn what version of VBScript you are using be sure to read: Determining the Server-Side Scripting Language and Version.)

Ok let's get into the code. First off, if you need to get familiarized with VBScript classes, just do a search on this site, or read Using Classes within VBScript. All of the following code is inside the class, called XML_Handler. To start, there are two private global variables in the class: XMLDocument and XSLDocument. These variables will hold their respective objects in memory so that they can be modified if needed. To create the objects there are two public functions, but since the code for both is identical except for the variable names, I will only show one of them, plus a private function to create the MSXML3 object (note that the complete class code is downloadable at the end of this article):

Public Function LoadXML(XMLDoc) 
    Set XMLDocument = LoadMSXML2() 
End Function 

Private Function LoadMSXML2()
	Dim objXML 'As MSXML2.DOMDocument
	Set objXML = Server.CreateObject("MSXML2.DOMDocument")
	With objXML
	    .async = False 
	    .validateOnParse = False 
	    .preserveWhiteSpace = True
	    .resolveExternals = False 
	End With
	Set LoadMSXML2 = objXML
	Set objXML = Nothing
End Function

You pass the full path of the XML/XSL document as the only parameter. Then the DOM object itself is created in a separate, private function. Why is it done this way? Well, it avoids duplicate code in both Load functions, and yet another way to show off the usefulness of this technique! The code for the private function, called LoadMSXML2(), simply creates the object, sets a few properties, and passes back the object reference. Note that both objects do not have to be created. For example, when developing for an IE5+ platform, it is possible to return XML directly to the browser, so there would be no need to create the XSL object.

Now that the XML/XSL objects have been created it is time to see how to manipulate them. There are several different scenarios that you are likely to encounter that this class is designed to handle. These are:

  1. Returning XML to the client
  2. Adding a reference to an XSL style sheet inside the XML document, and sending it to the client
  3. Transforming XML/XSL and returning html
  4. Transforming XML/XSL, where the XSL document has parameters that need to be set.

For all four of the scenarios, there is an Execute() function that must be called. This function is responsible for actually returning data, either in XML or HTML format, back into the main ASP code so that it can be rendered with the rest of the page. The code for Execute() is simple, and looks like this:

Public Function Execute(strMethod) 
    If strMethod = "HTML" Then 'Returns HTML for client side transformations 
        Execute = XMLDocument.transformNode(XSLDocument) 
    End If
    If strMethod = "XML" Then 'Returns XML for use with IE 
        Execute = XMLDocument.xml 
    End If 
    Set XMLDocument = Nothing 'Destroy XML objects created earlier 
    Set XSLDocument = Nothing 
End Function  

The function takes one parameter that determines which format the data is returned in. For HTML, a transformation is run with both XMLDocument and XSLDocument, while if XML is desired the .xml Microsoft-only method is run to return the entire xml document as text. Lastly, the global XML DOM objects must be destroyed.

Now, if making changes to either the XML or XSL document are not necessary, then calling the Load() and Execute() functions are all that is needed. However, if the situation requires changing variables in the XSL style sheet then the AssignParameter() function can be used (code below).

strParameter = "//xsl:param[@name='" & strParameter & "']"
Set XSLParam = XSLDocument.selectSingleNode(strParameter)
XSLParam.childNodes(0).nodeValue = strValue		  

The AssignParameter() function takes the name of a parameter and its value and changes the XSL document using the selectSingleNode method to find the proper xsl:param element.

Likewise, in a situation where XML is being sent directly to the browser, to add a reference to a style sheet in the XML document itself the AddStyleSheet() function can be used. This function takes a local reference to the style sheet (NOTE: this is different from the AssignParameter() function, which needs the full path) and looks like:

Set XMLInstruct = XMLDocument.createProcessingInstruction ("xml:stylesheet", _
	"type=""text/xsl"" href=" & chr(34) & strStyleSheet & chr(34) & "")
If Instr(1,XMLDocument.childNodes(0).xml, "?xml") Then
	Set topNode = XMLDocument.childNodes(1)
	Set topNode = XMLDocument.childNodes(0)
End If
XMLDocument.insertBefore XMLInstruct, topNode

In the code above, the first line creates the XML processing instruction, which look like <?...?>. The text inside those elements must be in a specific format, with attribute values in double quotes. Thus the second parameter of this method uses both escaped double quotes and ASCII values for slightly easier reading. Then the If statement checks the XML document for existence of the standard declaration: <?xml version="1.0"?>. Because the best method of inserting data into an XML document is the insertBefore method, if the XML declaration exists then the new processing instruction must be inserted after (i.e. before childnode 1). Otherwise it can be inserted at the top (which is childnode 0).

In addition to the XML_Handler class, there are two separate functions that act as wrappers to facilitate its use. The TransformXMLWithXSL() performs a simple transformation (without changing any parameters) and returns HTML, while ReturnXMLWithXSL() returns an XML document with an XSL style sheet reference. These two functions allow for better integration with HTML in long documents. For example, if XML data is transformed on the server into a table through XSL, it can be output like this:

<!-- HTML content -->
<!-- Now create table with XML/XSL data-->
<%Response.Write(TransformXMLWithXSL(strXMLDoc, strXSLDoc))%>
<!-- More HTML Content -->

Hopefully, through this article I have shown the advantages of using classes to simplify your ASP pages, as well as how easy it can be to use XML and XSL in them. Encapsulation through VBS classes can increase both flexibility and scalability compared to a more conventional way of coding ASP pages. The use of this class allows the MSXML DOM objects to be held in memory and be modified without using variables global to the entire ASP page. This encapsulation allows for better flexibility. For example, the AssignParameter() function can be called as many times as needed. Likewise, it is certainly possible to create more functions besides the two I have included in or outside of the class. For example, you could add a function to change xsl:variable elements, or a new wrapper function customized to change a specific number of parameters. Thanks for reading!

Happy Programming!

  • By Richard Chisholm


  • View the complete XML_Handler class
  • View a live demo!

  • ASP.NET [1.x] [2.0] | ASPFAQs.com | Advertise | Feedback | Author an Article