diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index e06b03d3ab26f883122d15206d0e166779fc7f9c..27f6a9f4203b10576bb32ab6dc47a265fa02564b 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -75,6 +75,7 @@ static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r'
  * We need to preserve this when reloading a document,
  * and also need access to it from the libxml backend. */
 typedef struct _domdoc_properties {
+    MSXML_VERSION version;
     VARIANT_BOOL preserving;
     IXMLDOMSchemaCollection2* schemaCache;
     struct list selectNsList;
@@ -249,20 +250,31 @@ static domdoc_properties * create_properties(const GUID *clsid)
 {
     domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties));
 
-    list_init( &properties->selectNsList );
+    list_init(&properties->selectNsList);
     properties->preserving = VARIANT_FALSE;
     properties->schemaCache = NULL;
     properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
     properties->selectNsStr_len = 0;
 
     /* properties that are dependent on object versions */
-    if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
-        IsEqualCLSID( clsid, &CLSID_DOMDocument60 ))
+    if (IsEqualCLSID(clsid, &CLSID_DOMDocument30))
     {
+        properties->version = MSXML3;
+        properties->XPath = FALSE;
+    }
+    else if (IsEqualCLSID(clsid, &CLSID_DOMDocument40))
+    {
+        properties->version = MSXML4;
+        properties->XPath = TRUE;
+    }
+    else if (IsEqualCLSID(clsid, &CLSID_DOMDocument60))
+    {
+        properties->version = MSXML6;
         properties->XPath = TRUE;
     }
     else
     {
+        properties->version = MSXML_DEFAULT;
         properties->XPath = FALSE;
     }
 
@@ -279,6 +291,7 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties)
 
     if (pcopy)
     {
+        pcopy->version = properties->version;
         pcopy->preserving = properties->preserving;
         pcopy->schemaCache = properties->schemaCache;
         pcopy->XPath = properties->XPath;
@@ -630,33 +643,34 @@ static inline domdoc *impl_from_IConnectionPointContainer(IConnectionPointContai
 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
     IPersistStreamInit *iface, REFIID riid, void **ppvObj)
 {
-    domdoc *this = impl_from_IPersistStreamInit(iface);
-    return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
+    domdoc* This = impl_from_IPersistStreamInit(iface);
+    return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3*)&This->lpVtbl, riid, ppvObj);
 }
 
 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
     IPersistStreamInit *iface)
 {
-    domdoc *this = impl_from_IPersistStreamInit(iface);
-    return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
+    domdoc* This = impl_from_IPersistStreamInit(iface);
+    return IXMLDOMDocument3_AddRef((IXMLDOMDocument3*)&This->lpVtbl);
 }
 
 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
     IPersistStreamInit *iface)
 {
-    domdoc *this = impl_from_IPersistStreamInit(iface);
-    return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
+    domdoc* This = impl_from_IPersistStreamInit(iface);
+    return IXMLDOMDocument3_Release((IXMLDOMDocument3*)&This->lpVtbl);
 }
 
 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
     IPersistStreamInit *iface, CLSID *classid)
 {
-    TRACE("(%p,%p): stub!\n", iface, classid);
+    domdoc* This = impl_from_IPersistStreamInit(iface);
+    TRACE("(%p)->(%p)\n", This, classid);
 
     if(!classid)
         return E_POINTER;
 
-    *classid = CLSID_DOMDocument2;
+    *classid = *DOMDocument_version(This->properties->version);
 
     return S_OK;
 }
diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index cc287ced59d6c2d3767f577340c3741af52e5e5a..4e7d29e919edffa5b03f7e7d6fc0fd15c778743a 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -204,7 +204,6 @@ static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv
     return hres;
 }
 
-static ClassFactory schemacf = { &ClassFactoryVtbl, SchemaCache_create };
 static ClassFactory xmldoccf = { &ClassFactoryVtbl, XMLDocument_create };
 static ClassFactory saxreadcf = { &ClassFactoryVtbl, SAXXMLReader_create };
 static ClassFactory httpreqcf = { &ClassFactoryVtbl, XMLHTTPRequest_create };
