Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. MSXML2::IXMLDOMDocument2 transformNodeToObject

MSXML2::IXMLDOMDocument2 transformNodeToObject

Scheduled Pinned Locked Moved C / C++ / MFC
xmlwpfregexjsonquestion
2 Posts 2 Posters 6 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Maximilien
    wrote on last edited by
    #1

    (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

    D 1 Reply Last reply
    0
    • M Maximilien

      (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

      D Offline
      D Offline
      Doc Lobster
      wrote on last edited by
      #2

      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 the IXMLDOMDocument's. Probaby you have to check if the documents are fully loaded before you operate on them otherwise. 2) When calling transformNodeToObject(...), 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 ;)

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups