perfectxml.com
 Basic Search  Advanced Search   
Topics Resources Free Library Software XML News About Us
  You are here: home Focus MSXML » DOM Saturday, 23 February 2008
 
NEWS
MSXML 4.0 SP2 now available!

 
MSXML
Basics
DOM
SAX
XPath
XSLT
Schemas
SOM
HTTP Access
.NET
Data Islands
Ask a Question
   Past Q&As
C++ Samples
DLL/Version Info
Reference Guide
Books
KB Articles
   HOW TO
   SAMPLE
   INFO
   BUG/PRB
   FIX
   Misc.
MSXML Tips
   August 2002
   September 2002
MSXML Tools

Microsoft XML Core Services

DOM or Document Object Model is a W3C specification that defines a standard programming API to build, navigate, update and transform XML documents. MSXML supports DOM Level 2.

With DOM, the parser reads the input XML document and builds the hierarchical tree representation of this document in the memory. Once the complete document is loaded into the memory, the parser DOM methods allow to navigate and edit the document. This method is well-suited if you need random access to the document or need to update the document. However, DOM is not a viable choice for huge XML documents. Refer to the parser SDK documentation for more help on how to use MSXML DOM.       Tip: Chapter 2 (Document Object Model in MSXML) in the book XML Application Development with MSXML 4.0 covers MSXML DOM features in great details.

Let's now look at how to use MSXML 4.0 DOM in JavaScript, VBScript (ASP Pages), Visual Basic, Visual C++, C# (.NET) and VB.NET (early binding and late binding).

The following example(s) simply load a local XML document using DOM and spits out the document's contents.

JavaScript

<script language="JScript">
<!--
	try
	{
		var objDOMDoc = new ActiveXObject("Msxml2.DOMDocument.4.0");
		objDOMDoc.async = false;
		if (objDOMDoc.load("c:\\po.xml"))
		{
			alert(objDOMDoc.xml);
		}
		else
		{
			alert("Error: " + objDOMDoc.parseError.reason);
		}
	}
	catch(e)
	{
		alert("Error: " + e);
	}
//-->
</script>
			

VBScript (ASP Pages)

<%
	Option Explicit
	Response.CacheControl = "no-cache"
	Response.AddHeader "Pragma", "no-cache"
	Response.Expires = -1
	Response.Buffer = TRUE

	Dim objDOMDoc
	On Error Resume Next

	Set objDOMDoc = Server.CreateObject("Msxml2.DOMDocument.4.0")
	If Err Then
		Response.ContentType = "text/html"
		Response.Write "Error: " & Err.Description
		Err.Clear()
		Response.End
	End If
	objDOMDoc.async = False
	If objDOMDoc.load (Server.MapPath("po.xml")) Then
		Response.ContentType = "text/xml"
		Response.write objDOMDoc.xml
	Else
		Response.ContentType = "text/html"
		Response.write "Error: " & objDOMDoc.parseError.reason
	End If	
	
%>

Visual Basic

Start Visual Basic 6.0 and create a new Standard EXE project. Add reference (Project | Reference) to Microsoft XML v4.0, double click on the form and write following code under the Form_Load() method:
    Dim objDOMDoc As New MSXML2.DOMDocument40
    
    objDOMDoc.async = False
    If objDOMDoc.Load("c:\po.xml") Then
        MsgBox objDOMDoc.xml
    Else
        MsgBox "Error: " & objDOMDoc.parseError.reason
    End If
    
    Set objDOMDoc = Nothing

Visual C++

Start Visual C++ 6.0, create a new project of type Win32 Console Application and name the project as MSXMLDOMTest. Click OK and select A Simple Application from the next screen and then click on Finish button and then OK. Open MSXMLDOMTest.cpp file and update the file with following code:
#include "stdafx.h"
#include "stdio.h"
#import "msxml4.dll"
using namespace MSXML2;

inline void EVAL_HR( HRESULT _hr ) 
   { if FAILED(_hr) throw(_hr); }

