Trouble with IXMLDOMDocument::save

Posted on 2004-08-14
Last Modified: 2012-05-05
So at last I figured out how to grab the xml contents of an IE browser.  The only problem I have now is that it won't save it for me.  Every time I call IXMLDOMDocument::save (even to a constant string location that I know permissions are not a problem for) it returns E_ACCESSDENIED.  Any ideas?  Here is my code:

// Get the document's IDispatchEx
pHTMLDocument2->QueryInterface(IID_IDispatchEx, (void**) &spDispEx);
      bstr = ConvertStringToBSTR("XMLDocument");

      // Get the XMLDocument expando property
      hr = spDispEx->GetDispID(bstr, fdexNameCaseSensitive, &dispid);

      if(hr==E_OUTOFMEMORY) throw 2000;
      if(hr==DISP_E_UNKNOWNNAME) throw 1003;

      // Get the XMLDocument value
      hr = spDispEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpNoArgs, &var, NULL, NULL);
      if(hr==S_OK && var.vt==VT_DISPATCH){
            // Get the IXMLDOMDocument interface
            var.pdispVal->QueryInterface(IID_IXMLDOMDocument, (void**) &pXMLDoc);
                  _variant_t varString = _T("C:\\sample.xml");
                  hr = pXMLDoc->save(varString);
                  if(hr!=S_OK) throw 2001;
}else throw 1003;

Any ideas why it seems to not be able to create the file?  It doesn't seem to matter where I try to put it - it just won't write the file.

David Johns
Question by:david_johns
  • 2

Expert Comment

ID: 11811970
The documentation is quite explicit when trying to save to a file-name:
"This mode is not intended for use from a secure client, such as Microsoft® Internet Explorer."

I would suggest creating a secondary DOM document, loading the XML into it, and saving it from there:

IXMLDOMDocument *pNewDoc = 0;
       IID_IXMLDOMDocument, reinterpret_cast<void**>(&pNewDoc));

BSTR *pbstrXml = 0;
pXmlDoc->xml ( pbstrXml );

VARIANT_BOOL  isSuccessful;
pNewDoc->loadXml ( *pbstrXml, &isSuccessful );

pNewDoc->save ( varString );

Accepted Solution

_ys_ earned 250 total points
ID: 11812373
Complete illsutration code:

#import "msxml.dll" named_guids raw_interfaces_only

int main(int argc, char* argv[])
    MSXML::IXMLDOMDocument *pXmlDoc = 0;
    HRESULT hr = CoInitialize (0);

    if (SUCCEEDED (hr))
        if (SUCCEEDED (hr = CoCreateInstance (MSXML::CLSID_DOMDocument, 0, CLSCTX_SERVER,
            MSXML::IID_IXMLDOMDocument, reinterpret_cast<void**>(&pXmlDoc))))
            BSTR bstrXml = SysAllocString (L"<test>abc</test>");

            VARIANT_BOOL isLoaded;
            pXmlDoc->loadXML (bstrXml, &isLoaded);
            SysFreeString (bstrXml);

            pXmlDoc->get_xml (&bstrXml);

            MSXML::IXMLDOMDocument *pNewDoc = 0;
            if (SUCCEEDED (hr = CoCreateInstance (MSXML::CLSID_DOMDocument, 0, CLSCTX_SERVER,
                MSXML::IID_IXMLDOMDocument, reinterpret_cast<void**>(&pNewDoc))))
                pNewDoc->loadXML (bstrXml, &isLoaded);
                pNewDoc->save (_variant_t (L"C:\\TestXml.xml") );

            SysFreeString (bstrXml);
            pXmlDoc->Release ();

        CoUninitialize ();

    return 0;

Where pXmlDoc and pNewDoc are your original IE XMl document and new SML Document respectively.

Author Comment

ID: 11816958
Excellent Post!!! I actually found that phrase in MSDN just after posting and had thought about trying to copy the xml document into another object, but couldn't get IXMLDOMDocument::save to save it into another document.  This was a clever approach that I hadn't thought of.  Thanks.

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question