Click here to Skip to main content
13,866,505 members
Click here to Skip to main content
Add your own
alternative version


113 bookmarked
Posted 1 Jan 2002

C++ Wrapper classes for the COM interfaces of Microsoft XML parser (MSXML)

, 1 Jan 2002
Rate this:
Please Sign up or sign in to vote.
The provided MFC extension DLL provides easy to use wrapper classes for all COM-interfaces of Microsoft's DOM-/SAX implementation.


  1. Introduction
  2. What is MSXMLCPP
  3. Concepts
  4. XML SAX wrapper nodes
  5. Drawbacks
  6. Requirements
  7. Unicode support
  8. How the wrapper classes have been generated
  9. The code examples


No matter if you want to do interprocess communication, store your application's settings or documents or format text - XML provides a good solution for all those cases. Further on, Microsoft provides a full implementation of the XML DOM (Document Object Model) and SAX (Simple API for XML), which allows reading and writing XML in an abstract manner: The Microsoft XML parser (MSXML).

Besides the advantage of providing all features you will ever need when handling XML data the Microsoft XML parser also provides the advantage of being available on every future Windows system. The drawback for us, as C++ developers is, that the Microsoft XML parser provides all these features through COM-interfaces.

Using COM-interfaces in C++ always produces a lot of overhead in the source code - you have to handle the HRESULT return values, you have to provide variables for the logical return values, no matter if you are interested in it or not, because they are passed by the parameter list, you have to convert between zero terminated strings and BSTR. You have to take care about reference counting and so on.

Simply take a look at the two following code examples. Both are doing the same things: They are reading the value of an attribute of an XML element using Microsoft's implementation of the XML DOM:

CString GetAttributeValue(IXMLDOMDocument *pDoc, CString strElementPath, 
                                              CString strAttribute)
  IXMLDOMNode         *pNode = NULL;
  IXMLDOMNamedNodeMap *pAttributes = NULL;
  BSTR                bstrPath = strElementPath.AllocSysString();
  BSTR                bstrAttribute = strAttribute.AllocSysString();

    HRESULT hr;
    hr = pDoc->selectSingleNode(strElementPath, &pNode);
    if (hr != S_OK)
      throw hr;
    hr = pNode->get_attributes(&pAttributes);
    if (hr != S_OK)
      throw hr;
    hr = pAttributes->getNamedItem(bstrAttribute, &pNode);
    if (hr != S_OK)
      throw hr;
    BSTR  bstrValue;
    hr = pNode->get_text(&bstrValue);
    if (hr != S_OK)
      throw hr;
    return (LPCTSTR)_bstr_t(bstrValue, false);
  catch (HRESULT hr)
    if (pNode)
    if (pAttributes)
    return _T("");
Visual Basic
Function GetAttributeValue(Doc As IXMLDOMDocument, _
        strElementPath As String, strAttribute As String) As String
    GetAttributeValue = Doc.selectSingleNode(strElementPath)._
End Function

It's nearly unbelievable: Both code examples are doing the same. OK, admittedly the C++ example does a better error handling ;-). But the differences shown here are making clear, why so many people are writing there own XML-classes, instead of using the Microsoft XML parser - the usage is much to unwieldy.


That is where MSXMLCPP (MSXML C++) comes in. MSXMLCPP is a MFC extension DLL which provides wrapper classes for all the interfaces of the Microsoft DOM and SAX implementation.

The features are:

  • C++ wrapper classes for all the interfaces of the Microsoft DOM and SAX implementation.
  • C++ wrapper classes for easier implementation of interfaces you have to pass to the Microsoft implementation (i.e. ISAXContentHandler)
  • Smart reference counting for wrapped interfaces.
  • Wrapper methods are returning the real (logical) return values instead of HRESULT.
  • C++ exceptions for reporting unexpected HRESULTs.
  • Automatic translation of BSTR to CString and vice versa.
  • Automatic translation of VARIANT to the more comfortable _variant_t.

If you have ever dreamed of writing:

