c++xmlxsltmsxml6

Call to transformNodeToObject fails


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>

Solution

  • 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()).