Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - DOM Developer's Guide

Source: saveDOM.cpp

This C/C++ source code performs the following steps:

  1. Creates an XML DOM object (pXMLDom) and sets it to synchronous mode.
  2. Loads an XML string to pXMLDom.
  3. Calls the loadXML method on pXMLDom, specifying the XML data as the following string:
    <r>\n<t>top</t>\n<b>bottom</b>\n</r>
  4. Displays the resulting XML DOM in the console window.
  5. Calls the save method on pXMLDom to serialize the DOM content to a file (myData.xml).

C/C++ Source File (saveDOM.cpp)

#include <stdio.h>
#include <windows.h>
#import <msxml5.dll> raw_interfaces_only
using namespace MSXML2;

// Macro that calls a COM method returning HRESULT value:
#define HRCALL(a, errmsg) \
do { \
    hr = (a); \
    if (FAILED(hr)) { \
        dprintf( "%s:%d  HRCALL Failed: %s\n  0x%.8x = %s\n", \
                __FILE__, __LINE__, errmsg, hr, #a ); \
        goto clean; \
    } \
} while (0)

// Helper function that puts output in stdout and debug window
// in Visual Studio:
void dprintf( char * format, ...)
{
    static char buf[1024];
    va_list args;
    va_start( args, format );
    vsprintf( buf, format, args );
    va_end( args);
    OutputDebugStringA( buf);
    printf("%s", buf);
}

// Helper function to create a DOM instance: 
IXMLDOMDocument * DomFromCOM()
{
   HRESULT hr;
   IXMLDOMDocument *pxmldoc = NULL;

    HRCALL( CoCreateInstance(__uuidof(DOMDocument50),
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      __uuidof(IXMLDOMDocument),
                      (void**)&pxmldoc),
            "Create a new DOMDocument");

    HRCALL( pxmldoc->put_async(VARIANT_FALSE),
            "should never fail");
    HRCALL( pxmldoc->put_validateOnParse(VARIANT_FALSE),
            "should never fail");
    HRCALL( pxmldoc->put_resolveExternals(VARIANT_FALSE),
            "should never fail");

   return pxmldoc;
clean:
   if (pxmldoc)
    {
      pxmldoc->Release();
    }
   return NULL;
}



int main(int argc, char* argv[])
{
   IXMLDOMDocument *pXMLDom=NULL;
   IXMLDOMParseError *pXMLErr=NULL;
   BSTR bstr = NULL;
   VARIANT_BOOL status;
   VARIANT var;
   HRESULT hr;

   CoInitialize(NULL);

   pXMLDom = DomFromCOM();
   if (!pXMLDom) goto clean;

   bstr = SysAllocString(L"<r>\n<t>top</t>\n<b>bottom</b>\n</r>");
   HRCALL(pXMLDom->loadXML(bstr, &status), 
               "dom->loadXML(): ");
   SysFreeString(bstr);

   if (status!=VARIANT_TRUE) {
      HRCALL(pXMLDom->get_parseError(&pXMLErr),
               "dom->get_parseError: ");
      HRCALL(pXMLErr->get_reason(&bstr),
               "parseError->get_reason: ");
      dprintf("Failed to load DOM from xml string. %S\n",
               bstr);
      goto clean;
   }
   HRCALL(pXMLDom->get_xml(&bstr), "dom->get_xml: ");
   dprintf("XML DOM loaded from stocks.xml:\n%S\n",bstr);

   VariantInit(&var);
   V_BSTR(&var) = SysAllocString(L"myData.xml");
   V_VT(&var) = VT_BSTR;
   HRCALL(pXMLDom->save(var), "dom->save: ");
   dprintf("XML DOM saved to myData.xml\n");

clean:
   if (bstr) SysFreeString(bstr);
   if (&var) VariantClear(&var);
   if (pXMLErr) pXMLErr->Release();
   if (pXMLDom) pXMLDom->Release();

   CoUninitialize();
   return 0;
}

To add saveDOM.cpp to the project

  1. Create a new C++ source file. For detailed instructions on how to do this, see Set Up My Visual C++ Project. Name the new file saveDOM.cpp.
  2. Copy the C/C++ source code above and paste it into the source file you just created.

Next, build and run the saveDOM project. The result should be the output shown in the following topic.