CString GetAttributeValue(CXMLDOMDocument &Doc, 
           CString strElementPath, CString strAttribute)
  return Doc.SelectSingleNode(strElementPath).GetAttributes().

in C++, instead of the multi-lined source example given above, then: Hey, welcome to your solution.


This section describes the basic concepts of MSXMLCPP.

Wrapper Types

MSXMLCPP provides three kinds of wrapper classes:

  1. Calling wrappers
  2. Implementation wrappers
  3. Coclass wrappers

Calling wrappers

Calling wrappers are classes you can use to invoke methods of the interface wrapped by the specific class. All calling wrappers are derived from the template class CInterfaceCallingWrapper (defined in InterfaceWrapper.h).

Before using calling wrappers you have to attach an interface to an instance of the class. This can be done using a constructor, the assignment operator or explicitly using the Attach() method. Before assigning a new interface pointer to a wrapper, you always have to detach a previously attached one by calling the Detach() method.

The calling wrapper classes are handling the reference counting for the attached interface pointers, so that you won't have to care about it with normal usage. The classes are providing several operator overridings that allow you to use the wrapper class everywhere, instead of the original interface pointer. For more information about the calling wrappers, take a look at the well documented declaration of CInterfaceCallingWrapper in InterfaceWrapper.h

A calling wrapper class provides all the methods and properties provided by the belonging COM interface, but there are some slight differences:

  • The method names have been adapted to the MFC conventions (beginning with a capital letter).
  • The methods for getting a property are prefixed with a Get and the methods for setting a property are prefixed with a Set or SetRef.
  • The method return values are reflecting the logical result of the operation (MIDL-[retval] attribute).
  • BSTR parameters are replaced by LPCTSTR, BSTR* parameters are replaced by CString& and BSTR return values are replaced by CString return values.
  • VARIANT parameters are replaced by _variant_t, VARIANT* parameters are replaced by _variant_t& and VARIANT return values are replaced by _variant_t return values.
  • If an interface's method returns a pointer to an interface for which a wrapper class has been defined, the wrapping method returns an object of this wrapper class instead.

Because the calling wrapper classes are not returning any HRESULT values, they are using the C++ exception mechanism to inform you about unexpected values returned by the original interface methods. Each time a HRESULT value is received for which the SUCCEEDED macro does not return TRUE, an exception of the type CComException* is thrown.

Implementation wrappers

Implementation wrappers are classes that allow you to implement the belonging interface simply by deriving your class from the implementation wrapper class and overriding the high level pure virtual functions. The implementation wrappers are derived from CInterfaceImplementationWrapper or CDispatchInterfaceImplementationWrapper, depending on if there related interfaces are derived from IUnknown or IDispatch.

Implementation wrapping is simply done by aggregation: The implementation wrapper class contains a member (m_x...) that is an implementation of the original interface. Each method of this implementation calls the virtual method MethodPrologue() of the aggregating class and afterwards the belonging virtual wrapper method of the aggregating class. Those wrapper methods are pure virtual methods you have to implement in your derived class. They are identical with the interface's original method, apart from some changes:

  • The method names have been adapted to the MFC conventions (beginning with a capital letter).
  • The methods for getting a property are prefixed with a Get and the methods for setting a property are prefixed with a Set or SetRef.
  • The method return values are reflecting the logical result of the operation (MIDL-[retval] attribute).
  • BSTR parameters are replaced by LPCTSTR, BSTR* parameters are replaced by CString& and BSTR return values are replaced by CString return values.
  • VARIANT parameters are replaced by _variant_t, VARIANT* parameters are replaced by _variant_t& and VARIANT return values are replaced by _variant_t return values.

This makes implementation much more easier than implementing the original interfaces with all their BSTRs, VARIANTs and HRESULTs.

