BUG: DTDs and Schemas Not Resolved When Using loadXML Method

ID: Q235344


The information in this article applies to:


SYMPTOMS

When using the IXMLDOMDocument::loadXML method to load XML data into the MSXML parser via a string parameter, the MSXML parser does not correctly resolve any external files such as DTDs or Schemas.

Script in a Web page will not suffer from this bug because MSHTML, Internet Explorer's HTML engine, provides a valid security site object to the MSXML parser.


CAUSE

Due to a security constraint, resolveExternals is turned off while parsing the XML data loaded with loadXML.


RESOLUTION

The easiest workaround might be to call IXMLDOMDocument::load with a URL referencing an XML file. If loading from memory is preferred, there are three alternatives that will load XML Documents from memory sources and correctly resolve all external files:


STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.


MORE INFORMATION

Following are two sections of example code that create a fake site object and attach it to an XML Document.

C++ Example

Code using this alternative should call the XMLDummySecurity method and pass the IXMLDOMDocument pointer before using it to load the XML document with loadXML.

class DummySite : public IUnknown
{
public:
    DummySite() : _ulRefCount(1) {}

public:
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject)
    {
        if (!ppvObject)
            return E_POINTER;

        if (riid == IID_IUnknown)
        {
            this->AddRef();
            *ppvObject = (IUnknown*)this;
        }
        else
        {
            *ppvObject = NULL;
            return E_NOINTERFACE;
        }

        return S_OK;
    }

    virtual ULONG STDMETHODCALLTYPE AddRef( void)
    {
        return ++_ulRefCount;
    }

    virtual ULONG STDMETHODCALLTYPE Release( void)
    {
        ULONG ul = --_ulRefCount;
        if (!ul)
            delete this;
        return ul;
    }

protected:
    ULONG _ulRefCount;
};

HRESULT XMLDummySecurity(IXMLDOMDocument * pXMLDocument)
{
    HRESULT hr;
    IObjectWithSite * pObjWithSite = NULL;
    if (SUCCEEDED(hr = pXMLDocument->QueryInterface(IID_IObjectWithSite, (void **)&pObjWithSite)))
    {
        DummySite * pObj = new DummySite();
        pObjWithSite->SetSite(pObj);
        pObjWithSite->Release();
    }
    return hr;
} 

Visual Basic Example

Follow these steps to create a dummy security class in your project and attach it as a site to the XML Document object:
  1. Create a new text file called Objwithsite.idl and add the following code into it:
    
    [
       uuid(FC4801A3-2BA9-11CF-A229-00AA003D7353),
       version(1.0),
       helpstring("IObjectWithSite TLB")
    ]
    library IOBJWITHSITELib
    {
       [
          object,
          uuid(FC4801A3-2BA9-11CF-A229-00AA003D7352),
          pointer_default(unique)
       ]
       interface IObjectWithSite : IUnknown
       {
          typedef IObjectWithSite * LPOBJECTWITHSITE;
       
          HRESULT SetSite(
          [in] IUnknown * pUnkSite
          );
       
          HRESULT GetSite(
             [in] REFIID riid,
             [out, iid_is(riid)] void ** ppvSite);
       }
    }; 


  2. Use the MIDL utility included with the Platform SDK or Visual Studio to create a Type Library (.tlb) from this IDL file.


  3. Add a reference to the resultant type library to the XML project.


  4. Create a new empty class in the project called CDummySecurity and set its Instancing property to "PublicNotCreatable."


  5. Make sure the XML project is an ActiveX project (ActiveX EXE, ActiveX DLL, and so forth). If your existing project is a standard EXE that uses a default startup form, you'll need to add a Main procedure to your project and load the form from there.


  6. Use the following code to set the fake security object before calling loadXML on the XML Document:
    
    Dim objDummySecurity As New CDummySecurity
    Dim site As IObjectWithSite
    Set site = objXMLDoc
    site.SetSite objDummySecurity
       
    'Now you can load the document and external references will be resolved. 
    objXMLDoc.loadXML(strXMLWithDTD) 


Additional query words:


Keywords          : kbGrpInet kbIE500bug kbXML kbDSupport 
Version           : WINDOWS:5.0
Platform          : WINDOWS 
Issue type        : kbbug 

Last Reviewed: August 5, 1999