Solved

Trouble with IXMLDOMDocument::save

Posted on 2004-08-14
3
1,501 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
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.

839 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