@@ -231,7 +230,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache40 ) ||
              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache60 ))
     {
-        cf = (IClassFactory*) &schemacf.lpVtbl;
+        return DOMClassFactory_Create(rclsid, riid, ppv, SchemaCache_create);
     }
     else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
     {
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 8a2b1b59e09f9f407838e49e0fab91a8f935ff71..0e7971e94e37d33f74cf62c4f5ae67db6b8f335e 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -29,6 +29,13 @@
 # error You must include config.h to use this header
 #endif
 
+typedef enum {
+    MSXML_DEFAULT = 0,
+    MSXML3 = 30,
+    MSXML4 = 40,
+    MSXML6 = 60
+} MSXML_VERSION;
+
 /* typelibs */
 typedef enum tid_t {
     IXMLDOMAttribute_tid,
@@ -371,11 +378,53 @@ MAKE_FUNCPTR(xsltParseStylesheetDoc);
 extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
                                              LONG line, LONG linepos, LONG filepos );
 extern HRESULT DOMDocument_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj );
-extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, void **pObj );
+extern HRESULT SchemaCache_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj );
 extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, void **pObj );
 extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, void **pObj );
 extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, void **pObj);
 
+static inline const CLSID* DOMDocument_version(const MSXML_VERSION v)
+{
+    CLSID const* clsid;
+    switch (v)
+    {
+        case MSXML_DEFAULT:
+            clsid = &CLSID_DOMDocument;
+            break;
+        case MSXML3:
+            clsid = &CLSID_DOMDocument30;
+            break;
+        case MSXML4:
+            clsid = &CLSID_DOMDocument40;
+            break;
+        case MSXML6:
+            clsid = &CLSID_DOMDocument60;
+            break;
+    }
+    return clsid;
+}
+
+static inline const CLSID* SchemaCache_version(const MSXML_VERSION v)
+{
+    CLSID const* clsid;
+    switch (v)
+    {
+        case MSXML_DEFAULT:
+            clsid = &CLSID_XMLSchemaCache;
+            break;
+        case MSXML3:
+            clsid = &CLSID_XMLSchemaCache30;
+            break;
+        case MSXML4:
+            clsid = &CLSID_XMLSchemaCache40;
+            break;
+        case MSXML6:
+            clsid = &CLSID_XMLSchemaCache60;
+            break;
+    }
+    return clsid;
+}
+
 typedef struct bsc_t bsc_t;
 
 HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**);
diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c
index eb6b6d3eb09f25bd575ad3bc8567a56a8d1247e4..cddbc5c82a67eac3abf70f08be537f14571cbed6 100644
--- a/dlls/msxml3/schema.c
+++ b/dlls/msxml3/schema.c
@@ -85,6 +85,7 @@ typedef enum _SCHEMA_TYPE {
 typedef struct _schema_cache
 {
     const struct IXMLDOMSchemaCollection2Vtbl* lpVtbl;
+    MSXML_VERSION version;
     xmlHashTablePtr cache;
     LONG ref;
 } schema_cache;
@@ -818,7 +819,7 @@ static BOOL link_datatypes(xmlDocPtr schema)
     return TRUE;
 }
 
-static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI)
+static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI, MSXML_VERSION v)
 {
     cache_entry* entry = heap_alloc(sizeof(cache_entry));
     xmlSchemaParserCtxtPtr spctx;
@@ -834,7 +835,7 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI
 
     if ((entry->schema = Schema_parse(spctx)))
     {
-        xmldoc_init(entry->schema->doc, &CLSID_DOMDocument40);
+        xmldoc_init(entry->schema->doc, DOMDocument_version(v));
         entry->doc = entry->schema->doc;
         xmldoc_add_ref(entry->doc);
     }
@@ -849,7 +850,7 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI
     return entry;
 }
 
