perfectxml.com
 Basic Search  Advanced Search   
Topics Resources Free Library Software XML News About Us
  You are here: home Focus MSXML » .NET Monday, 25 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

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# .NET

This 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...

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