An ASP Class for XML Data Transfer

An ASP Class for XML Data Transfer

It is assumed that the reader has a good understanding of ASP, VBScript classes and XPath.

Hey, I wrote the “A Couple of ASP Functions for XML Data Transfer” functions and, as any self-respecting programmer, was unhappy with its stiffness. I decided enough is enough and created an actual class that handles more things. clsXML.asp is the actual class and objXML.asp is an implementation of the class. It can actually be used in a huge variety of ways. For example, if there is a need to store a recordset in XML, this class greatly aids in that process. It is very robust and allows for some pretty neat things.

Only one property: File. It needs to know where to look otherwise a new XML document must be created. In other words, if you try to get fields before specifying the document, it will not work.

Here are some of the methods included:

  1. createFile – creates a new XML file by specifying the file name and the new root node
  2. getField – returns all fields returned by an XPath query
  3. updateField – updates all fields specified by an XPath query
  4. createRootChild – can you guess?
  5. createRootNodeWAttr – This function allows the creation of a root child with any attribute scheme imagined
  6. createChildNode – This allows for a child node to be created under any node that is returned by an XPath query
  7. createChildNodeWAttr – Ditto, but with the functionality of 5
  8. deleteNode – Deletes any node that is returned by the XPath Query

A couple of errors you might encounter:

  1. If the XML file is not well-formed, the XML object will not be created properly, also if the file does not exist (duh!).
  2. When writing to a file, there might be a permissions error. Make sure that the directory which is being written to has all of the necessary permissions.

Happy programming!

File Listings

clsXML.asp
<%
Class clsXML
  'strFile must be full path to document, ie C:\XML\XMLFile.XML
  'objDoc is the XML Object
  Private strFile, objDoc

  '*********************************************************************
  ' Initialization/Termination
  '*********************************************************************

  'Initialize Class Members
  Private Sub Class_Initialize()
    strFile = ""
  End Sub

  'Terminate and unload all created objects
  Private Sub Class_Terminate()
    Set objDoc = Nothing
  End Sub

  '*********************************************************************
  ' Properties
  '*********************************************************************

  'Set XML File and objDoc
  Public Property Let File(str)
    Set objDoc = Server.CreateObject("Microsoft.XMLDOM")
    objDoc.async = False
    strFile = str
    objDoc.Load strFile
  End Property

  'Get XML File
  Public Property Get File()
    File = strFile
  End Property

  '*********************************************************************
  ' Functions
  '*********************************************************************

  'Create Blank XML File, set current obj File to newly created file
  Public Function createFile(strPath, strRoot)
    Dim objFSO, objTextFile
    Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
    Set objTextFile = objFSO.CreateTextFile(strPath, True)
    objTextFile.WriteLine("<?xml version=""1.0""?>")
    objTextFile.WriteLine("<" & strRoot & "/>")
    objTextFile.Close
    Me.File = strPath
    Set objTextFile = Nothing
    Set objFSO = Nothing
  End Function

  'Get XML Field(s) based on XPath input from root node
  Public Function getField(strXPath)
    Dim objNodeList, arrResponse(), i
    Set objNodeList = objDoc.documentElement.selectNodes(strXPath)
    ReDim arrResponse(objNodeList.length)
    For i = 0 To objNodeList.length - 1
      arrResponse(i) = objNodeList.item(i).Text
    Next
    getField = arrResponse
  End Function

  'Update existing node(s) based on XPath specs
  Public Function updateField(strXPath, strData)
    Dim objField
    For Each objField In objDoc.documentElement.selectNodes(strXPath)
      objField.Text = strData
    Next
    objDoc.Save strFile
    Set objField = Nothing
    updateField = True
  End Function

  'Create node directly under root
  Public Function createRootChild(strNode)
    Dim objChild
    Set objChild = objDoc.createNode(1, strNode, "")
    objDoc.documentElement.appendChild(objChild)
    objDoc.Save strFile
    Set objChild = Nothing
  End Function

  'Create a child node under root node with attributes
  Public Function createRootNodeWAttr(strNode, attr, val)
    Dim objChild, objAttr
    Set objChild = objDoc.createNode(1, strNode, "")
    If IsArray(attr) And IsArray(val) Then
      If UBound(attr)-LBound(attr) <> UBound(val)-LBound(val) Then
        Exit Function
      Else
        Dim i
        For i = LBound(attr) To UBound(attr)
          Set objAttr = objDoc.createAttribute(attr(i))
          objChild.setAttribute attr(i), val(i)
        Next
      End If
    Else
      Set objAttr = objDoc.createAttribute(attr)
      objChild.setAttribute attr, val
    End If
    objDoc.documentElement.appendChild(objChild)
    objDoc.Save strFile
    Set objChild = Nothing
  End Function

  'Create a child node under the specified XPath Node
  Public Function createChildNode(strXPath, strNode)
    Dim objParent, objChild
    For Each objParent In objDoc.documentElement.selectNodes(strXPath)
      Set objChild = objDoc.createNode(1, strNode, "")
      objParent.appendChild(objChild)
    Next
    objDoc.Save strFile
    Set objParent = Nothing
    Set objChild = Nothing
  End Function

  'Create a child node(s) under the specified XPath Node with attributes
  Public Function createChildNodeWAttr(strXPath, strNode, attr, val)
    Dim objParent, objChild, objAttr
    For Each objParent In objDoc.documentElement.selectNodes(strXPath)
      Set objChild = objDoc.createNode(1, strNode, "")
      If IsArray(attr) And IsArray(val) Then
        If UBound(attr)-LBound(attr) <> UBound(val)-LBound(val) Then
          Exit Function
        Else
          Dim i
          For i = LBound(attr) To UBound(attr)
            Set objAttr = objDoc.createAttribute(attr(i))
            objChild.SetAttribute attr(i), val(i)
          Next
        End If
      Else
        Set objAttr = objDoc.createAttribute(attr)
        objChild.setAttribute attr, val
      End If
      objParent.appendChild(objChild)
    Next
    objDoc.Save strFile
    Set objParent = Nothing
    Set objChild = Nothing
  End Function

  'Delete the node specified by the XPath
  Public Function deleteNode(strXPath)
    Dim objOld
    For Each objOld In objDoc.documentElement.selectNodes(strXPath)
      objDoc.documentElement.removeChild objOld
    Next
    objDoc.Save strFile
    Set objOld = Nothing
  End Function
