MSXML2::IXMLDOMDocument2 transformNodeToObject
-
(XML API/stuff I'm not really used to work with) I'm trying to transform an XML with an external XSL file ( to add indentation and line-feed to the output file) In one instance ( on one generated XML file ) it works very well, on another instance (other generated XML file), it does not, it "copies" the XSL to the outgoing XML (when applying the transformation). Both the generated XML and the XSL files are valid XML files, and when using an external tool (XmlPad) to apply the transformation on the XML file with the XSL file it works : The code looks like this : The return value from
transformNodeToObject
is S_OK even if it looks to not work.CString sInputPath;// valid input path initialized.
sInputPath+= "StyleSheet.xsl";MSXML2::IXMLDOMDocument2Ptr pXMLDocResult;
CMtXmlParser xlsParser; // our own XML parser.
xlsParser.InitDoc();VARIANT_BOOL vResult = xmlParser.LoadDocument(sInputPath);
if( ((BOOL)vResult ) == false ) // fail!
{
// if cannot load the XLS file, just save as-is.
hr = xmlParser.SaveDocument( sPath );
return FAILED( hr );
}MSXML2::IXMLDOMDocument2Ptr pXslStyleSheet;
pXslStyleSheet = xmlParser.GetDOMDocument();hr = CoCreateInstance( MSXML2::CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, MSXML2::IID_IXMLDOMDocument2, (void**)&pXMLDocResult);
ASSERT( !FAILED(hr));IDispatch* pDispatch;
hr = pXMLDocResult->QueryInterface(IID_IDispatch, (void**)&pDispatch);
ASSERT( !FAILED(hr));VARIANT vOutput;
vOutput.vt = VT_DISPATCH;
vOutput.pdispVal = pDispatch;try
{
// Apply transform to doc before saving ...
HRESULT hr = pXMLDoc->transformNodeToObject( pXslStyleSheet, vOutput );
ASSERT( !FAILED(hr));
}
catch ( ... )
{
// if cannot transform, just save as-is.
hr = xmlParser.SaveDocument( sPath );
return FAILED( hr );
}BSTR s = xmlParser.AsciiToBSTR(sPath );
hr = pXMLDocResult->save(s);
ASSERT(!FAILED(hr));The XSL file is :
<xsl:stylesheet version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
xsl:copy
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>Anyone used
transformNodeToObject
and have any insights ? Thanks. Max.Maximilien Lincourt Your Head A Splo
-
(XML API/stuff I'm not really used to work with) I'm trying to transform an XML with an external XSL file ( to add indentation and line-feed to the output file) In one instance ( on one generated XML file ) it works very well, on another instance (other generated XML file), it does not, it "copies" the XSL to the outgoing XML (when applying the transformation). Both the generated XML and the XSL files are valid XML files, and when using an external tool (XmlPad) to apply the transformation on the XML file with the XSL file it works : The code looks like this : The return value from
transformNodeToObject
is S_OK even if it looks to not work.CString sInputPath;// valid input path initialized.
sInputPath+= "StyleSheet.xsl";MSXML2::IXMLDOMDocument2Ptr pXMLDocResult;
CMtXmlParser xlsParser; // our own XML parser.
xlsParser.InitDoc();VARIANT_BOOL vResult = xmlParser.LoadDocument(sInputPath);
if( ((BOOL)vResult ) == false ) // fail!
{
// if cannot load the XLS file, just save as-is.
hr = xmlParser.SaveDocument( sPath );
return FAILED( hr );
}MSXML2::IXMLDOMDocument2Ptr pXslStyleSheet;
pXslStyleSheet = xmlParser.GetDOMDocument();hr = CoCreateInstance( MSXML2::CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, MSXML2::IID_IXMLDOMDocument2, (void**)&pXMLDocResult);
ASSERT( !FAILED(hr));IDispatch* pDispatch;
hr = pXMLDocResult->QueryInterface(IID_IDispatch, (void**)&pDispatch);
ASSERT( !FAILED(hr));VARIANT vOutput;
vOutput.vt = VT_DISPATCH;
vOutput.pdispVal = pDispatch;try
{
// Apply transform to doc before saving ...
HRESULT hr = pXMLDoc->transformNodeToObject( pXslStyleSheet, vOutput );
ASSERT( !FAILED(hr));
}
catch ( ... )
{
// if cannot transform, just save as-is.
hr = xmlParser.SaveDocument( sPath );
return FAILED( hr );
}BSTR s = xmlParser.AsciiToBSTR(sPath );
hr = pXMLDocResult->save(s);
ASSERT(!FAILED(hr));The XSL file is :
<xsl:stylesheet version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
xsl:copy
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>Anyone used
transformNodeToObject
and have any insights ? Thanks. Max.Maximilien Lincourt Your Head A Splo
Hi, I got similar code in one of my projects, there are two differences that may be of importance: 1) I always apply
pXMLDoc->put_async(VARIANT_FALSE)
to theIXMLDOMDocument
's. Probaby you have to check if the documents are fully loaded before you operate on them otherwise. 2) When callingtransformNodeToObject(...)
, I don't give the document pointer but a node pointer as argument:IXMLDOMElement* pElemInterface = NULL;
pXMLDoc->get_documentElement(&pElemInterface);IXMLDOMNode* pNodeInterface = NULL;
pElemInterface->QueryInterface(IID_IXMLDOMNode, (void **)&pNodeInterface);
pElemInterface->Release();pXMLDoc->transformNodeToObject( pNodeInterface, vOutput );
It has been a while since I coded that so I can only guess there should have been a reason for this. In VBS, using the document directly works fine. Hope that helps ;)