If your are implementing an interface based on the implementation wrappers, as a stand alone class, the standard mechanisms for reference counting implemented in CInterfaceImplementationWrapper should be OK, but if you want to use your interface implementation as part of a class that implements more interfaces or as part of a CCmdTarget derived class, you will have to modify the reference counting by overriding the virtual AddRef() and Release() methods. Further on you can override the QueryInterface() method and the MethodPrologue() method, which will be necessary in most MFC applications to activate the right module state (i.e. calling AFX_MANAGE_STATE(AfxGetStaticModuleState()) would be a good idea).

Because you do not have the possibility of signaling errors by a HRESULT return value in your derived classes, you can throw a CComException by calling the global AfxThrowComException() - All the method calls in the implementation wrapper are encapsulated by a try statement with a catch(CComException *pE) chained to. If you throw a CComException in your implementation, the implementation wrapper will return the given HRESULT value to the caller instead of the usual S_OK.

CoClass wrappers

The CoClass wrappers are small wrapper classes which allow you to create COM objects and retrieve the specified interfaces. This frees you from calling CoCreateInstance().


Because the HRESULT values are encapsulated by the wrapper classes, it was necessary to provide a mechanism that allows your software to handle unexpected HRESULTs. Therefore the class CComException has been declared in InterfaceWrapper.h. The class is derived from CException and contains a single attribute m_hr of the type HRESULT.

To throw a CComException you should use the static CComException::Throw() method or the global AfxThrowComException() function. Both are creating a CComException object on the heap, setting its m_hr attribute to the specified value and throwing the pointer.

If you have caught a pointer to a CComException object and you do not need it any more, you should call its Delete() method to destroy it.

XML SAX wrapper nodes

For the SAX implementation, Microsoft provides two kinds of interfaces: the C++ interfaces and the Visual Basic interfaces. Because I have generated all the wrapper classes with a tool, that analysis the parameters of each method to generate the method wrapper, I needed to use the Visual Basic interfaces to get "nice" wrapper classes. The problem with the C++ interfaces (which may be a little bit faster) is, that they are using two parameters for each string: the string itself and a length argument. I did not want to modify the generation tool to recognize this, because this case is very seldom and so I used the somehow slower Visual Basic interfaces, which are using normal BSTRs, which are recognized by the generation tool.


As everything good, even MSXMLCPP has a drawback: The wrapper classes are producing some time-overhead for all the type conversion and additional function calls. So if your application has to be very fast, it may be better to work on the raw interfaces, but I think the time-overhead should be that small, to justify the advantage of more readable code.


To use the MSXMLCPP library with your application, simply include the msxmlcpp.h header file into your stdafx.h (or anywhere else) and link to the msxmlcpp.lib (msxmlcppD.lib for debug version). MSXMLCPP uses RTTI (Runtime Type Information), so it would be a good idea to enable it for your application too.

To run an application using the MSXMLCPP DLL, the Microsoft XML parser (MSXML) has to be installed on the system. You can download it from Microsoft homepage.

This should run on Windows 95 or later and Windows NT 3.1 or later.

Unicode support

Though I haven't tested it, there is no reason, why this should not work with Unicode.

How the wrapper classes have been generated

All the wrapper classes have been generated with a tool of mine, that gets a typelibrary and some rules as input and generates the wrapper classes out of the information in the typelibrary. I hope I will be able to provide a first free beta of this tool in a few weeks, on CodeProject. I think this will make the work for all of us C++ programmers, much more easier.

The code examples

Two code examples, which are using the library are supported with the full download. Both examples are simple console applications, to concentrate on the interesting stuff. Both examples are expecting a file name as command line parameter to be used as XML file - a valid file (books.xml) is contained in the Output directory of the ZIP-archive.

The application DOMXMLDemo, demonstrates how to read and write an XML file using the DOM wrapper classes.

The application SAXXMLDemo demonstrates how to read XML files using the SAX wrapper classes. This also shows how to implement interfaces using implementation wrapper classes.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Sven Wiegand
Web Developer
Germany Germany
Sven Wiegand (1976), IT professional living in Berlin (Germany), develops open source software in his free time. His most successfull project is the LaTeX IDE TeXnicCenter which is distributed under the terms of the GNU-GPL and has more than 100,000 users all about the world.

