I am newbie to xml and xslt area. I have written simple COM utility to transform xsl using xslt. But is failing at transformNodeToObject function call. I am using visual studio 15.
As you can see i am using the msxml6.dll import.
There was another type of call m_hrDOMInitStatus = CoCreateInstance(MSXML2::CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, MSXML2::IID_IXMLDOMDocument3, (void**)&m_pDoc); Not sure whether i need to use this API
#include "stdafx.h"
#include <windows.h>
#include "iostream"
#include <WTypes.h>
#include <comdef.h>
#include <wchar.h>
#include <vector>
#import <msxml6.dll>
using namespace MSXML2;
using namespace std;
int main()
{
HRESULT hResult = S_OK;
hResult = CoInitialize(NULL);
if (FAILED(hResult))
{
cerr << "Failed to initialize COM environment" << endl;
return 0;
}
// MSXML COM smart pointers
// Use the Document2 class to enable schema validation
IXMLDOMDocument2Ptr spDocSource;
IXMLDOMDocument2Ptr spDocResult;
IXMLDOMDocument2Ptr spDocStylesheet;
struct IDispatch * pDispatch;
// Create the COM DOM Document objects
hResult = spDocSource.CreateInstance(__uuidof(DOMDocument60));
if FAILED(hResult)
{
cerr << "Failed to create Source Document instance" << endl;
return 1;
}
hResult = spDocResult.CreateInstance(__uuidof(DOMDocument60));
if FAILED(hResult)
{
cerr << "Failed to create Result Document instance" << endl;
return 1;
}
hResult = spDocStylesheet.CreateInstance(__uuidof(DOMDocument60));
if FAILED(hResult)
{
cerr << "Failed to create Stylesheet Document instance" << endl;
return 1;
}
// Load the source document
spDocSource->async = VARIANT_FALSE;
hResult = spDocSource->load("xmlinputfile.xml");
if (hResult != VARIANT_TRUE)
{
cout << "Error parsing xmlinputfile.xml" << endl;
return 1;
}
spDocSource->async = VARIANT_FALSE;
hResult = spDocSource->load("XSLTFile1.xslt");
if (hResult != VARIANT_TRUE)
{
cout << "Error parsing XSLTFile1.xml" << endl;
return 1;
}
spDocResult->QueryInterface(IID_IDispatch, (void **)&pDispatch);
VARIANT vResultDoc;
vResultDoc.vt = VT_DISPATCH;
vResultDoc.pdispVal = pDispatch;
hResult = spDocSource->transformNodeToObject(spDocStylesheet, vResultDoc);
if FAILED(hResult)
{
cout << "Error in performing transformation" << endl;
return 1;
}
return 0;
}
xml input:
_____________
<?xml version="1.0"?>
-<MODEL-LIST ENTERPRISE-XML-VERSION="3">
<MODEL TYPE="Enhanced Macrocell" ID="450 MHz Default"> </MODEL>
</MODEL-LIST>
xslt:
----
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<MODEL-LIST>
<xsl:for-each select="MODEL">
<xsl:element name="MODEL">
<xsl:attribute name="ID">
<xsl:value-of select="@ID"/>
</xsl:attribute>
<xsl:attribute name="TYPE">
<xsl:value-of select="@TYPE"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</MODEL-LIST>
</xsl:template>
</xsl:stylesheet>
The Microsoft online examples on using MSXML with smart pointers, like https://msdn.microsoft.com/en-us/ie/ms766389(v=vs.100), suggest that the call to transformNode
would simply work as spDocSource->transformNodeToObject(spDocStylesheet, spDocResult.GetInterfacePtr())
.