Easy way to writing XML
The Microsoft XML component was OK for me, till I needed to write XML to be created, as previously I mostly needed it for parsing existing XML files. The biggest drawback I found was that it didnot format the generated XML with indents etc, and the result xml was a long string. As I was supposed to provide indentation also, I did it anyhow by calculating spaces required for each node... don't ask me how? It took me time, and if ever need to re-do the same, that would take even more...
At last my work finished, but what will happen when I am required to do similar thing again? I decided to give more time and rewrite the XML formation part as a DLL component, which I reproduce here. I have written the component referencing the "Microsoft XML 2.6" (msxml2.dll) and have not tested it over later versions. Since this component exposes limited properties and methods, it is relatively easier (mmm...more than that) to use for minimal requirement of writing XML files.
Dim objXMLText As DOMDocument Dim objNodes As IXMLDOMElement Private intCurTree As Integer Private iChar As String Dim varNodeTree(0 To 10)
Since, I have used Array for storing node references, the depth of nodes will be limited to the Upper bound in the Dim statement as shown above. For me 10 was more than sufficient. I feel to rewrite it using collections but I better change the upper bound there for now.
The Component exposes two Properties indentChar and XMLText
indentChar is a write-only property which allows you to specify the Characters/length you need to use for indent. By default, it assigns vbTab (tab Character)
XMLText property gives you the XML text at any moment of time. Though SaveXML method is recommended if you need to save it.
Private Sub Class_Initialize()
iChar = vbTab
End Sub
Public Property Let indentChar(ByVal strIChar As String)
iChar = strIChar
End Property
Public Property Get XMLText()
XMLText = objXMLText.XML
End Property
To start writing the XML you need to call CreateXML method
Public Sub CreateXML()
Set objXMLText = New DOMDocument
End Sub
The root element is created using CreateRootElement Method. It takes for parameter the tagname which you need to assign to root element.
Public Sub CreateRootElement(ByVal strRootName As String)
Set varNodeTree(0) = objXMLText.createElement(strRootName)
objXMLText.appendChild varNodeTree(0)
intCurTree = 0
End Sub
All other node are created using CreateXMLElement method which takes a number, the node depth of parent node counting from root ( Zero for nodes whose parent is the Root Node ) apart from the tagname which is the second parameter.
Public Sub CreateXMLElement(ByVal intParent As Integer, ByVal strElementName As String)
Dim ctr As Integer
Dim striChars As String
striChars = String((intParent + 1) * Len(iChar), iChar)
varNodeTree(intParent).appendChild objXMLText.createTextNode(vbNewLine)
varNodeTree(intParent).appendChild objXMLText.createTextNode(striChars)
For ctr = intCurTree - 1 To intParent + 1 Step -1
striChars = String(ctr * Len(iChar), iChar)
varNodeTree(ctr).appendChild objXMLText.createTextNode(vbNewLine)
varNodeTree(ctr).appendChild objXMLText.createTextNode(striChars)
Next
Set varNodeTree(intParent + 1) = objXMLText.createElement(strElementName)
varNodeTree(intParent).appendChild varNodeTree(intParent + 1)
intCurTree = intParent + 1
End Sub
Attributes and its value can be set using method SetXMLAttr which takes the index of node as described above, the attribute name and the value for the parameters.
Public Sub SetXMLAttr(ByVal intIndex As Integer, ByVal strAttrName As String, ByVal strAttrValue As String)
varNodeTree(intIndex).setAttribute strAttrName, strAttrValue
End Sub
The text or comments between the opening and closing tag can be added using the AddText and AddComment methods passing index of node and the Text string as parameters
Public Sub AddText(ByVal intIndex As Integer, ByVal strText As String)
varNodeTree(intIndex).appendChild objXMLText.createTextNode(strText)
End Sub
Public Sub AddComment(ByVal inIndex As Integer, ByVal strComment As String)
varNodeTree(intIndex).appendChild objXMLText.createTextNode(vbCrLf)
varNodeTree(intIndex).appendChild objXMLText.createComment(strComment)
End Sub
And the SaveXML method can be used to save the generated XML to a file passed as parameter.
Public Sub SaveXML(ByVal strFilePath As String)
For ctr = intCurTree - 1 To 0 Step -1
striChars = String(ctr * Len(iChar), iChar)
varNodeTree(ctr).appendChild objXMLText.createTextNode(vbNewLine)
varNodeTree(ctr).appendChild objXMLText.createTextNode(striChars)
Next
objXMLText.save (strFilePath)
End Sub
All this little description, it would be better if I place a little code enhance the understanding more.
A code as this one :
Dim XMLPage As New MyXMLWriter.XML XMLPage.CreateXML XMLPage.indentChar = " " XMLPage.CreateRootElement "html" XMLPage.AddComment 0, "Comment in the HTML File" XMLPage.CreateXMLElement 0, "head" XMLPage.CreateXMLElement 1, "title" XMLPage.AddText 2, "The page Title" XMLPage.CreateXMLElement 0, "body" XMLPage.CreateXMLElement 1, "table" XMLPage.SetXMLAttr 2, "Border", 1 XMLPage.CreateXMLElement 2, "tr" XMLPage.CreateXMLElement 3, "th" XMLPage.AddText 4, "Heading 1" XMLPage.CreateXMLElement 3, "th" XMLPage.AddText 4, "Heading 2" XMLPage.CreateXMLElement 2, "tr" XMLPage.CreateXMLElement 3, "td" XMLPage.AddText 4, "data 1" XMLPage.CreateXMLElement 3, "td" XMLPage.AddText 4, "data 2" XMLPage.SaveXML "c:\\demo.html"
will generate a page as below :
<html>
<!--Comment in the HTML File-->
<head>
<title>The page Title</title>
</head>
<body>
<table Border="1">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
</tr>
<tr>
<td>data 1</td>
<td>data 2</td>
</tr>
</table>
</body>
</html>


