Microsoft KB Archive/317750

= HOW TO: Use MSXML 4.0 with COM Interop in Visual C# .NET =

PSS ID Number: 317750

Article Last Modified on 2/10/2003

-

The information in this article applies to:


 * Microsoft .NET Framework Class Libraries 1.0
 * Microsoft Visual C# .NET (2002)

-



This article was previously published under Q317750



For a Microsoft Visual Basic .NET version of this article, see 317728.

IN THIS TASK

 * SUMMARY
 * ** Requirements
 * Import MSXML 4.0 Type Library as an Assembly
 * Steps to Create a Sample Application
 * REFERENCES



SUMMARY
This step-by-step article demonstrates how to use Microsoft XML Core Services 4.0 (MSXML) in Visual C# .NET projects by using the COM interoperability features of .NET.

The Microsoft .NET Framework provides ways to interoperate with the existing COM components. Because MSXML 4.0 is COM-based, when you use MSXML with the .NET applications, MSXML runs as unmanaged code outside of the common language runtime (CLR).

Applications that you develop solely with System.Xml provide numerous benefits, such as interoperability with ADO.NET components, scalability, and other enhancements that System.Xml and the .NET Framework offer. However, you may want to use MSXML 4.0 in .NET to do the following:
 * Port the existing code with minimal changes and use the current skillset.
 * Work with an existing code base that uses Simple API for XML (SAX) or msxsl:script elements (with older scripting languages) in Extensible Stylesheet Language Transformations (XSLT).

NOTE: System.Xml supports scripting with the CLR compliant languages.


 * Interoperate with MSXML 3.0 to use the older XSL stylesheet standard.
 * Overcome the XSLT performance issue with the System.Xml.XslTransform class.

Please refer to the following knowledge base article for more information about the XSLT performance issue:

317691 XSL Transformations may perform slower with System.Xml than MSXML 4.0

For more information about interoperability in the .NET Framework, refer to the links in the &quot;References&quot; section of this article.

back to the top

Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
 * Microsoft Windows XP, Microsoft Windows 2000, or Microsoft Windows NT 4.0 Service Pack 6a
 * Microsoft Data Access Components 2.6 (MDAC) or later
 * Microsoft Visual Studio .NET
 * MSXML 4.0

This article assumes that you are familiar with the following topics:
 * Visual C# .NET syntax
 * XML and the related standards
 * Using MSXML 4.0

back to the top

Import MSXML 4.0 Type Library as an Assembly
You must convert COM type definitions in the type libraries into metadata of assemblies. .NET provides several ways to convert COM type definitions. For detailed information, refer to the topic, &quot;Importing a Type Library as an Assembly,&quot; in the .NET Framework Developer's Guide.

Typically, you can generate this metadata when you use the Visual Studio .NET integrated development environment (IDE) or the Type Library Importer (Tlbimp.exe) command line tool to add a project reference to the native DLL. This article examines these methods with MSXML 4.0. You can use the other methods as provided in the documentation, also.
 * Using Visual Studio .NET

To add a reference to MSXML 4.0 in your project, follow these steps.

NOTE: This procedure automatically creates an assembly named &quot;Interop.MSXML2.dll&quot; in the bin directory of your application.


 * *# From the Project menu, click Add Reference.Click the COM tab.Click the Microsoft XML, 4.0 component, and then click Select. The Selected Components pane displays the MSXML 4.0 entry.Click OK.
 * Click the COM tab.Click the Microsoft XML, 4.0 component, and then click Select. The Selected Components pane displays the MSXML 4.0 entry.Click OK.
 * Click the Microsoft XML, 4.0 component, and then click Select. The Selected Components pane displays the MSXML 4.0 entry.Click OK.
 * Click OK.

  Using the Type Library Importer

Use the following command to create an assembly from MSXML 4.0 native DLL. To run this assembly, point the Path environment variable to the installation location of Tlbimp.exe or explicitly specify the full path to Tlbimp.exe. The output assembly name can be any valid name; this example uses the name, &quot;Msxml4net.dll&quot; (this name is used as the namespace name, also). c:\>tlbimp &quot;c:\winnt\system32\msxml4.dll&quot; /out:&quot;c:\winnt\system32\msxml4net.dll&quot; NOTE: The following warning, or any similar warning that you may receive during the conversion, is related to SAX. You must use unsafe code to handle the method specified in the warning.

TlbImp warning: At least one of the arguments for 'InterfaceName.MethodName' can not be marshaled by the runtime marshaler. Such arguments will therefore be passed as a pointer and may require unsafe code to manipulate.

After you create the assembly, you can use the COM types in this new assembly in managed clients, just as you use any other managed type. You can obtain and release a reference of these COM types in a similar manner to that of managed types, and the runtime handles the reference count.

You can use a type library importer to marshal MSXML objects such as DOM documents between .NET processes, in which case you must use the same assembly. 

back to the top

Steps to Create a Sample Application
The following code example demonstrates how you can intertwine MSXML 4.0 in .NET. This code example performs the following tasks:
 * 1) Use MSXML 4.0 to transform the XML.Load the results into an XmlDocument object.Run an XPath query with MSXML 4.0 to collect data.Add the collected data to a new XmDocument instance.
 * 2) Load the results into an XmlDocument object.Run an XPath query with MSXML 4.0 to collect data.Add the collected data to a new XmDocument instance.
 * 3) Run an XPath query with MSXML 4.0 to collect data.Add the collected data to a new XmDocument instance.
 * 4) Add the collected data to a new XmDocument instance.

