The source code listed below demonstrates how to call the transformNode method and the transformNodeToObject method in a C/C++ program. Specifically, the code performs the following steps:
pXMLDom).pXSLDoc).transformNode(pXSLDoc) method on pXMLDom to do the transformation, holds the result in a string, and prints the output to the console.pXMLOut) to hold the output of the transformNodeToObject method.transformNodeToObject method on pXMLDom to do the transformation; holds the resulting object in pXMLOut; prints out the XML result; and serializes the output object in an HTML file, stocks.htm.C/C++ Source File (XSLT.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;
IXMLDOMDocument *pXSLDoc=NULL;
IXMLDOMParseError *pXMLErr=NULL;
IXMLDOMDocument *pXMLOut = NULL;
IDispatch *pDisp=NULL;
BSTR bstr = NULL;
long ecode;
VARIANT_BOOL status;
VARIANT var;
HRESULT hr;
CoInitialize(NULL);
pXMLDom = DomFromCOM();
if (!pXMLDom) goto clean;
VariantInit(&var);
V_BSTR(&var) = SysAllocString(L"stocks.xml");
V_VT(&var) = VT_BSTR;
HRCALL(pXMLDom->load(var,&status),"dom->load(): ");
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 stocks.xml. %S\n",
bstr);
goto clean;
}
pXSLDoc = DomFromCOM();
if (!pXSLDoc) goto clean;
VariantClear(&var);
V_BSTR(&var) = SysAllocString(L"stocks.xsl");
V_VT(&var) = VT_BSTR;
HRCALL(pXSLDoc->load(var,&status), "xsl->load(): ");
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 stocks.xsl. %S\n",
bstr);
goto clean;
}
// Transform dom to a string:
HRCALL(pXMLDom->transformNode(pXSLDoc, &bstr),"");
HRCALL(pXMLDom->get_parseError(&pXMLErr), "");
HRCALL(pXMLErr->get_errorCode(&ecode), "");
if (ecode != 0) {
if (bstr) SysFreeString(bstr);
HRCALL(pXMLErr->get_reason(&bstr),"");
dprintf("Failed to transformNode:\n%S\n", bstr);
goto clean;
}
dprintf("output from transformNode:\n%S\n",bstr);
// Transform dom to another dom object:
pXMLOut = DomFromCOM();
if (!pXMLOut) goto clean;
HRCALL(pXMLOut->QueryInterface(IID_IDispatch,(void**)&pDisp),
"QI(IDispatch): ");
VariantClear(&var);
var.vt = VT_DISPATCH;
var.pdispVal = pDisp;
HRCALL(pXMLDom->transformNodeToObject(pXSLDoc, var),
"tramsformNodeToObject: ");
if (bstr) SysFreeString(bstr);
HRCALL(pXMLOut->get_xml(&bstr), "");
dprintf("output from transformNodeToObject:\n%S\n",bstr);
VariantClear(&var);
pDisp=NULL;
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"stocks.htm");
HRCALL(pXMLOut->save(var), "XMLOut->save: ");
dprintf("The above output is also saved in stocks.htm.\n");
clean:
if (bstr) SysFreeString(bstr);
if (&var) VariantClear(&var);
if (pXMLErr) { pXMLErr->Release();}
if (pXMLDom) { pXMLDom->Release();}
if (pXMLOut) { pXMLOut->Release();}
if (pXSLDoc) { pXSLDoc->Release();}
CoUninitialize();
return 0;
}
To add XSLT.cpp to the project
Next, we'll add the resource files to the XSLT project.