int main(int argc, char* argv[])
{
   try 
   {
		IXMLDOMDocumentPtr objDOMDoc;

		EVAL_HR(CoInitialize(NULL)); 
		EVAL_HR(objDOMDoc.CreateInstance("Msxml2.DOMDocument.4.0"));

		_variant_t varXml("C:\\po.xml");
		_variant_t varOut((bool)TRUE);

		objDOMDoc->async = false;
		varOut = objDOMDoc->load(varXml);
		
		if ((bool)varOut == FALSE)
		 throw(0);
		
		printf(_bstr_t(objDOMDoc->xml)) ;
		printf("\n\nPress ENTER to continue...\n");
		getchar();
		return 0;
	}
	
	catch(...)
	{
		printf("Exception occurred");
		printf("\n\nPress ENTER to continue...\n");
		getchar();
		return -1;
	}

	CoUninitialize();   
}

C# .NET

Note that the .NET framework contains a namespace called System.Xml that contains various classes to work with XML. The following method (using MSXML in .NET applications using COM Interop) should only be used if it is required to quickly migrate (or reuse) the existing code.

The following code is written using .NET Framework Beta 2.


It's really easy to use MSXML with Visual Studio .NET. Simply by Adding Reference to Microsoft XML, v4.0 from the COM tab, creates a runtime callable wrapper that we can use to import the MSXML classes into our .NET application and use then as any other .NET class.

Let's do the same thing using the command prompt tools:

Start the DOS Command prompt (or better, Visual Studio .NET Command Prompt by clicking on Start | Programs | Microsoft Visual Studio .NET | Visual Studio .NET Tools) and type the following command at the prompt:

    >tlbimp msxml4.dll /out:MSXML4DotNet.dll

The type library importer (tlbimp) command line tool builds a proxy class that contains the necessary information used to create the runtime callable wrapper. You might see some warnings and can safely ignore them for now. The above command creates a file named MSXML4DotNet.dll. Start notepad and write the following C# code:
using System;
using MSXML4DotNet;

public class CSharpMSXML
{
	public static void Main()
	{
		try
		{
			DOMDocument40 objDOMDoc = new DOMDocument40();

			objDOMDoc.async = false;

			if (objDOMDoc.load(@"c:\po.xml"))
			{
				Console.WriteLine(objDOMDoc.xml);
			}

			else
			{
				Console.WriteLine("Parse Error: " 
					+ objDOMDoc.parseError.reason 
					+ objDOMDoc.parseError.srcText);
			}
			
		}
		catch(Exception e)
		{
			Console.WriteLine("Error: " + e.Message);
		}
		Console.ReadLine();
	}
}


Save the above file as msxmlcsharp.cs and complile it using the following command on the DOS Command Prompt:

    >csc.exe msxmlcsharp.cs /r:MSXML4DotNet.dll

Run msxmlcsharp.exe. This example illustrated using unmanaged COM code from within .NET C# application using early binding, let's see an example of using COM component through late binding.With the following approach (late binding), it is not required to run tlbimp.exe (or add a reference) to create a proxy class:

using System;
using System.Reflection;

public class CSharpMSXML2
{
	public static void Main()
	{
		try
		{
			Type typDOM = Type.GetTypeFromProgID("Msxml2.DOMDocument.4.0");

			object objDOMDocDisp = Activator.CreateInstance(typDOM);

			object [] param = new object[1];
			param[0] = false;

			typDOM.InvokeMember("async", BindingFlags.SetProperty, 
						null, objDOMDocDisp, param); 

			param[0] = @"c:\po.xml";

			object loadResult = null;

			loadResult = typDOM.InvokeMember("load", BindingFlags.InvokeMethod, 
						null, objDOMDocDisp, param);
			if ((bool)loadResult == true)
			{
				String s = (String)typDOM.InvokeMember("xml", 
							BindingFlags.GetProperty, 
							null, objDOMDocDisp, new object[]{});
				Console.WriteLine(s);
			}
			else
			{
				object pe = typDOM.InvokeMember("parseError", 
						BindingFlags.GetProperty, 
						null, objDOMDocDisp, new object[]{});

				String s = (String)typDOM.InvokeMember("reason", 
						BindingFlags.GetProperty, 
						null, pe, new object[]{});

				Console.WriteLine("Parse Error: " + s);
			}
		}
		catch(Exception e)
		{
			Console.WriteLine("Error: " + e.Message);
		}
		Console.ReadLine();
	}
}


Save the above file as latebinding.cs and run following command on the command prompt to complie the above C# code:

    >csc.exe latebinding.cs

Run latebinding.exe.

VB .NET

Assuming that you have already created the MSXML 4.0 Runtime Callable Wrapper DLL using tlbimp (as described above), here is the VB .NET code equivalent to above C# code:
Option Explicit On
Option Strict On

Imports System
Imports MSXML4DotNet

Public Class VBNETMSXML
	Shared Sub Main
		Try
			Dim objDOMDoc as DOMDocument40 = New DOMDocument40()
			With objDOMDoc
				.async = False
			
				If (.load ("c:\po.xml")) Then
					Console.WriteLine (.xml)
				Else
					Console.WriteLine ("Parse Error: " & _
						.parseError.reason & _
						.parseError.srcText)
				End If
			End With
		Catch e as Exception
			Console.WriteLine ("Error: " & e.Message)
		End Try
		Console.ReadLine()
	End Sub
End Class

Save the above file as vbnetmsxml.vb and complile it using the following command on the DOS Command Prompt:

    >vbc.exe vbnetmsxml.vb /r:MSXML4DotNet.dll

Run vbnetmsxml.exe.


Let's look at another small example to load an XML document and search for a specific node.

Here is the source XML document (c:\1.xml):
<?xml version="1.0"?>
<customers>

 <row ID="1">
  <CustomerID>ALFKI</CustomerID>
  <CompanyName>Alfreds Futterkiste</CompanyName>
  <ContactName>Maria Anders</ContactName>
 </row>

 <row ID="2">
  <CustomerID>ANATR</CustomerID>
  <CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
  <ContactName>Ana Trujillo</ContactName>
 </row>

</customers>
Let's now look at Visual Basic code to load the above XML document using MSXML DOM and then search for an element based on the CustomerID.

Start Visual Basic 6.0, create a Standard EXE Project, add reference (Project | References) to Microsoft XML, v4.0 (MSXML4.DLL), double click on the form and write following code inside the Form_Load method:
Dim objDOMDoc As New MSXML2.DOMDocument40
Dim ResultNode As MSXML2.IXMLDOMNode

objDOMDoc.async = False

If objDOMDoc.Load("c:\1.xml") Then
    Set ResultNode = objDOMDoc.selectSingleNode("/customers/row/CustomerID[.='ANATR']")
    
    'Uncomment the following line to try out unmatching element
    'Set ResultNode = objDOMDoc.selectSingleNode("/customers/row/CustomerID[.='PPPPP']")
    If ResultNode Is Nothing Then
        MsgBox "Not found!"
    Else
        MsgBox "Found: " & vbNewLine & ResultNode.parentNode.xml
    End If
    
    'Searching based on Attribute
    Set ResultNode = objDOMDoc.selectSingleNode("/customers/row[@ID='1']")
    
    'Uncomment the following line to try out unmatching element
    'Set ResultNode = objDOMDoc.selectSingleNode("/customers/row[@ID='99']")
    If ResultNode Is Nothing Then
        MsgBox "Not found!"
    Else
        MsgBox "Found: " & vbNewLine & ResultNode.xml
    End If

Else
    MsgBox "Error: " & objDOMDoc.parseError.reason
End If
The above code loads the XML document (c:\1.xml). If the load succeeds, we use the selectSingleNode method to search for an element by passing the XPath expression as its parameter. We then use the Visual Basic Is Nothing clause to check if the matching node was found or not.

MSXML DOM Resources Around The Web

  Contact Us | E-mail Us | Site Guide | About PerfectXML | Advertise ©2004 perfectxml.com. All rights reserved. | Privacy