One caveat is that the System.Xml objects and the MSXML COM objects are not interchangeable; for example, casting an IXMLDOMNode instance to a System.Xml.XmlNode instance does not work.   Use Notepad or a similar text editor to save the following data as a file named &quot;Q317750.xml&quot;:    Principle of Relativity Albert Einstein <Genre>Physics</Genre> </Book> <Book> Cosmos</Title> Carl Sagan</Author> <Genre>Cosmology</Genre> </Book> </Collection> </li>  Save the following data as a file named &quot;Q317750.xsl&quot;. This XSL style sheet returns a copy of the same XML data: <?xml version=&quot;1.0&quot;?> <xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; > <xsl:template match=&quot;/ | @* | node&quot;> <xsl:copy> <xsl:apply-templates select=&quot;@* | node&quot;/> </xsl:copy> </xsl:template> </xsl:stylesheet> </li> Create a new Visual C# .NET Console Application project. Set a reference to MSXML 4.0, as explained in the section, &quot;Using Visual Studio .NET,&quot; so that the code uses the MSXML2 namespace. If you want to use the Msxml4net.dll assembly, set a reference to the Msxml4net.dll assembly and then use the MSXML4NET namespace.</li>  Replace the code in Class1.cs with the following sample code.

NOTE: With Interop, COM classes are exposed as both interfaces and classes. Classes have the &quot;Class&quot; extension appended to the interface name. One difference is that the interfaces cannot act as base classes. This code sample uses class syntax, for example DOMDocument40Class, whereas you can use the interface syntax DOMDocument40, also. using System; using MSXML2; using System.Xml; using System.IO;

namespace VCInterop {  class Class1 {     static void Main(string[] args) {        try {           // 1. Working with MSXML 4.0 DOMDocuments. DOMDocument40Class msXmlDoc = new DOMDocument40Class; DOMDocument40Class msXslDoc = new DOMDocument40Class;

// Load the XML and XSL data. bool isSuccess = false; isSuccess = msXmlDoc.load(&quot;Q317750.xml&quot;); if (isSuccess == false) throw new Exception(msXmlDoc.parseError.errorCode + &quot; &quot; + msXmlDoc.parseError.reason);

isSuccess = msXslDoc.load(&quot;Q317750.xsl&quot;); if (isSuccess == false) throw new Exception(msXslDoc.parseError.errorCode + &quot; &quot; + msXslDoc.parseError.reason);

// 2. Transform XML by using MSXML 4.0, and then load the results into XmlDocument. System.Xml.XmlDocument netXmlDoc = new System.Xml.XmlDocument; netXmlDoc.LoadXml(msXmlDoc.transformNode(msXslDoc));

// Display the content of the DOM Document. Console.Write(&quot;\n{0}\n&quot;, netXmlDoc.OuterXml);

// 3. Run an XPath query with MSXML 4.0, and then process the results. IXMLDOMNodeList msXmlNodeList = msXmlDoc.selectNodes(&quot;//Book/Title&quot;);

// Display the results. for (int i = 0; i <= msXmlNodeList.length - 1; i++) Console.Write(&quot;\n{0}&quot;, msXmlNodeList[i].xml);

// 4. Create a new System.Xml.XmlDocument from an MSXML node list. netXmlDoc.LoadXml(&quot;<BookTitles></BookTitles>&quot;); XmlNode newElem; for (int i = 0; i <= msXmlNodeList.length - 1; i++) {              newElem = netXmlDoc.CreateNode(XmlNodeType.Element, msXmlNodeList[i].nodeName, null);

newElem.InnerText = msXmlNodeList[i].text;

netXmlDoc.DocumentElement.AppendChild(newElem); }

// Display the content of the new XmlDocument. Console.Write(&quot;\n\n{0}\n\n&quot;, netXmlDoc.OuterXml);

}        catch(XmlException xmlEx)        // Handle the Xml Exceptions here. {           Console.WriteLine(&quot;{0}&quot;, xmlEx.Message); }        catch(Exception ex)              // Handle the generic Exceptions here. {           Console.WriteLine(&quot;{0}&quot;, ex.Message); }        finally {           Console.ReadLine; }     }   } } </li> Read the inline comments to understand the functionality of the code.</li> Compile and run the application.

NOTE: Either the XML and XSL files must be in the same directory as the executable or you must specify the path, such as &quot;C:\\ConsoleApps\\XmlInterop\\Q317750.xml&quot;.

The output should look similar to the following.</li></ol>

<?xml version=&quot;1.0&quot;?> <Collection> <Book>Principle of Relativity</Title>Albert Einstein</Author><Genre>Physics</Genre></Book> <Book>Cosmos</Title>Carl Sagan</Author><Genre>Cosmology</Genre></Book> </Collection>

Principle of Relativity</Title> Cosmos</Title>

<BookTitles>Principle of Relativity</Title>Cosmos</Title></BookTitles>

back to the top