Solved

Trouble with IXMLDOMDocument::save

Posted on 2004-08-14
3
1,467 Views
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);
if(spDispEx){
      bstr = ConvertStringToBSTR("XMLDocument");

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

      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);
            if(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.

Thanks,
David Johns
0
Comment
Question by:david_johns
  • 2
3 Comments
 
LVL 9

Expert Comment

by:_ys_
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."
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/xmmthsave.asp

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

IXMLDOMDocument *pNewDoc = 0;
CoCreateInstance(CLSID_DOMDocument30, NULL, CLSCTX_INPROC_SERVER,
       IID_IXMLDOMDocument, reinterpret_cast<void**>(&pNewDoc));

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

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

pNewDoc->save ( varString );
0
 
LVL 9

Accepted Solution

by:
_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.
0
 

Author Comment

by:david_johns
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.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

762 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

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now