"The picture shows me with my racing bike on the top of the Roque de los Muchachos (2426m) - the highest point of the canarian island La Palma."

You may also be interested in...

Comments and Discussions

QuestionHelp: I want put a segment binary(ImageData) into CDATA(xmlnode),when run CXMLDOMDocument2::CreateCDATASection(LPCTSTR data),but error in "HRESULT hr = P()->createCDATASection(bstrdata, &o)",why? Pin
tsstsstss30-Oct-11 22:27
membertsstsstss30-Oct-11 22:27 
QuestionNeed link for installing Microsoft XML parser Pin
santu9-Dec-10 20:01
membersantu9-Dec-10 20:01 
QuestionLicense Pin
santu14-Sep-10 21:44
membersantu14-Sep-10 21:44 
GeneralGetting error in my test app in MFC Pin
apurv1464-Jun-10 4:22
memberapurv1464-Jun-10 4:22 
QuestionHow can I create new XML file through this parser? Pin
apurv1464-Jun-10 1:26
memberapurv1464-Jun-10 1:26 
QuestionSave with line breaks and indenting Pin
premod9-Jul-09 21:40
memberpremod9-Jul-09 21:40 
GeneralChanging to MsXml6 Pin
cbo18-Aug-08 23:55
membercbo18-Aug-08 23:55 
Generalunicode Pin
prudnik20-Oct-07 3:43
memberprudnik20-Oct-07 3:43 
GeneralmsxmlcppD.lib Pin
djerbi13-Aug-07 22:31
memberdjerbi13-Aug-07 22:31 
Generalstatic linking Pin
Galatei18-Jan-07 3:13
memberGalatei18-Jan-07 3:13 
GeneralMSXMLCPP.DLL Terminating status code Pin
plm57-Dec-06 8:07
professionalplm57-Dec-06 8:07 
Generalbug: BOOL vs VARIANT_BOOL in DOMXML.cpp Pin
rblaa5-Dec-06 15:19
memberrblaa5-Dec-06 15:19 
GeneralText converting Pin
HN123454-Nov-06 1:05
memberHN123454-Nov-06 1:05 
Questionhow do i add msxml to my installer ? Pin
code4jigar5-Sep-06 3:14
membercode4jigar5-Sep-06 3:14 
QuestionMSXML 6 ??? Pin
Hochiminh7-May-06 17:13
memberHochiminh7-May-06 17:13 
AnswerRe: MSXML 6 ??? Pin
Satriani18-May-06 22:07
memberSatriani18-May-06 22:07 
QuestionHow to create xml file from scratch with CXMLDOMDocument2? Pin
z1616619-Apr-06 18:22
memberz1616619-Apr-06 18:22 
GeneralVS 2003 - Building example fails - Linker error Pin
Satriani16-Jul-05 2:12
memberSatriani16-Jul-05 2:12 
GeneralRe: VS 2003 - Building example fails - Linker error Pin
yrleu25-Jul-05 4:52
memberyrleu25-Jul-05 4:52 
GeneralRe: VS 2003 - Building example fails - Solved Pin
Satriani3-Aug-05 0:39
memberSatriani3-Aug-05 0:39 
GeneralRe: VS 2003 - Building example fails - Solved Pin
yrleu5-Sep-05 21:38
memberyrleu5-Sep-05 21:38 
General[Message Deleted] Pin
Vicky_Jain7-Feb-08 8:40
memberVicky_Jain7-Feb-08 8:40 
AnswerRe: VS 2003 - Building example fails - Solved Pin
shazzababs8-Feb-08 1:39
membershazzababs8-Feb-08 1:39 
Generalmsxmlcpp library Pin
ikasovitch19-May-05 21:20
memberikasovitch19-May-05 21:20 
GeneralRe: msxmlcpp library Pin
z161664-Jun-07 22:12
memberz161664-Jun-07 22:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190214.1 | Last Updated 2 Jan 2002
Article Copyright 2002 by Sven Wiegand
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid