The .NET Framework contains excellent support for XML and related standards (such as XSLT, Schemas, etc.). The System.Xml namespace provided by .NET Framework contains classes to work with XML. However, in some situations it might be required to use MSXML COM API from within .NET applications.
As MSXML API is nothing but a COM DLL, it can be very easily used from .NET application using the .NET Framework's COM Interop Services. The Runtime Callable Wrapper (RCW) facilitates the communication between the managed (.NET) and unmanaged (COM) code.
Note that use of MSXML is however not supported in .NET applications. The KB article 815112 indicates that:
MSXML uses threading models and garbage collection mechanisms that are not compatible with the .NET Framework. Using MSXML in .NET applications through COM interoperability can result in unexpected and problems that are difficult to debug. Microsoft does not recommend or support directly instantiating and using MSXML objects in .NET code, nor does Microsoft recommend or support marshalling MSXML interface pointers across the interop boundary.
Tip: Chapter 8 (MSXML) in the book Professional XML for .NET Developers talks about using MSXML in .NET and also compares MSXML classes with .NET Framework XML classes.
Let's look at an C# .NET application that uses MSXML SOM (Schema Object Model) to get the data types of each element in an XML document. But first, let's look at source XML document and XSD schema file:
XML Document (emp.xml) |
XSD Schema File (emp.xsd) |
<?xml version="1.0"?>
<empNS:employees xmlns:empNS="urn:ISEmployees">
<employee>
<name>Tom Thomas</name>
<salary>3000</salary>
<startdate>2000-08-14</startdate>
</employee>
</empNS:employees>
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:ISEmployees"
xmlns:e="urn:ISEmployees">
<xs:element name="employees" type="e:empDetails"/>
<xs:complexType name="empDetails">
<xs:sequence>
<xs:element name="employee" type="e:empData"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="empData">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="salary" type="xs:float"/>
<xs:element name="startdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
|
C# .NETThis example is written using .NET Framework Beta 2 and Visual Studio .NET Beta 2.
Start Visual Studio .NET and create a new C# Console Application Project and name it MSXMLSOM. Add a COM reference to Microsoft XML, v4.0 (MSXML4.dll) (Click on Project | Add Reference, select COM tab, scroll down to Microsoft XML, v4.0, MSXML4.dll, double click on it and then click on OK button).
Here is the C# code:
using System;
using System.Collections;
using MSXML2;
namespace MSXMLSOM
{
class Class1
{
static void Main(string[] args)
{
XMLSchemaCache40 sc = new XMLSchemaCache40();
XMLSchemaCache40 docNamespaces = new XMLSchemaCache40();
DOMDocument40 doc = new DOMDocument40();
ISchemaElement oDecl;
IXMLDOMNode node;
int cntChildNodes, iIndex;
sc.add("urn:ISEmployees", @"c:\emp.xsd");
doc.schemas = sc;
doc.async = false;
doc.setProperty("SelectionNamespaces", "xmlns:empNS='urn:ISEmployees'");
doc.load(@"c:\emp.xml");
IEnumerator enumChilds = doc.documentElement.childNodes.GetEnumerator();
try
{
enumChilds.MoveNext();
IXMLDOMNodeList childs = ((IXMLDOMNode)(enumChilds.Current)).childNodes;
cntChildNodes = childs.length;
for (iIndex=0; iIndex < cntChildNodes; iIndex++)
{
node = childs.nextNode();
oDecl = (ISchemaElement)((IXMLDOMSchemaCollection2)(doc.namespaces)).getDeclaration(node);
Console.WriteLine ("Data type of " + node.nodeName + " is " + oDecl.type.name);
}
Console.WriteLine("\n\nPress ENTER to continue...");
Console.ReadLine();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
The above lines first load the .xsd schema file in the SchemaCache object and then the source XML document in XMLDOMDocument object. Next, we get the childNodes enumerator, get the first (and only one) child element (employee) and then we get the sub-elements (childNodes of employee node) list. Finally, using the SOM getDeclaration method we get the ISchemaElement interface and use its type.name property to get the data type of the element in the source XML file.
Here is the output that above code produces:
Data type of name is string
Data type of salary is float
Data type of startdate is date
Press ENTER to continue...
|