End Class
%>

This implementation of the class creates a new XML document. If you simply want to use an existing XML document, simply call the File property and specify the path.

objXML.asp
<%@ Language=VBScript %>
<% Option Explicit %>
<!--#INCLUDE FILE="clsXML.asp"-->
<%
Dim objXML, strPath, str
Set objXML = New clsXML

strPath = Server.MapPath(".") & "\New.xml"

objXML.createFile strPath, "Root"
'Or If using an existing XML file:
'objXML.File = "C:\File.xml"

objXML.createRootChild "Images"

'Here only one attribute is added to the Images/Image Node
objXML.createChildNodeWAttr "Images", "Image", "id", "1"
objXML.updateField "Images//Image[@id=1]", "super.gif"
objXML.createRootNodeWAttr "Jobs", Array("Size", "Length", "Width"), _
	Array(24, 31, 30)
objXML.createRootNodeWAttr "Jobs", Array("Size", "Length", "Width"), _
	Array(24, 30, 29)
objXML.createRootNodeWAttr "Jobs", Array("Size", "Length", "Width"), _
	Array(24, 31, 85)

'Notice that all three job nodes have size 24, all of those 
'nodes will be updated
objXML.updateField "Jobs[@Size=24]", "24's"

'Notice that only two nodes have the specified XPath, hence 
'only two new child nodes will be added
objXML.createChildNodeWAttr "Jobs[@Size=24 and @Length=31]", "Specs", _
	Array("Wood", "Metal", "Color"), _
	Array("Cedar", "Aluminum", "Green")

'It is always important to iterate through all of the nodes
'returned by this XPath query.
For Each str In objXML.getField("Jobs[@Size=24]")
	Response.Write(str & "<br>")
Next
Set objXML = Nothing

Response.Redirect "New.xml"
%>

Here is the output of the implementation:

<?xml version="1.0"?>
<Root>
	<Images>
		<Image id="1">super.gif</Image>
	</Images>
	<Jobs Size="24" Length="31" Width="30">
		24's
		<Specs Wood="Cedar" Metal="Aluminum" Color="Green"/>
	</Jobs>
	<Jobs Size="24" Length="30" Width="29">
		24's
	</Jobs>
	<Jobs Size="24" Length="31" Width="85">
		24's
		<Specs Wood="Cedar" Metal="Aluminum" Color="Green"/>
	</Jobs>
</Root>

Questions? Email me!

In part 2 we’ll look at the .NET implementation of the exact same thing.

Seth Juarez
Technology Consultant
Holman’s of Nevada Inc.
e-mail: [email protected]

Download

You can download all the files listed above in this one zip file.

Related posts

SOAP Soup

Introduction Simple Object Access Protocol is one of the neatest XML based technologies to be introduced as of late, yet many people are still trying to get a handle on all of the new terms and acronyms that SOAP has uncovered. This article is written to help you dig through the SOAP...

Read More

Using XML to build an ASP+ config.web Editor

Introduction ASP+ configuration information is stored in XML-based configuration files. Using built-in features of IIS 5.0 and IE 5.0 such as the FileSystemObject, the XML Document Object Model (DOM) and XML Data Islands, we can easily develop a rich tool for modifying and editing these configuration files. In this...

Read More

Saving HTML Form Data to XML

Introduction This example assumes that you are familiar with ASP, XML and HTML 4.0. Storing your form submissions in XML Usually form submissions in ASP are written to some sort of database management system. However, if you need your form submission data to be more portable, it can be...

Read More