-static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI)
+static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI, MSXML_VERSION v)
 {
     cache_entry* entry = heap_alloc(sizeof(cache_entry));
     xmlSchemaParserCtxtPtr spctx;
@@ -864,8 +865,8 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI
     if ((entry->schema = Schema_parse(spctx)))
     {
         entry->doc = new_doc;
-        xmldoc_init(entry->schema->doc, &CLSID_DOMDocument30);
-        xmldoc_init(entry->doc, &CLSID_DOMDocument30);
+        xmldoc_init(entry->schema->doc, DOMDocument_version(v));
+        xmldoc_init(entry->doc, DOMDocument_version(v));
         xmldoc_add_ref(entry->doc);
         xmldoc_add_ref(entry->schema->doc);
     }
@@ -882,12 +883,12 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI
     return entry;
 }
 
-static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI)
+static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI, MSXML_VERSION v)
 {
     cache_entry* entry;
     IXMLDOMDocument3* domdoc = NULL;
     xmlDocPtr doc = NULL;
-    HRESULT hr = DOMDocument_create(&CLSID_DOMDocument, NULL, (void**)&domdoc);
+    HRESULT hr = DOMDocument_create(DOMDocument_version(v), NULL, (void**)&domdoc);
     VARIANT_BOOL b = VARIANT_FALSE;
     SCHEMA_TYPE type = SCHEMA_TYPE_INVALID;
 
@@ -916,10 +917,10 @@ static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI)
     switch (type)
     {
         case SCHEMA_TYPE_XSD:
-            entry = cache_entry_from_xsd_doc(doc, nsURI);
+            entry = cache_entry_from_xsd_doc(doc, nsURI, v);
             break;
         case SCHEMA_TYPE_XDR:
-            entry = cache_entry_from_xdr_doc(doc, nsURI);
+            entry = cache_entry_from_xdr_doc(doc, nsURI, v);
             break;
         case SCHEMA_TYPE_INVALID:
             entry = NULL;
@@ -1073,7 +1074,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri
 
         case VT_BSTR:
             {
-                cache_entry* entry = cache_entry_from_url(var, name);
+                cache_entry* entry = cache_entry_from_url(var, name, This->version);
 
                 if (entry)
                 {
@@ -1111,11 +1112,11 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri
 
                 if (type == SCHEMA_TYPE_XSD)
                 {
-                    entry = cache_entry_from_xsd_doc(doc, name);
+                    entry = cache_entry_from_xsd_doc(doc, name, This->version);
                 }
                 else if (type == SCHEMA_TYPE_XDR)
                 {
-                    entry = cache_entry_from_xdr_doc(doc, name);
+                    entry = cache_entry_from_xdr_doc(doc, name, This->version);
                 }
                 else
                 {
@@ -1405,7 +1406,7 @@ XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node)
     return dt;
 }
 
-HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj)
+HRESULT SchemaCache_create(const GUID *clsid, IUnknown* pUnkOuter, void** ppObj)
 {
     schema_cache* This = heap_alloc(sizeof(schema_cache));
     if (!This)
@@ -1415,13 +1416,22 @@ HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj)
     This->cache = xmlHashCreate(DEFAULT_HASHTABLE_SIZE);
     This->ref = 1;
 
+    if (IsEqualCLSID(clsid, &CLSID_XMLSchemaCache30))
+        This->version = MSXML3;
+    else if (IsEqualCLSID(clsid, &CLSID_DOMDocument40))
+        This->version = MSXML4;
+    else if (IsEqualCLSID(clsid, &CLSID_DOMDocument60))
+        This->version = MSXML6;
+    else
+        This->version = MSXML_DEFAULT;
+
     *ppObj = &This->lpVtbl;
     return S_OK;
 }
 
 #else
 
-HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj)
+HRESULT SchemaCache_create(const GUID *clsid, IUnknown* pUnkOuter, void** ppObj)
 {
     MESSAGE("This program tried to use a SchemaCache object, but\n"
             "libxml2 support was not present at compile time.\n");