include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / msxml3 / tests / domdoc.c
blobce2e7e655ebeb7de29a61c4fa3f8f745fbc61fe2
1 /*
2 * XML test
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2007-2008 Alistair Leslie-Hughes
6 * Copyright 2010-2011 Adam Martinson for CodeWeavers
7 * Copyright 2010-2013 Nikolay Sivov for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define COBJMACROS
26 #define CONST_VTABLE
28 #include <stdio.h>
29 #include <assert.h>
31 #include "windows.h"
33 #include "msxml.h"
34 #include "msxml2.h"
35 #include "msxml2did.h"
36 #include "ole2.h"
37 #include "dispex.h"
38 #include "objsafe.h"
39 #include "mshtml.h"
40 #include "docobj.h"
41 #include "xmlparser.h"
42 #include "initguid.h"
43 #include "asptlb.h"
44 #include "shlwapi.h"
46 #include "wine/test.h"
48 #define XML_E_UNEXPECTED_ATTRIBUTE 0xC00CE56C
50 /* undef the #define in msxml2 so that we can access all versions */
51 #undef CLSID_DOMDocument
53 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
54 DEFINE_GUID(IID_transformdest_unknown,0xf5078f3a,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21);
56 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
57 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
59 IUnknown *iface = iface_ptr;
60 HRESULT hr, expected_hr;
61 IUnknown *unk;
63 expected_hr = supported ? S_OK : E_NOINTERFACE;
65 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
66 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
67 if (SUCCEEDED(hr))
68 IUnknown_Release(unk);
71 static int g_unexpectedcall, g_expectedcall;
73 struct msxmlsupported_data_t
75 const GUID *clsid;
76 const char *name;
77 const IID *ifaces[3];
78 BOOL supported[3];
81 static struct msxmlsupported_data_t domdoc_support_data[] =
83 { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
84 { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
85 { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
86 { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
87 { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
88 { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
89 { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
90 { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} },
91 { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
92 { NULL }
95 static const char *debugstr_msxml_guid(REFIID riid)
97 if(!riid)
98 return "(null)";
100 if (IsEqualIID(&IID_IXMLDOMDocument, riid))
101 return "IXMLDOMDocument";
102 else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
103 return "IXMLDOMDocument2";
104 else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
105 return "IXMLDOMDocument3";
106 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
107 return "IXMLDOMSchemaCollection";
108 else if (IsEqualIID(&IID_IXSLTemplate, riid))
109 return "IXSLTemplate";
110 else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
111 return "IMXNamespaceManager";
112 else
113 return wine_dbgstr_guid(riid);
116 static void get_class_support_data(struct msxmlsupported_data_t *table)
118 while (table->clsid)
120 IUnknown *unk;
121 HRESULT hr;
122 int i;
124 for (i = 0; i < ARRAY_SIZE(table->ifaces) && table->ifaces[i] != NULL; i++)
126 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
127 if (hr == S_OK) IUnknown_Release(unk);
129 table->supported[i] = hr == S_OK;
130 if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
133 table++;
137 static BOOL is_clsid_supported(const GUID *clsid, REFIID riid)
139 const struct msxmlsupported_data_t *table = domdoc_support_data;
140 while (table->clsid)
142 if (table->clsid == clsid)
144 int i;
146 for (i = 0; i < ARRAY_SIZE(table->ifaces) && table->ifaces[i] != NULL; i++)
147 if (table->ifaces[i] == riid) return table->supported[i];
150 table++;
152 return FALSE;
155 typedef struct
157 IDispatch IDispatch_iface;
158 LONG ref;
159 } dispevent;
161 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
163 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
166 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
168 *ppvObject = NULL;
170 if ( IsEqualGUID( riid, &IID_IDispatch) ||
171 IsEqualGUID( riid, &IID_IUnknown) )
173 *ppvObject = iface;
175 else
176 return E_NOINTERFACE;
178 IDispatch_AddRef( iface );
180 return S_OK;
183 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
185 dispevent *This = impl_from_IDispatch( iface );
186 return InterlockedIncrement( &This->ref );
189 static ULONG WINAPI dispevent_Release(IDispatch *iface)
191 dispevent *This = impl_from_IDispatch( iface );
192 ULONG ref = InterlockedDecrement( &This->ref );
194 if (ref == 0)
195 free(This);
197 return ref;
200 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
202 g_unexpectedcall++;
203 *pctinfo = 0;
204 return S_OK;
207 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
208 LCID lcid, ITypeInfo **ppTInfo)
210 g_unexpectedcall++;
211 return S_OK;
214 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
215 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
217 g_unexpectedcall++;
218 return S_OK;
221 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
222 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
223 EXCEPINFO *excepInfo, UINT *argErr)
225 ok(member == 0, "expected 0 member, got %ld\n", member);
226 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %lx\n", lcid);
227 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
229 ok(params->cArgs == 0, "got %d\n", params->cArgs);
230 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
231 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
232 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
234 ok(result == NULL, "got %p\n", result);
235 ok(excepInfo == NULL, "got %p\n", excepInfo);
236 ok(argErr == NULL, "got %p\n", argErr);
238 g_expectedcall++;
239 return E_FAIL;
242 static const IDispatchVtbl dispeventVtbl =
244 dispevent_QueryInterface,
245 dispevent_AddRef,
246 dispevent_Release,
247 dispevent_GetTypeInfoCount,
248 dispevent_GetTypeInfo,
249 dispevent_GetIDsOfNames,
250 dispevent_Invoke
253 static IDispatch* create_dispevent(void)
255 dispevent *event = malloc(sizeof(*event));
257 event->IDispatch_iface.lpVtbl = &dispeventVtbl;
258 event->ref = 1;
260 return &event->IDispatch_iface;
263 /* IStream */
264 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
266 *ppvObject = NULL;
268 if (IsEqualGUID(riid, &IID_IStream) ||
269 IsEqualGUID(riid, &IID_IUnknown))
270 *ppvObject = iface;
271 else
272 return E_NOINTERFACE;
274 return S_OK;
277 static ULONG WINAPI istream_AddRef(IStream *iface)
279 return 2;
282 static ULONG WINAPI istream_Release(IStream *iface)
284 return 1;
287 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread)
289 ok(0, "unexpected call\n");
290 return E_NOTIMPL;
293 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
295 *written = len/2;
296 return S_OK;
299 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
301 ok(0, "unexpected call\n");
302 return E_NOTIMPL;
305 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size)
307 ok(0, "unexpected call\n");
308 return E_NOTIMPL;
311 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len,
312 ULARGE_INTEGER *pread, ULARGE_INTEGER *written)
314 ok(0, "unexpected call\n");
315 return E_NOTIMPL;
318 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags)
320 ok(0, "unexpected call\n");
321 return E_NOTIMPL;
324 static HRESULT WINAPI istream_Revert(IStream *iface)
326 ok(0, "unexpected call\n");
327 return E_NOTIMPL;
330 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
331 ULARGE_INTEGER len, DWORD locktype)
333 ok(0, "unexpected call\n");
334 return E_NOTIMPL;
337 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
338 ULARGE_INTEGER len, DWORD locktype)
340 ok(0, "unexpected call\n");
341 return E_NOTIMPL;
344 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
346 ok(0, "unexpected call\n");
347 return E_NOTIMPL;
350 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream)
352 ok(0, "unexpected call\n");
353 return E_NOTIMPL;
356 static const IStreamVtbl StreamVtbl = {
357 istream_QueryInterface,
358 istream_AddRef,
359 istream_Release,
360 istream_Read,
361 istream_Write,
362 istream_Seek,
363 istream_SetSize,
364 istream_CopyTo,
365 istream_Commit,
366 istream_Revert,
367 istream_LockRegion,
368 istream_UnlockRegion,
369 istream_Stat,
370 istream_Clone
373 static IStream savestream = { &StreamVtbl };
375 static HRESULT WINAPI response_QI(IResponse *iface, REFIID riid, void **obj)
377 if (IsEqualIID(&IID_IResponse, riid) ||
378 IsEqualIID(&IID_IDispatch, riid) ||
379 IsEqualIID(&IID_IUnknown, riid))
381 *obj = iface;
382 return S_OK;
385 if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid))
386 ok(0, "unexpected call\n");
387 return E_NOINTERFACE;
390 static ULONG WINAPI response_AddRef(IResponse *iface)
392 return 2;
395 static ULONG WINAPI response_Release(IResponse *iface)
397 return 1;
400 static HRESULT WINAPI response_GetTypeInfoCount(IResponse *iface, UINT *count)
402 ok(0, "unexpected call\n");
403 return E_NOTIMPL;
406 static HRESULT WINAPI response_GetTypeInfo(IResponse *iface, UINT ti, LCID lcid, ITypeInfo **tinfo)
408 ok(0, "unexpected call\n");
409 return E_NOTIMPL;
412 static HRESULT WINAPI response_GetIDsOfNames(IResponse *iface, REFIID riid, LPOLESTR *names,
413 UINT cnames, LCID lcid, DISPID *rgDispId)
415 ok(0, "unexpected call\n");
416 return E_NOTIMPL;
419 static HRESULT WINAPI response_Invoke(IResponse *iface, DISPID dispid, REFIID riid, LCID lcid,
420 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr)
422 ok(0, "unexpected call\n");
423 return E_NOTIMPL;
426 static HRESULT WINAPI response_get_Buffer(IResponse *iface, VARIANT_BOOL *fIsBuffering)
428 ok(0, "unexpected call\n");
429 return E_NOTIMPL;
432 static HRESULT WINAPI response_put_Buffer(IResponse *iface, VARIANT_BOOL fIsBuffering)
434 ok(0, "unexpected call\n");
435 return E_NOTIMPL;
438 static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet)
440 ok(0, "unexpected call\n");
441 return E_NOTIMPL;
444 static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType)
446 ok(0, "unexpected call\n");
447 return E_NOTIMPL;
450 static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet)
452 ok(0, "unexpected call\n");
453 return E_NOTIMPL;
456 static HRESULT WINAPI response_put_Expires(IResponse *iface, LONG lExpiresMinutes)
458 ok(0, "unexpected call\n");
459 return E_NOTIMPL;
462 static HRESULT WINAPI response_get_ExpiresAbsolute(IResponse *iface, VARIANT *pvarExpiresRet)
464 ok(0, "unexpected call\n");
465 return E_NOTIMPL;
468 static HRESULT WINAPI response_put_ExpiresAbsolute(IResponse *iface, DATE dtExpires)
470 ok(0, "unexpected call\n");
471 return E_NOTIMPL;
474 static HRESULT WINAPI response_get_Cookies(IResponse *iface, IRequestDictionary **ppCookies)
476 ok(0, "unexpected call\n");
477 return E_NOTIMPL;
480 static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet)
482 ok(0, "unexpected call\n");
483 return E_NOTIMPL;
486 static HRESULT WINAPI response_put_Status(IResponse *iface, BSTR bstrStatus)
488 ok(0, "unexpected call\n");
489 return E_NOTIMPL;
492 static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName)
494 ok(0, "unexpected call\n");
495 return E_NOTIMPL;
498 static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue)
500 ok(0, "unexpected call\n");
501 return E_NOTIMPL;
504 static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry)
506 ok(0, "unexpected call\n");
507 return E_NOTIMPL;
510 static HRESULT WINAPI response_BinaryWrite(IResponse *iface, VARIANT input)
512 HRESULT hr;
513 LONG bound;
514 UINT dim;
516 ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input));
518 dim = SafeArrayGetDim(V_ARRAY(&input));
519 ok(dim == 1, "got wrong array dimensions %u\n", dim);
521 bound = 1;
522 hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound);
523 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
524 ok(bound == 0, "wrong array low bound %ld\n", bound);
526 bound = 0;
527 hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound);
528 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
529 ok(bound > 0, "wrong array high bound %ld\n", bound);
531 return E_NOTIMPL;
534 static HRESULT WINAPI response_Clear(IResponse *iface)
536 ok(0, "unexpected call\n");
537 return E_NOTIMPL;
540 static HRESULT WINAPI response_End(IResponse *iface)
542 ok(0, "unexpected call\n");
543 return E_NOTIMPL;
546 static HRESULT WINAPI response_Flush(IResponse *iface)
548 ok(0, "unexpected call\n");
549 return E_NOTIMPL;
552 static HRESULT WINAPI response_Redirect(IResponse *iface, BSTR bstrURL)
554 ok(0, "unexpected call\n");
555 return E_NOTIMPL;
558 static HRESULT WINAPI response_Write(IResponse *iface, VARIANT varText)
560 ok(0, "unexpected call\n");
561 return E_NOTIMPL;
564 static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber)
566 ok(0, "unexpected call\n");
567 return E_NOTIMPL;
570 static HRESULT WINAPI response_IsClientConnected(IResponse *iface, VARIANT_BOOL *pfIsClientConnected)
572 ok(0, "unexpected call\n");
573 return E_NOTIMPL;
576 static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet)
578 ok(0, "unexpected call\n");
579 return E_NOTIMPL;
582 static HRESULT WINAPI response_put_CharSet(IResponse *iface, BSTR bstrCharSet)
584 ok(0, "unexpected call\n");
585 return E_NOTIMPL;
588 static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue)
590 ok(0, "unexpected call\n");
591 return E_NOTIMPL;
594 static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl)
596 ok(0, "unexpected call\n");
597 return E_NOTIMPL;
600 static HRESULT WINAPI response_put_CacheControl(IResponse *iface, BSTR bstrCacheControl)
602 ok(0, "unexpected call\n");
603 return E_NOTIMPL;
606 static HRESULT WINAPI response_get_CodePage(IResponse *iface, LONG *plvar)
608 ok(0, "unexpected call\n");
609 return E_NOTIMPL;
612 static HRESULT WINAPI response_put_CodePage(IResponse *iface, LONG codepage)
614 ok(0, "unexpected call\n");
615 return E_NOTIMPL;
618 static HRESULT WINAPI response_get_LCID(IResponse *iface, LONG *lcid)
620 ok(0, "unexpected call\n");
621 return E_NOTIMPL;
624 static HRESULT WINAPI response_put_LCID(IResponse *iface, LONG lcid)
626 ok(0, "unexpected call\n");
627 return E_NOTIMPL;
630 static const IResponseVtbl testresponsevtbl =
632 response_QI,
633 response_AddRef,
634 response_Release,
635 response_GetTypeInfoCount,
636 response_GetTypeInfo,
637 response_GetIDsOfNames,
638 response_Invoke,
639 response_get_Buffer,
640 response_put_Buffer,
641 response_get_ContentType,
642 response_put_ContentType,
643 response_get_Expires,
644 response_put_Expires,
645 response_get_ExpiresAbsolute,
646 response_put_ExpiresAbsolute,
647 response_get_Cookies,
648 response_get_Status,
649 response_put_Status,
650 response_Add,
651 response_AddHeader,
652 response_AppendToLog,
653 response_BinaryWrite,
654 response_Clear,
655 response_End,
656 response_Flush,
657 response_Redirect,
658 response_Write,
659 response_WriteBlock,
660 response_IsClientConnected,
661 response_get_CharSet,
662 response_put_CharSet,
663 response_Pics,
664 response_get_CacheControl,
665 response_put_CacheControl,
666 response_get_CodePage,
667 response_put_CodePage,
668 response_get_LCID,
669 response_put_LCID,
672 static IResponse testresponse = { &testresponsevtbl };
674 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
675 static void _expect_children(IXMLDOMNode *node, int line)
677 VARIANT_BOOL b;
678 HRESULT hr;
680 b = VARIANT_FALSE;
681 hr = IXMLDOMNode_hasChildNodes(node, &b);
682 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, %#lx.\n", hr);
683 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
686 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
687 static void _expect_no_children(IXMLDOMNode *node, int line)
689 VARIANT_BOOL b;
690 HRESULT hr;
692 b = VARIANT_TRUE;
693 hr = IXMLDOMNode_hasChildNodes(node, &b);
694 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, %#lx.\n", hr);
695 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
698 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
699 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
701 ULONG rc;
702 IUnknown_AddRef(obj);
703 rc = IUnknown_Release(obj);
704 ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc);
707 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
708 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
710 LONG length;
711 HRESULT hr;
713 length = 0;
714 hr = IXMLDOMNodeList_get_length(list, &length);
715 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
716 ok_(__FILE__,line)(length == len, "got %ld, expected %ld\n", length, len);
719 #define EXPECT_PARSE_ERROR(doc, hr_exp, hr_todo) _expect_parse_error(doc, hr_exp, hr_todo, __LINE__)
720 static void _expect_parse_error(IXMLDOMDocument *doc, HRESULT hr_exp, BOOL hr_todo, int line)
722 IXMLDOMParseError *error;
723 HRESULT hr;
724 LONG code;
726 error = NULL;
727 hr = IXMLDOMDocument_get_parseError(doc, &error);
728 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
729 ok_(__FILE__,line)(!!error, "got NULL parseError\n");
731 code = 0xdeadbeef;
732 hr = IXMLDOMParseError_get_errorCode(error, &code);
733 if (FAILED(hr_exp))
735 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
736 ok_(__FILE__,line)(FAILED(code), "expected failure HRESULT\n");
737 todo_wine_if(hr_todo)
738 ok_(__FILE__,line)(hr_exp == code, "expected %#lx, unexpected hr %#lx.\n", hr_exp, code);
740 else
742 ok_(__FILE__,line)(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
743 ok_(__FILE__,line)(SUCCEEDED(code), "expected successful HRESULT\n");
746 IXMLDOMParseError_Release(error);
749 static const WCHAR szComplete1[] = L"<?xml version='1.0'?>\n<open></open>\n";
750 static const char complete4A[] =
751 "<?xml version=\'1.0\'?>\n"
752 "<lc dl=\'str1\'>\n"
753 "<bs vr=\'str2\' sz=\'1234\'>"
754 "fn1.txt\n"
755 "</bs>\n"
756 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
757 "fn2.txt\n"
758 "</pr>\n"
759 "<empty></empty>\n"
760 "<fo>\n"
761 "<ba>\n"
762 "f1\n"
763 "</ba>\n"
764 "</fo>\n"
765 "</lc>\n";
767 static const WCHAR szComplete5[] =
768 L"<S:search xmlns:D=\"DAV:\" xmlns:C=\"urn:schemas-microsoft-com:office:clipgallery\" xmlns:S=\"urn:schemas-microsoft-com:office:clipgallery:search\">"
769 "<S:scope><S:deep>/</S:deep></S:scope><S:contentfreetext><C:textorproperty/>computer</S:contentfreetext></S:search>";
771 static const char complete7[] = {
772 "<?xml version=\"1.0\"?>\n\t"
773 "<root>\n"
774 "\t<a/>\n"
775 "\t<b/>\n"
776 "\t<c/>\n"
777 "</root>"
780 #define DECL_GBK \
781 "<?xml version=\"1.0\" encoding=\"gbk\"?>"
783 static const char gbkxml[] =
784 DECL_GBK
785 "<open></open>";
787 #define DECL_WIN_936 \
788 "<?xml version=\"1.0\" encoding=\"Windows-936\"?>"
790 static const char win936xml[] =
791 DECL_WIN_936
792 "<open></open>";
794 #define DECL_WIN_1252 \
795 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
797 static const char win1252xml[] =
798 DECL_WIN_1252
799 "<open></open>";
801 static const char win1252decl[] =
802 DECL_WIN_1252
805 static const char nocontent[] = "no xml content here";
807 static const char szExampleXML[] =
808 "<?xml version='1.0' encoding='utf-8'?>\n"
809 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
810 " <elem>\n"
811 " <a>A1 field</a>\n"
812 " <b>B1 field</b>\n"
813 " <c>C1 field</c>\n"
814 " <d>D1 field</d>\n"
815 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
816 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
817 " <![CDATA[]]> This is<strong> a</strong> <i>description</i><dot>. </dot><bar:x/>\n"
818 " </html>\n"
819 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
820 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
821 " </html>\n"
822 " </description>\n"
823 " </elem>\n"
824 "\n"
825 " <elem a='a'>\n"
826 " <a>A2 field</a>\n"
827 " <b>B2 field</b>\n"
828 " <c type=\"old\">C2 field</c>\n"
829 " <d>D2 field</d>\n"
830 " </elem>\n"
831 "\n"
832 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
833 " <a>A3 field</a>\n"
834 " <b>B3 field</b>\n"
835 " <c>C3 field</c>\n"
836 " </elem>\n"
837 "\n"
838 " <elem>\n"
839 " <a>A4 field</a>\n"
840 " <b>B4 field</b>\n"
841 " <foo:c>C4 field</foo:c>\n"
842 " <d>D4 field</d>\n"
843 " </elem>\n"
844 "</root>\n";
846 static const char charrefsxml[] =
847 "<?xml version='1.0'?>"
848 "<a>"
849 "<b1> Text &#65; end </b1>"
850 "<b2>&#65;&#66; &#67; </b2>"
851 "</a>";
853 static const CHAR szNodeTypesXML[] =
854 "<?xml version='1.0'?>"
855 "<!-- comment node 0 -->"
856 "<root id='0' depth='0'>"
857 " <!-- comment node 1 -->"
858 " text node 0"
859 " <x id='1' depth='1'>"
860 " <?foo value='PI for x'?>"
861 " <!-- comment node 2 -->"
862 " text node 1"
863 " <a id='3' depth='2'/>"
864 " <b id='4' depth='2'/>"
865 " <c id='5' depth='2'/>"
866 " </x>"
867 " <y id='2' depth='1'>"
868 " <?bar value='PI for y'?>"
869 " <!-- comment node 3 -->"
870 " text node 2"
871 " <a id='6' depth='2'/>"
872 " <b id='7' depth='2'/>"
873 " <c id='8' depth='2'/>"
874 " </y>"
875 "</root>";
877 static const CHAR szTransformXML[] =
878 "<?xml version=\"1.0\"?>\n"
879 "<greeting>\n"
880 "Hello World\n"
881 "</greeting>";
883 static const CHAR szTransformSSXML[] =
884 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
885 " <xsl:output method=\"html\"/>\n"
886 " <xsl:template match=\"/\">\n"
887 " <xsl:apply-templates select=\"greeting\"/>\n"
888 " </xsl:template>\n"
889 " <xsl:template match=\"greeting\">\n"
890 " <html>\n"
891 " <body>\n"
892 " <h1>\n"
893 " <xsl:value-of select=\".\"/>\n"
894 " </h1>\n"
895 " </body>\n"
896 " </html>\n"
897 " </xsl:template>\n"
898 "</xsl:stylesheet>";
900 static const CHAR szTransformOutput[] =
901 "<html><body><h1>"
902 "Hello World"
903 "</h1></body></html>";
905 static const CHAR szTypeValueXML[] =
906 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
907 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
908 " <string>Wine</string>\n"
909 " <string2 dt:dt=\"string\">String </string2>\n"
910 " <string3> Wine Wine </string3>\n"
911 " <string4>\nWine Wine\t</string4>\n"
912 " <string5> </string5>\n"
913 " <nested><s1> s1 </s1><s2>\ns2 s2\t</s2></nested>\n"
914 " <number dt:dt=\"number\">12.44</number>\n"
915 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
916 " <int dt:dt=\"int\">-13</int>\n"
917 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
918 " <bool dt:dt=\"boolean\">1</bool>\n"
919 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
920 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
921 " <date dt:dt=\"date\">3721-11-01</date>\n"
922 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
923 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
924 " <i1 dt:dt=\"i1\">-13</i1>\n"
925 " <i2 dt:dt=\"i2\">31915</i2>\n"
926 " <i4 dt:dt=\"i4\">-312232</i4>\n"
927 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
928 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
929 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
930 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
931 " <r8 dt:dt=\"r8\">0.412</r8>\n"
932 " <float dt:dt=\"float\">41221.421</float>\n"
933 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
934 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
935 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
936 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
937 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
938 "</root>";
940 static const CHAR szBasicTransformSSXMLPart1[] =
941 "<?xml version=\"1.0\"?>"
942 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
943 "<xsl:output method=\"html\"/>\n"
944 "<xsl:template match=\"/\">"
945 "<HTML><BODY><TABLE>"
946 " <xsl:apply-templates select='document(\"";
948 static const CHAR szBasicTransformSSXMLPart2[] =
949 "\")/bottle/wine'>"
950 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
951 " </xsl:apply-templates>"
952 "</TABLE></BODY></HTML>"
953 "</xsl:template>"
954 "<xsl:template match=\"bottle\">"
955 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
956 "</xsl:template>"
957 "<xsl:template match=\"name\">"
958 " <TD><xsl:apply-templates /></TD>"
959 "</xsl:template>"
960 "<xsl:template match=\"cost\">"
961 " <TD><xsl:apply-templates /></TD>"
962 "</xsl:template>"
963 "</xsl:stylesheet>";
965 static const CHAR szBasicTransformXML[] =
966 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
968 static const CHAR szBasicTransformOutput[] =
969 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
971 #define SZ_EMAIL_DTD \
972 "<!DOCTYPE email ["\
973 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
974 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
975 " <!ATTLIST email sent (yes|no) \"no\">"\
976 " <!ELEMENT recipients (to+,cc*)>"\
977 " <!ELEMENT to (#PCDATA)>"\
978 " <!ATTLIST to name CDATA #IMPLIED>"\
979 " <!ELEMENT cc (#PCDATA)>"\
980 " <!ATTLIST cc name CDATA #IMPLIED>"\
981 " <!ELEMENT from (#PCDATA)>"\
982 " <!ATTLIST from name CDATA #IMPLIED>"\
983 " <!ELEMENT reply-to (#PCDATA)>"\
984 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
985 " <!ELEMENT subject ANY>"\
986 " <!ELEMENT body ANY>"\
987 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
988 " <!ELEMENT attachment (#PCDATA)>"\
989 " <!ATTLIST attachment id ID #REQUIRED>"\
990 "]>"
992 static const CHAR szEmailXML[] =
993 "<?xml version=\"1.0\"?>"
994 SZ_EMAIL_DTD
995 "<email attachments=\"patch1\">"
996 " <recipients>"
997 " <to>wine-patches@winehq.org</to>"
998 " </recipients>"
999 " <from name=\"Anonymous\">user@localhost</from>"
1000 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
1001 " <body>"
1002 " It no longer causes spontaneous combustion..."
1003 " </body>"
1004 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1005 "</email>";
1007 static const CHAR szEmailXML_0D[] =
1008 "<?xml version=\"1.0\"?>"
1009 SZ_EMAIL_DTD
1010 "<email attachments=\"patch1\">"
1011 " <recipients>"
1012 " <to>wine-patches@winehq.org</to>"
1013 " </recipients>"
1014 " <from name=\"Anonymous\">user@localhost</from>"
1015 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
1016 " <body>"
1017 " <undecl />"
1018 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
1019 " </body>"
1020 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1021 "</email>";
1023 static const CHAR szEmailXML_0E[] =
1024 "<?xml version=\"1.0\"?>"
1025 SZ_EMAIL_DTD
1026 "<email attachments=\"patch1\">"
1027 " <recipients>"
1028 " <to>wine-patches@winehq.org</to>"
1029 " </recipients>"
1030 " <from name=\"Anonymous\">user@localhost</from>"
1031 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
1032 " <body>"
1033 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1034 " </body>"
1035 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1036 "</email>";
1038 static const CHAR szEmailXML_11[] =
1039 "<?xml version=\"1.0\"?>"
1040 SZ_EMAIL_DTD
1041 "<email attachments=\"patch1\">"
1042 " <recipients>"
1043 " </recipients>"
1044 " <from name=\"Anonymous\">user@localhost</from>"
1045 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
1046 " <body>"
1047 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1048 " </body>"
1049 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1050 "</email>";
1052 static const CHAR szEmailXML_13[] =
1053 "<?xml version=\"1.0\"?>"
1054 SZ_EMAIL_DTD
1055 "<msg attachments=\"patch1\">"
1056 " <recipients>"
1057 " <to>wine-patches@winehq.org</to>"
1058 " </recipients>"
1059 " <from name=\"Anonymous\">user@localhost</from>"
1060 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
1061 " <body>"
1062 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
1063 " </body>"
1064 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1065 "</msg>";
1067 static const CHAR szEmailXML_14[] =
1068 "<?xml version=\"1.0\"?>"
1069 SZ_EMAIL_DTD
1070 "<email attachments=\"patch1\">"
1071 " <to>wine-patches@winehq.org</to>"
1072 " <from name=\"Anonymous\">user@localhost</from>"
1073 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
1074 " <body>"
1075 " XML_INVALID_CONTENT 0xC00CE014"
1076 " </body>"
1077 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1078 "</email>";
1080 static const CHAR szEmailXML_15[] =
1081 "<?xml version=\"1.0\"?>"
1082 SZ_EMAIL_DTD
1083 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1084 " <recipients>"
1085 " <to>wine-patches@winehq.org</to>"
1086 " </recipients>"
1087 " <from name=\"Anonymous\">user@localhost</from>"
1088 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
1089 " <body>"
1090 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1091 " </body>"
1092 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1093 "</email>";
1095 static const CHAR szEmailXML_16[] =
1096 "<?xml version=\"1.0\"?>"
1097 SZ_EMAIL_DTD
1098 "<email attachments=\"patch1\">"
1099 " <recipients>"
1100 " <to>wine-patches@winehq.org</to>"
1101 " </recipients>"
1102 " <from name=\"Anonymous\">user@localhost</from>"
1103 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
1104 " <body enc=\"ASCII\">"
1105 " XML_ATTRIBUTE_FIXED 0xC00CE016"
1106 " </body>"
1107 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1108 "</email>";
1110 static const CHAR szEmailXML_17[] =
1111 "<?xml version=\"1.0\"?>"
1112 SZ_EMAIL_DTD
1113 "<email attachments=\"patch1\" sent=\"true\">"
1114 " <recipients>"
1115 " <to>wine-patches@winehq.org</to>"
1116 " </recipients>"
1117 " <from name=\"Anonymous\">user@localhost</from>"
1118 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
1119 " <body>"
1120 " XML_ATTRIBUTE_VALUE 0xC00CE017"
1121 " </body>"
1122 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1123 "</email>";
1125 static const CHAR szEmailXML_18[] =
1126 "<?xml version=\"1.0\"?>"
1127 SZ_EMAIL_DTD
1128 "<email attachments=\"patch1\">"
1129 " oops"
1130 " <recipients>"
1131 " <to>wine-patches@winehq.org</to>"
1132 " </recipients>"
1133 " <from name=\"Anonymous\">user@localhost</from>"
1134 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
1135 " <body>"
1136 " XML_ILLEGAL_TEXT 0xC00CE018"
1137 " </body>"
1138 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1139 "</email>";
1141 static const CHAR szEmailXML_20[] =
1142 "<?xml version=\"1.0\"?>"
1143 SZ_EMAIL_DTD
1144 "<email>"
1145 " <recipients>"
1146 " <to>wine-patches@winehq.org</to>"
1147 " </recipients>"
1148 " <from name=\"Anonymous\">user@localhost</from>"
1149 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
1150 " <body>"
1151 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1152 " </body>"
1153 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1154 "</email>";
1156 static const char xpath_simple_list[] =
1157 "<?xml version=\"1.0\"?>"
1158 "<root>"
1159 " <a attr1=\"1\" attr2=\"2\" />"
1160 " <b/>"
1161 " <c/>"
1162 " <d/>"
1163 "</root>";
1165 static const char default_ns_doc[] = {
1166 "<?xml version=\"1.0\"?>"
1167 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1168 " d=\"d attr\" />"
1171 static const char attributes_map[] = {
1172 "<?xml version=\"1.0\"?>"
1173 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1176 static const WCHAR nonexistent_fileW[] = L"c:\\Nonexistent.xml";
1178 static const WCHAR szStrangeChars[] = L"&x \x2103";
1180 #define expect_bstr_eq_and_free(bstr, expect) { \
1181 BSTR bstrExp = alloc_str_from_narrow(expect); \
1182 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1183 SysFreeString(bstr); \
1184 SysFreeString(bstrExp); \
1187 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1189 #define ole_expect(expr, expect) { \
1190 HRESULT r = expr; \
1191 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1194 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1196 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1198 void *obj = NULL;
1199 HRESULT hr;
1201 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1202 ok(hr == S_OK, "failed to create %s instance: hr %#lx.\n", name, hr);
1204 return obj;
1207 #define _create(cls) cls, #cls
1209 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1210 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1211 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1212 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1214 static BSTR alloc_str_from_narrow(const char *str)
1216 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1217 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
1218 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1219 return ret;
1222 static BSTR alloced_bstrs[256];
1223 static int alloced_bstrs_count;
1225 static BSTR _bstr_(const char *str)
1227 assert(alloced_bstrs_count < ARRAY_SIZE(alloced_bstrs));
1228 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1229 return alloced_bstrs[alloced_bstrs_count++];
1232 static void free_bstrs(void)
1234 int i;
1235 for (i = 0; i < alloced_bstrs_count; i++)
1236 SysFreeString(alloced_bstrs[i]);
1237 alloced_bstrs_count = 0;
1240 static VARIANT _variantbstr_(const char *str)
1242 VARIANT v;
1243 V_VT(&v) = VT_BSTR;
1244 V_BSTR(&v) = _bstr_(str);
1245 return v;
1248 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1250 for (;;)
1252 while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1253 while (*sRight == '\r' || *sRight == '\n') sRight++;
1254 if (*sLeft != *sRight) return FALSE;
1255 if (!*sLeft) return TRUE;
1256 sLeft++;
1257 sRight++;
1261 static void get_str_for_type(DOMNodeType type, char *buf)
1263 switch (type)
1265 case NODE_ATTRIBUTE:
1266 strcpy(buf, "A");
1267 break;
1268 case NODE_ELEMENT:
1269 strcpy(buf, "E");
1270 break;
1271 case NODE_DOCUMENT:
1272 strcpy(buf, "D");
1273 break;
1274 case NODE_TEXT:
1275 strcpy(buf, "T");
1276 break;
1277 case NODE_COMMENT:
1278 strcpy(buf, "C");
1279 break;
1280 case NODE_PROCESSING_INSTRUCTION:
1281 strcpy(buf, "P");
1282 break;
1283 default:
1284 wsprintfA(buf, "[%d]", type);
1288 static int get_node_position(IXMLDOMNode *node)
1290 HRESULT r;
1291 int pos = 0;
1293 IXMLDOMNode_AddRef(node);
1296 IXMLDOMNode *new_node;
1298 pos++;
1299 r = IXMLDOMNode_get_previousSibling(node, &new_node);
1300 ok(SUCCEEDED(r), "get_previousSibling failed\n");
1301 IXMLDOMNode_Release(node);
1302 node = new_node;
1303 } while (r == S_OK);
1304 return pos;
1307 static void node_to_string(IXMLDOMNode *node, char *buf)
1309 HRESULT hr = S_OK;
1310 DOMNodeType type;
1312 if (node == NULL)
1314 lstrcpyA(buf, "(null)");
1315 return;
1318 IXMLDOMNode_AddRef(node);
1319 while (hr == S_OK)
1321 IXMLDOMNode *new_node;
1323 hr = IXMLDOMNode_get_nodeType(node, &type);
1324 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1325 get_str_for_type(type, buf);
1326 buf+=strlen(buf);
1328 if (type == NODE_ATTRIBUTE)
1330 BSTR bstr;
1331 hr = IXMLDOMNode_get_nodeName(node, &bstr);
1332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1333 *(buf++) = '\'';
1334 wsprintfA(buf, "%ws", bstr);
1335 buf += strlen(buf);
1336 *(buf++) = '\'';
1337 SysFreeString(bstr);
1339 hr = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1341 else
1343 hr = IXMLDOMNode_get_parentNode(node, &new_node);
1344 sprintf(buf, "%d", get_node_position(node));
1345 buf += strlen(buf);
1348 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
1349 IXMLDOMNode_Release(node);
1350 node = new_node;
1351 if (hr == S_OK)
1352 *(buf++) = '.';
1355 *buf = 0;
1358 static char *list_to_string(IXMLDOMNodeList *list)
1360 static char buf[4096];
1361 char *pos = buf;
1362 LONG len = 0;
1363 HRESULT hr;
1364 int i;
1366 if (list == NULL)
1368 strcpy(buf, "(null)");
1369 return buf;
1371 hr = IXMLDOMNodeList_get_length(list, &len);
1372 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1373 for (i = 0; i < len; i++)
1375 IXMLDOMNode *node;
1376 if (i > 0)
1377 *(pos++) = ' ';
1378 hr = IXMLDOMNodeList_nextNode(list, &node);
1379 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1380 node_to_string(node, pos);
1381 pos += strlen(pos);
1382 IXMLDOMNode_Release(node);
1384 *pos = 0;
1385 return buf;
1388 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
1389 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
1391 struct docload_ret_t {
1392 VARIANT_BOOL b;
1393 HRESULT hr;
1396 struct leading_spaces_t {
1397 const CLSID *clsid;
1398 const char *name;
1399 struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
1402 static const struct leading_spaces_t leading_spaces_classdata[] = {
1403 { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1404 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1405 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1406 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1407 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1408 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1409 { NULL }
1412 static const char* leading_spaces_xmldata[] = {
1413 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1414 " <?xml version=\"1.0\"?><root/>",
1415 "\n<?xml version=\"1.0\"?><root/>",
1416 "\t<?xml version=\"1.0\"?><root/>",
1417 "\r\n<?xml version=\"1.0\"?><root/>",
1418 "\r<?xml version=\"1.0\"?><root/>",
1419 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1423 static void test_domdoc( void )
1425 IXMLDOMDocument *doc;
1426 IXMLDOMParseError *error;
1427 IXMLDOMElement *element = NULL;
1428 IXMLDOMNode *node;
1429 IXMLDOMText *nodetext = NULL;
1430 IXMLDOMComment *node_comment = NULL;
1431 IXMLDOMAttribute *node_attr = NULL;
1432 IXMLDOMNode *nodeChild = NULL;
1433 IXMLDOMProcessingInstruction *nodePI = NULL;
1434 const struct leading_spaces_t *class_ptr;
1435 const char **data_ptr;
1436 VARIANT_BOOL b;
1437 VARIANT var;
1438 BSTR str;
1439 LONG code, ref;
1440 LONG nLength = 0;
1441 WCHAR buff[100];
1442 char path[MAX_PATH];
1443 HRESULT hr;
1444 int index;
1446 GetTempPathA(MAX_PATH, path);
1447 strcat(path, "leading_spaces.xml");
1449 /* Load document with leading spaces
1451 * Test all CLSIDs with all test data XML strings
1453 class_ptr = leading_spaces_classdata;
1454 index = 0;
1455 while (class_ptr->clsid)
1457 HRESULT hr;
1458 int i;
1460 if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
1462 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
1464 else
1466 class_ptr++;
1467 index++;
1468 continue;
1471 data_ptr = leading_spaces_xmldata;
1472 i = 0;
1473 while (*data_ptr) {
1474 BSTR data = _bstr_(*data_ptr);
1475 DWORD written;
1476 HANDLE file;
1478 file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1479 ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %lu\n", path, GetLastError());
1481 WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
1482 CloseHandle(file);
1484 b = 0xc;
1485 V_VT(&var) = VT_BSTR;
1486 V_BSTR(&var) = _bstr_(path);
1487 hr = IXMLDOMDocument_load(doc, var, &b);
1488 ok(hr == class_ptr->ret[0].hr, "Unexpected hr %#lx.\n", hr);
1489 ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
1491 DeleteFileA(path);
1493 b = 0xc;
1494 hr = IXMLDOMDocument_loadXML(doc, data, &b);
1495 ok(hr == class_ptr->ret[1].hr, "Unexpected hr %#lx.\n", hr);
1496 ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
1498 data_ptr++;
1499 i++;
1502 class_ptr++;
1503 index++;
1504 free_bstrs();
1507 doc = create_document(&IID_IXMLDOMDocument);
1508 if (!doc) return;
1510 check_interface(doc, &IID_IXMLDOMDocument, TRUE);
1511 check_interface(doc, &IID_IPersistStreamInit, TRUE);
1512 check_interface(doc, &IID_IObjectWithSite, TRUE);
1513 check_interface(doc, &IID_IObjectSafety, TRUE);
1514 check_interface(doc, &IID_IConnectionPointContainer, TRUE);
1515 check_interface(doc, &IID_IDispatch, TRUE);
1516 check_interface(doc, &IID_IDispatchEx, TRUE);
1518 if (0)
1520 /* crashes on native */
1521 IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
1524 /* try some stupid things */
1525 hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1526 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1528 b = VARIANT_TRUE;
1529 hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
1530 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1531 ok( b == VARIANT_FALSE, "failed to load XML string\n");
1533 /* try to load a document from a nonexistent file */
1534 b = VARIANT_TRUE;
1535 str = SysAllocString( nonexistent_fileW );
1536 VariantInit(&var);
1537 V_VT(&var) = VT_BSTR;
1538 V_BSTR(&var) = str;
1540 hr = IXMLDOMDocument_load( doc, var, &b);
1541 ok(hr == S_FALSE, "loadXML succeeded\n");
1542 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1543 SysFreeString( str );
1545 str = (void *)0xdeadbeef;
1546 hr = IXMLDOMDocument_get_url(doc, &str);
1547 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1548 ok(str == NULL, "got %p\n", str);
1550 /* try load an empty document */
1551 b = VARIANT_TRUE;
1552 str = SysAllocString( L"" );
1553 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1554 ok(hr == S_FALSE, "loadXML succeeded\n");
1555 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1556 SysFreeString( str );
1558 hr = IXMLDOMDocument_get_async( doc, &b );
1559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1560 ok( b == VARIANT_TRUE, "Wrong default value\n");
1562 /* check that there's no document element */
1563 element = NULL;
1564 hr = IXMLDOMDocument_get_documentElement( doc, &element );
1565 ok(hr == S_FALSE, "should be no document element\n");
1567 /* try finding a node */
1568 node = NULL;
1569 str = SysAllocString( L"str1" );
1570 hr = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1571 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1572 SysFreeString( str );
1574 b = VARIANT_TRUE;
1575 str = SysAllocString( L"<?xml version='1.0'?>\n" );
1576 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1577 ok(hr == S_FALSE, "loadXML succeeded\n");
1578 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1579 SysFreeString( str );
1581 /* check that there's no document element */
1582 element = (IXMLDOMElement*)1;
1583 hr = IXMLDOMDocument_get_documentElement( doc, &element );
1584 ok(hr == S_FALSE, "should be no document element\n");
1585 ok( element == NULL, "Element should be NULL\n");
1587 /* test for BSTR handling, pass broken BSTR */
1588 memcpy(&buff[2], szComplete1, sizeof(szComplete1));
1589 /* just a big length */
1590 *(DWORD*)buff = 0xf0f0;
1591 b = VARIANT_FALSE;
1592 hr = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1593 ok(hr == S_OK, "loadXML failed\n");
1594 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1596 /* loadXML ignores the encoding attribute and always expects Unicode */
1597 b = VARIANT_FALSE;
1598 str = SysAllocString( L"<?xml version='1.0' encoding='Windows-1252'?>\n<open></open>\n" );
1599 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1600 ok(hr == S_OK, "loadXML failed\n");
1601 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1602 SysFreeString( str );
1604 /* try a BSTR containing a Windows-1252 document */
1605 b = VARIANT_TRUE;
1606 str = SysAllocStringByteLen( win1252xml, strlen(win1252xml) );
1607 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1608 ok(hr == S_FALSE, "loadXML succeeded\n");
1609 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1610 SysFreeString( str );
1612 /* try to load something valid */
1613 b = VARIANT_FALSE;
1614 str = SysAllocString( szComplete1 );
1615 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1616 ok(hr == S_OK, "loadXML failed\n");
1617 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1618 SysFreeString( str );
1620 /* check if nodename is correct */
1621 hr = IXMLDOMDocument_get_nodeName( doc, NULL );
1622 ok ( hr == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1624 str = (void *)0xdeadbeef;
1625 hr = IXMLDOMDocument_get_baseName( doc, &str );
1626 ok ( hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1627 ok (str == NULL, "got %p\n", str);
1629 /* content doesn't matter here */
1630 str = NULL;
1631 hr = IXMLDOMDocument_get_nodeName( doc, &str );
1632 ok ( hr == S_OK, "get_nodeName wrong code\n");
1633 ok ( str != NULL, "str is null\n");
1634 ok( !lstrcmpW( str, L"#document" ), "incorrect nodeName\n");
1635 SysFreeString( str );
1637 /* test put_text */
1638 hr = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
1639 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
1641 /* check that there's a document element */
1642 element = NULL;
1643 hr = IXMLDOMDocument_get_documentElement( doc, &element );
1644 ok(hr == S_OK, "should be a document element\n");
1645 if( element )
1647 IObjectIdentity *ident;
1649 hr = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1650 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1652 IXMLDOMElement_Release( element );
1653 element = NULL;
1656 /* as soon as we call loadXML again, the document element will disappear */
1657 b = 2;
1658 hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1659 ok(hr == S_FALSE, "loadXML failed\n");
1660 ok( b == 2, "variant modified\n");
1661 hr = IXMLDOMDocument_get_documentElement( doc, &element );
1662 ok(hr == S_FALSE, "should be no document element\n");
1664 /* try to load something else simple and valid */
1665 b = VARIANT_FALSE;
1666 str = SysAllocString( L"<?xml version='1.0'?>\n<a></a>\n" );
1667 hr = IXMLDOMDocument_loadXML( doc, str, &b );
1668 ok(hr == S_OK, "loadXML failed\n");
1669 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1670 SysFreeString( str );
1672 /* try something a little more complicated */
1673 b = FALSE;
1674 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1675 ok(hr == S_OK, "loadXML failed\n");
1676 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1678 hr = IXMLDOMDocument_get_parseError( doc, &error );
1679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1681 hr = IXMLDOMParseError_get_errorCode( error, &code );
1682 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1683 ok( code == 0, "code %ld\n", code );
1684 IXMLDOMParseError_Release( error );
1686 /* test createTextNode */
1687 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1689 IXMLDOMText_Release(nodetext);
1691 str = SysAllocString( L"open" );
1692 hr = IXMLDOMDocument_createTextNode(doc, str, NULL);
1693 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1694 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1695 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1696 SysFreeString( str );
1697 if(nodetext)
1699 hr = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1700 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1702 /* Text Last Child Checks */
1703 hr = IXMLDOMText_get_lastChild(nodetext, NULL);
1704 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1706 nodeChild = (IXMLDOMNode*)0x1;
1707 hr = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1708 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1709 ok(nodeChild == NULL, "nodeChild not NULL\n");
1711 /* test length property */
1712 hr = IXMLDOMText_get_length(nodetext, NULL);
1713 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1715 hr = IXMLDOMText_get_length(nodetext, &nLength);
1716 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1717 ok(nLength == 4, "expected 4 got %ld\n", nLength);
1719 /* put data Tests */
1720 hr = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1721 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1723 /* get data Tests */
1724 hr = IXMLDOMText_get_data(nodetext, &str);
1725 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1726 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect put_data string\n");
1727 SysFreeString(str);
1729 /* Confirm XML text is good */
1730 hr = IXMLDOMText_get_xml(nodetext, &str);
1731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1732 ok(!lstrcmpW(str, L"This &amp;is a ; test &lt;&gt;\\"), "incorrect xml string\n");
1733 SysFreeString(str);
1735 /* Confirm we get the put_data Text back */
1736 hr = IXMLDOMText_get_text(nodetext, &str);
1737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1738 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect xml string\n");
1739 SysFreeString(str);
1741 /* test substringData */
1742 hr = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1743 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1745 /* test substringData - Invalid offset */
1746 str = (void *)0xdeadbeef;
1747 hr = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1748 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1749 ok( str == NULL, "incorrect string\n");
1751 /* test substringData - Invalid offset */
1752 str = (void *)0xdeadbeef;
1753 hr = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1754 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1755 ok( str == NULL, "incorrect string\n");
1757 /* test substringData - Invalid size */
1758 str = (void *)0xdeadbeef;
1759 hr = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1760 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1761 ok( str == NULL, "incorrect string\n");
1763 /* test substringData - Invalid size */
1764 str = (void *)0xdeadbeef;
1765 hr = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1766 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1767 ok( str == NULL, "incorrect string\n");
1769 /* test substringData - Start of string */
1770 hr = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1772 ok(!lstrcmpW(str, L"This"), "incorrect substringData string\n");
1773 SysFreeString(str);
1775 /* test substringData - Middle of string */
1776 hr = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1778 ok(!lstrcmpW(str, L"test"), "incorrect substringData string\n");
1779 SysFreeString(str);
1781 /* test substringData - End of string */
1782 hr = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1783 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1784 ok(!lstrcmpW(str, L"\\"), "incorrect substringData string\n");
1785 SysFreeString(str);
1787 /* test appendData */
1788 hr = IXMLDOMText_appendData(nodetext, NULL);
1789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1791 hr = IXMLDOMText_appendData(nodetext, _bstr_(""));
1792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1794 hr = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1795 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1797 hr = IXMLDOMText_get_text(nodetext, &str);
1798 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1799 ok(!lstrcmpW(str, L"This &is a ; test <>\\Append"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1800 SysFreeString(str);
1802 /* test insertData */
1803 str = SysAllocStringLen(NULL, 0);
1804 hr = IXMLDOMText_insertData(nodetext, -1, str);
1805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1807 hr = IXMLDOMText_insertData(nodetext, -1, NULL);
1808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1810 hr = IXMLDOMText_insertData(nodetext, 1000, str);
1811 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1813 hr = IXMLDOMText_insertData(nodetext, 1000, NULL);
1814 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1816 hr = IXMLDOMText_insertData(nodetext, 0, NULL);
1817 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1819 hr = IXMLDOMText_insertData(nodetext, 0, str);
1820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1821 SysFreeString(str);
1823 hr = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1824 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1826 hr = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1827 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1829 hr = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1830 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1832 hr = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1833 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1835 hr = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1838 hr = IXMLDOMText_get_text(nodetext, &str);
1839 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1840 ok(!lstrcmpW(str, L"Begin This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1841 SysFreeString(str);
1843 /* delete data */
1844 /* invalid arguments */
1845 hr = IXMLDOMText_deleteData(nodetext, -1, 1);
1846 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1848 hr = IXMLDOMText_deleteData(nodetext, 0, 0);
1849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1851 hr = IXMLDOMText_deleteData(nodetext, 0, -1);
1852 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1854 hr = IXMLDOMText_get_length(nodetext, &nLength);
1855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1856 ok(nLength == 43, "expected 43 got %ld\n", nLength);
1858 hr = IXMLDOMText_deleteData(nodetext, nLength, 1);
1859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1861 hr = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1862 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1864 /* delete from start */
1865 hr = IXMLDOMText_deleteData(nodetext, 0, 5);
1866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1868 hr = IXMLDOMText_get_length(nodetext, &nLength);
1869 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1870 ok(nLength == 38, "expected 38 got %ld\n", nLength);
1872 hr = IXMLDOMText_get_text(nodetext, &str);
1873 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1874 ok(!lstrcmpW(str, L"This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1875 SysFreeString(str);
1877 /* delete from end */
1878 hr = IXMLDOMText_deleteData(nodetext, 35, 3);
1879 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1881 hr = IXMLDOMText_get_length(nodetext, &nLength);
1882 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1883 ok(nLength == 35, "expected 35 got %ld\n", nLength);
1885 hr = IXMLDOMText_get_text(nodetext, &str);
1886 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1887 ok(!lstrcmpW(str, L"This &is a Middle; test <>\\Append"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1888 SysFreeString(str);
1890 /* delete from inside */
1891 hr = IXMLDOMText_deleteData(nodetext, 1, 33);
1892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1894 hr = IXMLDOMText_get_length(nodetext, &nLength);
1895 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1896 ok(nLength == 2, "expected 2 got %ld\n", nLength);
1898 hr = IXMLDOMText_get_text(nodetext, &str);
1899 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1900 ok(!lstrcmpW(str, L""), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1901 SysFreeString(str);
1903 /* delete whole data ... */
1904 hr = IXMLDOMText_get_length(nodetext, &nLength);
1905 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1907 hr = IXMLDOMText_deleteData(nodetext, 0, nLength);
1908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1909 /* ... and try again with empty string */
1910 hr = IXMLDOMText_deleteData(nodetext, 0, nLength);
1911 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1913 /* test put_data */
1914 V_VT(&var) = VT_BSTR;
1915 V_BSTR(&var) = SysAllocString(L"str1");
1916 hr = IXMLDOMText_put_nodeValue(nodetext, var);
1917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1918 VariantClear(&var);
1920 hr = IXMLDOMText_get_text(nodetext, &str);
1921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1922 ok( !lstrcmpW( str, L"str1" ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1923 SysFreeString(str);
1925 /* test put_data */
1926 V_VT(&var) = VT_I4;
1927 V_I4(&var) = 99;
1928 hr = IXMLDOMText_put_nodeValue(nodetext, var);
1929 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1930 VariantClear(&var);
1932 hr = IXMLDOMText_get_text(nodetext, &str);
1933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1934 ok(!lstrcmpW(str, L"99"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1935 SysFreeString(str);
1937 /* ::replaceData() */
1938 V_VT(&var) = VT_BSTR;
1939 V_BSTR(&var) = SysAllocString(L"str1");
1940 hr = IXMLDOMText_put_nodeValue(nodetext, var);
1941 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1942 VariantClear(&var);
1944 hr = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1945 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1946 hr = IXMLDOMText_get_text(nodetext, &str);
1947 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1948 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1949 SysFreeString(str);
1951 hr = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1952 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1953 hr = IXMLDOMText_get_text(nodetext, &str);
1954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1955 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1956 SysFreeString(str);
1958 /* NULL pointer means delete */
1959 hr = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1960 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1961 hr = IXMLDOMText_get_text(nodetext, &str);
1962 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1963 ok(!lstrcmpW(str, L"tr1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1964 SysFreeString(str);
1966 /* empty string means delete */
1967 hr = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1968 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1969 hr = IXMLDOMText_get_text(nodetext, &str);
1970 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1971 ok(!lstrcmpW(str, L"r1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1972 SysFreeString(str);
1974 /* zero count means insert */
1975 hr = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1976 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1977 hr = IXMLDOMText_get_text(nodetext, &str);
1978 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1979 ok(!lstrcmpW(str, L"ar1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1980 SysFreeString(str);
1982 hr = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1983 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1985 hr = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1986 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1987 hr = IXMLDOMText_get_text(nodetext, &str);
1988 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1989 ok(!lstrcmpW(str, L"m1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1990 SysFreeString(str);
1992 /* nonempty string, count greater than its length */
1993 hr = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1994 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1995 hr = IXMLDOMText_get_text(nodetext, &str);
1996 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1997 ok(!lstrcmpW(str, L"a1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
1998 SysFreeString(str);
2000 /* nonempty string, count less than its length */
2001 hr = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2003 hr = IXMLDOMText_get_text(nodetext, &str);
2004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2005 ok(!lstrcmpW(str, L"wine1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
2006 SysFreeString(str);
2008 IXMLDOMText_Release( nodetext );
2011 /* test Create Comment */
2012 hr = IXMLDOMDocument_createComment(doc, NULL, NULL);
2013 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2014 node_comment = (IXMLDOMComment*)0x1;
2016 /* empty comment */
2017 hr = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2019 str = NULL;
2020 hr = IXMLDOMComment_get_data(node_comment, &str);
2021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2022 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2023 IXMLDOMComment_Release(node_comment);
2024 SysFreeString(str);
2026 hr = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2027 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2028 str = NULL;
2029 hr = IXMLDOMComment_get_data(node_comment, &str);
2030 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2031 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2032 IXMLDOMComment_Release(node_comment);
2033 SysFreeString(str);
2035 str = SysAllocString(L"A Comment");
2036 hr = IXMLDOMDocument_createComment(doc, str, &node_comment);
2037 SysFreeString(str);
2038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2039 if(node_comment)
2041 /* Last Child Checks */
2042 hr = IXMLDOMComment_get_lastChild(node_comment, NULL);
2043 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2045 nodeChild = (IXMLDOMNode*)0x1;
2046 hr = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2047 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2048 ok(nodeChild == NULL, "pLastChild not NULL\n");
2050 /* baseName */
2051 str = (void *)0xdeadbeef;
2052 hr = IXMLDOMComment_get_baseName(node_comment, &str);
2053 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2054 ok(str == NULL, "Expected NULL\n");
2056 IXMLDOMComment_Release( node_comment );
2059 /* test Create Attribute */
2060 str = SysAllocString(L"Attr");
2061 hr = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2062 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2063 hr = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2064 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2065 IXMLDOMAttribute_Release( node_attr);
2066 SysFreeString(str);
2068 /* test Processing Instruction */
2069 str = SysAllocStringLen(NULL, 0);
2070 hr = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2071 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2072 hr = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2073 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2074 hr = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2075 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2076 SysFreeString(str);
2078 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2079 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2080 if(nodePI)
2082 /* Last Child Checks */
2083 hr = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2084 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2086 nodeChild = (IXMLDOMNode*)0x1;
2087 hr = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2088 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2089 ok(nodeChild == NULL, "nodeChild not NULL\n");
2091 /* test nodeName */
2092 hr = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2093 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2094 ok(!lstrcmpW(str, L"xml"), "incorrect nodeName string\n");
2095 SysFreeString(str);
2097 /* test baseName */
2098 str = NULL;
2099 hr = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2100 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2101 ok(!lstrcmpW(str, L"xml"), "incorrect nodeName string\n");
2102 SysFreeString(str);
2104 /* test Target */
2105 hr = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2106 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2107 ok(!lstrcmpW(str, L"xml"), "incorrect target string\n");
2108 SysFreeString(str);
2110 /* test get_data */
2111 hr = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2112 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2113 ok(!lstrcmpW(str, L"version=\"1.0\""), "incorrect data string\n");
2114 SysFreeString(str);
2116 /* test put_data */
2117 hr = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2118 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2120 /* test put_data */
2121 V_VT(&var) = VT_BSTR;
2122 V_BSTR(&var) = SysAllocString(L"open"); /* Doesn't matter what the string is, cannot set an xml node. */
2123 hr = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2124 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2125 VariantClear(&var);
2127 /* test get nodeName */
2128 hr = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2129 ok(!lstrcmpW(str, L"xml"), "incorrect nodeName string\n");
2130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2131 SysFreeString(str);
2133 IXMLDOMProcessingInstruction_Release(nodePI);
2136 ref = IXMLDOMDocument_Release( doc );
2137 ok( ref == 0, "got %ld\n", ref);
2139 free_bstrs();
2142 static void test_persiststream(void)
2144 IPersistStreamInit *streaminit;
2145 IPersistStream *stream;
2146 IXMLDOMDocument *doc;
2147 ULARGE_INTEGER size;
2148 IStream *istream;
2149 HRESULT hr;
2150 CLSID clsid;
2152 doc = create_document(&IID_IXMLDOMDocument);
2154 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2155 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2157 hr = IPersistStreamInit_InitNew(streaminit);
2158 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2160 hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
2161 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
2163 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStream, (void **)&stream);
2164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2165 ok((IUnknown *)stream == (IUnknown *)streaminit, "got %p, %p\n", stream, streaminit);
2167 check_interface(stream, &IID_IPersist, FALSE);
2168 check_interface(doc, &IID_IPersist, FALSE);
2170 hr = IPersistStreamInit_GetClassID(streaminit, NULL);
2171 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2173 memset(&clsid, 0, sizeof(clsid));
2174 hr = IPersistStreamInit_GetClassID(streaminit, &clsid);
2175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2176 ok(IsEqualGUID(&clsid, &CLSID_DOMDocument2), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
2178 IPersistStream_Release(stream);
2180 /* test Load */
2181 istream = SHCreateMemStream((const BYTE*)complete4A, strlen(complete4A));
2182 hr = IPersistStreamInit_Load(streaminit, istream);
2183 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2184 IStream_Release(istream);
2185 EXPECT_PARSE_ERROR(doc, S_OK, FALSE);
2187 istream = SHCreateMemStream((const BYTE*)"", 0);
2188 hr = IPersistStreamInit_Load(streaminit, istream);
2189 todo_wine ok(hr == XML_E_MISSINGROOT, "Unexpected hr %#lx.\n", hr);
2190 ok(FAILED(hr), "got success\n");
2191 IStream_Release(istream);
2192 EXPECT_PARSE_ERROR(doc, XML_E_MISSINGROOT, TRUE);
2194 IPersistStreamInit_Release(streaminit);
2195 IXMLDOMDocument_Release(doc);
2198 static void test_domnode( void )
2200 IXMLDOMDocument *doc, *owner = NULL;
2201 IXMLDOMElement *element = NULL;
2202 IXMLDOMNamedNodeMap *map = NULL;
2203 IXMLDOMNode *node = NULL, *next = NULL;
2204 IXMLDOMNodeList *list = NULL;
2205 IXMLDOMAttribute *attr = NULL;
2206 DOMNodeType type = NODE_INVALID;
2207 VARIANT_BOOL b;
2208 HRESULT hr;
2209 BSTR str;
2210 VARIANT var;
2211 LONG count;
2213 doc = create_document(&IID_IXMLDOMDocument);
2215 b = FALSE;
2216 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2217 ok(hr == S_OK, "loadXML failed\n");
2218 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2220 EXPECT_CHILDREN(doc);
2222 hr = IXMLDOMDocument_get_documentElement( doc, &element );
2223 ok(hr == S_OK, "should be a document element\n");
2224 ok( element != NULL, "should be an element\n");
2226 VariantInit(&var);
2227 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2229 hr = IXMLDOMDocument_get_nodeValue( doc, NULL );
2230 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2232 hr = IXMLDOMDocument_get_nodeValue( doc, &var );
2233 ok(hr == S_FALSE, "get_nodeValue returned wrong code\n");
2234 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2235 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2237 if (element)
2239 IXMLDOMNamedNodeMap *attributes;
2241 owner = NULL;
2242 hr = IXMLDOMElement_get_ownerDocument( element, &owner );
2243 ok(hr == S_OK, "get_ownerDocument return code\n");
2244 ok( owner != doc, "get_ownerDocument return\n");
2245 IXMLDOMDocument_Release(owner);
2247 type = NODE_INVALID;
2248 hr = IXMLDOMElement_get_nodeType( element, &type);
2249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2250 ok( type == NODE_ELEMENT, "node not an element\n");
2252 str = NULL;
2253 hr = IXMLDOMElement_get_baseName( element, &str );
2254 ok(hr == S_OK, "get_baseName returned wrong code\n");
2255 ok( !lstrcmpW(str, L"lc"), "Unexpected basename.\n");
2256 SysFreeString(str);
2258 /* check if nodename is correct */
2259 hr = IXMLDOMElement_get_nodeName( element, NULL );
2260 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2262 /* content doesn't matter here */
2263 str = NULL;
2264 hr = IXMLDOMElement_get_nodeName( element, &str );
2265 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2266 ok ( str != NULL, "str is null\n");
2267 ok( !lstrcmpW( str, L"lc" ), "Unexpected nodeName\n");
2268 SysFreeString( str );
2270 str = SysAllocString( nonexistent_fileW );
2271 V_VT(&var) = VT_I4;
2272 V_I4(&var) = 0x1234;
2273 hr = IXMLDOMElement_getAttribute( element, str, &var );
2274 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2275 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2276 VariantClear(&var);
2277 SysFreeString(str);
2279 str = SysAllocString( L"dl" );
2280 V_VT(&var) = VT_I4;
2281 V_I4(&var) = 0x1234;
2282 hr = IXMLDOMElement_getAttribute( element, str, &var );
2283 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2284 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2285 ok( !lstrcmpW(V_BSTR(&var), L"str1"), "wrong attr value\n");
2286 VariantClear( &var );
2288 hr = IXMLDOMElement_getAttribute( element, NULL, &var );
2289 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2291 hr = IXMLDOMElement_getAttribute( element, str, NULL );
2292 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2294 attr = NULL;
2295 hr = IXMLDOMElement_getAttributeNode( element, str, &attr);
2296 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2297 ok( attr != NULL, "getAttributeNode returned NULL\n" );
2298 if (attr)
2300 hr = IXMLDOMAttribute_get_parentNode( attr, NULL );
2301 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2303 /* attribute doesn't have a parent in msxml interpretation */
2304 node = (IXMLDOMNode*)0xdeadbeef;
2305 hr = IXMLDOMAttribute_get_parentNode( attr, &node );
2306 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2307 ok( node == NULL, "Expected NULL, got %p\n", node );
2309 IXMLDOMAttribute_Release(attr);
2312 SysFreeString( str );
2314 hr = IXMLDOMElement_get_attributes( element, &map );
2315 ok(hr == S_OK, "get_attributes returned wrong code\n");
2316 ok( map != NULL, "should be attributes\n");
2318 EXPECT_CHILDREN(element);
2320 hr = IXMLDOMElement_get_childNodes( element, &list );
2321 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2322 hr = IXMLDOMNodeList_nextNode( list, &node ); /* <bs> */
2323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2324 IXMLDOMNode_Release( node );
2325 hr = IXMLDOMNodeList_nextNode( list, &node ); /* <pr> */
2326 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2327 IXMLDOMNode_Release( node );
2328 hr = IXMLDOMNodeList_nextNode( list, &node ); /* <empty> */
2329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2330 hr = IXMLDOMNode_get_attributes( node, &attributes );
2331 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2332 next = (IXMLDOMNode*)0xdeadbeef;
2333 hr = IXMLDOMNamedNodeMap_nextNode( attributes, &next );
2334 ok(hr == S_FALSE, "Unexpected %#lx.\n", hr);
2335 ok( next == NULL, "Expected NULL, ret %p\n", next );
2336 IXMLDOMNamedNodeMap_Release( attributes );
2337 IXMLDOMNode_Release( node );
2338 node = NULL;
2339 next = NULL;
2340 IXMLDOMNodeList_Release( list );
2341 list = NULL;
2343 else
2344 ok( FALSE, "no element\n");
2346 if (map)
2348 str = SysAllocString( L"dl" );
2349 hr = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2350 ok(hr == S_OK, "getNamedItem returned wrong code\n");
2351 ok( node != NULL, "should be attributes\n");
2352 IXMLDOMNode_Release(node);
2353 SysFreeString( str );
2355 str = SysAllocString( L"dl" );
2356 hr = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2357 ok(hr == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2358 SysFreeString( str );
2360 /* something that isn't in complete4A */
2361 str = SysAllocString( L"open" );
2362 node = (IXMLDOMNode *) 1;
2363 hr = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2364 ok(hr == S_FALSE, "getNamedItem found a node that wasn't there\n");
2365 ok( node == NULL, "getNamedItem should have returned NULL\n");
2366 SysFreeString( str );
2368 /* test indexed access of attributes */
2369 hr = IXMLDOMNamedNodeMap_get_length( map, NULL );
2370 ok ( hr == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2372 hr = IXMLDOMNamedNodeMap_get_length( map, &count );
2373 ok ( hr == S_OK, "get_length wrong code\n");
2374 ok ( count == 1, "get_length != 1\n");
2376 node = NULL;
2377 hr = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2378 ok ( hr == S_FALSE, "get_item (-1) wrong code\n");
2379 ok ( node == NULL, "there is no node\n");
2381 node = NULL;
2382 hr = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2383 ok ( hr == S_FALSE, "get_item (1) wrong code\n");
2384 ok ( node == NULL, "there is no attribute\n");
2386 node = NULL;
2387 hr = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2388 ok ( hr == S_OK, "get_item (0) wrong code\n");
2389 ok ( node != NULL, "should be attribute\n");
2391 hr = IXMLDOMNode_get_nodeName( node, NULL );
2392 ok ( hr == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2394 /* content doesn't matter here */
2395 str = NULL;
2396 hr = IXMLDOMNode_get_nodeName( node, &str );
2397 ok ( hr == S_OK, "get_nodeName wrong code\n");
2398 ok ( str != NULL, "str is null\n");
2399 ok( !lstrcmpW( str, L"dl" ), "incorrect node name\n");
2400 SysFreeString( str );
2401 IXMLDOMNode_Release( node );
2403 /* test sequential access of attributes */
2404 node = NULL;
2405 hr = IXMLDOMNamedNodeMap_nextNode( map, &node );
2406 ok ( hr == S_OK, "nextNode (first time) wrong code\n");
2407 ok ( node != NULL, "nextNode, should be attribute\n");
2408 IXMLDOMNode_Release( node );
2410 hr = IXMLDOMNamedNodeMap_nextNode( map, &node );
2411 ok ( hr != S_OK, "nextNode (second time) wrong code\n");
2412 ok ( node == NULL, "nextNode, there is no attribute\n");
2414 hr = IXMLDOMNamedNodeMap_reset( map );
2415 ok ( hr == S_OK, "reset should return S_OK\n");
2417 hr = IXMLDOMNamedNodeMap_nextNode( map, &node );
2418 ok ( hr == S_OK, "nextNode (third time) wrong code\n");
2419 ok ( node != NULL, "nextNode, should be attribute\n");
2421 else
2422 ok( FALSE, "no map\n");
2424 if (node)
2426 type = NODE_INVALID;
2427 hr = IXMLDOMNode_get_nodeType( node, &type);
2428 ok(hr == S_OK, "get_nodeType returned wrong code\n");
2429 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2431 str = NULL;
2432 hr = IXMLDOMNode_get_baseName( node, NULL );
2433 ok(hr == E_INVALIDARG, "get_baseName returned wrong code\n");
2435 str = NULL;
2436 hr = IXMLDOMNode_get_baseName( node, &str );
2437 ok(hr == S_OK, "get_baseName returned wrong code\n");
2438 ok( !lstrcmpW(str, L"dl"), "Unexpected basename.\n");
2439 SysFreeString( str );
2441 hr = IXMLDOMNode_get_childNodes( node, NULL );
2442 ok(hr == E_INVALIDARG, "get_childNodes returned wrong code\n");
2444 hr = IXMLDOMNode_get_childNodes( node, &list );
2445 ok(hr == S_OK, "get_childNodes returned wrong code\n");
2447 if (list)
2449 hr = IXMLDOMNodeList_nextNode( list, &next );
2450 ok(hr == S_OK, "nextNode returned wrong code\n");
2452 else
2453 ok( FALSE, "no childlist\n");
2455 if (next)
2457 EXPECT_NO_CHILDREN(next);
2459 type = NODE_INVALID;
2460 hr = IXMLDOMNode_get_nodeType( next, &type);
2461 ok(hr == S_OK, "get_nodeType returned wrong code\n");
2462 ok( type == NODE_TEXT, "node not text\n");
2464 str = (void *)0xdeadbeef;
2465 hr = IXMLDOMNode_get_baseName( next, &str );
2466 ok(hr == S_FALSE, "get_baseName returned wrong code\n");
2467 ok( str == NULL, "basename was wrong\n");
2468 SysFreeString(str);
2470 else
2471 ok( FALSE, "no next\n");
2473 if (next)
2474 IXMLDOMNode_Release( next );
2475 next = NULL;
2476 if (list)
2477 IXMLDOMNodeList_Release( list );
2478 list = NULL;
2479 if (node)
2480 IXMLDOMNode_Release( node );
2482 else
2483 ok( FALSE, "no node\n");
2484 node = NULL;
2486 if (map)
2487 IXMLDOMNamedNodeMap_Release( map );
2489 /* now traverse the tree from the root element */
2490 if (element)
2492 hr = IXMLDOMElement_get_childNodes( element, &list );
2493 ok(hr == S_OK, "get_childNodes returned wrong code\n");
2495 /* using get_item for child list doesn't advance the position */
2496 hr = IXMLDOMNodeList_get_item(list, 1, &node);
2497 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2498 expect_node(node, "E2.E2.D1");
2499 IXMLDOMNode_Release(node);
2500 hr = IXMLDOMNodeList_nextNode(list, &node);
2501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2502 expect_node(node, "E1.E2.D1");
2503 IXMLDOMNode_Release(node);
2504 hr = IXMLDOMNodeList_reset(list);
2505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2507 IXMLDOMNodeList_AddRef(list);
2508 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2509 hr = IXMLDOMNodeList_reset(list);
2510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2512 node = (void*)0xdeadbeef;
2513 str = SysAllocString(L"dl");
2514 hr = IXMLDOMElement_selectSingleNode( element, str, &node );
2515 SysFreeString(str);
2516 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
2517 ok( node == NULL, "node %p\n", node );
2519 node = (void*)0xdeadbeef;
2520 hr = IXMLDOMElement_selectSingleNode( element, _bstr_("In Valid"), &node );
2521 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
2522 ok( node == NULL, "node %p\n", node );
2524 str = SysAllocString(L"bs");
2525 hr = IXMLDOMElement_selectSingleNode( element, str, &node );
2526 SysFreeString(str);
2527 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2528 IXMLDOMNode_Release( node );
2530 else
2531 ok( FALSE, "no element\n");
2533 if (list)
2535 hr = IXMLDOMNodeList_get_item(list, 0, NULL);
2536 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2538 hr = IXMLDOMNodeList_get_length(list, NULL);
2539 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2541 hr = IXMLDOMNodeList_get_length( list, &count );
2542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2543 ok( count == 4, "get_length got %ld\n", count );
2545 hr = IXMLDOMNodeList_nextNode(list, NULL);
2546 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2548 hr = IXMLDOMNodeList_nextNode( list, &node );
2549 ok(hr == S_OK, "nextNode returned wrong code\n");
2551 else
2552 ok( FALSE, "no list\n");
2554 if (node)
2556 type = NODE_INVALID;
2557 hr = IXMLDOMNode_get_nodeType( node, &type);
2558 ok(hr == S_OK, "get_nodeType returned wrong code\n");
2559 ok( type == NODE_ELEMENT, "node not text\n");
2561 hr = IXMLDOMNode_hasChildNodes( node, NULL );
2562 ok(hr == E_INVALIDARG, "hasChildNodes bad return\n");
2564 EXPECT_CHILDREN(node);
2566 str = NULL;
2567 hr = IXMLDOMNode_get_baseName( node, &str );
2568 ok(hr == S_OK, "get_baseName returned wrong code\n");
2569 ok( !lstrcmpW(str, L"bs"), "Unexpected basename.\n");
2570 SysFreeString(str);
2572 else
2573 ok( FALSE, "no node\n");
2575 if (node)
2576 IXMLDOMNode_Release( node );
2577 if (list)
2578 IXMLDOMNodeList_Release( list );
2579 if (element)
2580 IXMLDOMElement_Release( element );
2582 b = FALSE;
2583 str = SysAllocString( szComplete5 );
2584 hr = IXMLDOMDocument_loadXML( doc, str, &b );
2585 ok(hr == S_OK, "loadXML failed\n");
2586 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2587 SysFreeString( str );
2589 EXPECT_CHILDREN(doc);
2591 hr = IXMLDOMDocument_get_documentElement( doc, &element );
2592 ok(hr == S_OK, "should be a document element\n");
2593 ok( element != NULL, "should be an element\n");
2595 if (element)
2597 BSTR tag = NULL;
2599 /* check if the tag is correct */
2600 hr = IXMLDOMElement_get_tagName( element, &tag );
2601 ok(hr == S_OK, "couldn't get tag name\n");
2602 ok( tag != NULL, "tag was null\n");
2603 ok( !lstrcmpW( tag, L"S:search" ), "incorrect tag name\n");
2604 SysFreeString( tag );
2606 IXMLDOMElement_Release( element );
2608 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2610 free_bstrs();
2613 typedef struct {
2614 DOMNodeType type;
2615 REFIID iid;
2616 } refcount_test_t;
2618 static const refcount_test_t refcount_test[] = {
2619 { NODE_ELEMENT, &IID_IXMLDOMElement },
2620 { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute },
2621 { NODE_TEXT, &IID_IXMLDOMText },
2622 { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection },
2623 { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference },
2624 { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
2625 { NODE_COMMENT, &IID_IXMLDOMComment },
2626 { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment },
2627 { NODE_INVALID, &IID_NULL }
2630 static void test_refs(void)
2632 IXMLDOMImplementation *impl, *impl2;
2633 IXMLDOMElement *element, *elem2;
2634 IXMLDOMNodeList *node_list = NULL;
2635 IXMLDOMNode *node, *node2, *node3;
2636 const refcount_test_t *ptr;
2637 IXMLDOMDocument *doc;
2638 IUnknown *unk, *unk2;
2639 VARIANT_BOOL b;
2640 HRESULT hr;
2641 LONG ref;
2643 doc = create_document(&IID_IXMLDOMDocument);
2645 ptr = refcount_test;
2646 while (ptr->type != NODE_INVALID)
2648 IUnknown *node_typed, *node_typed2;
2649 IDispatchEx *dispex, *dispex2;
2650 IDispatch *disp, *disp2;
2651 VARIANT type;
2653 V_VT(&type) = VT_I1;
2654 V_I1(&type) = ptr->type;
2656 EXPECT_REF(doc, 1);
2657 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
2658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2659 EXPECT_REF(doc, 1);
2660 EXPECT_REF(node, 1);
2662 /* try IDispatch and IUnknown from IXMLDOMNode */
2663 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
2664 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2665 EXPECT_REF(unk, 2);
2666 todo_wine {
2667 EXPECT_REF(node, 1);
2668 ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
2670 EXPECT_REF(unk, 2);
2671 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2673 todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
2674 EXPECT_REF(unk, 3);
2675 todo_wine EXPECT_REF(disp, 1);
2677 EXPECT_REF(unk, 3);
2678 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
2679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2680 todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
2681 EXPECT_REF(unk, 4);
2682 todo_wine EXPECT_REF(disp2, 1);
2684 IDispatch_Release(disp);
2685 IDispatch_Release(disp2);
2687 /* get IXMLDOMNode from this IUnknown */
2688 EXPECT_REF(unk, 2);
2689 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
2690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2691 todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
2692 EXPECT_REF(unk, 3);
2693 todo_wine EXPECT_REF(node2, 1);
2695 EXPECT_REF(unk, 3);
2696 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
2697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2698 todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
2699 EXPECT_REF(unk, 4);
2700 todo_wine EXPECT_REF(node3, 1);
2702 IXMLDOMNode_Release(node2);
2703 IXMLDOMNode_Release(node3);
2705 /* try IDispatchEx from IUnknown */
2706 EXPECT_REF(unk, 2);
2707 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
2708 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2709 ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
2710 EXPECT_REF(unk, 3);
2711 todo_wine EXPECT_REF(dispex, 1);
2713 EXPECT_REF(unk, 3);
2714 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
2715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2716 todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
2717 EXPECT_REF(unk, 4);
2718 todo_wine EXPECT_REF(dispex2, 1);
2720 IDispatchEx_Release(dispex);
2721 IDispatchEx_Release(dispex2);
2723 /* try corresponding IXMLDOM* */
2724 EXPECT_REF(unk, 2);
2725 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
2726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2727 EXPECT_REF(unk, 3);
2728 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
2729 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2730 EXPECT_REF(unk, 4);
2731 todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
2732 IUnknown_Release(node_typed);
2733 IUnknown_Release(node_typed2);
2735 /* try invalid IXMLDOM* */
2736 hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
2737 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
2739 IUnknown_Release(unk);
2741 EXPECT_REF(node, 1);
2742 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
2743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2744 EXPECT_REF(node, 2);
2745 ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
2747 EXPECT_REF(node, 2);
2748 hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
2749 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2750 EXPECT_REF(node, 3);
2751 todo_wine {
2752 EXPECT_REF(node_typed, 2);
2753 ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
2755 IUnknown_Release(node_typed);
2757 IXMLDOMNode_Release(node2);
2758 IXMLDOMNode_Release(node);
2760 ptr++;
2763 EXPECT_REF(doc, 1);
2764 ref = IXMLDOMDocument_Release(doc);
2765 ok( ref == 0, "ref %ld\n", ref);
2767 /* check IUnknown after releasing DOM iface */
2768 doc = create_document(&IID_IXMLDOMDocument);
2769 EXPECT_REF(doc, 1);
2770 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2772 todo_wine {
2773 EXPECT_REF(unk, 3);
2774 EXPECT_REF(doc, 1);
2776 IXMLDOMDocument_Release(doc);
2777 EXPECT_REF(unk, 1);
2778 IUnknown_Release(unk);
2780 doc = create_document(&IID_IXMLDOMDocument);
2782 EXPECT_REF(doc, 1);
2783 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2784 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2785 todo_wine {
2786 EXPECT_REF(unk, 3);
2787 EXPECT_REF(doc, 1);
2789 IUnknown_Release(unk);
2791 /* IXMLDOMImplementation */
2792 EXPECT_REF(doc, 1);
2793 hr = IXMLDOMDocument_get_implementation(doc, &impl);
2794 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2795 EXPECT_REF(doc, 1);
2796 EXPECT_REF(impl, 1);
2797 hr = IXMLDOMDocument_get_implementation(doc, &impl2);
2798 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2799 EXPECT_REF(doc, 1);
2800 EXPECT_REF(impl2, 1);
2801 ok(impl != impl2, "got %p, %p\n", impl, impl2);
2802 IXMLDOMImplementation_Release(impl);
2803 IXMLDOMImplementation_Release(impl2);
2805 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2806 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2807 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2809 EXPECT_REF(doc, 1);
2810 IXMLDOMDocument_AddRef( doc );
2811 EXPECT_REF(doc, 2);
2812 IXMLDOMDocument_AddRef( doc );
2813 EXPECT_REF(doc, 3);
2815 IXMLDOMDocument_Release( doc );
2816 IXMLDOMDocument_Release( doc );
2818 EXPECT_REF(doc, 1);
2819 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2821 todo_wine {
2822 EXPECT_REF(unk, 3);
2823 EXPECT_REF(doc, 1);
2825 hr = IXMLDOMDocument_get_documentElement(doc, &element);
2826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2827 todo_wine {
2828 EXPECT_REF(doc, 1);
2829 EXPECT_REF(element, 2);
2831 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
2832 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2834 todo_wine {
2835 EXPECT_REF(doc, 1);
2836 EXPECT_REF(element, 2);
2837 EXPECT_REF(elem2, 2);
2839 IXMLDOMElement_AddRef(element);
2840 todo_wine EXPECT_REF(element, 3);
2841 IXMLDOMElement_Release(element);
2843 /* get IUnknown from a node doesn't touch node instance refcount */
2844 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2845 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2846 EXPECT_REF(element, 2);
2847 todo_wine {
2848 EXPECT_REF(unk, 4);
2849 EXPECT_REF(elem2, 2);
2851 hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
2852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2853 todo_wine {
2854 EXPECT_REF(unk, 5);
2855 EXPECT_REF(unk2, 5);
2857 EXPECT_REF(element, 2);
2858 EXPECT_REF(elem2, 2);
2860 todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
2861 IUnknown_Release(unk);
2863 /* IUnknown refcount is not affected by node refcount */
2864 todo_wine EXPECT_REF(unk2, 4);
2865 IXMLDOMElement_AddRef(elem2);
2866 todo_wine EXPECT_REF(unk2, 4);
2867 IXMLDOMElement_Release(elem2);
2869 IXMLDOMElement_Release(elem2);
2870 todo_wine EXPECT_REF(unk2, 3);
2872 IUnknown_Release(unk2);
2874 hr = IXMLDOMElement_get_childNodes( element, &node_list );
2875 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2877 todo_wine EXPECT_REF(element, 2);
2878 EXPECT_REF(node_list, 1);
2880 hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
2881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2882 EXPECT_REF(node_list, 1);
2883 EXPECT_REF(node, 1);
2885 hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2886 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2887 EXPECT_REF(node_list, 1);
2888 EXPECT_REF(node2, 1);
2890 ref = IXMLDOMNode_Release( node );
2891 ok( ref == 0, "ref %ld\n", ref );
2892 ref = IXMLDOMNode_Release( node2 );
2893 ok( ref == 0, "ref %ld\n", ref );
2895 ref = IXMLDOMNodeList_Release( node_list );
2896 ok( ref == 0, "ref %ld\n", ref );
2898 ok( node != node2, "node %p node2 %p\n", node, node2 );
2900 ref = IXMLDOMDocument_Release( doc );
2901 todo_wine ok( ref == 0, "ref %ld\n", ref );
2903 todo_wine EXPECT_REF(element, 2);
2905 /* IUnknown must be unique however we obtain it */
2906 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2908 EXPECT_REF(element, 2);
2909 hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
2910 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2911 todo_wine EXPECT_REF(element, 2);
2912 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2914 todo_wine EXPECT_REF(element, 2);
2915 ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
2916 todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
2918 IUnknown_Release( unk2 );
2919 IUnknown_Release( unk );
2920 IXMLDOMNode_Release( node );
2921 todo_wine EXPECT_REF(element, 2);
2923 IXMLDOMElement_Release( element );
2925 free_bstrs();
2928 static void test_create(void)
2930 VARIANT var;
2931 BSTR str, name;
2932 IXMLDOMDocument *doc;
2933 IXMLDOMElement *element;
2934 IXMLDOMComment *comment;
2935 IXMLDOMText *text;
2936 IXMLDOMCDATASection *cdata;
2937 IXMLDOMNode *root, *node, *child;
2938 IXMLDOMNamedNodeMap *attr_map;
2939 IUnknown *unk;
2940 HRESULT hr;
2941 LONG ref;
2942 LONG num;
2944 doc = create_document(&IID_IXMLDOMDocument);
2946 EXPECT_REF(doc, 1);
2948 /* types not supported for creation */
2949 V_VT(&var) = VT_I1;
2950 V_I1(&var) = NODE_DOCUMENT;
2951 node = (IXMLDOMNode*)0x1;
2952 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2953 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2954 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2956 V_VT(&var) = VT_I1;
2957 V_I1(&var) = NODE_DOCUMENT_TYPE;
2958 node = (IXMLDOMNode*)0x1;
2959 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2960 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2961 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2963 V_VT(&var) = VT_I1;
2964 V_I1(&var) = NODE_ENTITY;
2965 node = (IXMLDOMNode*)0x1;
2966 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2967 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2968 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2970 V_VT(&var) = VT_I1;
2971 V_I1(&var) = NODE_NOTATION;
2972 node = (IXMLDOMNode*)0x1;
2973 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2974 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2975 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2977 /* NODE_COMMENT */
2978 V_VT(&var) = VT_I1;
2979 V_I1(&var) = NODE_COMMENT;
2980 node = NULL;
2981 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2982 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2983 ok( node != NULL, "\n");
2985 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2986 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2987 IXMLDOMNode_Release(node);
2989 str = NULL;
2990 hr = IXMLDOMComment_get_data(comment, &str);
2991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2992 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2993 IXMLDOMComment_Release(comment);
2994 SysFreeString(str);
2996 node = (IXMLDOMNode*)0x1;
2997 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2998 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3000 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3002 IXMLDOMNode_Release(node);
3004 str = NULL;
3005 hr = IXMLDOMComment_get_data(comment, &str);
3006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3007 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3008 IXMLDOMComment_Release(comment);
3009 SysFreeString(str);
3011 node = (IXMLDOMNode*)0x1;
3012 hr = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3015 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
3016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3017 IXMLDOMNode_Release(node);
3019 str = NULL;
3020 hr = IXMLDOMComment_get_data(comment, &str);
3021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3022 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3023 IXMLDOMComment_Release(comment);
3024 SysFreeString(str);
3026 /* NODE_TEXT */
3027 V_VT(&var) = VT_I1;
3028 V_I1(&var) = NODE_TEXT;
3029 node = NULL;
3030 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3031 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3032 ok( node != NULL, "\n");
3034 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3035 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3036 IXMLDOMNode_Release(node);
3038 str = NULL;
3039 hr = IXMLDOMText_get_data(text, &str);
3040 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3041 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3042 IXMLDOMText_Release(text);
3043 SysFreeString(str);
3045 node = (IXMLDOMNode*)0x1;
3046 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3047 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3049 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3050 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3051 IXMLDOMNode_Release(node);
3053 str = NULL;
3054 hr = IXMLDOMText_get_data(text, &str);
3055 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3056 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3057 IXMLDOMText_Release(text);
3058 SysFreeString(str);
3060 node = (IXMLDOMNode*)0x1;
3061 hr = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3062 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3064 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3065 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3066 IXMLDOMNode_Release(node);
3068 str = NULL;
3069 hr = IXMLDOMText_get_data(text, &str);
3070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3071 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3072 IXMLDOMText_Release(text);
3073 SysFreeString(str);
3075 /* NODE_CDATA_SECTION */
3076 V_VT(&var) = VT_I1;
3077 V_I1(&var) = NODE_CDATA_SECTION;
3078 node = NULL;
3079 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3081 ok( node != NULL, "\n");
3083 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3084 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3085 IXMLDOMNode_Release(node);
3087 str = NULL;
3088 hr = IXMLDOMCDATASection_get_data(cdata, &str);
3089 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3090 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3091 IXMLDOMCDATASection_Release(cdata);
3092 SysFreeString(str);
3094 node = (IXMLDOMNode*)0x1;
3095 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3098 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3100 IXMLDOMNode_Release(node);
3102 str = NULL;
3103 hr = IXMLDOMCDATASection_get_data(cdata, &str);
3104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3105 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3106 IXMLDOMCDATASection_Release(cdata);
3107 SysFreeString(str);
3109 node = (IXMLDOMNode*)0x1;
3110 hr = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3111 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3113 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3114 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3115 IXMLDOMNode_Release(node);
3117 str = NULL;
3118 hr = IXMLDOMCDATASection_get_data(cdata, &str);
3119 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3120 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3121 IXMLDOMCDATASection_Release(cdata);
3122 SysFreeString(str);
3124 /* NODE_ATTRIBUTE */
3125 V_VT(&var) = VT_I1;
3126 V_I1(&var) = NODE_ATTRIBUTE;
3127 node = (IXMLDOMNode*)0x1;
3128 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3129 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3130 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3132 V_VT(&var) = VT_I1;
3133 V_I1(&var) = NODE_ATTRIBUTE;
3134 node = (IXMLDOMNode*)0x1;
3135 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3136 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3137 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3139 V_VT(&var) = VT_I1;
3140 V_I1(&var) = NODE_ATTRIBUTE;
3141 str = SysAllocString( L"lc" );
3142 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3144 if (SUCCEEDED(hr)) IXMLDOMNode_Release(node);
3145 SysFreeString(str);
3147 /* a name is required for attribute, try a BSTR with first null wchar */
3148 V_VT(&var) = VT_I1;
3149 V_I1(&var) = NODE_ATTRIBUTE;
3150 str = SysAllocString( L"str1" );
3151 str[0] = 0;
3152 node = (IXMLDOMNode*)0x1;
3153 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3154 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3155 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3156 SysFreeString(str);
3158 /* NODE_PROCESSING_INSTRUCTION */
3159 V_VT(&var) = VT_I1;
3160 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3161 node = (IXMLDOMNode*)0x1;
3162 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3163 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3164 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3166 V_VT(&var) = VT_I1;
3167 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3168 node = (IXMLDOMNode*)0x1;
3169 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3170 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3171 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3173 V_VT(&var) = VT_I1;
3174 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3175 hr = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3176 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3178 /* NODE_ENTITY_REFERENCE */
3179 V_VT(&var) = VT_I1;
3180 V_I1(&var) = NODE_ENTITY_REFERENCE;
3181 node = (IXMLDOMNode*)0x1;
3182 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3183 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3184 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3186 V_VT(&var) = VT_I1;
3187 V_I1(&var) = NODE_ENTITY_REFERENCE;
3188 node = (IXMLDOMNode*)0x1;
3189 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3190 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3191 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3193 /* NODE_ELEMENT */
3194 V_VT(&var) = VT_I1;
3195 V_I1(&var) = NODE_ELEMENT;
3196 node = (IXMLDOMNode*)0x1;
3197 hr = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3198 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3199 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3201 V_VT(&var) = VT_I1;
3202 V_I1(&var) = NODE_ELEMENT;
3203 node = (IXMLDOMNode*)0x1;
3204 hr = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3205 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3206 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3208 V_VT(&var) = VT_I1;
3209 V_I1(&var) = NODE_ELEMENT;
3210 str = SysAllocString( L"lc" );
3211 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3212 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3213 if( SUCCEEDED(hr) ) IXMLDOMNode_Release( node );
3215 V_VT(&var) = VT_I1;
3216 V_I1(&var) = NODE_ELEMENT;
3217 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3218 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3220 V_VT(&var) = VT_R4;
3221 V_R4(&var) = NODE_ELEMENT;
3222 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3223 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3224 if( SUCCEEDED(hr) ) IXMLDOMNode_Release( node );
3226 V_VT(&var) = VT_BSTR;
3227 V_BSTR(&var) = SysAllocString( L"1" );
3228 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3230 if( SUCCEEDED(hr) ) IXMLDOMNode_Release( node );
3231 VariantClear(&var);
3233 V_VT(&var) = VT_BSTR;
3234 V_BSTR(&var) = SysAllocString( L"1Garbage" );
3235 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3236 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3237 if( SUCCEEDED(hr) ) IXMLDOMNode_Release( node );
3238 VariantClear(&var);
3240 V_VT(&var) = VT_I4;
3241 V_I4(&var) = NODE_ELEMENT;
3242 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3245 EXPECT_REF(doc, 1);
3246 hr = IXMLDOMDocument_appendChild( doc, node, &root );
3247 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3248 ok( node == root, "%p %p\n", node, root );
3249 EXPECT_REF(doc, 1);
3251 EXPECT_REF(node, 2);
3253 ref = IXMLDOMNode_Release( node );
3254 ok(ref == 1, "ref %ld\n", ref);
3255 SysFreeString( str );
3257 V_VT(&var) = VT_I4;
3258 V_I4(&var) = NODE_ELEMENT;
3259 str = SysAllocString( L"bs" );
3260 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3262 SysFreeString( str );
3264 EXPECT_REF(node, 1);
3266 hr = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3269 EXPECT_REF(unk, 2);
3271 V_VT(&var) = VT_EMPTY;
3272 child = NULL;
3273 hr = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3275 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3277 todo_wine EXPECT_REF(unk, 4);
3279 IXMLDOMNode_Release( child );
3280 IUnknown_Release( unk );
3282 V_VT(&var) = VT_NULL;
3283 V_DISPATCH(&var) = (IDispatch*)node;
3284 hr = IXMLDOMNode_insertBefore( root, node, var, &child );
3285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3286 ok( node == child, "%p %p\n", node, child );
3287 IXMLDOMNode_Release( child );
3289 V_VT(&var) = VT_NULL;
3290 V_DISPATCH(&var) = (IDispatch*)node;
3291 hr = IXMLDOMNode_insertBefore( root, node, var, NULL );
3292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3293 IXMLDOMNode_Release( node );
3295 hr = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3296 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3298 hr = IXMLDOMElement_get_attributes( element, &attr_map );
3299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3300 hr = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3302 ok( num == 0, "num %ld\n", num );
3303 IXMLDOMNamedNodeMap_Release( attr_map );
3305 V_VT(&var) = VT_BSTR;
3306 V_BSTR(&var) = SysAllocString( L"str1" );
3307 name = SysAllocString( L"dl" );
3308 hr = IXMLDOMElement_setAttribute( element, name, var );
3309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3310 hr = IXMLDOMElement_get_attributes( element, &attr_map );
3311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3312 hr = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3313 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3314 ok( num == 1, "num %ld\n", num );
3315 IXMLDOMNamedNodeMap_Release( attr_map );
3316 VariantClear(&var);
3318 V_VT(&var) = VT_BSTR;
3319 V_BSTR(&var) = SysAllocString( L"str2" );
3320 hr = IXMLDOMElement_setAttribute( element, name, var );
3321 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3322 hr = IXMLDOMElement_get_attributes( element, &attr_map );
3323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3324 hr = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3326 ok( num == 1, "num %ld\n", num );
3327 IXMLDOMNamedNodeMap_Release( attr_map );
3328 VariantClear(&var);
3329 hr = IXMLDOMElement_getAttribute( element, name, &var );
3330 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3331 ok( !lstrcmpW(V_BSTR(&var), L"str2"), "wrong attr value\n");
3332 VariantClear(&var);
3333 SysFreeString(name);
3335 V_VT(&var) = VT_BSTR;
3336 V_BSTR(&var) = SysAllocString( L"str1" );
3337 name = SysAllocString( L"lc" );
3338 hr = IXMLDOMElement_setAttribute( element, name, var );
3339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3340 hr = IXMLDOMElement_get_attributes( element, &attr_map );
3341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3342 hr = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3343 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3344 ok( num == 2, "num %ld\n", num );
3345 IXMLDOMNamedNodeMap_Release( attr_map );
3346 VariantClear(&var);
3347 SysFreeString(name);
3349 V_VT(&var) = VT_I4;
3350 V_I4(&var) = 10;
3351 name = SysAllocString( L"bs" );
3352 hr = IXMLDOMElement_setAttribute( element, name, var );
3353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3354 VariantClear(&var);
3355 hr = IXMLDOMElement_getAttribute( element, name, &var );
3356 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3357 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3358 VariantClear(&var);
3359 SysFreeString(name);
3361 /* Create an Attribute */
3362 V_VT(&var) = VT_I4;
3363 V_I4(&var) = NODE_ATTRIBUTE;
3364 str = SysAllocString( L"Attr" );
3365 hr = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3366 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3367 ok( node != NULL, "node was null\n");
3368 SysFreeString(str);
3370 IXMLDOMElement_Release( element );
3371 IXMLDOMNode_Release( root );
3372 IXMLDOMDocument_Release( doc );
3375 struct queryresult_t {
3376 const char *query;
3377 const char *result;
3378 int len;
3381 static const struct queryresult_t elementsbytagname[] = {
3382 { "", "P1.D1 E2.D1 E1.E2.D1 T1.E1.E2.D1 E2.E2.D1 T1.E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1 T1.E1.E4.E2.D1", 10 },
3383 { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
3384 { "bs", "E1.E2.D1", 1 },
3385 { "dl", "", 0 },
3386 { "str1","", 0 },
3387 { NULL }
3390 static void test_getElementsByTagName(void)
3392 const struct queryresult_t *ptr = elementsbytagname;
3393 IXMLDOMNodeList *node_list;
3394 IXMLDOMDocument *doc;
3395 IXMLDOMElement *elem;
3396 WCHAR buff[100];
3397 VARIANT_BOOL b;
3398 HRESULT hr;
3399 LONG len;
3400 BSTR str;
3402 doc = create_document(&IID_IXMLDOMDocument);
3404 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3405 ok(hr == S_OK, "loadXML failed\n");
3406 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3408 /* null arguments cases */
3409 hr = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3410 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3411 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL);
3412 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3414 while (ptr->query)
3416 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list);
3417 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3418 hr = IXMLDOMNodeList_get_length(node_list, &len);
3419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3420 ok(len == ptr->len, "%s: got len %ld, expected %d\n", ptr->query, len, ptr->len);
3421 expect_list_and_release(node_list, ptr->result);
3423 free_bstrs();
3424 ptr++;
3427 /* broken query BSTR */
3428 memcpy(&buff[2], L"*", 2 * sizeof(WCHAR));
3429 /* just a big length */
3430 *(DWORD*)buff = 0xf0f0;
3431 hr = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3432 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3433 hr = IXMLDOMNodeList_get_length( node_list, &len );
3434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3435 ok( len == 6, "len %ld\n", len );
3436 IXMLDOMNodeList_Release( node_list );
3438 /* test for element */
3439 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
3440 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3442 str = SysAllocString( L"*" );
3444 /* null arguments cases */
3445 hr = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3446 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3447 hr = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3448 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3450 hr = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3452 hr = IXMLDOMNodeList_get_length( node_list, &len );
3453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3454 ok( len == 5, "len %ld\n", len );
3455 expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3456 SysFreeString( str );
3458 /* broken query BSTR */
3459 memcpy(&buff[2], L"*", 2 * sizeof(WCHAR));
3460 /* just a big length */
3461 *(DWORD*)buff = 0xf0f0;
3462 hr = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3463 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3464 hr = IXMLDOMNodeList_get_length( node_list, &len );
3465 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3466 ok( len == 5, "len %ld\n", len );
3467 IXMLDOMNodeList_Release( node_list );
3469 IXMLDOMElement_Release(elem);
3471 IXMLDOMDocument_Release( doc );
3473 free_bstrs();
3476 static void test_get_text(void)
3478 BSTR str;
3479 VARIANT_BOOL b;
3480 IXMLDOMDocument *doc;
3481 IXMLDOMNode *node, *node2, *node3;
3482 IXMLDOMNode *nodeRoot;
3483 IXMLDOMNodeList *node_list;
3484 IXMLDOMNamedNodeMap *node_map;
3485 HRESULT hr;
3486 LONG len;
3488 doc = create_document(&IID_IXMLDOMDocument);
3490 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3491 ok(hr == S_OK, "loadXML failed\n");
3492 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3494 str = SysAllocString( L"bs" );
3495 hr = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3497 SysFreeString(str);
3499 /* Test to get all child node text. */
3500 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3502 if (hr == S_OK)
3504 hr = IXMLDOMNode_get_text( nodeRoot, &str );
3505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3506 expect_bstr_eq_and_free(str, "fn1.txt\n \nfn2.txt\n \nf1");
3508 IXMLDOMNode_Release(nodeRoot);
3511 hr = IXMLDOMNodeList_get_length( node_list, NULL );
3512 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3514 hr = IXMLDOMNodeList_get_length( node_list, &len );
3515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3516 ok( len == 1, "expect 1 got %ld\n", len );
3518 hr = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3519 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3521 hr = IXMLDOMNodeList_nextNode( node_list, NULL );
3522 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3524 hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
3525 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3526 IXMLDOMNodeList_Release( node_list );
3528 /* Invalid output parameter*/
3529 hr = IXMLDOMNode_get_text( node, NULL );
3530 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3532 hr = IXMLDOMNode_get_text( node, &str );
3533 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3534 ok( !lstrcmpW(str, L"fn1.txt"), "wrong string\n" );
3535 SysFreeString(str);
3537 hr = IXMLDOMNode_get_attributes( node, &node_map );
3538 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3540 str = SysAllocString( L"vr" );
3541 hr = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3543 SysFreeString(str);
3545 hr = IXMLDOMNode_get_text( node2, &str );
3546 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3547 ok( !lstrcmpW(str, L"str2"), "Unexpected string.\n" );
3548 SysFreeString(str);
3550 hr = IXMLDOMNode_get_firstChild( node2, &node3 );
3551 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3553 hr = IXMLDOMNode_get_text( node3, &str );
3554 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3555 ok( !lstrcmpW(str, L"str2"), "Unexpected string.\n" );
3556 SysFreeString(str);
3559 IXMLDOMNode_Release( node3 );
3560 IXMLDOMNode_Release( node2 );
3561 IXMLDOMNamedNodeMap_Release( node_map );
3562 IXMLDOMNode_Release( node );
3563 IXMLDOMDocument_Release( doc );
3565 free_bstrs();
3568 static void test_get_childNodes(void)
3570 IXMLDOMNodeList *node_list, *node_list2;
3571 IEnumVARIANT *enum1, *enum2, *enum3;
3572 VARIANT_BOOL b;
3573 IXMLDOMDocument *doc;
3574 IXMLDOMNode *node, *node2;
3575 IXMLDOMElement *element;
3576 IUnknown *unk1, *unk2;
3577 ULONG fetched;
3578 VARIANT v[2];
3579 HRESULT hr;
3580 BSTR str;
3581 LONG len;
3583 doc = create_document(&IID_IXMLDOMDocument);
3585 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3587 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3589 hr = IXMLDOMDocument_get_documentElement( doc, &element );
3590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3592 hr = IXMLDOMElement_get_childNodes( element, &node_list );
3593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3595 hr = IXMLDOMNodeList_get_length( node_list, &len );
3596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3597 ok( len == 4, "len %ld\n", len);
3599 /* refcount tests for IEnumVARIANT support */
3600 EXPECT_REF(node_list, 1);
3601 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
3602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3603 EXPECT_REF(node_list, 1);
3604 EXPECT_REF(enum1, 2);
3606 EXPECT_REF(node_list, 1);
3607 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
3608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3609 EXPECT_REF(node_list, 1);
3610 ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
3611 IEnumVARIANT_Release(enum2);
3613 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3615 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
3616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3617 EXPECT_REF(node_list, 3);
3618 EXPECT_REF(enum1, 2);
3619 ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
3620 IUnknown_Release(unk1);
3621 IUnknown_Release(unk2);
3623 EXPECT_REF(node_list, 1);
3624 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
3625 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3626 EXPECT_REF(node_list, 2);
3627 EXPECT_REF(enum2, 1);
3628 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
3630 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
3631 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3632 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3633 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
3634 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3635 EXPECT_REF(node_list, 3);
3636 EXPECT_REF(enum2, 2);
3637 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
3638 IUnknown_Release(unk1);
3639 IUnknown_Release(unk2);
3641 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
3642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3643 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
3644 IEnumVARIANT_Release(enum3);
3645 IEnumVARIANT_Release(enum2);
3647 /* iteration tests */
3648 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
3649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3650 hr = IXMLDOMNode_get_nodeName(node, &str);
3651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3652 ok(!lstrcmpW(str, L"bs"), "got %s\n", wine_dbgstr_w(str));
3653 SysFreeString(str);
3654 IXMLDOMNode_Release(node);
3656 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3657 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3658 hr = IXMLDOMNode_get_nodeName(node, &str);
3659 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3660 ok(!lstrcmpW(str, L"bs"), "got %s\n", wine_dbgstr_w(str));
3661 SysFreeString(str);
3662 IXMLDOMNode_Release(node);
3664 V_VT(&v[0]) = VT_EMPTY;
3665 hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL);
3666 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3667 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
3668 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
3669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3670 hr = IXMLDOMNode_get_nodeName(node, &str);
3671 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3672 ok(!lstrcmpW(str, L"bs"), "got node name %s\n", wine_dbgstr_w(str));
3673 SysFreeString(str);
3674 IXMLDOMNode_Release(node);
3675 VariantClear(&v[0]);
3677 V_VT(&v[1]) = VT_EMPTY;
3678 V_VT(&v[0]) = VT_EMPTY;
3679 hr = IEnumVARIANT_Next(enum1, 2, v, &fetched);
3680 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3681 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
3682 ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1]));
3683 ok(fetched == 2, "got %ld, expected 2\n", fetched);
3684 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
3685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3686 hr = IXMLDOMNode_get_nodeName(node, &str);
3687 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3688 ok(!lstrcmpW(str, L"pr"), "got node name %s\n", wine_dbgstr_w(str));
3689 SysFreeString(str);
3690 IXMLDOMNode_Release(node);
3691 hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node);
3692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3693 hr = IXMLDOMNode_get_nodeName(node, &str);
3694 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3695 ok(!lstrcmpW(str, L"empty"), "got node name %s\n", wine_dbgstr_w(str));
3696 SysFreeString(str);
3697 IXMLDOMNode_Release(node);
3698 VariantClear(&v[1]);
3699 VariantClear(&v[0]);
3701 V_VT(&v[1]) = VT_NULL;
3702 V_VT(&v[0]) = VT_EMPTY;
3703 hr = IEnumVARIANT_Next(enum1, 2, v, &fetched);
3704 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
3705 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
3706 ok(V_VT(&v[1]) == VT_EMPTY, "got var type %d\n", V_VT(&v[1]));
3707 ok(fetched == 1, "got %ld, expected 1\n", fetched);
3708 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
3709 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3710 hr = IXMLDOMNode_get_nodeName(node, &str);
3711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3712 ok(!lstrcmpW(str, L"fo"), "got node name %s\n", wine_dbgstr_w(str));
3713 SysFreeString(str);
3714 VariantClear(&v[0]);
3716 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3717 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3718 hr = IXMLDOMNode_get_nodeName(node, &str);
3719 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3720 ok(!lstrcmpW(str, L"pr"), "got %s\n", wine_dbgstr_w(str));
3721 SysFreeString(str);
3722 IXMLDOMNode_Release(node);
3724 IEnumVARIANT_Release(enum1);
3726 hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3729 hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3732 hr = IXMLDOMNodeList_get_length( node_list2, &len );
3733 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3734 ok( len == 0, "len %ld\n", len);
3736 hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3737 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
3739 IXMLDOMNodeList_Release( node_list2 );
3740 IXMLDOMNode_Release( node );
3741 IXMLDOMNodeList_Release( node_list );
3742 IXMLDOMElement_Release( element );
3744 /* test for children of <?xml ..?> node */
3745 hr = IXMLDOMDocument_get_firstChild(doc, &node);
3746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3748 str = NULL;
3749 hr = IXMLDOMNode_get_nodeName(node, &str);
3750 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3751 ok(!lstrcmpW(str, L"xml"), "got %s\n", wine_dbgstr_w(str));
3752 SysFreeString(str);
3754 /* it returns empty but valid node list */
3755 node_list = (void*)0xdeadbeef;
3756 hr = IXMLDOMNode_get_childNodes(node, &node_list);
3757 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3759 len = -1;
3760 hr = IXMLDOMNodeList_get_length(node_list, &len);
3761 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3762 ok(len == 0, "got %ld\n", len);
3764 IXMLDOMNodeList_Release( node_list );
3765 IXMLDOMNode_Release(node);
3767 IXMLDOMDocument_Release( doc );
3768 free_bstrs();
3771 static void test_get_firstChild(void)
3773 IXMLDOMDocument *doc;
3774 IXMLDOMNode *node;
3775 VARIANT_BOOL b;
3776 HRESULT hr;
3777 BSTR str;
3779 doc = create_document(&IID_IXMLDOMDocument);
3781 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3782 ok(hr == S_OK, "loadXML failed\n");
3783 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3785 hr = IXMLDOMDocument_get_firstChild( doc, &node );
3786 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3788 hr = IXMLDOMNode_get_nodeName( node, &str );
3789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3791 ok(!lstrcmpW(str, L"xml"), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3793 SysFreeString(str);
3794 IXMLDOMNode_Release( node );
3795 IXMLDOMDocument_Release( doc );
3797 free_bstrs();
3800 static void test_get_lastChild(void)
3802 IXMLDOMDocument *doc;
3803 IXMLDOMNode *node, *child;
3804 VARIANT_BOOL b;
3805 HRESULT hr;
3806 BSTR str;
3808 doc = create_document(&IID_IXMLDOMDocument);
3810 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3811 ok(hr == S_OK, "loadXML failed\n");
3812 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3814 hr = IXMLDOMDocument_get_lastChild( doc, &node );
3815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3817 hr = IXMLDOMNode_get_nodeName( node, &str );
3818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3820 ok(!lstrcmpW(str, L"lc"), "Unexpected node name.\n");
3821 SysFreeString(str);
3823 hr = IXMLDOMNode_get_lastChild( node, &child );
3824 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3826 hr = IXMLDOMNode_get_nodeName( child, &str );
3827 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3829 ok(!lstrcmpW(str, L"fo"), "Unexpected node name.\n");
3830 SysFreeString(str);
3832 IXMLDOMNode_Release( child );
3833 IXMLDOMNode_Release( node );
3834 IXMLDOMDocument_Release( doc );
3836 free_bstrs();
3839 static void test_removeChild(void)
3841 VARIANT_BOOL b;
3842 IXMLDOMDocument *doc;
3843 IXMLDOMElement *element, *lc_element;
3844 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
3845 IXMLDOMNodeList *root_list, *fo_list;
3846 HRESULT hr;
3848 doc = create_document(&IID_IXMLDOMDocument);
3850 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3851 ok(hr == S_OK, "loadXML failed\n");
3852 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3854 hr = IXMLDOMDocument_get_documentElement( doc, &element );
3855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3856 todo_wine EXPECT_REF(element, 2);
3858 hr = IXMLDOMElement_get_childNodes( element, &root_list );
3859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3860 EXPECT_REF(root_list, 1);
3862 hr = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3864 EXPECT_REF(fo_node, 1);
3866 hr = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3867 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3868 EXPECT_REF(fo_list, 1);
3870 hr = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3871 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3872 EXPECT_REF(ba_node, 1);
3874 /* invalid parameter: NULL ptr */
3875 removed_node = (void*)0xdeadbeef;
3876 hr = IXMLDOMElement_removeChild( element, NULL, &removed_node );
3877 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3878 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3880 /* ba_node is a descendant of element, but not a direct child. */
3881 removed_node = (void*)0xdeadbeef;
3882 EXPECT_REF(ba_node, 1);
3883 EXPECT_CHILDREN(fo_node);
3884 hr = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
3885 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3886 ok( removed_node == NULL, "%p\n", removed_node );
3887 EXPECT_REF(ba_node, 1);
3888 EXPECT_CHILDREN(fo_node);
3890 EXPECT_REF(ba_node, 1);
3891 EXPECT_REF(fo_node, 1);
3892 hr = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
3893 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3894 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
3895 EXPECT_REF(fo_node, 2);
3896 EXPECT_REF(ba_node, 1);
3898 /* try removing already removed child */
3899 temp_node = (void*)0xdeadbeef;
3900 hr = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
3901 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3902 ok( temp_node == NULL, "%p\n", temp_node );
3903 IXMLDOMNode_Release( fo_node );
3905 /* the removed node has no parent anymore */
3906 hr = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
3907 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
3908 ok( temp_node == NULL, "%p\n", temp_node );
3910 IXMLDOMNode_Release( removed_node );
3911 IXMLDOMNode_Release( ba_node );
3912 IXMLDOMNodeList_Release( fo_list );
3914 hr = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3915 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3917 hr = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
3918 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3920 /* MS quirk: passing wrong interface pointer works, too */
3921 hr = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
3922 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3923 IXMLDOMElement_Release( lc_element );
3925 temp_node = (void*)0xdeadbeef;
3926 hr = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
3927 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
3928 ok( temp_node == NULL, "%p\n", temp_node );
3930 IXMLDOMNode_Release( lc_node );
3931 IXMLDOMNodeList_Release( root_list );
3932 IXMLDOMElement_Release( element );
3933 IXMLDOMDocument_Release( doc );
3935 free_bstrs();
3938 static void test_replaceChild(void)
3940 VARIANT_BOOL b;
3941 IXMLDOMDocument *doc;
3942 IXMLDOMElement *element, *ba_element;
3943 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
3944 IXMLDOMNodeList *root_list, *fo_list;
3945 IUnknown * unk1, *unk2;
3946 HRESULT hr;
3947 LONG len;
3949 doc = create_document(&IID_IXMLDOMDocument);
3951 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3952 ok(hr == S_OK, "loadXML failed\n");
3953 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3955 hr = IXMLDOMDocument_get_documentElement( doc, &element );
3956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3958 hr = IXMLDOMElement_get_childNodes( element, &root_list );
3959 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3961 hr = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3962 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3964 hr = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3965 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3967 hr = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3968 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3970 hr = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3973 IXMLDOMNodeList_Release( fo_list );
3975 /* invalid parameter: NULL ptr for element to remove */
3976 removed_node = (void*)0xdeadbeef;
3977 hr = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3978 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3979 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3981 /* invalid parameter: NULL for replacement element. (Sic!) */
3982 removed_node = (void*)0xdeadbeef;
3983 hr = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3984 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3985 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3987 /* invalid parameter: OldNode is not a child */
3988 removed_node = (void*)0xdeadbeef;
3989 hr = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3990 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3991 ok( removed_node == NULL, "%p\n", removed_node );
3992 IXMLDOMNode_Release( lc_node );
3994 /* invalid parameter: would create loop */
3995 removed_node = (void*)0xdeadbeef;
3996 hr = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3997 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3998 ok( removed_node == NULL, "%p\n", removed_node );
4000 hr = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
4001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4003 hr = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
4004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4006 /* ba_node and temp_node refer to the same node, yet they
4007 are different interface pointers */
4008 ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
4009 hr = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
4010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4011 hr = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
4012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4013 todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
4015 IUnknown_Release( unk1 );
4016 IUnknown_Release( unk2 );
4018 /* ba_node should have been removed from below fo_node */
4019 hr = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
4020 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4022 /* MS quirk: replaceChild also accepts elements instead of nodes */
4023 hr = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
4024 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4025 EXPECT_REF(ba_element, 2);
4027 removed_node = NULL;
4028 hr = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
4029 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4030 ok( removed_node != NULL, "got %p\n", removed_node);
4031 EXPECT_REF(ba_element, 3);
4032 IXMLDOMElement_Release( ba_element );
4034 hr = IXMLDOMNodeList_get_length( fo_list, &len);
4035 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4036 ok(len == 0, "len %ld\n", len);
4038 IXMLDOMNodeList_Release( fo_list );
4040 IXMLDOMNode_Release(ba_node);
4041 IXMLDOMNode_Release(fo_node);
4042 IXMLDOMNode_Release(temp_node);
4043 IXMLDOMNodeList_Release( root_list );
4044 IXMLDOMElement_Release( element );
4045 IXMLDOMDocument_Release( doc );
4047 free_bstrs();
4050 static void test_removeNamedItem(void)
4052 IXMLDOMDocument *doc;
4053 IXMLDOMElement *element;
4054 IXMLDOMNode *node, *removed_node, *removed_node2;
4055 IXMLDOMNodeList *root_list;
4056 IXMLDOMNamedNodeMap *map;
4057 VARIANT_BOOL b;
4058 HRESULT hr;
4059 BSTR str;
4060 LONG len;
4062 doc = create_document(&IID_IXMLDOMDocument);
4064 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4065 ok(hr == S_OK, "loadXML failed\n");
4066 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4068 hr = IXMLDOMDocument_get_documentElement( doc, &element );
4069 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4071 hr = IXMLDOMElement_get_childNodes( element, &root_list );
4072 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4074 hr = IXMLDOMNodeList_get_item( root_list, 1, &node );
4075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4077 hr = IXMLDOMNode_get_attributes( node, &map );
4078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4080 hr = IXMLDOMNamedNodeMap_get_length( map, &len );
4081 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4082 ok( len == 3, "length %ld\n", len);
4084 removed_node = (void*)0xdeadbeef;
4085 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, NULL, &removed_node );
4086 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4087 ok(removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4089 removed_node = (void*)0xdeadbeef;
4090 str = SysAllocString(L"vr");
4091 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, str, &removed_node );
4092 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4094 removed_node2 = (void*)0xdeadbeef;
4095 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, str, &removed_node2 );
4096 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4097 ok(removed_node2 == NULL, "got %p\n", removed_node2 );
4099 hr = IXMLDOMNamedNodeMap_get_length( map, &len );
4100 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4101 ok(len == 2, "length %ld\n", len);
4103 hr = IXMLDOMNamedNodeMap_setNamedItem( map, removed_node, NULL );
4104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4105 IXMLDOMNode_Release(removed_node);
4107 hr = IXMLDOMNamedNodeMap_get_length( map, &len );
4108 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4109 ok(len == 3, "length %ld\n", len);
4111 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, str, NULL );
4112 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4114 hr = IXMLDOMNamedNodeMap_get_length( map, &len );
4115 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4116 ok(len == 2, "length %ld\n", len);
4118 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, str, NULL );
4119 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4121 SysFreeString(str);
4123 IXMLDOMNamedNodeMap_Release( map );
4124 IXMLDOMNode_Release( node );
4125 IXMLDOMNodeList_Release( root_list );
4126 IXMLDOMElement_Release( element );
4128 /* test with namespaces */
4129 hr = IXMLDOMDocument_loadXML( doc, _bstr_(default_ns_doc), &b );
4130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4132 hr = IXMLDOMDocument_selectSingleNode( doc, _bstr_("a"), &node );
4133 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4135 hr = IXMLDOMNode_QueryInterface( node, &IID_IXMLDOMElement, (void**)&element );
4136 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4137 IXMLDOMNode_Release( node );
4139 hr = IXMLDOMElement_get_attributes( element, &map );
4140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4142 removed_node = (void*)0xdeadbeef;
4143 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, _bstr_("foo:bar"), &removed_node );
4144 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4145 ok ( removed_node == NULL, "got %p\n", removed_node );
4147 removed_node = NULL;
4148 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, _bstr_("d"), &removed_node );
4149 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4150 IXMLDOMNode_Release( removed_node );
4152 removed_node = NULL;
4153 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, _bstr_("ns:b"), &removed_node );
4154 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4155 IXMLDOMNode_Release( removed_node );
4157 removed_node = NULL;
4158 hr = IXMLDOMNamedNodeMap_removeNamedItem( map, _bstr_("xml:lang"), &removed_node );
4159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4160 IXMLDOMNode_Release( removed_node );
4162 len = -1;
4163 hr = IXMLDOMNamedNodeMap_get_length( map, &len );
4164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4165 ok( len == 2, "length %ld\n", len );
4167 IXMLDOMNamedNodeMap_Release( map );
4168 IXMLDOMElement_Release( element );
4169 IXMLDOMDocument_Release( doc );
4170 free_bstrs();
4173 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4174 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4175 HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4176 DWORD expected2)
4178 DWORD enabled, supported;
4179 HRESULT hr;
4181 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4182 if (result == result2)
4183 ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %#lx, returned %#lx\n", result, hr );
4184 else
4185 ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4186 "SetInterfaceSafetyOptions: expected %#lx, got %#lx\n", result2, hr );
4188 supported = enabled = 0xCAFECAFE;
4189 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4190 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4191 if (expected == expected2)
4192 ok_(__FILE__,line)(enabled == expected, "Expected %#lx, got %#lx\n", expected, enabled);
4193 else
4194 ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4195 "Expected %#lx, got %#lx\n", expected2, enabled);
4197 /* reset the safety options */
4199 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4200 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4202 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4204 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4205 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4206 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %#lx\n", enabled);
4209 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4210 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4212 DWORD enabled = 0, supported = 0;
4213 HRESULT hr;
4215 /* get */
4216 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4217 ok_(__FILE__,line)(hr == E_POINTER, "Unexpected hr %#lx.\n", hr );
4218 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4219 ok_(__FILE__,line)(hr == E_POINTER, "Unexpected hr %#lx.\n", hr );
4221 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4222 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4223 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4224 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4225 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4226 "got %#lx\n", supported);
4227 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %#lx\n", enabled);
4229 /* set -- individual flags */
4231 test_IObjectSafety_set(safety, S_OK, S_OK,
4232 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4233 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4235 test_IObjectSafety_set(safety, S_OK, S_OK,
4236 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4237 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4239 test_IObjectSafety_set(safety, S_OK, S_OK,
4240 INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4241 0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4243 /* set INTERFACE_USES_DISPEX */
4245 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4246 INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4247 0, 0);
4249 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4250 INTERFACE_USES_DISPEX, 0,
4251 0, 0);
4253 test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4254 0, INTERFACE_USES_DISPEX,
4255 0, 0);
4257 /* set option masking */
4259 test_IObjectSafety_set(safety, S_OK, S_OK,
4260 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4261 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4262 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4263 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4265 test_IObjectSafety_set(safety, S_OK, S_OK,
4266 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4267 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4268 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4269 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4271 test_IObjectSafety_set(safety, S_OK, S_OK,
4272 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4273 INTERFACE_USES_SECURITY_MANAGER,
4277 /* set -- inheriting previous settings */
4279 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4280 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4281 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4282 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4283 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4284 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4285 ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %#lx\n", enabled);
4286 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4287 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4288 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4289 "got %#lx.\n", supported);
4291 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4292 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4293 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4294 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4295 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4296 ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr );
4297 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4298 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4299 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %#lx\n", enabled);
4300 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4301 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4302 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4303 "got %#lx\n", supported);
4306 static void test_IXMLDOMDocument2(void)
4308 IXMLDOMDocument2 *doc2, *dtddoc2;
4309 IXMLDOMDocument *doc;
4310 IXMLDOMParseError* err;
4311 IDispatchEx *dispex;
4312 VARIANT_BOOL b;
4313 VARIANT var;
4314 HRESULT hr;
4315 LONG res;
4317 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4319 doc = create_document(&IID_IXMLDOMDocument);
4320 dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4322 hr = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4324 ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4326 hr = IXMLDOMDocument2_get_readyState(doc2, NULL);
4327 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4328 hr = IXMLDOMDocument2_get_readyState(doc2, &res);
4329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4330 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %ld\n", res);
4332 err = NULL;
4333 hr = IXMLDOMDocument2_validate(doc2, NULL);
4334 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4335 hr = IXMLDOMDocument2_validate(doc2, &err);
4336 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4337 ok(err != NULL, "expected a pointer\n");
4338 if (err)
4340 res = 0;
4341 hr = IXMLDOMParseError_get_errorCode(err, &res);
4342 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4343 /* XML_E_NOTWF */
4344 ok(res == E_XML_NOTWF, "Unexpected code %#lx.\n", res);
4345 IXMLDOMParseError_Release(err);
4348 hr = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b );
4349 ok(hr == S_OK, "loadXML failed\n");
4350 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4352 hr = IXMLDOMDocument_get_readyState(doc, &res);
4353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4354 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %ld\n", res);
4356 err = NULL;
4357 hr = IXMLDOMDocument2_validate(doc2, &err);
4358 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4359 ok(err != NULL, "expected a pointer\n");
4360 if (err)
4362 res = 0;
4363 hr = IXMLDOMParseError_get_errorCode(err, &res);
4364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4365 /* XML_E_NODTD */
4366 ok(res == E_XML_NODTD, "Unexpected code %#lx.\n", res);
4367 IXMLDOMParseError_Release(err);
4370 hr = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4372 if(hr == S_OK)
4373 IDispatchEx_Release(dispex);
4375 /* we will check if the variant got cleared */
4376 IXMLDOMDocument2_AddRef(doc2);
4377 EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4379 V_VT(&var) = VT_UNKNOWN;
4380 V_UNKNOWN(&var) = (IUnknown *)doc2;
4382 /* invalid calls */
4383 hr = IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var);
4384 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
4385 expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4386 hr = IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL);
4387 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4389 /* valid call */
4390 hr = IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var);
4391 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4392 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4393 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4394 V_VT(&var) = VT_R4;
4396 /* the variant didn't get cleared*/
4397 expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4399 /* setProperty tests */
4400 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var);
4401 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
4402 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var);
4403 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
4404 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk"));
4405 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
4406 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
4407 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4408 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
4409 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4410 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
4411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4413 V_VT(&var) = VT_BSTR;
4414 V_BSTR(&var) = SysAllocString(L"");
4415 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4416 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4417 VariantClear(&var);
4419 V_VT(&var) = VT_I2;
4420 V_I2(&var) = 0;
4421 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4422 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
4424 /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4425 hr = IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var);
4426 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4427 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4428 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4430 IXMLDOMDocument2_Release( doc2 );
4431 IXMLDOMDocument_Release( doc );
4433 /* DTD validation */
4434 hr = IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE);
4435 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4436 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b);
4437 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4438 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4439 err = NULL;
4440 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4441 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4442 ok(err != NULL, "expected pointer\n");
4443 if (err)
4445 res = 0;
4446 hr = IXMLDOMParseError_get_errorCode(err, &res);
4447 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4448 ok(res == 0, "Unexpected code %#lx.\n", res);
4449 IXMLDOMParseError_Release(err);
4452 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b);
4453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4454 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4455 err = NULL;
4456 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4457 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4458 ok(err != NULL, "expected pointer\n");
4459 if (err)
4461 res = 0;
4462 hr = IXMLDOMParseError_get_errorCode(err, &res);
4463 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4464 /* XML_ELEMENT_UNDECLARED */
4465 todo_wine ok(res == 0xC00CE00D, "Unexpected code %#lx.\n", res);
4466 IXMLDOMParseError_Release(err);
4469 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b);
4470 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4471 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4472 err = NULL;
4473 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4474 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4475 ok(err != NULL, "expected pointer\n");
4476 if (err)
4478 res = 0;
4479 hr = IXMLDOMParseError_get_errorCode(err, &res);
4480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4481 /* XML_ELEMENT_ID_NOT_FOUND */
4482 todo_wine ok(res == 0xC00CE00E, "Unexpected code %#lx.\n", res);
4483 IXMLDOMParseError_Release(err);
4486 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b);
4487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4488 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4489 err = NULL;
4490 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4491 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4492 ok(err != NULL, "expected pointer\n");
4493 if (err)
4495 res = 0;
4496 hr = IXMLDOMParseError_get_errorCode(err, &res);
4497 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4498 /* XML_EMPTY_NOT_ALLOWED */
4499 todo_wine ok(res == 0xC00CE011, "Unexpected code %#lx.\n", res);
4500 IXMLDOMParseError_Release(err);
4503 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b);
4504 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4505 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4506 err = NULL;
4507 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4508 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4509 ok(err != NULL, "expected pointer\n");
4510 if (err)
4512 res = 0;
4513 hr = IXMLDOMParseError_get_errorCode(err, &res);
4514 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4515 /* XML_ROOT_NAME_MISMATCH */
4516 todo_wine ok(res == 0xC00CE013, "Unexpected code %#lx.\n", res);
4517 IXMLDOMParseError_Release(err);
4520 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b);
4521 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4522 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4523 err = NULL;
4524 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4525 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4526 ok(err != NULL, "expected pointer\n");
4527 if (err)
4529 res = 0;
4530 hr = IXMLDOMParseError_get_errorCode(err, &res);
4531 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4532 /* XML_INVALID_CONTENT */
4533 todo_wine ok(res == 0xC00CE014, "Unexpected code %#lx.\n", res);
4534 IXMLDOMParseError_Release(err);
4537 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b);
4538 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4539 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4540 err = NULL;
4541 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4542 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4543 ok(err != NULL, "expected pointer\n");
4544 if (err)
4546 res = 0;
4547 hr = IXMLDOMParseError_get_errorCode(err, &res);
4548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4549 /* XML_ATTRIBUTE_NOT_DEFINED */
4550 todo_wine ok(res == 0xC00CE015, "Unexpected code %#lx.\n", res);
4551 IXMLDOMParseError_Release(err);
4554 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b);
4555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4556 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4557 err = NULL;
4558 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4559 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4560 ok(err != NULL, "expected pointer\n");
4561 if (err)
4563 res = 0;
4564 hr = IXMLDOMParseError_get_errorCode(err, &res);
4565 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4566 /* XML_ATTRIBUTE_FIXED */
4567 todo_wine ok(res == 0xC00CE016, "Unexpected code %#lx.\n", res);
4568 IXMLDOMParseError_Release(err);
4571 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b);
4572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4573 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4574 err = NULL;
4575 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4576 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4577 ok(err != NULL, "expected pointer\n");
4578 if (err)
4580 res = 0;
4581 hr = IXMLDOMParseError_get_errorCode(err, &res);
4582 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4583 /* XML_ATTRIBUTE_VALUE */
4584 todo_wine ok(res == 0xC00CE017, "Unexpected code %#lx.\n", res);
4585 IXMLDOMParseError_Release(err);
4588 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b);
4589 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4590 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4591 err = NULL;
4592 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4593 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4594 ok(err != NULL, "expected pointer\n");
4595 if (err)
4597 res = 0;
4598 hr = IXMLDOMParseError_get_errorCode(err, &res);
4599 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4600 /* XML_ILLEGAL_TEXT */
4601 todo_wine ok(res == 0xC00CE018, "Unexpected code %#lx.\n", res);
4602 IXMLDOMParseError_Release(err);
4605 hr = IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b);
4606 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4607 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4608 err = NULL;
4609 hr = IXMLDOMDocument2_validate(dtddoc2, &err);
4610 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
4611 ok(err != NULL, "expected pointer\n");
4612 if (err)
4614 res = 0;
4615 hr = IXMLDOMParseError_get_errorCode(err, &res);
4616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4617 /* XML_REQUIRED_ATTRIBUTE_MISSING */
4618 todo_wine ok(res == 0xC00CE020, "Unexpected code %#lx.\n", res);
4619 IXMLDOMParseError_Release(err);
4622 IXMLDOMDocument2_Release( dtddoc2 );
4623 free_bstrs();
4626 #define helper_ole_check_ver(expr) { \
4627 HRESULT hr = expr; \
4628 ok_(__FILE__, line)(hr == S_OK, "-> %i (%s): " #expr " returned %#lx.\n", __LINE__, ver, hr); \
4631 #define helper_expect_list_and_release(list, expstr) { \
4632 char *str = list_to_string(list); \
4633 ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i (%s): Invalid node list: %s, expected %s\n", __LINE__, ver, str, expstr); \
4634 if (list) IXMLDOMNodeList_Release(list); \
4637 #define helper_expect_bstr_and_release(bstr, str) { \
4638 ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
4639 "=> %i (%s): got %s\n", __LINE__, ver, wine_dbgstr_w(bstr)); \
4640 SysFreeString(bstr); \
4643 #define check_ws_ignored(ver, doc, str) _check_ws_ignored(__LINE__, ver, doc, str)
4644 static inline void _check_ws_ignored(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4646 IXMLDOMNode *node1, *node2;
4647 IXMLDOMNodeList *list;
4648 BSTR bstr;
4650 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4651 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4652 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4653 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4654 helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
4656 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4657 helper_expect_list_and_release(list,
4658 "[4]1.E1.E5.E1.E2.D1 T2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 "
4659 "E4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1 E6.E1.E5.E1.E2.D1");
4660 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4661 if (str)
4663 helper_expect_bstr_and_release(bstr, str);
4665 else
4667 helper_expect_bstr_and_release(bstr, " This is a description.");
4669 IXMLDOMNode_Release(node1);
4671 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4672 helper_expect_list_and_release(list,
4673 "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 "
4674 "E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
4675 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4676 helper_expect_bstr_and_release(bstr,
4677 "\n This is a description with preserved whitespace. \n ");
4678 IXMLDOMNode_Release(node2);
4681 #define check_ws_preserved(ver, doc, str) _check_ws_preserved(__LINE__, ver, doc, str)
4682 static inline void _check_ws_preserved(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4684 IXMLDOMNode *node1, *node2;
4685 IXMLDOMNodeList *list;
4686 BSTR bstr;
4688 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4689 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4690 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4691 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4692 helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
4694 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4695 helper_expect_list_and_release(list,
4696 "T1.E2.E10.E2.E2.D1 [4]2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 "
4697 "E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 "
4698 "E7.E2.E10.E2.E2.D1 E8.E2.E10.E2.E2.D1 T9.E2.E10.E2.E2.D1");
4699 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4700 if (str)
4702 helper_expect_bstr_and_release(bstr, str);
4704 else
4706 helper_expect_bstr_and_release(bstr, "\n This is a description. \n ");
4708 IXMLDOMNode_Release(node1);
4710 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4711 helper_expect_list_and_release(list,
4712 "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 "
4713 "E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
4714 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4715 helper_expect_bstr_and_release(bstr,
4716 "\n This is a description with preserved whitespace. \n ");
4717 IXMLDOMNode_Release(node2);
4720 static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
4722 IXMLDOMNodeList *list;
4723 IXMLDOMElement *root;
4724 IXMLDOMNode *node;
4725 const WCHAR *text;
4726 VARIANT_BOOL b;
4727 HRESULT hr;
4728 BSTR s;
4730 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, preserve);
4731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4733 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(charrefsxml), &b);
4734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4736 hr = IXMLDOMDocument2_get_documentElement(doc, &root);
4737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4739 hr = IXMLDOMElement_get_childNodes(root, &list);
4740 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4741 IXMLDOMElement_Release(root);
4743 text = preserve == VARIANT_TRUE ? L" Text A end " : L"Text A end";
4744 hr = IXMLDOMNodeList_get_item(list, 0, &node);
4745 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4746 hr = IXMLDOMNode_get_text(node, &s);
4747 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4748 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4749 SysFreeString(s);
4750 IXMLDOMNode_Release(node);
4752 text = preserve == VARIANT_TRUE ? L"AB C " : L"AB C";
4753 hr = IXMLDOMNodeList_get_item(list, 1, &node);
4754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4755 hr = IXMLDOMNode_get_text(node, &s);
4756 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4757 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4758 SysFreeString(s);
4759 IXMLDOMNode_Release(node);
4761 IXMLDOMNodeList_Release(list);
4764 struct whitespace_t {
4765 const CLSID *clsid;
4766 const char *name;
4769 static const struct whitespace_t whitespace_test_data[] = {
4770 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
4771 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
4772 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
4773 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
4774 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
4775 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
4776 { 0 }
4779 static void test_whitespace(void)
4781 const struct whitespace_t *class_ptr = whitespace_test_data;
4783 while (class_ptr->clsid)
4785 IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
4786 IXMLDOMNodeList *list;
4787 IXMLDOMElement *root;
4788 VARIANT_BOOL b;
4789 HRESULT hr;
4790 LONG len;
4792 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument2))
4794 class_ptr++;
4795 continue;
4798 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4799 &IID_IXMLDOMDocument2, (void**)&doc1);
4800 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4802 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4803 &IID_IXMLDOMDocument2, (void**)&doc2);
4804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4806 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE);
4807 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4808 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b);
4809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4810 ok(b == VARIANT_FALSE, "expected false\n");
4811 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b);
4812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4813 ok(b == VARIANT_TRUE, "expected true\n");
4815 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b);
4816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4817 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4818 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b);
4819 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4820 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4822 /* switch to XPath */
4823 hr = IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
4824 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4825 hr = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
4826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4828 check_ws_ignored(class_ptr->name, doc1, NULL);
4829 check_ws_preserved(class_ptr->name, doc2, NULL);
4831 /* new instances copy the property */
4832 hr = IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3);
4833 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4834 hr = IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4);
4835 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4837 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b);
4838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4839 ok(b == VARIANT_FALSE, "expected false\n");
4840 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b);
4841 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4842 ok(b == VARIANT_TRUE, "expected true\n");
4844 check_ws_ignored(class_ptr->name, doc3, NULL);
4845 check_ws_preserved(class_ptr->name, doc4, NULL);
4847 /* setting after loading xml affects trimming of leading/trailing ws only */
4848 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE);
4849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4850 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE);
4851 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4853 /* the trailing "\n " isn't there, because it was ws-only node */
4854 check_ws_ignored(class_ptr->name, doc1, " This is a description. ");
4855 check_ws_preserved(class_ptr->name, doc2, " This is a description.");
4857 /* it takes effect on reload */
4858 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b);
4859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4860 ok(b == VARIANT_TRUE, "expected true\n");
4861 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b);
4862 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4863 ok(b == VARIANT_FALSE, "expected false\n");
4865 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b);
4866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4867 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4868 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b);
4869 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4870 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4872 check_ws_preserved(class_ptr->name, doc1, NULL);
4873 check_ws_ignored(class_ptr->name, doc2, NULL);
4875 /* other instances follow suit */
4876 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b);
4877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4878 ok(b == VARIANT_TRUE, "expected true\n");
4879 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b);
4880 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4881 ok(b == VARIANT_FALSE, "expected false\n");
4883 check_ws_preserved(class_ptr->name, doc3, NULL);
4884 check_ws_ignored(class_ptr->name, doc4, NULL);
4886 IXMLDOMDocument2_Release(doc2);
4887 IXMLDOMDocument2_Release(doc3);
4888 IXMLDOMDocument2_Release(doc4);
4890 /* text with char references */
4891 test_preserve_charref(doc1, VARIANT_TRUE);
4892 test_preserve_charref(doc1, VARIANT_FALSE);
4894 /* formatting whitespaces */
4895 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
4896 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4898 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
4899 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4900 ok(b == VARIANT_TRUE, "for %x\n", b);
4902 hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
4903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4904 hr = IXMLDOMElement_get_childNodes(root, &list);
4905 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4906 len = 0;
4907 hr = IXMLDOMNodeList_get_length(list, &len);
4908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4909 ok(len == 3, "got %ld\n", len);
4910 IXMLDOMNodeList_Release(list);
4911 IXMLDOMElement_Release(root);
4913 IXMLDOMDocument2_Release(doc1);
4915 free_bstrs();
4917 class_ptr++;
4921 typedef struct {
4922 const GUID *clsid;
4923 const char *name;
4924 const char *ns;
4925 HRESULT hr;
4926 } selection_ns_t;
4928 /* supposed to be tested with szExampleXML */
4929 static const selection_ns_t selection_ns_data[] = {
4930 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4931 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4932 { &CLSID_DOMDocument, "CLSID_DOMDocument", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4933 { &CLSID_DOMDocument, "CLSID_DOMDocument", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4935 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4936 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4937 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4938 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4940 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4941 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4942 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4943 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4945 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4946 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4947 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4948 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4950 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4951 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4952 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4953 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4955 { NULL }
4958 typedef struct {
4959 const char *query;
4960 const char *list;
4961 } xpath_test_t;
4963 static const xpath_test_t xpath_test[] = {
4964 { "*/a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4965 { "*/b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4966 { "*/c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4967 { "*/d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4968 { "//a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4969 { "//b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4970 { "//c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4971 { "//d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4972 { "//c[@type]", "E3.E2.E2.D1" },
4973 { "//c[@type]/ancestor::node()[1]", "E2.E2.D1" },
4974 { "//c[@type]/ancestor-or-self::node()[1]", "E3.E2.E2.D1" },
4975 { "//c[@type]/attribute::node()[1]", "A'type'.E3.E2.E2.D1" },
4976 { "//c[@type]/child::node()[1]", "T1.E3.E2.E2.D1" },
4977 { "//c[@type]/descendant::node()[1]", "T1.E3.E2.E2.D1" },
4978 { "//c[@type]/descendant-or-self::node()[1]", "E3.E2.E2.D1" },
4979 { "//c[@type]/following::node()[1]", "E4.E2.E2.D1" },
4980 { "//c[@type]/following-sibling::node()[1]", "E4.E2.E2.D1" },
4981 { "//c[@type]/parent::node()[1]", "E2.E2.D1" },
4982 { "//c[@type]/preceding::node()[1]", "T1.E2.E2.E2.D1" },
4983 { "//c[@type]/self::node()[1]", "E3.E2.E2.D1" },
4984 { "child::*", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4985 { "child::node()", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4986 { "child::text()", "" },
4987 { "child::*/..", "E2.D1" },
4988 { "child::*//@*/..", "E2.E5.E1.E2.D1 E2.E2.D1 E3.E2.E2.D1" },
4989 { "self::node()", "E2.D1" },
4990 { "ancestor::node()", "D1" },
4991 { "elem[c][last()]/a", "E1.E2.E2.D1"},
4992 { "ancestor-or-self::node()[1]", "E2.D1" },
4993 { "((//a)[1])[last()]", "E1.E1.E2.D1" },
4994 { "//elem[@*]", "E2.E2.D1" },
4995 { NULL }
4998 static void test_XPath(void)
5000 const selection_ns_t *ptr = selection_ns_data;
5001 const xpath_test_t *xptest = xpath_test;
5002 VARIANT var;
5003 VARIANT_BOOL b;
5004 IXMLDOMDocument2 *doc;
5005 IXMLDOMDocument *doc2;
5006 IXMLDOMNode *rootNode;
5007 IXMLDOMNode *elem1Node;
5008 IXMLDOMNode *node;
5009 IXMLDOMNodeList *list;
5010 IXMLDOMElement *elem;
5011 IXMLDOMAttribute *attr;
5012 DOMNodeType type;
5013 HRESULT hr;
5014 LONG len;
5015 BSTR str;
5017 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
5018 doc = create_document(&IID_IXMLDOMDocument2);
5020 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5022 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5024 /* switch to XPath */
5025 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5026 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5028 /* some simple queries*/
5029 EXPECT_REF(doc, 1);
5030 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5031 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5032 EXPECT_REF(doc, 1);
5033 EXPECT_LIST_LEN(list, 1);
5035 EXPECT_REF(list, 1);
5036 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5037 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5038 EXPECT_REF(list, 1);
5039 EXPECT_REF(rootNode, 1);
5041 hr = IXMLDOMNodeList_reset(list);
5042 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5043 expect_list_and_release(list, "E2.D1");
5045 /* perform xpath tests */
5046 for ( ; xptest->query ; xptest++ )
5048 char *str;
5050 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(xptest->query), &list);
5051 ok(hr == S_OK, "query evaluation failed for query=%s\n", xptest->query);
5053 if (hr != S_OK)
5054 continue;
5056 str = list_to_string(list);
5058 ok(!strcmp(str, xptest->list), "query=%s, invalid node list: \"%s\", expected \"%s\"\n",
5059 xptest->query, str, xptest->list);
5061 if (list)
5062 IXMLDOMNodeList_Release(list);
5065 if (0)
5067 /* namespace:: axis test is disabled until namespace definitions
5068 are supported as attribute nodes, currently it's another node type */
5069 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
5070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5071 len = -1;
5072 hr = IXMLDOMNodeList_get_length(list, &len);
5073 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5074 ok(len == 2, "got %ld\n", len);
5076 hr = IXMLDOMNodeList_nextNode(list, &node);
5077 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5078 type = NODE_INVALID;
5079 hr = IXMLDOMNode_get_nodeType(node, &type);
5080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5081 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
5082 IXMLDOMNode_Release(node);
5084 IXMLDOMNodeList_Release(list);
5087 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list);
5088 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5089 expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
5091 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list);
5092 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5093 expect_list_and_release(list, "E3.E2.E2.D1");
5095 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list);
5096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5097 /* using get_item for query results advances the position */
5098 hr = IXMLDOMNodeList_get_item(list, 1, &node);
5099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5100 expect_node(node, "E2.E2.D1");
5101 IXMLDOMNode_Release(node);
5102 hr = IXMLDOMNodeList_nextNode(list, &node);
5103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5104 expect_node(node, "E4.E2.D1");
5105 IXMLDOMNode_Release(node);
5106 hr = IXMLDOMNodeList_reset(list);
5107 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5108 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
5110 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list);
5111 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5112 expect_list_and_release(list, "E2.D1");
5114 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list);
5115 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5116 hr = IXMLDOMNodeList_get_item(list, 0, &elem1Node);
5117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5118 hr = IXMLDOMNodeList_reset(list);
5119 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5120 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
5122 /* select an attribute */
5123 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list);
5124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5125 expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
5127 /* would evaluate to a number */
5128 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list);
5129 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5130 /* would evaluate to a boolean */
5131 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list);
5132 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5133 /* would evaluate to a string */
5134 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list);
5135 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5137 /* no results */
5138 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list);
5139 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5140 expect_list_and_release(list, "");
5141 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("elem//c"), &list);
5142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5143 expect_list_and_release(list, "");
5144 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem[4]"), &list);
5145 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5146 expect_list_and_release(list, "");
5147 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list);
5148 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5149 expect_list_and_release(list, "");
5151 /* foo undeclared in document node */
5152 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list);
5153 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5154 /* undeclared in <root> node */
5155 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list);
5156 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5157 /* undeclared in <elem> node */
5158 hr = IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list);
5159 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5160 /* but this trick can be used */
5161 hr = IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list);
5162 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5163 expect_list_and_release(list, "E3.E4.E2.D1");
5165 /* it has to be declared in SelectionNamespaces */
5166 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5167 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'"));
5168 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5170 /* now the namespace can be used */
5171 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5172 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5173 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5174 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list);
5175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5176 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5177 hr = IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list);
5178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5179 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5180 hr = IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list);
5181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5182 expect_list_and_release(list, "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
5184 /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
5185 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5186 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###"));
5187 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5189 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list);
5190 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5192 VariantInit(&var);
5193 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5195 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
5196 if (V_VT(&var) == VT_BSTR)
5197 expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
5199 /* extra attributes - same thing*/
5200 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
5201 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'"));
5202 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5203 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list);
5204 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5206 IXMLDOMNode_Release(rootNode);
5207 IXMLDOMNode_Release(elem1Node);
5209 /* alter document with already built list */
5210 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5211 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5212 EXPECT_LIST_LEN(list, 1);
5214 hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5215 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5216 EXPECT_REF(rootNode, 1);
5217 EXPECT_REF(doc, 1);
5219 hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5220 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5221 IXMLDOMNode_Release(rootNode);
5223 EXPECT_LIST_LEN(list, 1);
5225 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5226 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5227 EXPECT_REF(rootNode, 1);
5229 IXMLDOMNodeList_Release(list);
5231 hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5233 ok(!lstrcmpW(str, L"root"), "got %s\n", wine_dbgstr_w(str));
5234 SysFreeString(str);
5235 IXMLDOMNode_Release(rootNode);
5237 /* alter node from list and get it another time */
5238 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5239 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5240 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5242 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5244 EXPECT_LIST_LEN(list, 1);
5246 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5247 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5249 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5250 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5252 V_VT(&var) = VT_I2;
5253 V_I2(&var) = 1;
5254 hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5256 IXMLDOMElement_Release(elem);
5257 IXMLDOMNode_Release(rootNode);
5259 /* now check attribute to be present */
5260 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5263 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5266 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5268 IXMLDOMAttribute_Release(attr);
5270 IXMLDOMElement_Release(elem);
5271 IXMLDOMNode_Release(rootNode);
5273 /* and now check for attribute in original document */
5274 hr = IXMLDOMDocument2_get_documentElement(doc, &elem);
5275 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5277 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5278 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5279 IXMLDOMAttribute_Release(attr);
5281 IXMLDOMElement_Release(elem);
5283 /* attach node from list to another document */
5284 doc2 = create_document(&IID_IXMLDOMDocument);
5286 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5288 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5290 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5291 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5292 EXPECT_LIST_LEN(list, 1);
5294 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5296 EXPECT_REF(rootNode, 1);
5298 hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5300 EXPECT_REF(rootNode, 1);
5301 EXPECT_REF(doc2, 1);
5302 EXPECT_REF(list, 1);
5304 EXPECT_LIST_LEN(list, 1);
5306 IXMLDOMNode_Release(rootNode);
5307 IXMLDOMNodeList_Release(list);
5308 IXMLDOMDocument_Release(doc2);
5309 IXMLDOMDocument2_Release(doc);
5311 while (ptr->clsid)
5313 if (is_clsid_supported(ptr->clsid, &IID_IXMLDOMDocument2))
5315 hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5316 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5318 else
5320 ptr++;
5321 continue;
5324 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5326 ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5328 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5331 V_VT(&var) = VT_BSTR;
5332 V_BSTR(&var) = _bstr_(ptr->ns);
5334 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5335 ok(hr == ptr->hr, "Unexpected hr %#lx., for %s, %s\n", hr, ptr->name, ptr->ns);
5337 V_VT(&var) = VT_EMPTY;
5338 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5340 ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5341 ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5342 VariantClear(&var);
5344 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5346 if (hr == S_OK)
5347 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5349 IXMLDOMDocument2_Release(doc);
5350 ptr++;
5351 free_bstrs();
5354 free_bstrs();
5357 static void test_cloneNode(void )
5359 IXMLDOMDocument2 *doc, *doc_clone;
5360 IXMLDOMDocument *doc2;
5361 VARIANT_BOOL b;
5362 IXMLDOMNodeList *pList;
5363 IXMLDOMNamedNodeMap *mapAttr;
5364 LONG length, length1;
5365 LONG attr_cnt, attr_cnt1;
5366 IXMLDOMNode *node, *attr;
5367 IXMLDOMNode *node_clone;
5368 IXMLDOMNode *node_first;
5369 VARIANT v;
5370 HRESULT hr;
5372 doc = create_document(&IID_IXMLDOMDocument2);
5374 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b);
5375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5376 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5378 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v);
5379 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5380 ok(!lstrcmpW(V_BSTR(&v), L"XSLPattern"), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5381 VariantClear(&v);
5383 V_BSTR(&v) = _bstr_("XPath");
5384 V_VT(&v) = VT_BSTR;
5385 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v);
5386 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5388 /* clone document node */
5389 hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node);
5390 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5391 ok( node != NULL, "node %p\n", node );
5393 hr = IXMLDOMNode_get_childNodes(node, &pList);
5394 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5395 length = 0;
5396 hr = IXMLDOMNodeList_get_length(pList, &length);
5397 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5398 ok(length == 2, "got %ld\n", length);
5399 IXMLDOMNodeList_Release(pList);
5401 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone);
5402 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5404 /* cloned document inherits properties */
5405 hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v);
5406 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5407 ok(!lstrcmpW(V_BSTR(&v), L"XPath"), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5408 VariantClear(&v);
5410 IXMLDOMDocument2_Release(doc_clone);
5411 IXMLDOMNode_Release(node);
5413 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5414 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5415 ok( node != NULL, "node %p\n", node );
5417 /* Check invalid parameter */
5418 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5419 ok( hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5421 /* All Children */
5422 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5423 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5424 ok( node_clone != NULL, "node %p\n", node );
5426 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5427 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5428 hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5429 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5430 IXMLDOMDocument_Release(doc2);
5431 IXMLDOMNode_Release(node_first);
5433 hr = IXMLDOMNode_get_childNodes(node, &pList);
5434 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5435 length = 0;
5436 hr = IXMLDOMNodeList_get_length(pList, &length);
5437 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5438 ok(length == 1, "got %ld\n", length);
5439 IXMLDOMNodeList_Release(pList);
5441 hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5442 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5443 attr_cnt = 0;
5444 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5445 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5446 ok(attr_cnt == 3, "got %ld\n", attr_cnt);
5447 IXMLDOMNamedNodeMap_Release(mapAttr);
5449 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5450 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5451 length1 = 0;
5452 hr = IXMLDOMNodeList_get_length(pList, &length1);
5453 ok(length1 == 1, "got %ld\n", length1);
5454 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5455 IXMLDOMNodeList_Release(pList);
5457 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5458 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5459 attr_cnt1 = 0;
5460 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5461 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5462 ok(attr_cnt1 == 3, "got %ld\n", attr_cnt1);
5463 /* now really get some attributes from cloned element */
5464 attr = NULL;
5465 hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr);
5466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5467 IXMLDOMNode_Release(attr);
5468 IXMLDOMNamedNodeMap_Release(mapAttr);
5470 ok(length == length1, "wrong Child count (%ld, %ld)\n", length, length1);
5471 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%ld, %ld)\n", attr_cnt, attr_cnt1);
5472 IXMLDOMNode_Release(node_clone);
5474 /* No Children */
5475 hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5476 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr );
5477 ok( node_clone != NULL, "node %p\n", node );
5479 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5480 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5482 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5484 hr = IXMLDOMNodeList_get_length(pList, &length1);
5485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5486 ok( length1 == 0, "Length should be 0 (%ld)\n", length1);
5487 IXMLDOMNodeList_Release(pList);
5489 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5491 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5492 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5493 ok(attr_cnt1 == 3, "Attribute count should be 3 (%ld)\n", attr_cnt1);
5494 IXMLDOMNamedNodeMap_Release(mapAttr);
5496 ok(length != length1, "wrong Child count (%ld, %ld)\n", length, length1);
5497 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%ld, %ld)\n", attr_cnt, attr_cnt1);
5498 IXMLDOMNode_Release(node_clone);
5500 IXMLDOMNode_Release(node);
5501 IXMLDOMDocument2_Release(doc);
5502 free_bstrs();
5505 static void test_xmlTypes(void)
5507 IXMLDOMDocument *doc;
5508 IXMLDOMElement *pRoot;
5509 HRESULT hr;
5510 IXMLDOMComment *pComment;
5511 IXMLDOMElement *pElement;
5512 IXMLDOMAttribute *pAttribute;
5513 IXMLDOMNamedNodeMap *pAttribs;
5514 IXMLDOMCDATASection *pCDataSec;
5515 IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5516 IXMLDOMDocumentFragment *pDocFrag = NULL;
5517 IXMLDOMEntityReference *pEntityRef = NULL;
5518 BSTR str;
5519 IXMLDOMNode *pNextChild;
5520 VARIANT v;
5521 LONG len = 0;
5523 doc = create_document(&IID_IXMLDOMDocument);
5525 hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5526 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5528 pNextChild = (void*)0xdeadbeef;
5529 hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5530 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5531 ok(pNextChild == NULL, "pDocChild not NULL\n");
5533 /* test previous Sibling */
5534 hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5535 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5537 pNextChild = (void*)0xdeadbeef;
5538 hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5539 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5540 ok(pNextChild == NULL, "pNextChild not NULL\n");
5542 /* test get_dataType */
5543 V_VT(&v) = VT_EMPTY;
5544 hr = IXMLDOMDocument_get_dataType(doc, &v);
5545 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5546 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5547 VariantClear(&v);
5549 /* test implementation */
5550 hr = IXMLDOMDocument_get_implementation(doc, NULL);
5551 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5553 hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5554 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5555 if(hr == S_OK)
5557 VARIANT_BOOL hasFeature = VARIANT_TRUE;
5558 BSTR sEmpty = SysAllocStringLen(NULL, 0);
5560 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5561 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5563 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5564 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5566 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5567 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5568 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5570 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5571 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5572 ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5574 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5576 ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5578 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5579 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5580 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5582 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5583 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5584 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5586 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5588 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5590 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5591 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5592 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5594 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5595 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5596 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5598 SysFreeString(sEmpty);
5599 IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5602 pRoot = (IXMLDOMElement*)0x1;
5603 hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5604 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5605 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5607 pRoot = (IXMLDOMElement*)0x1;
5608 hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5609 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
5610 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5612 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5614 if(hr == S_OK)
5616 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5618 if(hr == S_OK)
5620 /* Comment */
5621 str = SysAllocString(L"A Comment");
5622 hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5623 SysFreeString(str);
5624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5625 if(hr == S_OK)
5627 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5628 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5630 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5631 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5632 ok( !lstrcmpW( str, L"#comment" ), "incorrect comment node Name\n");
5633 SysFreeString(str);
5635 hr = IXMLDOMComment_get_xml(pComment, &str);
5636 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5637 ok( !lstrcmpW( str, L"<!--A Comment-->" ), "incorrect comment xml\n");
5638 SysFreeString(str);
5640 /* put data Tests */
5641 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5644 /* get data Tests */
5645 hr = IXMLDOMComment_get_data(pComment, &str);
5646 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5647 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect get_data string\n");
5648 SysFreeString(str);
5650 /* Confirm XML text is good */
5651 hr = IXMLDOMComment_get_xml(pComment, &str);
5652 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5653 ok(!lstrcmpW(str, L"<!--This &is a ; test <>\\-->"), "incorrect xml string\n");
5654 SysFreeString(str);
5656 /* Confirm we get the put_data Text back */
5657 hr = IXMLDOMComment_get_text(pComment, &str);
5658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5659 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect xml string\n");
5660 SysFreeString(str);
5662 /* test length property */
5663 hr = IXMLDOMComment_get_length(pComment, &len);
5664 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5665 ok(len == 21, "expected 21 got %ld\n", len);
5667 /* test substringData */
5668 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5669 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5671 /* test substringData - Invalid offset */
5672 str = (void *)0xdeadbeef;
5673 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5674 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5675 ok( str == NULL, "incorrect string\n");
5677 /* test substringData - Invalid offset */
5678 str = (void *)0xdeadbeef;
5679 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5680 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5681 ok( str == NULL, "incorrect string\n");
5683 /* test substringData - Invalid size */
5684 str = (void *)0xdeadbeef;
5685 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5686 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5687 ok( str == NULL, "incorrect string\n");
5689 /* test substringData - Invalid size */
5690 str = (void *)0xdeadbeef;
5691 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5692 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5693 ok( str == NULL, "incorrect string\n");
5695 /* test substringData - Start of string */
5696 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5698 ok(!lstrcmpW(str, L"This"), "incorrect substringData string\n");
5699 SysFreeString(str);
5701 /* test substringData - Middle of string */
5702 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5703 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5704 ok(!lstrcmpW(str, L"test"), "incorrect substringData string\n");
5705 SysFreeString(str);
5707 /* test substringData - End of string */
5708 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5709 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5710 ok(!lstrcmpW(str, L"\\"), "incorrect substringData string\n");
5711 SysFreeString(str);
5713 /* test appendData */
5714 hr = IXMLDOMComment_appendData(pComment, NULL);
5715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5717 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5720 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5721 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5723 hr = IXMLDOMComment_get_text(pComment, &str);
5724 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5725 ok(!lstrcmpW(str, L"This &is a ; test <>\\Append"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5726 SysFreeString(str);
5728 /* test insertData */
5729 str = SysAllocStringLen(NULL, 0);
5730 hr = IXMLDOMComment_insertData(pComment, -1, str);
5731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5733 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5736 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5739 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5740 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5742 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5745 hr = IXMLDOMComment_insertData(pComment, 0, str);
5746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5747 SysFreeString(str);
5749 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5750 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5752 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5753 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5755 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5756 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5758 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5759 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5761 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5764 hr = IXMLDOMComment_get_text(pComment, &str);
5765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5766 ok(!lstrcmpW(str, L"Begin This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5767 SysFreeString(str);
5769 /* delete data */
5770 /* invalid arguments */
5771 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
5772 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5774 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
5775 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5777 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
5778 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5780 hr = IXMLDOMComment_get_length(pComment, &len);
5781 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5782 ok(len == 43, "expected 43 got %ld\n", len);
5784 hr = IXMLDOMComment_deleteData(pComment, len, 1);
5785 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5787 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
5788 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5790 /* delete from start */
5791 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
5792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5794 hr = IXMLDOMComment_get_length(pComment, &len);
5795 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5796 ok(len == 38, "expected 38 got %ld\n", len);
5798 hr = IXMLDOMComment_get_text(pComment, &str);
5799 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5800 ok(!lstrcmpW(str, L" This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5801 SysFreeString(str);
5803 /* delete from end */
5804 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
5805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5807 hr = IXMLDOMComment_get_length(pComment, &len);
5808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5809 ok(len == 35, "expected 35 got %ld\n", len);
5811 hr = IXMLDOMComment_get_text(pComment, &str);
5812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5813 ok(!lstrcmpW(str, L" This &is a Middle; test <>\\Append "), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5814 SysFreeString(str);
5816 /* delete from inside */
5817 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
5818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5820 hr = IXMLDOMComment_get_length(pComment, &len);
5821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5822 ok(len == 2, "expected 2 got %ld\n", len);
5824 hr = IXMLDOMComment_get_text(pComment, &str);
5825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5826 ok(!lstrcmpW(str, L" "), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5827 SysFreeString(str);
5829 /* delete whole data ... */
5830 hr = IXMLDOMComment_get_length(pComment, &len);
5831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5833 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5834 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5835 /* ... and try again with empty string */
5836 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5837 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5839 /* ::replaceData() */
5840 V_VT(&v) = VT_BSTR;
5841 V_BSTR(&v) = SysAllocString(L"str1");
5842 hr = IXMLDOMComment_put_nodeValue(pComment, v);
5843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5844 VariantClear(&v);
5846 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
5847 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5848 hr = IXMLDOMComment_get_text(pComment, &str);
5849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5850 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5851 SysFreeString(str);
5853 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
5854 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5855 hr = IXMLDOMComment_get_text(pComment, &str);
5856 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5857 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5858 SysFreeString(str);
5860 /* NULL pointer means delete */
5861 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
5862 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5863 hr = IXMLDOMComment_get_text(pComment, &str);
5864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5865 ok(!lstrcmpW(str, L"tr1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5866 SysFreeString(str);
5868 /* empty string means delete */
5869 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
5870 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5871 hr = IXMLDOMComment_get_text(pComment, &str);
5872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5873 ok(!lstrcmpW(str, L"r1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5874 SysFreeString(str);
5876 /* zero count means insert */
5877 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
5878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5879 hr = IXMLDOMComment_get_text(pComment, &str);
5880 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5881 ok(!lstrcmpW(str, L"ar1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5882 SysFreeString(str);
5884 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
5885 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5887 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
5888 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5889 hr = IXMLDOMComment_get_text(pComment, &str);
5890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5891 ok(!lstrcmpW(str, L"m1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5892 SysFreeString(str);
5894 /* nonempty string, count greater than its length */
5895 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
5896 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5897 hr = IXMLDOMComment_get_text(pComment, &str);
5898 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5899 ok(!lstrcmpW(str, L"a1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5900 SysFreeString(str);
5902 /* nonempty string, count less than its length */
5903 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
5904 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5905 hr = IXMLDOMComment_get_text(pComment, &str);
5906 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5907 ok(!lstrcmpW(str, L"wine1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
5908 SysFreeString(str);
5910 IXMLDOMComment_Release(pComment);
5913 /* Element */
5914 str = SysAllocString(L"EleTest");
5915 hr = IXMLDOMDocument_createElement(doc, str, &pElement);
5916 SysFreeString(str);
5917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5918 if(hr == S_OK)
5920 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5923 hr = IXMLDOMElement_get_nodeName(pElement, &str);
5924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5925 ok( !lstrcmpW( str, L"EleTest" ), "incorrect element node Name\n");
5926 SysFreeString(str);
5928 hr = IXMLDOMElement_get_xml(pElement, &str);
5929 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5930 ok( !lstrcmpW( str, L"<EleTest/>" ), "incorrect element xml\n");
5931 SysFreeString(str);
5933 /* Attribute */
5934 pAttribute = (IXMLDOMAttribute*)0x1;
5935 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
5936 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5937 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5939 pAttribute = (IXMLDOMAttribute*)0x1;
5940 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
5941 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
5942 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5944 str = SysAllocString(L"Attr");
5945 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
5946 SysFreeString(str);
5947 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5948 if(hr == S_OK)
5950 IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
5952 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
5953 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5955 pNextChild = (IXMLDOMNode *)0x1;
5956 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
5957 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5958 ok(pNextChild == NULL, "pNextChild not NULL\n");
5960 /* test Previous Sibling*/
5961 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
5962 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
5964 pNextChild = (IXMLDOMNode *)0x1;
5965 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
5966 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
5967 ok(pNextChild == NULL, "pNextChild not NULL\n");
5969 hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
5970 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
5971 ok(pNewChild == NULL, "pNewChild not NULL\n");
5973 hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
5974 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5975 if ( hr == S_OK )
5977 hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
5978 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5980 IXMLDOMNamedNodeMap_Release(pAttribs);
5983 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5984 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5985 ok( !lstrcmpW( str, L"Attr" ), "incorrect attribute node Name\n");
5986 SysFreeString(str);
5988 /* test nodeName */
5989 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5991 ok( !lstrcmpW( str, L"Attr" ), "incorrect nodeName string\n");
5992 SysFreeString(str);
5994 /* test name property */
5995 hr = IXMLDOMAttribute_get_name(pAttribute, &str);
5996 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
5997 ok( !lstrcmpW( str, L"Attr" ), "incorrect name string\n");
5998 SysFreeString(str);
6000 hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
6001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6002 ok( !lstrcmpW( str, L"Attr=\"\"" ), "incorrect attribute xml\n");
6003 SysFreeString(str);
6005 IXMLDOMAttribute_Release(pAttribute);
6007 /* Check Element again with the Add Attribute*/
6008 hr = IXMLDOMElement_get_xml(pElement, &str);
6009 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6010 ok( !lstrcmpW( str, L"<EleTest Attr=\"\"/>" ), "incorrect element xml\n");
6011 SysFreeString(str);
6014 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
6015 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6017 hr = IXMLDOMElement_get_xml(pElement, &str);
6018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6019 ok( !lstrcmpW( str, L"<EleTest Attr=\"\">TestingNode</EleTest>" ), "incorrect element xml\n");
6020 SysFreeString(str);
6022 /* Test for reversible escaping */
6023 str = SysAllocString( szStrangeChars );
6024 hr = IXMLDOMElement_put_text(pElement, str);
6025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6026 SysFreeString( str );
6028 hr = IXMLDOMElement_get_xml(pElement, &str);
6029 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6030 ok( !lstrcmpW( str, L"<EleTest Attr=\"\">&amp;x \x2103</EleTest>" ), "incorrect element xml\n");
6031 SysFreeString(str);
6033 hr = IXMLDOMElement_get_text(pElement, &str);
6034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6035 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
6036 SysFreeString(str);
6038 IXMLDOMElement_Release(pElement);
6041 /* CData Section */
6042 str = SysAllocString(L"[1]*2=3; &gee that is not right!");
6043 hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
6044 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6046 hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
6047 SysFreeString(str);
6048 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6049 if(hr == S_OK)
6051 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
6052 VARIANT var;
6054 VariantInit(&var);
6056 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
6057 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
6059 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
6060 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6062 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
6063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6064 ok( !lstrcmpW( str, L"#cdata-section" ), "incorrect cdata node Name\n");
6065 SysFreeString(str);
6067 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6068 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6069 ok( !lstrcmpW( str, L"<![CDATA[[1]*2=3; &gee that is not right!]]>" ), "incorrect cdata xml\n");
6070 SysFreeString(str);
6072 /* test lastChild */
6073 pNextChild = (IXMLDOMNode*)0x1;
6074 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
6075 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6076 ok(pNextChild == NULL, "pNextChild not NULL\n");
6078 /* put data Tests */
6079 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
6080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6082 /* Confirm XML text is good */
6083 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
6084 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6085 ok(!lstrcmpW(str, L"<![CDATA[This &is a ; test <>\\]]>"), "incorrect xml string\n");
6086 SysFreeString(str);
6088 /* Confirm we get the put_data Text back */
6089 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6090 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6091 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect text string\n");
6092 SysFreeString(str);
6094 /* test length property */
6095 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6097 ok(len == 21, "expected 21 got %ld\n", len);
6099 /* test get data */
6100 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
6101 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6102 ok(!lstrcmpW(str, L"This &is a ; test <>\\"), "incorrect text string\n");
6103 SysFreeString(str);
6105 /* test substringData */
6106 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
6107 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6109 /* test substringData - Invalid offset */
6110 str = (void *)0xdeadbeef;
6111 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
6112 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6113 ok( str == NULL, "incorrect string\n");
6115 /* test substringData - Invalid offset */
6116 str = (void *)0xdeadbeef;
6117 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
6118 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6119 ok( str == NULL, "incorrect string\n");
6121 /* test substringData - Invalid size */
6122 str = (void *)0xdeadbeef;
6123 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
6124 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6125 ok( str == NULL, "incorrect string\n");
6127 /* test substringData - Invalid size */
6128 str = (void *)0xdeadbeef;
6129 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
6130 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6131 ok( str == NULL, "incorrect string\n");
6133 /* test substringData - Start of string */
6134 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
6135 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6136 ok(!lstrcmpW(str, L"This"), "incorrect substringData string\n");
6137 SysFreeString(str);
6139 /* test substringData - Middle of string */
6140 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
6141 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6142 ok(!lstrcmpW(str, L"test"), "incorrect substringData string\n");
6143 SysFreeString(str);
6145 /* test substringData - End of string */
6146 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
6147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6148 ok(!lstrcmpW(str, L"\\"), "incorrect substringData string\n");
6149 SysFreeString(str);
6151 /* test appendData */
6152 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
6153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6155 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
6156 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6158 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
6159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6161 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6162 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6163 ok(!lstrcmpW(str, L"This &is a ; test <>\\Append"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6164 SysFreeString(str);
6166 /* test insertData */
6167 str = SysAllocStringLen(NULL, 0);
6168 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
6169 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6171 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
6172 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6174 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
6175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6177 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
6178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6180 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
6181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6183 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
6184 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6185 SysFreeString(str);
6187 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
6188 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6190 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
6191 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6193 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
6194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6196 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
6197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6199 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
6200 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6202 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6203 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6204 ok(!lstrcmpW(str, L"Begin This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6205 SysFreeString(str);
6207 /* delete data */
6208 /* invalid arguments */
6209 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
6210 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6212 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6215 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6216 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6218 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6219 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6220 ok(len == 43, "expected 43 got %ld\n", len);
6222 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6223 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6225 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6226 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6228 /* delete from start */
6229 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6230 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6232 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6234 ok(len == 38, "expected 38 got %ld\n", len);
6236 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6238 ok(!lstrcmpW(str, L" This &is a Middle; test <>\\Append End"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6239 SysFreeString(str);
6241 /* delete from end */
6242 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6245 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6246 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6247 ok(len == 35, "expected 35 got %ld\n", len);
6249 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6250 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6251 ok(!lstrcmpW(str, L" This &is a Middle; test <>\\Append "), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6252 SysFreeString(str);
6254 /* delete from inside */
6255 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6256 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6258 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6259 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6260 ok(len == 2, "expected 2 got %ld\n", len);
6262 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6264 ok(!lstrcmpW(str, L" "), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6265 SysFreeString(str);
6267 /* delete whole data ... */
6268 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6269 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6271 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6274 /* ... and try again with empty string */
6275 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6278 /* ::replaceData() */
6279 V_VT(&v) = VT_BSTR;
6280 V_BSTR(&v) = SysAllocString(L"str1");
6281 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6282 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6283 VariantClear(&v);
6285 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6286 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6287 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6288 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6289 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6290 SysFreeString(str);
6292 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6293 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6294 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6296 ok(!lstrcmpW(str, L"str1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6297 SysFreeString(str);
6299 /* NULL pointer means delete */
6300 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6302 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6303 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6304 ok(!lstrcmpW(str, L"tr1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6305 SysFreeString(str);
6307 /* empty string means delete */
6308 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6310 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6312 ok(!lstrcmpW(str, L"r1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6313 SysFreeString(str);
6315 /* zero count means insert */
6316 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6317 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6318 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6320 ok(!lstrcmpW(str, L"ar1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6321 SysFreeString(str);
6323 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6324 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6326 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6328 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6330 ok(!lstrcmpW(str, L"m1"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6331 SysFreeString(str);
6333 /* nonempty string, count greater than its length */
6334 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6336 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6337 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6338 ok(!lstrcmpW(str, L"a1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6339 SysFreeString(str);
6341 /* nonempty string, count less than its length */
6342 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6343 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6344 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6346 ok(!lstrcmpW(str, L"wine1.2"), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str));
6347 SysFreeString(str);
6349 IXMLDOMCDATASection_Release(pCDataSec);
6352 /* Document Fragments */
6353 hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6354 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6356 hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6358 if(hr == S_OK)
6360 IXMLDOMNode *node;
6362 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6363 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6365 node = (IXMLDOMNode *)0x1;
6366 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6367 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6368 ok(node == NULL, "expected NULL, got %p\n", node);
6370 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6373 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6375 ok( !lstrcmpW( str, L"#document-fragment" ), "incorrect docfragment node Name\n");
6376 SysFreeString(str);
6378 /* test next Sibling*/
6379 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6380 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6382 node = (IXMLDOMNode *)0x1;
6383 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6384 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6385 ok(node == NULL, "next sibling not NULL\n");
6387 /* test Previous Sibling*/
6388 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6389 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6391 node = (IXMLDOMNode *)0x1;
6392 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6393 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
6394 ok(node == NULL, "previous sibling not NULL\n");
6396 IXMLDOMDocumentFragment_Release(pDocFrag);
6399 /* Entity References */
6400 hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6401 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
6402 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6403 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
6405 str = SysAllocString(L"entityref");
6406 hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6407 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
6409 hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6410 SysFreeString(str);
6411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6412 if(hr == S_OK)
6414 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6417 /* test get_xml*/
6418 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6420 ok( !lstrcmpW( str, L"&entityref;" ), "incorrect xml string\n");
6421 SysFreeString(str);
6423 IXMLDOMEntityReference_Release(pEntityRef);
6426 IXMLDOMElement_Release( pRoot );
6430 IXMLDOMDocument_Release(doc);
6432 free_bstrs();
6435 typedef struct {
6436 const char *name;
6437 const char *type;
6438 HRESULT hr;
6439 } put_datatype_t;
6441 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6442 So many of the names have been changed to reflect this. */
6443 static put_datatype_t put_datatype_data[] = {
6444 { "test_inval", "abcdefg", E_FAIL },
6445 { "test_bool", "Boolean", S_OK },
6446 { "test_string", "String", S_OK },
6447 { "test_number", "number", S_OK },
6448 { "test_int", "InT", S_OK },
6449 { "test_fixed", "fixed.14.4", S_OK },
6450 { "test_datetime", "DateTime", S_OK },
6451 { "test_datetimetz", "DateTime.tz", S_OK },
6452 { "test_date", "Date", S_OK },
6453 { "test_time", "Time", S_OK },
6454 { "test_timetz", "Time.tz", S_OK },
6455 { "test_I1", "I1", S_OK },
6456 { "test_I2", "I2", S_OK },
6457 { "test_I4", "I4", S_OK },
6458 { "test_UI1", "UI1", S_OK },
6459 { "test_UI2", "UI2", S_OK },
6460 { "test_UI4", "UI4", S_OK },
6461 { "test_r4", "r4", S_OK },
6462 { "test_r8", "r8", S_OK },
6463 { "test_float", "float", S_OK },
6464 { "test_uuid", "UuId", S_OK },
6465 { "test_binhex", "bin.hex", S_OK },
6466 { "test_binbase64", "bin.base64", S_OK },
6467 { NULL }
6470 typedef struct {
6471 DOMNodeType type;
6472 HRESULT hr;
6473 } put_datatype_notype_t;
6475 static put_datatype_notype_t put_dt_notype[] = {
6476 { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6477 { NODE_DOCUMENT_FRAGMENT, E_FAIL },
6478 { NODE_ENTITY_REFERENCE, E_FAIL },
6479 { NODE_CDATA_SECTION, E_FAIL },
6480 { NODE_COMMENT, E_FAIL },
6481 { NODE_INVALID }
6484 static void test_put_dataType( void )
6486 const put_datatype_notype_t *ptr2 = put_dt_notype;
6487 const put_datatype_t *ptr = put_datatype_data;
6488 IXMLDOMElement *root, *element;
6489 BSTR nameW, type1W, type2W;
6490 IXMLDOMDocument *doc;
6491 HRESULT hr;
6493 doc = create_document(&IID_IXMLDOMDocument);
6495 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6496 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6498 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6499 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6501 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6502 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6504 hr = IXMLDOMElement_put_dataType(root, NULL);
6505 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6507 while (ptr->name)
6509 hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6511 if(hr == S_OK)
6513 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6514 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6516 hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6517 ok(hr == ptr->hr, "failed for %s:%s, %#lx.\n", ptr->name, ptr->type, ptr->hr);
6519 IXMLDOMElement_Release(element);
6521 ptr++;
6524 /* check changing types */
6525 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6528 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6529 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6531 hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6532 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6534 hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6537 IXMLDOMElement_Release(element);
6539 /* try to set type for node without a type */
6540 nameW = _bstr_("testname");
6541 type1W = _bstr_("string");
6542 type2W = _bstr_("number");
6543 while (ptr2->type != NODE_INVALID)
6545 IXMLDOMNode *node;
6546 VARIANT type;
6548 V_VT(&type) = VT_I2;
6549 V_I2(&type) = ptr2->type;
6551 hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
6552 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6553 if(hr == S_OK)
6555 hr = IXMLDOMElement_appendChild(root, node, NULL);
6556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6558 hr = IXMLDOMNode_put_dataType(node, NULL);
6559 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6561 hr = IXMLDOMNode_put_dataType(node, type1W);
6562 ok(hr == ptr2->hr, "failed for type %d, %#lx\n", ptr2->type, ptr->hr);
6563 hr = IXMLDOMNode_put_dataType(node, type2W);
6564 ok(hr == ptr2->hr, "failed for type %d, %#lx\n", ptr2->type, ptr->hr);
6566 IXMLDOMNode_Release(node);
6568 ptr2++;
6571 IXMLDOMElement_Release(root);
6572 IXMLDOMDocument_Release(doc);
6573 free_bstrs();
6576 static void test_save(void)
6578 static const char cheA[] = "<Testing che=\"\xd0\xa7\"/>";
6579 IXMLDOMDocument *doc, *doc2;
6580 IXMLDOMAttribute *attr;
6581 IXMLDOMElement *root;
6582 BSTR sOrig, sNew, filename;
6583 char buffer[100];
6584 IStream *stream;
6585 HGLOBAL global;
6586 VARIANT_BOOL b;
6587 DWORD read = 0;
6588 VARIANT v, dest;
6589 HANDLE hfile;
6590 HRESULT hr;
6591 char *ptr;
6593 doc = create_document(&IID_IXMLDOMDocument);
6594 doc2 = create_document(&IID_IXMLDOMDocument);
6596 /* save to IXMLDOMDocument */
6597 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6598 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6600 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6603 V_VT(&dest) = VT_UNKNOWN;
6604 V_UNKNOWN(&dest) = (IUnknown*)doc2;
6606 hr = IXMLDOMDocument_save(doc, dest);
6607 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6609 hr = IXMLDOMDocument_get_xml(doc, &sOrig);
6610 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6612 hr = IXMLDOMDocument_get_xml(doc2, &sNew);
6613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6615 ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
6617 SysFreeString(sOrig);
6618 SysFreeString(sNew);
6620 IXMLDOMElement_Release(root);
6621 IXMLDOMDocument_Release(doc2);
6623 /* save to path */
6624 V_VT(&dest) = VT_BSTR;
6625 V_BSTR(&dest) = _bstr_("test.xml");
6627 hr = IXMLDOMDocument_save(doc, dest);
6628 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6630 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6631 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %lu\n", GetLastError());
6632 if(hfile == INVALID_HANDLE_VALUE) return;
6634 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6635 ok(read != 0, "could not read file\n");
6636 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6638 CloseHandle(hfile);
6639 DeleteFileA("test.xml");
6641 /* save to path VT_BSTR | VT_BYREF */
6642 filename = _bstr_("test.xml");
6643 V_VT(&dest) = VT_BSTR | VT_BYREF;
6644 V_BSTRREF(&dest) = &filename;
6646 hr = IXMLDOMDocument_save(doc, dest);
6647 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6649 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6650 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %lu\n", GetLastError());
6651 if(hfile == INVALID_HANDLE_VALUE) return;
6653 if (hfile != INVALID_HANDLE_VALUE)
6655 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6656 ok(read != 0, "could not read file\n");
6657 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6659 CloseHandle(hfile);
6660 DeleteFileA("test.xml");
6663 /* save to stream */
6664 V_VT(&dest) = VT_UNKNOWN;
6665 V_UNKNOWN(&dest) = (IUnknown*)&savestream;
6667 hr = IXMLDOMDocument_save(doc, dest);
6668 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6670 /* loaded data contains xml declaration */
6671 hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b);
6672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6674 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
6675 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6676 V_VT(&dest) = VT_UNKNOWN;
6677 V_UNKNOWN(&dest) = (IUnknown*)stream;
6678 hr = IXMLDOMDocument_save(doc, dest);
6679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6681 hr = GetHGlobalFromStream(stream, &global);
6682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6683 ptr = GlobalLock(global);
6684 ok(!memcmp(ptr, win1252decl, strlen(win1252decl)), "got wrong xml declaration\n");
6685 GlobalUnlock(global);
6686 IStream_Release(stream);
6688 /* loaded data without xml declaration */
6689 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b);
6690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6692 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
6693 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6694 V_VT(&dest) = VT_UNKNOWN;
6695 V_UNKNOWN(&dest) = (IUnknown*)stream;
6696 hr = IXMLDOMDocument_save(doc, dest);
6697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6699 hr = GetHGlobalFromStream(stream, &global);
6700 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6701 ptr = GlobalLock(global);
6702 ok(ptr[0] == '<' && ptr[1] != '?', "got wrong start tag %c%c\n", ptr[0], ptr[1]);
6703 GlobalUnlock(global);
6704 IStream_Release(stream);
6706 IXMLDOMDocument_Release(doc);
6708 /* test default encoding with non-english characters */
6709 doc = create_document(&IID_IXMLDOMDocument);
6711 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6712 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6714 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6717 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("che"), &attr);
6718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6720 V_VT(&v) = VT_BSTR;
6721 V_BSTR(&v) = SysAllocString(L"\x0427");
6722 hr = IXMLDOMAttribute_put_value(attr, v);
6723 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6724 VariantClear(&v);
6726 hr = IXMLDOMElement_setAttributeNode(root, attr, NULL);
6727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6729 V_VT(&dest) = VT_BSTR;
6730 V_BSTR(&dest) = _bstr_("test.xml");
6732 hr = IXMLDOMDocument_save(doc, dest);
6733 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6735 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6736 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %lu\n", GetLastError());
6737 if (hfile != INVALID_HANDLE_VALUE)
6739 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6740 ok(read != 0, "could not read file\n");
6741 ok(!memcmp(buffer, cheA, sizeof(cheA)-1), "got: %s\n", buffer);
6743 CloseHandle(hfile);
6744 DeleteFileA("test.xml");
6747 IXMLDOMAttribute_Release(attr);
6748 IXMLDOMElement_Release(root);
6749 IXMLDOMDocument_Release(doc);
6751 free_bstrs();
6754 static void test_testTransforms(void)
6756 IXMLDOMDocument *doc, *docSS;
6757 IXMLDOMNode *pNode;
6758 VARIANT_BOOL bSucc;
6759 HRESULT hr;
6761 doc = create_document(&IID_IXMLDOMDocument);
6762 docSS = create_document(&IID_IXMLDOMDocument);
6764 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
6765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6767 hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
6768 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6770 hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
6771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6772 if(hr == S_OK)
6774 BSTR bOut;
6776 hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
6777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6778 if(hr == S_OK)
6780 ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(bOut));
6781 SysFreeString(bOut);
6784 IXMLDOMNode_Release(pNode);
6787 IXMLDOMDocument_Release(docSS);
6788 IXMLDOMDocument_Release(doc);
6790 free_bstrs();
6793 struct namespaces_change_t {
6794 const CLSID *clsid;
6795 const char *name;
6798 static const struct namespaces_change_t namespaces_change_test_data[] = {
6799 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
6800 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
6801 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
6802 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
6803 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
6804 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
6805 { 0 }
6808 static void test_namespaces_change(void)
6810 const struct namespaces_change_t *class_ptr = namespaces_change_test_data;
6812 while (class_ptr->clsid)
6814 IXMLDOMDocument *doc = NULL;
6815 IXMLDOMElement *elem = NULL;
6816 IXMLDOMNode *node = NULL;
6818 VARIANT var;
6819 HRESULT hr;
6820 BSTR str;
6822 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
6824 class_ptr++;
6825 continue;
6828 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
6829 &IID_IXMLDOMDocument, (void**)&doc);
6830 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6832 V_VT(&var) = VT_I2;
6833 V_I2(&var) = NODE_ELEMENT;
6835 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
6836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6838 hr = IXMLDOMDocument_appendChild(doc, node, NULL);
6839 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6841 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
6842 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6844 /* try same prefix, different uri */
6845 V_VT(&var) = VT_BSTR;
6846 V_BSTR(&var) = _bstr_("ns/uri2");
6848 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6849 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6851 /* try same prefix and uri */
6852 V_VT(&var) = VT_BSTR;
6853 V_BSTR(&var) = _bstr_("ns/uri");
6855 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6856 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6858 hr = IXMLDOMElement_get_xml(elem, &str);
6859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6860 ok(!lstrcmpW(str, L"<ns:elem xmlns:ns=\"ns/uri\"/>"), "got element %s for %s\n",
6861 wine_dbgstr_w(str), class_ptr->name);
6862 SysFreeString(str);
6864 IXMLDOMElement_Release(elem);
6865 IXMLDOMDocument_Release(doc);
6867 free_bstrs();
6869 class_ptr++;
6873 static void test_namespaces_basic(void)
6875 static const CHAR namespaces_xmlA[] =
6876 "<?xml version=\"1.0\"?>\n"
6877 "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
6878 " <XMI.content>"
6879 " <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
6880 " </XMI.content>"
6881 "</XMI>";
6883 IXMLDOMDocument *doc;
6884 IXMLDOMElement *elem;
6885 IXMLDOMNode *node;
6887 VARIANT_BOOL b;
6888 HRESULT hr;
6889 BSTR str;
6891 doc = create_document(&IID_IXMLDOMDocument);
6893 hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
6894 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6895 ok(b == VARIANT_TRUE, "got %d\n", b);
6897 str = (void *)0xdeadbeef;
6898 hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
6899 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
6900 ok(str == NULL, "got %p\n", str);
6902 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
6903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6904 if(hr == S_OK)
6906 IXMLDOMAttribute *attr;
6907 IXMLDOMNode *node2;
6909 hr = IXMLDOMNode_get_firstChild(node, &node2);
6910 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6911 ok(node2 != NULL, "got %p\n", node2);
6913 /* Test get_prefix */
6914 hr = IXMLDOMNode_get_prefix(node2, NULL);
6915 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6916 /* NOTE: Need to test that arg2 gets cleared on Error. */
6918 hr = IXMLDOMNode_get_prefix(node2, &str);
6919 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6920 ok(!lstrcmpW(str, L"Model"), "got %s\n", wine_dbgstr_w(str));
6921 SysFreeString(str);
6923 hr = IXMLDOMNode_get_nodeName(node2, &str);
6924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6925 ok(!lstrcmpW(str, L"Model:Package"), "got %s\n", wine_dbgstr_w(str));
6926 SysFreeString(str);
6928 /* Test get_namespaceURI */
6929 hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
6930 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6931 /* NOTE: Need to test that arg2 gets cleared on Error. */
6933 hr = IXMLDOMNode_get_namespaceURI(node2, &str);
6934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6935 ok(!lstrcmpW(str, L"http://omg.org/mof.Model/1.3"), "got %s\n", wine_dbgstr_w(str));
6936 SysFreeString(str);
6938 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
6939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6941 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
6942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6944 hr = IXMLDOMAttribute_get_nodeName(attr, &str);
6945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6946 ok(!lstrcmpW(str, L"Model:name2"), "got %s\n", wine_dbgstr_w(str));
6947 SysFreeString(str);
6949 hr = IXMLDOMAttribute_get_prefix(attr, &str);
6950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6951 ok(!lstrcmpW(str, L"Model"), "got %s\n", wine_dbgstr_w(str));
6952 SysFreeString(str);
6954 IXMLDOMAttribute_Release(attr);
6955 IXMLDOMElement_Release(elem);
6957 IXMLDOMNode_Release(node2);
6958 IXMLDOMNode_Release(node);
6961 IXMLDOMDocument_Release(doc);
6963 free_bstrs();
6966 static void test_FormattingXML(void)
6968 IXMLDOMDocument *doc;
6969 IXMLDOMElement *pElement;
6970 VARIANT_BOOL bSucc;
6971 HRESULT hr;
6972 BSTR str;
6973 static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
6974 static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
6976 doc = create_document(&IID_IXMLDOMDocument);
6978 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
6979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6980 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6982 if(bSucc == VARIANT_TRUE)
6984 hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
6985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6986 if(hr == S_OK)
6988 hr = IXMLDOMElement_get_xml(pElement, &str);
6989 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
6990 ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
6991 SysFreeString(str);
6993 IXMLDOMElement_Release(pElement);
6997 IXMLDOMDocument_Release(doc);
6999 free_bstrs();
7002 typedef struct _nodetypedvalue_t {
7003 const char *name;
7004 VARTYPE type;
7005 const char *value; /* value in string format */
7006 BOOL no_type;
7007 } nodetypedvalue_t;
7009 static const nodetypedvalue_t get_nodetypedvalue[] = {
7010 { "root/string", VT_BSTR, "Wine", TRUE },
7011 { "root/string2", VT_BSTR, "String " },
7012 { "root/string3", VT_BSTR, " Wine Wine ", TRUE },
7013 { "root/string4", VT_BSTR, "\nWine Wine\t", TRUE },
7014 { "root/string5", VT_BSTR, "", TRUE },
7015 { "root/nested", VT_BSTR, " s1 \ns2 s2\t", TRUE },
7016 { "root/number", VT_BSTR, "12.44" },
7017 { "root/number2", VT_BSTR, "-3.71e3" },
7018 { "root/int", VT_I4, "-13" },
7019 { "root/fixed", VT_CY, "7322.9371" },
7020 { "root/bool", VT_BOOL, "-1" },
7021 { "root/datetime", VT_DATE, "40135.14" },
7022 { "root/datetimetz",VT_DATE, "37813.59" },
7023 { "root/date", VT_DATE, "665413" },
7024 { "root/time", VT_DATE, "0.5813889" },
7025 { "root/timetz", VT_DATE, "1.112512" },
7026 { "root/i1", VT_I1, "-13" },
7027 { "root/i2", VT_I2, "31915" },
7028 { "root/i4", VT_I4, "-312232" },
7029 { "root/ui1", VT_UI1, "123" },
7030 { "root/ui2", VT_UI2, "48282" },
7031 { "root/ui4", VT_UI4, "949281" },
7032 { "root/r4", VT_R4, "213124" },
7033 { "root/r8", VT_R8, "0.412" },
7034 { "root/float", VT_R8, "41221.421" },
7035 { "root/uuid", VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
7036 { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
7037 { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
7038 { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
7039 { 0 }
7042 static const char *strip_spaces(const char *str)
7044 static char buf[256];
7045 const char *p;
7047 while (isspace(*str))
7048 ++str;
7050 p = str + strlen(str);
7051 while (p != str && isspace(p[-1]))
7052 --p;
7054 memcpy(buf, str, p - str);
7055 buf[p - str] = 0;
7057 return buf;
7060 static void test_nodeTypedValue(void)
7062 const nodetypedvalue_t *entry = get_nodetypedvalue;
7063 IXMLDOMDocumentType *doctype, *doctype2;
7064 IXMLDOMProcessingInstruction *pi;
7065 IXMLDOMDocumentFragment *frag;
7066 IXMLDOMDocument *doc, *doc2;
7067 IXMLDOMCDATASection *cdata;
7068 IXMLDOMComment *comment;
7069 IXMLDOMNode *node;
7070 VARIANT_BOOL b;
7071 VARIANT value;
7072 HRESULT hr;
7074 doc = create_document(&IID_IXMLDOMDocument);
7076 b = VARIANT_FALSE;
7077 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
7078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7079 ok(b == VARIANT_TRUE, "got %d\n", b);
7081 hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
7082 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
7084 V_VT(&value) = VT_BSTR;
7085 V_BSTR(&value) = NULL;
7086 hr = IXMLDOMDocument_get_nodeValue(doc, &value);
7087 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
7088 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7090 hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
7091 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
7093 V_VT(&value) = VT_EMPTY;
7094 hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
7095 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
7096 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7098 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
7099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7101 V_VT(&value) = VT_BSTR;
7102 V_BSTR(&value) = NULL;
7103 hr = IXMLDOMNode_get_nodeValue(node, &value);
7104 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
7105 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
7107 hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
7108 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr );
7110 IXMLDOMNode_Release(node);
7112 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
7113 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7115 BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
7117 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7118 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7119 ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
7120 ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
7121 if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
7122 ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
7123 VariantClear(&value);
7124 IXMLDOMNode_Release(node);
7127 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
7128 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7130 V_VT(&value) = VT_NULL;
7131 V_BSTR(&value) = (void*)0xdeadbeef;
7132 hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
7133 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7134 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7135 ok(!lstrcmpW(V_BSTR(&value), L"value"), "got wrong value\n");
7136 IXMLDOMProcessingInstruction_Release(pi);
7137 VariantClear(&value);
7140 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
7141 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7143 V_VT(&value) = VT_NULL;
7144 V_BSTR(&value) = (void*)0xdeadbeef;
7145 hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
7146 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7147 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7148 ok(!lstrcmpW(V_BSTR(&value), L"[1]*2=3; &gee that's not right!"), "got wrong value\n");
7149 IXMLDOMCDATASection_Release(cdata);
7150 VariantClear(&value);
7153 hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
7154 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7156 V_VT(&value) = VT_NULL;
7157 V_BSTR(&value) = (void*)0xdeadbeef;
7158 hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
7159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7160 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
7161 ok(!lstrcmpW(V_BSTR(&value), L"comment"), "got wrong value\n");
7162 IXMLDOMComment_Release(comment);
7163 VariantClear(&value);
7166 hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
7167 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7169 V_VT(&value) = VT_EMPTY;
7170 hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
7171 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
7172 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7173 IXMLDOMDocumentFragment_Release(frag);
7176 doc2 = create_document(&IID_IXMLDOMDocument);
7178 b = VARIANT_FALSE;
7179 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
7180 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7181 ok(b == VARIANT_TRUE, "got %d\n", b);
7183 EXPECT_REF(doc2, 1);
7185 hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
7186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7188 EXPECT_REF(doc2, 1);
7189 todo_wine EXPECT_REF(doctype, 2);
7192 V_VT(&value) = VT_EMPTY;
7193 hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
7194 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
7195 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
7198 hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
7199 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7200 ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
7202 IXMLDOMDocumentType_Release(doctype2);
7203 IXMLDOMDocumentType_Release(doctype);
7205 IXMLDOMDocument_Release(doc2);
7207 while (entry->name)
7209 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
7210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7212 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7214 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7216 if (entry->type == (VT_ARRAY|VT_UI1))
7218 ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
7219 "incorrect array size %ld\n", V_ARRAY(&value)->rgsabound[0].cElements);
7222 if (entry->type != VT_BSTR)
7224 if (entry->type == VT_DATE ||
7225 entry->type == VT_R8 ||
7226 entry->type == VT_CY)
7228 if (entry->type == VT_DATE)
7230 hr = VariantChangeType(&value, &value, 0, VT_R4);
7231 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7233 hr = VariantChangeTypeEx(&value, &value,
7234 MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
7235 VARIANT_NOUSEROVERRIDE, VT_BSTR);
7236 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7238 else
7240 hr = VariantChangeType(&value, &value, 0, VT_BSTR);
7241 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7244 /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
7245 if (entry->type == (VT_ARRAY|VT_UI1))
7247 ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
7248 "expected %s\n", entry->value);
7250 else
7251 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
7252 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
7254 else
7256 BSTR bstr, expected;
7258 expected = entry->no_type ? _bstr_(strip_spaces(entry->value)) : _bstr_(entry->value);
7259 ok(!wcscmp( V_BSTR(&value), expected ), "expected %s, got %s\n",
7260 debugstr_w(expected), wine_dbgstr_w(V_BSTR(&value)));
7261 if (entry->no_type)
7263 VariantClear( &value );
7265 hr = IXMLDOMDocument_get_preserveWhiteSpace(doc, &b);
7266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7267 ok(b == VARIANT_FALSE, "got %d\n", b);
7269 hr = IXMLDOMNode_get_text(node, &bstr);
7270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7271 ok(!wcscmp( bstr, expected ), "expected %s, got %s\n",
7272 debugstr_w(expected), wine_dbgstr_w(bstr));
7273 SysFreeString(bstr);
7275 hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE);
7276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7278 expected = _bstr_(entry->value);
7279 hr = IXMLDOMNode_get_text(node, &bstr);
7280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7281 ok(!wcscmp( bstr, expected ), "expected %s, got %s\n",
7282 debugstr_w(expected), wine_dbgstr_w(bstr));
7283 SysFreeString(bstr);
7285 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
7286 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7287 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
7288 ok(!wcscmp( V_BSTR(&value), expected ), "expected %s, got %s\n",
7289 debugstr_w(expected), wine_dbgstr_w(V_BSTR(&value)));
7291 hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_FALSE);
7292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7296 VariantClear( &value );
7297 IXMLDOMNode_Release(node);
7299 entry++;
7302 IXMLDOMDocument_Release(doc);
7303 free_bstrs();
7306 static void test_TransformWithLoadingLocalFile(void)
7308 IXMLDOMDocument *doc;
7309 IXMLDOMDocument *xsl;
7310 IXMLDOMNode *pNode;
7311 VARIANT_BOOL bSucc;
7312 HRESULT hr;
7313 HANDLE file;
7314 DWORD dwWritten;
7315 char lpPathBuffer[MAX_PATH];
7316 int i;
7318 /* Create a Temp File. */
7319 GetTempPathA(MAX_PATH, lpPathBuffer);
7320 strcat(lpPathBuffer, "customers.xml" );
7322 file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7323 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %lu\n", GetLastError());
7324 if(file == INVALID_HANDLE_VALUE)
7325 return;
7327 WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7328 CloseHandle(file);
7330 /* Correct path to not include an escape character. */
7331 for(i=0; i < strlen(lpPathBuffer); i++)
7333 if(lpPathBuffer[i] == '\\')
7334 lpPathBuffer[i] = '/';
7337 doc = create_document(&IID_IXMLDOMDocument);
7338 xsl = create_document(&IID_IXMLDOMDocument);
7340 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7342 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7343 if(bSucc == VARIANT_TRUE)
7345 BSTR sXSL;
7346 BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7347 BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7348 BSTR sFileName = _bstr_(lpPathBuffer);
7349 int nLength = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7351 sXSL = SysAllocStringLen(NULL, nLength);
7352 lstrcpyW(sXSL, sPart1);
7353 lstrcatW(sXSL, sFileName);
7354 lstrcatW(sXSL, sPart2);
7356 hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7358 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7359 if(bSucc == VARIANT_TRUE)
7361 BSTR sResult;
7363 hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7365 if(hr == S_OK)
7367 /* This will load the temp file via the XSL */
7368 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7369 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7370 if(hr == S_OK)
7372 ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7373 SysFreeString(sResult);
7376 IXMLDOMNode_Release(pNode);
7380 SysFreeString(sXSL);
7383 IXMLDOMDocument_Release(doc);
7384 IXMLDOMDocument_Release(xsl);
7386 DeleteFileA(lpPathBuffer);
7387 free_bstrs();
7390 static void test_put_nodeValue(void)
7392 IXMLDOMDocument *doc;
7393 IXMLDOMText *text;
7394 IXMLDOMEntityReference *entityref;
7395 IXMLDOMAttribute *attr;
7396 IXMLDOMNode *node;
7397 HRESULT hr;
7398 VARIANT data, type;
7400 doc = create_document(&IID_IXMLDOMDocument);
7402 /* test for unsupported types */
7403 /* NODE_DOCUMENT */
7404 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7405 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7406 V_VT(&data) = VT_BSTR;
7407 V_BSTR(&data) = _bstr_("one two three");
7408 hr = IXMLDOMNode_put_nodeValue(node, data);
7409 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
7410 IXMLDOMNode_Release(node);
7412 /* NODE_DOCUMENT_FRAGMENT */
7413 V_VT(&type) = VT_I1;
7414 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7415 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7416 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7417 V_VT(&data) = VT_BSTR;
7418 V_BSTR(&data) = _bstr_("one two three");
7419 hr = IXMLDOMNode_put_nodeValue(node, data);
7420 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
7421 IXMLDOMNode_Release(node);
7423 /* NODE_ELEMENT */
7424 V_VT(&type) = VT_I1;
7425 V_I1(&type) = NODE_ELEMENT;
7426 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7428 V_VT(&data) = VT_BSTR;
7429 V_BSTR(&data) = _bstr_("one two three");
7430 hr = IXMLDOMNode_put_nodeValue(node, data);
7431 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
7432 IXMLDOMNode_Release(node);
7434 /* NODE_ENTITY_REFERENCE */
7435 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7436 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7438 V_VT(&data) = VT_BSTR;
7439 V_BSTR(&data) = _bstr_("one two three");
7440 hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7441 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
7443 hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7445 V_VT(&data) = VT_BSTR;
7446 V_BSTR(&data) = _bstr_("one two three");
7447 hr = IXMLDOMNode_put_nodeValue(node, data);
7448 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr );
7449 IXMLDOMNode_Release(node);
7450 IXMLDOMEntityReference_Release(entityref);
7452 /* supported types */
7453 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7454 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7455 V_VT(&data) = VT_BSTR;
7456 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7457 hr = IXMLDOMText_put_nodeValue(text, data);
7458 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7459 IXMLDOMText_Release(text);
7461 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7462 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7463 V_VT(&data) = VT_BSTR;
7464 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7465 hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7467 hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7468 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7469 ok(!lstrcmpW(V_BSTR(&data), L"Jeeves & Wooster"), "got %s\n", wine_dbgstr_w(V_BSTR(&data)));
7470 VariantClear(&data);
7471 IXMLDOMAttribute_Release(attr);
7473 free_bstrs();
7475 IXMLDOMDocument_Release(doc);
7478 static void test_IObjectSafety(void)
7480 IXMLDOMDocument *doc;
7481 IObjectSafety *safety;
7482 HRESULT hr;
7484 doc = create_document(&IID_IXMLDOMDocument);
7486 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7489 test_IObjectSafety_common(safety);
7491 IObjectSafety_Release(safety);
7492 IXMLDOMDocument_Release(doc);
7494 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
7495 &IID_IObjectSafety, (void**)&safety);
7496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
7498 test_IObjectSafety_common(safety);
7500 IObjectSafety_Release(safety);
7504 typedef struct _property_test_t {
7505 const GUID *guid;
7506 const char *clsid;
7507 const char *property;
7508 const char *value;
7509 } property_test_t;
7511 static const property_test_t properties_test_data[] = {
7512 { &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7513 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7514 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7515 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7516 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7517 { 0 }
7520 static void test_default_properties(void)
7522 const property_test_t *entry = properties_test_data;
7524 while (entry->guid)
7526 IXMLDOMDocument2 *doc;
7527 VARIANT var;
7528 HRESULT hr;
7530 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
7532 entry++;
7533 continue;
7536 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7537 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7539 hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7540 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7541 ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7542 entry->value, entry->clsid);
7543 VariantClear(&var);
7545 IXMLDOMDocument2_Release(doc);
7547 entry++;
7551 typedef struct {
7552 const char *query;
7553 const char *list;
7554 BOOL todo;
7555 } xslpattern_test_t;
7557 static const xslpattern_test_t xslpattern_test[] = {
7558 { "root//elem[0]", "E1.E2.D1" },
7559 { "root//elem[index()=1]", "E2.E2.D1" },
7560 { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7561 { "root//elem[end()]", "E4.E2.D1" },
7562 { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7563 { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7564 { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7565 { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7566 { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7567 { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7568 { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7569 { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7570 { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7571 { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7572 { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7573 { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7574 { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7575 { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7576 { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7577 { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7578 { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7579 { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7580 { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7581 { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7582 { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7583 { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7584 { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7585 { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7586 { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7587 { "root/elem[0]", "E1.E2.D1" },
7588 { "root/elem[index()=1]", "E2.E2.D1" },
7589 { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7590 { "root/elem[end()]", "E4.E2.D1" },
7591 { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7592 { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7593 { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7594 { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7595 { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7596 { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7597 { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7598 { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7599 { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7600 { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7601 { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7602 { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7603 { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7604 { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7605 { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7606 { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7607 { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7608 { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7609 { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7610 { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7611 { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7612 { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7613 { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7614 { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7615 { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7616 { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7617 { "root/elem[@*]", "E2.E2.D1 E3.E2.D1", TRUE },
7618 { NULL }
7621 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7622 /* prefixes don't need to be registered, you may use them as they are in the doc */
7623 { "//bar:x", "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7624 /* prefixes must be explicitly specified in the name */
7625 { "//foo:elem", "" },
7626 { "//foo:c", "E3.E4.E2.D1" },
7627 { NULL }
7630 static const xslpattern_test_t xslpattern_test_func[] = {
7631 { "attribute()", "" },
7632 { "attribute('depth')", "" },
7633 { "root/attribute('depth')", "A'depth'.E3.D1" },
7634 { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7635 { "//x//attribute(id)", NULL },
7636 { "//x//attribute('id')", "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1" },
7637 { "comment()", "C2.D1" },
7638 { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7639 { "element()", "E3.D1" },
7640 { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7641 { "//element(a)", NULL },
7642 { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7643 { "node()", "P1.D1 C2.D1 E3.D1" },
7644 { "//x/node()", "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7645 { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7646 { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7647 { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7648 { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7649 { "pi()", "P1.D1" },
7650 { "//y/pi()", "P1.E4.E3.D1" },
7651 { "root/textnode()", "T2.E3.D1" },
7652 { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7653 { NULL }
7656 static void test_XSLPattern(void)
7658 const xslpattern_test_t *ptr = xslpattern_test;
7659 IXMLDOMDocument2 *doc;
7660 IXMLDOMNodeList *list;
7661 VARIANT_BOOL b;
7662 HRESULT hr;
7663 LONG len;
7665 doc = create_document(&IID_IXMLDOMDocument2);
7667 b = VARIANT_FALSE;
7668 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7670 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7672 /* switch to XSLPattern */
7673 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7674 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7676 /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7677 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7680 len = 0;
7681 hr = IXMLDOMNodeList_get_length(list, &len);
7682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7683 /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7684 ok(len == 3, "expected 3 entries in list, got %ld\n", len);
7685 IXMLDOMNodeList_Release(list);
7687 while (ptr->query)
7689 list = NULL;
7690 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7691 ok(hr == S_OK, "query=%s, failed with %#lx\n", ptr->query, hr);
7692 len = 0;
7693 hr = IXMLDOMNodeList_get_length(list, &len);
7694 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7695 ok(len != 0, "query=%s, empty list\n", ptr->query);
7696 if (len) {
7697 if (ptr->todo) {
7698 char *str = list_to_string(list);
7699 todo_wine
7700 ok(!strcmp(str, ptr->list), "Invalid node list: %s, expected %s\n", str, ptr->list);
7701 IXMLDOMNodeList_Release(list);
7703 else
7704 expect_list_and_release(list, ptr->list);
7707 ptr++;
7710 /* namespace handling */
7711 /* no registered namespaces */
7712 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7713 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7715 ptr = xslpattern_test_no_ns;
7716 while (ptr->query)
7718 list = NULL;
7719 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7720 ok(hr == S_OK, "query=%s, failed with %#lx.\n", ptr->query, hr);
7722 if (*ptr->list)
7724 len = 0;
7725 hr = IXMLDOMNodeList_get_length(list, &len);
7726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7727 ok(len != 0, "query=%s, empty list\n", ptr->query);
7729 else
7731 len = 1;
7732 hr = IXMLDOMNodeList_get_length(list, &len);
7733 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7734 ok(len == 0, "query=%s, empty list\n", ptr->query);
7736 if (len)
7737 expect_list_and_release(list, ptr->list);
7739 ptr++;
7742 /* explicitly register prefix foo */
7743 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
7744 _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'"));
7745 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7747 /* now we get the same behavior as XPath */
7748 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7749 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7750 len = 0;
7751 hr = IXMLDOMNodeList_get_length(list, &len);
7752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7753 ok(len != 0, "expected filled list\n");
7754 if (len)
7755 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
7757 /* set prefix foo to some nonexistent namespace */
7758 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
7759 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7761 /* the registered prefix takes precedence */
7762 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7763 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7764 len = 0;
7765 hr = IXMLDOMNodeList_get_length(list, &len);
7766 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7767 ok(len == 0, "expected empty list\n");
7768 IXMLDOMNodeList_Release(list);
7770 IXMLDOMDocument2_Release(doc);
7772 doc = create_document(&IID_IXMLDOMDocument2);
7774 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
7775 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7776 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7778 ptr = xslpattern_test_func;
7779 while (ptr->query)
7781 list = NULL;
7782 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7783 if (ptr->list)
7785 ok(hr == S_OK, "query=%s, failed with %#lx.\n", ptr->query, hr);
7786 len = 0;
7787 hr = IXMLDOMNodeList_get_length(list, &len);
7788 ok(hr == S_OK, "Failed to get list length, hr %#lx.\n", hr);
7789 if (*ptr->list)
7791 ok(len != 0, "query=%s, empty list\n", ptr->query);
7792 if (len)
7793 expect_list_and_release(list, ptr->list);
7795 else
7796 ok(len == 0, "query=%s, filled list\n", ptr->query);
7798 else
7799 ok(hr == E_FAIL, "query=%s, failed with %#lx.\n", ptr->query, hr);
7801 ptr++;
7804 IXMLDOMDocument2_Release(doc);
7805 free_bstrs();
7808 static void test_splitText(void)
7810 IXMLDOMCDATASection *cdata;
7811 IXMLDOMElement *root;
7812 IXMLDOMDocument *doc;
7813 IXMLDOMText *text, *text2;
7814 IXMLDOMNode *node;
7815 VARIANT var;
7816 VARIANT_BOOL success;
7817 LONG length;
7818 HRESULT hr;
7820 doc = create_document(&IID_IXMLDOMDocument);
7822 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
7823 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7825 hr = IXMLDOMDocument_get_documentElement(doc, &root);
7826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7828 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
7829 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7831 V_VT(&var) = VT_EMPTY;
7832 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
7833 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7835 length = 0;
7836 hr = IXMLDOMCDATASection_get_length(cdata, &length);
7837 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7838 ok(length > 0, "got %ld\n", length);
7840 hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
7841 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7843 text = (void*)0xdeadbeef;
7844 /* negative offset */
7845 hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
7846 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7847 ok(text == (void*)0xdeadbeef, "got %p\n", text);
7849 text = (void*)0xdeadbeef;
7850 /* offset outside data */
7851 hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
7852 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7853 ok(text == 0, "got %p\n", text);
7855 text = (void*)0xdeadbeef;
7856 /* offset outside data */
7857 hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
7858 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
7859 ok(text == 0, "got %p\n", text);
7861 /* no empty node created */
7862 node = (void*)0xdeadbeef;
7863 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7864 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
7865 ok(node == 0, "got %p\n", text);
7867 hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
7868 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7870 length = 0;
7871 hr = IXMLDOMText_get_length(text, &length);
7872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7873 ok(length == 7, "got %ld\n", length);
7875 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7876 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7877 IXMLDOMNode_Release(node);
7879 /* split new text node */
7880 hr = IXMLDOMText_get_length(text, &length);
7881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7883 node = (void*)0xdeadbeef;
7884 hr = IXMLDOMText_get_nextSibling(text, &node);
7885 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
7886 ok(node == 0, "got %p\n", text);
7888 hr = IXMLDOMText_splitText(text, 0, NULL);
7889 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7891 text2 = (void*)0xdeadbeef;
7892 /* negative offset */
7893 hr = IXMLDOMText_splitText(text, -1, &text2);
7894 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7895 ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
7897 text2 = (void*)0xdeadbeef;
7898 /* offset outside data */
7899 hr = IXMLDOMText_splitText(text, length + 1, &text2);
7900 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7901 ok(text2 == 0, "got %p\n", text2);
7903 text2 = (void*)0xdeadbeef;
7904 /* offset outside data */
7905 hr = IXMLDOMText_splitText(text, length, &text2);
7906 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
7907 ok(text2 == 0, "got %p\n", text);
7909 text2 = 0;
7910 hr = IXMLDOMText_splitText(text, 4, &text2);
7911 todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7912 if (text2) IXMLDOMText_Release(text2);
7914 node = 0;
7915 hr = IXMLDOMText_get_nextSibling(text, &node);
7916 todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7917 if (node) IXMLDOMNode_Release(node);
7919 IXMLDOMText_Release(text);
7920 IXMLDOMElement_Release(root);
7921 IXMLDOMCDATASection_Release(cdata);
7922 free_bstrs();
7925 typedef struct {
7926 const char *name;
7927 const char *uri;
7928 HRESULT hr;
7929 } ns_item_t;
7931 /* default_ns_doc used */
7932 static const ns_item_t qualified_item_tests[] = {
7933 { "xml:lang", NULL, S_FALSE },
7934 { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
7935 { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
7936 { "ns:b", NULL, S_FALSE },
7937 { "ns:b", "nshref", S_FALSE },
7938 { "b", "nshref", S_OK },
7939 { "d", NULL, S_OK },
7940 { NULL }
7943 static const ns_item_t named_item_tests[] = {
7944 { "xml:lang", NULL, S_OK },
7945 { "lang", NULL, S_FALSE },
7946 { "ns:b", NULL, S_OK },
7947 { "b", NULL, S_FALSE },
7948 { "d", NULL, S_OK },
7949 { NULL }
7952 static void test_getQualifiedItem(void)
7954 IXMLDOMNode *pr_node, *node;
7955 IXMLDOMNodeList *root_list;
7956 IXMLDOMNamedNodeMap *map;
7957 IXMLDOMElement *element;
7958 const ns_item_t* ptr;
7959 IXMLDOMDocument *doc;
7960 VARIANT_BOOL b;
7961 HRESULT hr;
7962 LONG len;
7964 doc = create_document(&IID_IXMLDOMDocument);
7966 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
7967 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7968 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7970 hr = IXMLDOMDocument_get_documentElement(doc, &element);
7971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7973 hr = IXMLDOMElement_get_childNodes(element, &root_list);
7974 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7976 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
7977 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7978 IXMLDOMNodeList_Release(root_list);
7980 hr = IXMLDOMNode_get_attributes(pr_node, &map);
7981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7982 IXMLDOMNode_Release(pr_node);
7984 len = 0;
7985 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7986 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7987 ok( len == 3, "length %ld\n", len);
7989 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
7990 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7992 node = (void*)0xdeadbeef;
7993 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
7994 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7995 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7997 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
7998 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8000 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
8001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8003 IXMLDOMNode_Release(node);
8004 IXMLDOMNamedNodeMap_Release(map);
8005 IXMLDOMElement_Release(element);
8007 hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
8008 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8010 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
8011 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8013 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8015 IXMLDOMNode_Release(node);
8017 hr = IXMLDOMElement_get_attributes(element, &map);
8018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8020 ptr = qualified_item_tests;
8021 while (ptr->name)
8023 node = (void*)0xdeadbeef;
8024 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
8025 ok(hr == ptr->hr, "%s, %s: unexpected hr %#lx, expected %#lx.\n", ptr->name, ptr->uri, hr, ptr->hr);
8026 if (hr == S_OK)
8027 IXMLDOMNode_Release(node);
8028 else
8029 ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
8030 ptr++;
8033 ptr = named_item_tests;
8034 while (ptr->name)
8036 node = (void*)0xdeadbeef;
8037 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
8038 ok(hr == ptr->hr, "%s: unexpected hr %#lx, expected %#lx.\n", ptr->name, hr, ptr->hr);
8039 if (hr == S_OK)
8040 IXMLDOMNode_Release(node);
8041 else
8042 ok(node == NULL, "%s: got %p\n", ptr->name, node);
8043 ptr++;
8046 IXMLDOMNamedNodeMap_Release(map);
8048 IXMLDOMElement_Release(element);
8049 IXMLDOMDocument_Release(doc);
8050 free_bstrs();
8053 static void test_removeQualifiedItem(void)
8055 IXMLDOMDocument *doc;
8056 IXMLDOMElement *element;
8057 IXMLDOMNode *pr_node, *node;
8058 IXMLDOMNodeList *root_list;
8059 IXMLDOMNamedNodeMap *map;
8060 VARIANT_BOOL b;
8061 LONG len;
8062 HRESULT hr;
8064 doc = create_document(&IID_IXMLDOMDocument);
8066 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8067 ok( hr == S_OK, "loadXML failed\n");
8068 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8070 hr = IXMLDOMDocument_get_documentElement(doc, &element);
8071 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8073 hr = IXMLDOMElement_get_childNodes(element, &root_list);
8074 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8076 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
8077 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8078 IXMLDOMNodeList_Release(root_list);
8080 hr = IXMLDOMNode_get_attributes(pr_node, &map);
8081 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8082 IXMLDOMNode_Release(pr_node);
8084 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
8085 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8086 ok( len == 3, "length %ld\n", len);
8088 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
8089 ok( hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8091 node = (void*)0xdeadbeef;
8092 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
8093 ok( hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8094 ok( node == (void*)0xdeadbeef, "got %p\n", node);
8096 /* out pointer is optional */
8097 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8098 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8100 /* already removed */
8101 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
8102 ok( hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8104 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
8105 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8106 IXMLDOMNode_Release(node);
8108 IXMLDOMNamedNodeMap_Release( map );
8109 IXMLDOMElement_Release( element );
8110 IXMLDOMDocument_Release( doc );
8111 free_bstrs();
8114 #define check_default_props(doc) _check_default_props(__LINE__, doc)
8115 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
8117 VARIANT_BOOL b;
8118 VARIANT var;
8119 HRESULT hr;
8121 VariantInit(&var);
8122 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var);
8123 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8124 VariantClear(&var);
8126 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
8127 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8128 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), L"") == 0, "expected empty string\n");
8129 VariantClear(&var);
8131 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b);
8132 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8133 ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
8135 hr = IXMLDOMDocument2_get_schemas(doc, &var);
8136 ok_(__FILE__, line)(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8137 VariantClear(&var);
8140 #define check_set_props(doc) _check_set_props(__LINE__, doc)
8141 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
8143 VARIANT_BOOL b;
8144 VARIANT var;
8145 HRESULT hr;
8147 VariantInit(&var);
8148 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var);
8149 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8150 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), L"XPath") == 0, "expected XPath\n");
8151 VariantClear(&var);
8153 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
8154 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8155 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), L"xmlns:wi=\'www.winehq.org\'") == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8156 VariantClear(&var);
8158 hr = IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b);
8159 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8160 ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
8162 hr = IXMLDOMDocument2_get_schemas(doc, &var);
8163 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8164 ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
8165 VariantClear(&var);
8168 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
8169 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
8171 VARIANT var;
8172 HRESULT hr;
8174 VariantInit(&var);
8175 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
8176 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8177 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'"));
8178 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8179 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE);
8180 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8181 V_VT(&var) = VT_DISPATCH;
8182 V_DISPATCH(&var) = NULL;
8183 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var));
8184 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8185 ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
8186 hr = IXMLDOMDocument2_putref_schemas(doc, var);
8187 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8188 VariantClear(&var);
8191 #define unset_props(doc) _unset_props(__LINE__, doc)
8192 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
8194 VARIANT var;
8195 HRESULT hr;
8197 VariantInit(&var);
8198 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
8199 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8200 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
8201 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8202 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE);
8203 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8204 V_VT(&var) = VT_NULL;
8205 hr = IXMLDOMDocument2_putref_schemas(doc, var);
8206 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8207 VariantClear(&var);
8210 static void test_get_ownerDocument(void)
8212 IXMLDOMDocument *doc1, *doc2, *doc3;
8213 IXMLDOMDocument2 *doc, *doc_owner;
8214 IXMLDOMNode *node;
8215 IXMLDOMSchemaCollection *cache;
8216 VARIANT_BOOL b;
8217 VARIANT var;
8218 IXMLDOMElement *element;
8219 IXMLDOMNodeList *node_list;
8220 IXMLDOMAttribute *attr;
8221 LONG i, len;
8222 HRESULT hr;
8223 const CHAR nodeXML[] =
8224 "<root id='0'>"
8225 " <!-- comment node 0 -->"
8226 " text node 0"
8227 " <x attr='val'></x>"
8228 " <?foo value='PI for x'?>"
8229 " <![CDATA[ cdata ]]>"
8230 "</root>";
8232 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
8233 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
8235 doc = create_document(&IID_IXMLDOMDocument2);
8236 cache = create_cache(&IID_IXMLDOMSchemaCollection);
8238 VariantInit(&var);
8240 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b);
8241 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8242 ok(b == VARIANT_TRUE, "failed to load XML string\n");
8244 check_default_props(doc);
8246 /* set properties and check that new instances use them */
8247 set_props(doc, cache);
8248 check_set_props(doc);
8250 hr = IXMLDOMDocument2_get_firstChild(doc, &node);
8251 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8252 hr = IXMLDOMNode_get_ownerDocument(node, &doc1);
8253 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8255 /* new interface keeps props */
8256 hr = IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner);
8257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8258 ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
8259 check_set_props(doc_owner);
8260 IXMLDOMDocument2_Release(doc_owner);
8262 hr = IXMLDOMNode_get_ownerDocument(node, &doc2);
8263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8264 IXMLDOMNode_Release(node);
8266 ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
8268 /* reload */
8269 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b);
8270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8271 ok(b == VARIANT_TRUE, "failed to load XML string\n");
8273 /* properties retained even after reload */
8274 check_set_props(doc);
8276 hr = IXMLDOMDocument2_get_firstChild(doc, &node);
8277 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8278 hr = IXMLDOMNode_get_ownerDocument(node, &doc3);
8279 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8280 IXMLDOMNode_Release(node);
8282 hr = IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner);
8283 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8284 ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
8285 check_set_props(doc_owner);
8287 /* changing properties for one instance changes them for all */
8288 unset_props(doc_owner);
8289 check_default_props(doc_owner);
8290 check_default_props(doc);
8292 /* NULL check */
8293 hr = IXMLDOMDocument_loadXML(doc1, _bstr_(nodeXML), &b);
8294 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8295 ok(b == VARIANT_TRUE, "failed to load XML string\n");
8297 hr = IXMLDOMDocument_get_documentElement(doc1, &element);
8298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8300 hr = IXMLDOMElement_get_childNodes(element, &node_list);
8301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8303 hr = IXMLDOMNodeList_get_length(node_list, &len);
8304 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8306 for(i = 0; i < len; i++) {
8307 hr = IXMLDOMNodeList_get_item(node_list, i, &node);
8308 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8310 hr = IXMLDOMNode_get_ownerDocument(node, NULL);
8311 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8313 IXMLDOMNode_Release(node);
8315 IXMLDOMElement_Release(element);
8317 /* Test Attribute Node */
8318 hr = IXMLDOMNodeList_get_item(node_list, 2, &node);
8319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8320 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
8321 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8322 IXMLDOMNode_Release(node);
8324 hr = IXMLDOMElement_getAttributeNode(element, _bstr_("attr"), &attr);
8325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8326 ok(attr != NULL, "attr == NULL\n");
8327 IXMLDOMElement_Release(element);
8328 hr = IXMLDOMAttribute_get_ownerDocument(attr, NULL);
8329 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8330 IXMLDOMAttribute_Release(attr);
8331 IXMLDOMNodeList_Release(node_list);
8333 IXMLDOMSchemaCollection_Release(cache);
8334 IXMLDOMDocument_Release(doc1);
8335 IXMLDOMDocument_Release(doc2);
8336 IXMLDOMDocument_Release(doc3);
8337 IXMLDOMDocument2_Release(doc);
8338 IXMLDOMDocument2_Release(doc_owner);
8339 free_bstrs();
8342 static void test_setAttributeNode(void)
8344 IXMLDOMDocument *doc, *doc2;
8345 IXMLDOMElement *elem, *elem2;
8346 IXMLDOMAttribute *attr, *attr2, *ret_attr;
8347 VARIANT_BOOL b;
8348 HRESULT hr;
8349 VARIANT v;
8350 BSTR str;
8351 ULONG ref1, ref2;
8353 doc = create_document(&IID_IXMLDOMDocument);
8355 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8356 ok( hr == S_OK, "loadXML failed\n");
8357 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8359 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8360 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8362 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8363 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8364 ok( elem2 != elem, "got same instance\n");
8366 ret_attr = (void*)0xdeadbeef;
8367 hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8368 ok( hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8369 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8371 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8372 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8374 ref1 = IXMLDOMElement_AddRef(elem);
8375 IXMLDOMElement_Release(elem);
8377 ret_attr = (void*)0xdeadbeef;
8378 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8379 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8380 ok( ret_attr == NULL, "got %p\n", ret_attr);
8382 /* no reference added */
8383 ref2 = IXMLDOMElement_AddRef(elem);
8384 IXMLDOMElement_Release(elem);
8385 ok(ref2 == ref1, "got %ld, expected %ld\n", ref2, ref1);
8387 EXPECT_CHILDREN(elem);
8388 EXPECT_CHILDREN(elem2);
8390 IXMLDOMElement_Release(elem2);
8392 attr2 = NULL;
8393 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8394 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8395 ok( attr2 != attr, "got same instance %p\n", attr2);
8396 IXMLDOMAttribute_Release(attr2);
8398 /* try to add it another time */
8399 ret_attr = (void*)0xdeadbeef;
8400 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8401 ok( hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
8402 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8404 IXMLDOMElement_Release(elem);
8406 /* initially used element is released, attribute still 'has' a container */
8407 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8408 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8409 ret_attr = (void*)0xdeadbeef;
8410 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8411 ok( hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
8412 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8413 IXMLDOMElement_Release(elem);
8415 /* add attribute already attached to another document */
8416 doc2 = create_document(&IID_IXMLDOMDocument);
8418 hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8419 ok( hr == S_OK, "loadXML failed\n");
8420 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8422 hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8423 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8424 hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8425 ok( hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
8426 IXMLDOMElement_Release(elem);
8428 IXMLDOMAttribute_Release(attr);
8430 /* create element, add attribute, see if it's copied or linked */
8431 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8432 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8434 attr = NULL;
8435 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8436 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8437 ok(attr != NULL, "got %p\n", attr);
8439 ref1 = IXMLDOMAttribute_AddRef(attr);
8440 IXMLDOMAttribute_Release(attr);
8442 V_VT(&v) = VT_BSTR;
8443 V_BSTR(&v) = _bstr_("attrvalue1");
8444 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8445 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8447 str = NULL;
8448 hr = IXMLDOMAttribute_get_xml(attr, &str);
8449 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8450 ok(lstrcmpW(str, L"attr=\"attrvalue1\"") == 0,
8451 "got %s\n", wine_dbgstr_w(str));
8452 SysFreeString(str);
8454 ret_attr = (void*)0xdeadbeef;
8455 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8457 ok(ret_attr == NULL, "got %p\n", ret_attr);
8459 /* attribute reference increased */
8460 ref2 = IXMLDOMAttribute_AddRef(attr);
8461 IXMLDOMAttribute_Release(attr);
8462 ok(ref1 == ref2, "got %ld, expected %ld\n", ref2, ref1);
8464 hr = IXMLDOMElement_get_xml(elem, &str);
8465 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8466 ok(lstrcmpW(str, L"<test attr=\"attrvalue1\"/>") == 0,
8467 "got %s\n", wine_dbgstr_w(str));
8468 SysFreeString(str);
8470 V_VT(&v) = VT_BSTR;
8471 V_BSTR(&v) = _bstr_("attrvalue2");
8472 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8473 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8475 hr = IXMLDOMElement_get_xml(elem, &str);
8476 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8477 todo_wine ok(lstrcmpW(str, L"<test attr=\"attrvalue2\"/>") == 0,
8478 "got %s\n", wine_dbgstr_w(str));
8479 SysFreeString(str);
8481 IXMLDOMElement_Release(elem);
8482 IXMLDOMAttribute_Release(attr);
8483 IXMLDOMDocument_Release(doc2);
8484 IXMLDOMDocument_Release(doc);
8485 free_bstrs();
8488 static void test_createNode(void)
8490 IXMLDOMDocument *doc;
8491 IXMLDOMElement *elem;
8492 IXMLDOMNode *node;
8493 VARIANT v, var;
8494 BSTR prefix, str;
8495 HRESULT hr;
8496 ULONG ref;
8498 doc = create_document(&IID_IXMLDOMDocument);
8500 EXPECT_REF(doc, 1);
8502 /* reference count tests */
8503 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8504 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8506 /* initial reference is 2 */
8507 todo_wine {
8508 EXPECT_REF(elem, 2);
8509 ref = IXMLDOMElement_Release(elem);
8510 ok(ref == 1, "got %ld\n", ref);
8511 /* it's released already, attempt to release now will crash it */
8514 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8515 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8516 todo_wine EXPECT_REF(elem, 2);
8517 IXMLDOMDocument_Release(doc);
8518 todo_wine EXPECT_REF(elem, 2);
8519 IXMLDOMElement_Release(elem);
8521 doc = create_document(&IID_IXMLDOMDocument);
8523 /* NODE_ELEMENT nodes */
8524 /* 1. specified namespace */
8525 V_VT(&v) = VT_I4;
8526 V_I4(&v) = NODE_ELEMENT;
8528 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8529 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8530 prefix = NULL;
8531 hr = IXMLDOMNode_get_prefix(node, &prefix);
8532 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8533 ok(lstrcmpW(prefix, L"ns1") == 0, "wrong prefix\n");
8534 SysFreeString(prefix);
8535 IXMLDOMNode_Release(node);
8537 /* 2. default namespace */
8538 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8539 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8540 prefix = (void*)0xdeadbeef;
8541 hr = IXMLDOMNode_get_prefix(node, &prefix);
8542 ok( hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8543 ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8544 /* check dump */
8545 hr = IXMLDOMNode_get_xml(node, &str);
8546 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8547 ok(lstrcmpW(str, L"<test xmlns=\"http://winehq.org/default\"/>") == 0,
8548 "got %s\n", wine_dbgstr_w(str));
8549 SysFreeString(str);
8551 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8552 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8554 V_VT(&var) = VT_BSTR;
8555 hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8556 ok( hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8557 ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8559 str = NULL;
8560 hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8561 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8562 ok(lstrcmpW(str, L"http://winehq.org/default") == 0, "expected default namespace\n");
8563 SysFreeString(str);
8565 IXMLDOMElement_Release(elem);
8566 IXMLDOMNode_Release(node);
8568 IXMLDOMDocument_Release(doc);
8569 free_bstrs();
8572 static const char get_prefix_doc[] =
8573 "<?xml version=\"1.0\" ?>"
8574 "<a xmlns:ns1=\"ns1 href\" />";
8576 static void test_get_prefix(void)
8578 IXMLDOMDocumentFragment *fragment;
8579 IXMLDOMCDATASection *cdata;
8580 IXMLDOMElement *element;
8581 IXMLDOMComment *comment;
8582 IXMLDOMDocument *doc;
8583 VARIANT_BOOL b;
8584 HRESULT hr;
8585 BSTR str;
8587 doc = create_document(&IID_IXMLDOMDocument);
8589 /* nodes that can't support prefix */
8590 /* 1. document */
8591 str = (void*)0xdeadbeef;
8592 hr = IXMLDOMDocument_get_prefix(doc, &str);
8593 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8594 ok(str == NULL, "got %p\n", str);
8596 hr = IXMLDOMDocument_get_prefix(doc, NULL);
8597 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8599 /* 2. cdata */
8600 hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8603 str = (void*)0xdeadbeef;
8604 hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8605 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8606 ok( str == 0, "got %p\n", str);
8608 hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8609 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8610 IXMLDOMCDATASection_Release(cdata);
8612 /* 3. comment */
8613 hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8616 str = (void*)0xdeadbeef;
8617 hr = IXMLDOMComment_get_prefix(comment, &str);
8618 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8619 ok( str == 0, "got %p\n", str);
8621 hr = IXMLDOMComment_get_prefix(comment, NULL);
8622 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8623 IXMLDOMComment_Release(comment);
8625 /* 4. fragment */
8626 hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8629 str = (void*)0xdeadbeef;
8630 hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8631 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8632 ok( str == 0, "got %p\n", str);
8634 hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8635 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8636 IXMLDOMDocumentFragment_Release(fragment);
8638 /* no prefix */
8639 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8642 hr = IXMLDOMElement_get_prefix(element, NULL);
8643 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8645 str = (void*)0xdeadbeef;
8646 hr = IXMLDOMElement_get_prefix(element, &str);
8647 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8648 ok(str == 0, "got %p\n", str);
8650 IXMLDOMElement_Release(element);
8652 /* with prefix */
8653 hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8654 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8656 str = (void*)0xdeadbeef;
8657 hr = IXMLDOMElement_get_prefix(element, &str);
8658 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
8659 ok(lstrcmpW(str, L"a") == 0, "expected prefix \"a\"\n");
8660 SysFreeString(str);
8662 str = (void*)0xdeadbeef;
8663 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8664 ok( hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8665 ok( str == 0, "got %p\n", str);
8667 IXMLDOMElement_Release(element);
8669 hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8670 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8672 hr = IXMLDOMDocument_get_documentElement(doc, &element);
8673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8675 str = (void*)0xdeadbeef;
8676 hr = IXMLDOMElement_get_prefix(element, &str);
8677 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8678 ok(str == NULL, "got %p\n", str);
8680 str = (void*)0xdeadbeef;
8681 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8682 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8683 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8685 IXMLDOMDocument_Release(doc);
8686 free_bstrs();
8689 static void test_selectSingleNode(void)
8691 IXMLDOMDocument *doc;
8692 IXMLDOMNodeList *list;
8693 IXMLDOMNode *node;
8694 VARIANT_BOOL b;
8695 HRESULT hr;
8696 LONG len;
8698 doc = create_document(&IID_IXMLDOMDocument);
8700 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8701 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8703 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8704 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8706 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8707 ok( hr == S_OK, "loadXML failed\n");
8708 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8710 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8711 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8713 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8714 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8716 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8717 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8719 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8720 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8722 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8723 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8724 IXMLDOMNode_Release(node);
8726 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8728 IXMLDOMNodeList_Release(list);
8730 list = (void*)0xdeadbeef;
8731 hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8732 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8733 ok(list == (void*)0xdeadbeef, "got %p\n", list);
8735 node = (void*)0xdeadbeef;
8736 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8737 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8738 ok(node == 0, "got %p\n", node);
8740 list = (void*)0xdeadbeef;
8741 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8742 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8743 len = 1;
8744 hr = IXMLDOMNodeList_get_length(list, &len);
8745 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8746 ok(len == 0, "got %ld\n", len);
8747 IXMLDOMNodeList_Release(list);
8749 IXMLDOMDocument_Release(doc);
8750 free_bstrs();
8753 static void test_events(void)
8755 IConnectionPointContainer *conn;
8756 IConnectionPoint *point;
8757 IXMLDOMDocument *doc;
8758 HRESULT hr;
8759 VARIANT v;
8760 IDispatch *event;
8762 doc = create_document(&IID_IXMLDOMDocument);
8764 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8767 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8768 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8769 IConnectionPoint_Release(point);
8770 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8772 IConnectionPoint_Release(point);
8773 hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8775 IConnectionPoint_Release(point);
8777 IConnectionPointContainer_Release(conn);
8779 /* ready state callback */
8780 VariantInit(&v);
8781 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8782 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr);
8784 event = create_dispevent();
8785 V_VT(&v) = VT_UNKNOWN;
8786 V_UNKNOWN(&v) = (IUnknown*)event;
8788 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8790 EXPECT_REF(event, 2);
8792 V_VT(&v) = VT_DISPATCH;
8793 V_DISPATCH(&v) = event;
8795 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8796 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8797 EXPECT_REF(event, 2);
8799 /* VT_NULL doesn't reset event handler */
8800 V_VT(&v) = VT_NULL;
8801 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8802 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr);
8803 EXPECT_REF(event, 2);
8805 V_VT(&v) = VT_DISPATCH;
8806 V_DISPATCH(&v) = NULL;
8808 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8810 EXPECT_REF(event, 1);
8812 V_VT(&v) = VT_UNKNOWN;
8813 V_DISPATCH(&v) = NULL;
8814 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8817 IDispatch_Release(event);
8819 IXMLDOMDocument_Release(doc);
8822 static void test_createProcessingInstruction(void)
8824 static const WCHAR xml1[] = L"<?xml version=\"1.0\"?>\r\n<test/>\r\n";
8825 static const char xml2[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\r\n<test/>\r\n";
8826 static const char xml2_wine[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n<test/>\n";
8827 static const char xml3[] = "<?xml version=\"1.0\" standalone=\"yes\"?>\r\n<test/>\r\n";
8828 static const char xml3_wine[] = "<?xml version=\"1.0\" standalone=\"yes\"?>\n<test/>\n";
8829 IXMLDOMProcessingInstruction *pi;
8830 IXMLDOMDocument *doc;
8831 IXMLDOMNode *node, *item;
8832 IXMLDOMNamedNodeMap *node_map;
8833 IXMLDOMElement *element;
8834 WCHAR buff[10];
8835 BSTR xml, bstr;
8836 VARIANT var;
8837 HRESULT hr;
8838 IStream *stream;
8839 LARGE_INTEGER off;
8840 VARIANT_BOOL b;
8841 HGLOBAL global;
8842 char *p;
8844 doc = create_document(&IID_IXMLDOMDocument);
8846 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding=\"windows-1252\" dummy=\"value\""), &pi);
8847 ok(hr == XML_E_UNEXPECTED_ATTRIBUTE, "Unexpected hr %#lx.\n", hr);
8848 hr = IXMLDOMDocument_createProcessingInstruction(doc, NULL, _bstr_("version=\"1.0\" encoding=\"UTF-8\""), &pi);
8849 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
8850 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), NULL, &pi);
8851 ok(hr == XML_E_XMLDECLSYNTAX, "Unexpected hr %#lx.\n", hr);
8852 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding=UTF-8"), &pi);
8853 ok(hr == XML_E_MISSINGQUOTE, "Unexpected hr %#lx.\n", hr);
8854 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding='UTF-8\""), &pi);
8855 ok(hr == XML_E_BADCHARINSTRING, "Unexpected hr %#lx.\n", hr);
8856 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding=\"UTF-8"), &pi);
8857 ok(hr == XML_E_BADCHARINSTRING, "Unexpected hr %#lx.\n", hr);
8858 pi = NULL;
8859 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding='UTF-8'"), &pi);
8860 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8861 hr = IXMLDOMProcessingInstruction_QueryInterface(pi, &IID_IXMLDOMNode, (void **)&node);
8862 node_map = NULL;
8863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8864 hr = IXMLDOMNode_get_attributes(node, &node_map);
8865 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8866 IXMLDOMNamedNodeMap_Release(node_map);
8867 IXMLDOMNode_Release(node);
8868 IXMLDOMProcessingInstruction_Release(pi);
8870 /* test for BSTR handling, pass broken BSTR */
8871 memcpy(&buff[2], L"test", 5 * sizeof(WCHAR));
8872 /* just a big length */
8873 *(DWORD*)buff = 0xf0f0;
8874 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
8875 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8877 IXMLDOMProcessingInstruction_Release(pi);
8878 IXMLDOMDocument_Release(doc);
8880 doc = create_document(&IID_IXMLDOMDocument);
8882 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\" encoding=\"windows-1252\""), &pi);
8883 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8884 hr = IXMLDOMProcessingInstruction_QueryInterface(pi, &IID_IXMLDOMNode, (void **)&node);
8885 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8886 hr = IXMLDOMDocument_appendChild(doc, node, NULL);
8887 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8889 hr = IXMLDOMNode_get_attributes(node, &node_map);
8890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8892 item = (void *)0xdeadbeef;
8893 hr = IXMLDOMNamedNodeMap_getNamedItem(node_map, _bstr_("xml"), &item);
8894 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
8895 ok(!item, "got %p\n", item);
8897 item = NULL;
8898 hr = IXMLDOMNamedNodeMap_getNamedItem(node_map, _bstr_("encoding"), &item);
8899 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8900 ok(item != NULL, "got NULL\n");
8902 hr = IXMLDOMNode_get_nodeName(item, &bstr);
8903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8904 ok(!lstrcmpW(bstr, L"encoding"), "got %s\n", wine_dbgstr_w(bstr));
8905 SysFreeString(bstr);
8907 VariantInit(&var);
8908 hr = IXMLDOMNode_get_nodeValue(item, &var);
8909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8910 ok(V_VT(&var) == VT_BSTR, "got %u\n", V_VT(&var));
8911 ok(!lstrcmpW(V_BSTR(&var), L"windows-1252"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
8912 VariantClear(&var);
8914 IXMLDOMNamedNodeMap_Release(node_map);
8915 IXMLDOMNode_Release(node);
8916 IXMLDOMProcessingInstruction_Release(pi);
8918 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &element);
8919 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8920 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode *)element, NULL);
8921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8922 IXMLDOMElement_Release(element);
8924 hr = IXMLDOMDocument_get_xml(doc, &xml);
8925 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8926 todo_wine
8927 ok(!wcscmp(xml, xml1), "got %s\n", wine_dbgstr_w(xml));
8928 SysFreeString(xml);
8930 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
8931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8932 V_VT(&var) = VT_UNKNOWN;
8933 V_UNKNOWN(&var) = (IUnknown*)stream;
8934 hr = IXMLDOMDocument_save(doc, var);
8935 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8937 hr = GetHGlobalFromStream(stream, &global);
8938 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8939 p = GlobalLock(global);
8940 ok(!memcmp(p, xml2, sizeof(xml2) - 1) || !memcmp(p, xml2_wine, sizeof(xml2_wine) - 1), "got %s\n", wine_dbgstr_a(p));
8941 GlobalUnlock(global);
8943 /* Verify the result after load+save */
8944 off.QuadPart = 0;
8945 hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
8946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8948 hr = IXMLDOMDocument_load(doc, var, &b);
8949 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8950 ok(b == VARIANT_TRUE, "got %d\n", b);
8952 off.QuadPart = 0;
8953 hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
8954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8956 hr = IXMLDOMDocument_save(doc, var);
8957 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8959 hr = GetHGlobalFromStream(stream, &global);
8960 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8961 p = GlobalLock(global);
8962 ok(!memcmp(p, xml2, sizeof(xml2) - 1) || !memcmp(p, xml2_wine, sizeof(xml2_wine) - 1), "got %s\n", wine_dbgstr_a(p));
8963 GlobalUnlock(global);
8965 IStream_Release(stream);
8967 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\" standalone=\"yes\"?>\r\n<test/>\r\n"), &b);
8968 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8969 ok(b == VARIANT_TRUE, "got %d\n", b);
8971 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
8972 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8974 V_VT(&var) = VT_UNKNOWN;
8975 V_UNKNOWN(&var) = (IUnknown*)stream;
8976 hr = IXMLDOMDocument_save(doc, var);
8977 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8979 hr = GetHGlobalFromStream(stream, &global);
8980 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8982 p = GlobalLock(global);
8983 ok(!memcmp(p, xml3, sizeof(xml3) - 1) || !memcmp(p, xml3_wine, sizeof(xml3_wine) - 1), "got %s\n", wine_dbgstr_a(p));
8984 GlobalUnlock(global);
8986 IStream_Release(stream);
8987 IXMLDOMDocument_Release(doc);
8990 static void test_put_nodeTypedValue(void)
8992 static const BYTE binhexdata[16] =
8993 {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
8994 IXMLDOMDocument *doc;
8995 IXMLDOMElement *elem;
8996 VARIANT type, value;
8997 LONG ubound, lbound;
8998 IXMLDOMNode *node;
8999 SAFEARRAY *array;
9000 HRESULT hr;
9001 BYTE *ptr;
9002 BSTR str;
9004 doc = create_document(&IID_IXMLDOMDocument);
9006 hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
9007 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9009 V_VT(&type) = VT_EMPTY;
9010 hr = IXMLDOMElement_get_dataType(elem, &type);
9011 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
9012 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9014 /* set typed value for untyped node */
9015 V_VT(&type) = VT_I1;
9016 V_I1(&type) = 1;
9017 hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
9018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9020 V_VT(&type) = VT_EMPTY;
9021 hr = IXMLDOMElement_get_dataType(elem, &type);
9022 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
9023 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
9025 /* no type info stored */
9026 V_VT(&type) = VT_EMPTY;
9027 hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
9028 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9029 ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
9030 ok(memcmp(V_BSTR(&type), L"1", 2*sizeof(WCHAR)) == 0,
9031 "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
9032 VariantClear(&type);
9034 /* int */
9035 hr = IXMLDOMElement_put_dataType(elem, _bstr_("int"));
9036 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9038 V_VT(&value) = VT_BSTR;
9039 V_BSTR(&value) = _bstr_("1");
9040 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9041 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9043 V_VT(&value) = VT_EMPTY;
9044 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9045 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9046 ok(V_VT(&value) == VT_I4, "got %d\n", V_VT(&value));
9047 ok(V_I4(&value) == 1, "got %ld\n", V_I4(&value));
9049 V_VT(&value) = VT_I2;
9050 V_I2(&value) = -1;
9051 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9054 V_VT(&value) = VT_EMPTY;
9055 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9056 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9057 ok(V_VT(&value) == VT_I4, "got %d\n", V_VT(&value));
9058 ok(V_I4(&value) == -1, "got %ld\n", V_I4(&value));
9060 hr = IXMLDOMElement_get_firstChild(elem, &node);
9061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9062 hr = IXMLDOMElement_removeChild(elem, node, NULL);
9063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9064 IXMLDOMNode_Release(node);
9066 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)elem, NULL);
9067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9069 /* bin.base64 */
9070 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.base64"));
9071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9073 V_VT(&value) = VT_BSTR;
9074 V_BSTR(&value) = _bstr_("ABCD");
9075 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9076 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9078 V_VT(&value) = VT_EMPTY;
9079 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9081 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9082 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9083 ubound = 0;
9084 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9085 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9086 ok(ubound == 2, "got %ld\n", ubound);
9087 lbound = 0;
9088 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9089 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9090 ok(lbound == 0, "got %ld\n", lbound);
9091 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9092 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9093 ok(ptr[0] == 0, "got %x\n", ptr[0]);
9094 ok(ptr[1] == 0x10, "got %x\n", ptr[1]);
9095 ok(ptr[2] == 0x83, "got %x\n", ptr[2]);
9096 SafeArrayUnaccessData(V_ARRAY(&value));
9097 VariantClear(&value);
9099 /* when set as VT_BSTR it's stored as is */
9100 hr = IXMLDOMElement_get_firstChild(elem, &node);
9101 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9102 hr = IXMLDOMNode_get_text(node, &str);
9103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9104 ok(!lstrcmpW(str, L"ABCD"), "%s\n", wine_dbgstr_w(str));
9105 IXMLDOMNode_Release(node);
9106 SysFreeString(str);
9108 array = SafeArrayCreateVector(VT_UI1, 0, 7);
9109 hr = SafeArrayAccessData(array, (void*)&ptr);
9110 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9111 memcpy(ptr, "dGVzdA=", strlen("dGVzdA="));
9112 SafeArrayUnaccessData(array);
9114 V_VT(&value) = VT_UI1|VT_ARRAY;
9115 V_ARRAY(&value) = array;
9116 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9119 V_VT(&value) = VT_EMPTY;
9120 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9122 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9123 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9124 ubound = 0;
9125 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9126 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9127 ok(ubound == 6, "got %ld\n", ubound);
9128 lbound = 0;
9129 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9131 ok(lbound == 0, "got %ld\n", lbound);
9132 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9133 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9134 ok(!memcmp(ptr, "dGVzdA=", strlen("dGVzdA=")), "got wrong data, %s\n", ptr);
9135 SafeArrayUnaccessData(V_ARRAY(&value));
9136 VariantClear(&value);
9138 /* if set with VT_UI1|VT_ARRAY it's encoded */
9139 hr = IXMLDOMElement_get_firstChild(elem, &node);
9140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9141 hr = IXMLDOMNode_get_text(node, &str);
9142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9143 ok(!lstrcmpW(str, L"ZEdWemRBPQ=="), "%s\n", wine_dbgstr_w(str));
9144 IXMLDOMNode_Release(node);
9145 SafeArrayDestroyData(array);
9146 SysFreeString(str);
9148 /* bin.hex */
9149 V_VT(&value) = VT_BSTR;
9150 V_BSTR(&value) = _bstr_("");
9151 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9152 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9154 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.hex"));
9155 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9157 array = SafeArrayCreateVector(VT_UI1, 0, 16);
9158 hr = SafeArrayAccessData(array, (void*)&ptr);
9159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9160 memcpy(ptr, binhexdata, sizeof(binhexdata));
9161 SafeArrayUnaccessData(array);
9163 V_VT(&value) = VT_UI1|VT_ARRAY;
9164 V_ARRAY(&value) = array;
9165 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
9166 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9168 V_VT(&value) = VT_EMPTY;
9169 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
9170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9171 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
9172 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
9173 ubound = 0;
9174 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
9175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9176 ok(ubound == 15, "got %ld\n", ubound);
9177 lbound = 0;
9178 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
9179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9180 ok(lbound == 0, "got %ld\n", lbound);
9181 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
9182 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9183 ok(!memcmp(ptr, binhexdata, sizeof(binhexdata)), "got wrong data\n");
9184 SafeArrayUnaccessData(V_ARRAY(&value));
9185 VariantClear(&value);
9187 /* if set with VT_UI1|VT_ARRAY it's encoded */
9188 hr = IXMLDOMElement_get_firstChild(elem, &node);
9189 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9190 hr = IXMLDOMNode_get_text(node, &str);
9191 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9192 ok(!lstrcmpW(str, L"000102030405060708090a0b0c0d0e0f"), "%s\n", wine_dbgstr_w(str));
9193 IXMLDOMNode_Release(node);
9194 SafeArrayDestroyData(array);
9195 SysFreeString(str);
9197 IXMLDOMElement_Release(elem);
9198 IXMLDOMDocument_Release(doc);
9199 free_bstrs();
9202 static void test_get_xml(void)
9204 static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
9205 static const char attrA[] = "attr=\"&quot;a &amp; b&quot;\"";
9206 static const char attr2A[] = "\"a & b\"";
9207 static const char attr3A[] = "attr=\"&amp;quot;a\"";
9208 static const char attr4A[] = "&quot;a";
9209 static const char fooA[] = "<foo/>";
9210 IXMLDOMProcessingInstruction *pi;
9211 IXMLDOMNode *first;
9212 IXMLDOMElement *elem = NULL;
9213 IXMLDOMAttribute *attr;
9214 IXMLDOMDocument *doc;
9215 VARIANT_BOOL b;
9216 VARIANT v;
9217 BSTR xml;
9218 HRESULT hr;
9220 doc = create_document(&IID_IXMLDOMDocument);
9222 b = VARIANT_TRUE;
9223 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9224 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9225 ok( b == VARIANT_TRUE, "got %d\n", b);
9227 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
9228 _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
9229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9231 hr = IXMLDOMDocument_get_firstChild(doc, &first);
9232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9234 V_UNKNOWN(&v) = (IUnknown*)first;
9235 V_VT(&v) = VT_UNKNOWN;
9237 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
9238 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9240 IXMLDOMProcessingInstruction_Release(pi);
9241 IXMLDOMNode_Release(first);
9243 hr = IXMLDOMDocument_get_xml(doc, &xml);
9244 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9246 ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
9247 "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
9248 SysFreeString(xml);
9250 IXMLDOMDocument_Release(doc);
9252 doc = create_document(&IID_IXMLDOMDocument);
9254 hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
9255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9257 hr = IXMLDOMDocument_putref_documentElement(doc, elem);
9258 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9260 hr = IXMLDOMDocument_get_xml(doc, &xml);
9261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9263 ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
9264 "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
9265 SysFreeString(xml);
9267 IXMLDOMElement_Release(elem);
9269 /* attribute node */
9270 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
9271 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9273 V_VT(&v) = VT_BSTR;
9274 V_BSTR(&v) = _bstr_("\"a & b\"");
9275 hr = IXMLDOMAttribute_put_value(attr, v);
9276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9278 xml = NULL;
9279 hr = IXMLDOMAttribute_get_xml(attr, &xml);
9280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9281 ok(!memcmp(xml, _bstr_(attrA), (sizeof(attrA)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
9282 SysFreeString(xml);
9284 VariantInit(&v);
9285 hr = IXMLDOMAttribute_get_value(attr, &v);
9286 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9287 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9288 ok(!memcmp(V_BSTR(&v), _bstr_(attr2A), (sizeof(attr2A)-1)*sizeof(WCHAR)),
9289 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9290 VariantClear(&v);
9292 V_VT(&v) = VT_BSTR;
9293 V_BSTR(&v) = _bstr_("&quot;a");
9294 hr = IXMLDOMAttribute_put_value(attr, v);
9295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9297 xml = NULL;
9298 hr = IXMLDOMAttribute_get_xml(attr, &xml);
9299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9300 ok(!memcmp(xml, _bstr_(attr3A), (sizeof(attr3A)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
9301 SysFreeString(xml);
9303 VariantInit(&v);
9304 hr = IXMLDOMAttribute_get_value(attr, &v);
9305 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9306 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9307 ok(!memcmp(V_BSTR(&v), _bstr_(attr4A), (sizeof(attr4A)-1)*sizeof(WCHAR)),
9308 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9309 VariantClear(&v);
9311 IXMLDOMAttribute_Release(attr);
9313 IXMLDOMDocument_Release(doc);
9315 free_bstrs();
9318 static void test_xsltemplate(void)
9320 IXMLDOMDocument *doc, *doc2, *doc3;
9321 IXSLTemplate *template;
9322 IXSLProcessor *processor;
9323 IStream *stream;
9324 VARIANT_BOOL b;
9325 HRESULT hr;
9326 ULONG ref1, ref2;
9327 VARIANT v;
9328 BSTR str;
9330 if (!is_clsid_supported(&CLSID_XSLTemplate, &IID_IXSLTemplate)) return;
9331 template = create_xsltemplate(&IID_IXSLTemplate);
9333 check_interface(template, &IID_IXSLTemplate, TRUE);
9334 check_interface(template, &IID_IDispatch, TRUE);
9335 check_interface(template, &IID_IDispatchEx, TRUE);
9337 /* works as reset */
9338 hr = IXSLTemplate_putref_stylesheet(template, NULL);
9339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9341 doc = create_document(&IID_IXMLDOMDocument);
9343 b = VARIANT_TRUE;
9344 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
9345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9346 ok( b == VARIANT_TRUE, "got %d\n", b);
9348 /* putref with non-xsl document */
9349 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9350 todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9352 b = VARIANT_TRUE;
9353 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9355 ok( b == VARIANT_TRUE, "got %d\n", b);
9357 /* not a freethreaded document */
9358 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9359 todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9361 IXMLDOMDocument_Release(doc);
9363 if (!is_clsid_supported(&CLSID_FreeThreadedDOMDocument, &IID_IXMLDOMDocument))
9365 IXSLTemplate_Release(template);
9366 return;
9369 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
9370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9372 b = VARIANT_TRUE;
9373 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
9374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9375 ok( b == VARIANT_TRUE, "got %d\n", b);
9377 /* freethreaded document */
9378 ref1 = IXMLDOMDocument_AddRef(doc);
9379 IXMLDOMDocument_Release(doc);
9380 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
9381 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9382 ref2 = IXMLDOMDocument_AddRef(doc);
9383 IXMLDOMDocument_Release(doc);
9384 ok(ref2 > ref1, "got %ld\n", ref2);
9386 /* processor */
9387 hr = IXSLTemplate_createProcessor(template, NULL);
9388 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9390 EXPECT_REF(template, 1);
9391 hr = IXSLTemplate_createProcessor(template, &processor);
9392 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9393 EXPECT_REF(template, 2);
9395 /* input no set yet */
9396 V_VT(&v) = VT_BSTR;
9397 V_BSTR(&v) = NULL;
9398 hr = IXSLProcessor_get_input(processor, &v);
9399 todo_wine {
9400 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9401 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
9404 hr = IXSLProcessor_get_output(processor, NULL);
9405 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9407 /* reset before it was set */
9408 V_VT(&v) = VT_EMPTY;
9409 hr = IXSLProcessor_put_output(processor, v);
9410 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9412 V_VT(&v) = VT_UNKNOWN;
9413 V_UNKNOWN(&v) = NULL;
9414 hr = IXSLProcessor_put_output(processor, v);
9415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9417 V_VT(&v) = VT_UNKNOWN;
9418 V_DISPATCH(&v) = NULL;
9419 hr = IXSLProcessor_put_output(processor, v);
9420 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9422 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
9423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9424 EXPECT_REF(stream, 1);
9426 V_VT(&v) = VT_UNKNOWN;
9427 V_UNKNOWN(&v) = (IUnknown*)stream;
9428 hr = IXSLProcessor_put_output(processor, v);
9429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9431 /* it seems processor grabs 2 references */
9432 todo_wine EXPECT_REF(stream, 3);
9434 V_VT(&v) = VT_EMPTY;
9435 hr = IXSLProcessor_get_output(processor, &v);
9436 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9437 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9438 ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
9440 todo_wine EXPECT_REF(stream, 4);
9441 VariantClear(&v);
9443 hr = IXSLProcessor_transform(processor, NULL);
9444 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9446 /* reset and check stream refcount */
9447 V_VT(&v) = VT_EMPTY;
9448 hr = IXSLProcessor_put_output(processor, v);
9449 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9451 EXPECT_REF(stream, 1);
9453 IStream_Release(stream);
9455 /* no output interface set, check output */
9456 doc2 = create_document(&IID_IXMLDOMDocument);
9458 b = VARIANT_FALSE;
9459 hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
9460 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9461 ok( b == VARIANT_TRUE, "got %d\n", b);
9463 V_VT(&v) = VT_UNKNOWN;
9464 V_UNKNOWN(&v) = (IUnknown*)doc2;
9465 hr = IXSLProcessor_put_input(processor, v);
9466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9468 hr = IXSLProcessor_transform(processor, &b);
9469 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9471 V_VT(&v) = VT_EMPTY;
9472 hr = IXSLProcessor_get_output(processor, &v);
9473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9474 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
9475 ok(*V_BSTR(&v) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
9476 VariantClear(&v);
9478 /* transform to document */
9479 b = VARIANT_FALSE;
9480 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformXML), &b);
9481 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9482 ok(b == VARIANT_TRUE, "got %d\n", b);
9484 V_VT(&v) = VT_UNKNOWN;
9485 V_UNKNOWN(&v) = (IUnknown*)doc2;
9486 hr = IXSLProcessor_put_input(processor, v);
9487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9489 doc3 = create_document(&IID_IXMLDOMDocument);
9490 V_VT(&v) = VT_UNKNOWN;
9491 V_UNKNOWN(&v) = (IUnknown *)doc3;
9492 hr = IXSLProcessor_put_output(processor, v);
9493 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9495 hr = IXMLDOMDocument_get_xml(doc3, &str);
9496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9497 ok(!*str, "Expected empty document\n");
9498 SysFreeString(str);
9500 hr = IXSLProcessor_transform(processor, &b);
9501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9503 V_VT(&v) = VT_EMPTY;
9504 hr = IXSLProcessor_get_output(processor, &v);
9505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9506 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
9507 VariantClear(&v);
9509 hr = IXMLDOMDocument_get_xml(doc3, &str);
9510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9511 ok(!!*str, "Expected document\n");
9512 SysFreeString(str);
9514 /* transform to IResponse */
9515 V_VT(&v) = VT_EMPTY;
9516 hr = IXSLProcessor_put_output(processor, v);
9517 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9519 V_VT(&v) = VT_UNKNOWN;
9520 V_UNKNOWN(&v) = (IUnknown *)&testresponse;
9521 hr = IXSLProcessor_put_output(processor, v);
9522 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9524 b = VARIANT_FALSE;
9525 hr = IXSLProcessor_transform(processor, &b);
9526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9527 ok(b == VARIANT_TRUE, "got %x\n", b);
9529 IXSLProcessor_Release(processor);
9530 IXMLDOMDocument_Release(doc2);
9531 IXMLDOMDocument_Release(doc3);
9533 /* drop reference */
9534 hr = IXSLTemplate_putref_stylesheet(template, NULL);
9535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9536 ref2 = IXMLDOMDocument_AddRef(doc);
9537 IXMLDOMDocument_Release(doc);
9538 ok(ref2 == ref1, "got %ld\n", ref2);
9540 IXMLDOMDocument_Release(doc);
9541 IXSLTemplate_Release(template);
9542 free_bstrs();
9545 static void test_insertBefore(void)
9547 IXMLDOMDocument *doc, *doc2, *doc3;
9548 IXMLDOMAttribute *attr;
9549 IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9550 IXMLDOMNode *node, *newnode, *cdata;
9551 HRESULT hr;
9552 VARIANT v;
9553 BSTR p;
9555 doc = create_document(&IID_IXMLDOMDocument);
9556 doc3 = create_document(&IID_IXMLDOMDocument);
9558 /* NULL to document */
9559 V_VT(&v) = VT_NULL;
9560 node = (void*)0xdeadbeef;
9561 hr = IXMLDOMDocument_insertBefore(doc, NULL, v, &node);
9562 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9563 ok(node == (void*)0xdeadbeef, "got %p\n", node);
9565 /* document to document */
9566 V_VT(&v) = VT_NULL;
9567 node = (void*)0xdeadbeef;
9568 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc3, v, &node);
9569 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9570 ok(node == NULL, "got %p\n", node);
9572 /* document to itself */
9573 V_VT(&v) = VT_NULL;
9574 node = (void*)0xdeadbeef;
9575 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc, v, &node);
9576 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9577 ok(node == NULL, "got %p\n", node);
9579 /* insertBefore behaviour for attribute node */
9580 V_VT(&v) = VT_I4;
9581 V_I4(&v) = NODE_ATTRIBUTE;
9583 attr = NULL;
9584 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9585 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9586 ok(attr != NULL, "got %p\n", attr);
9588 /* attribute to document */
9589 V_VT(&v) = VT_NULL;
9590 node = (void*)0xdeadbeef;
9591 hr = IXMLDOMDocument_insertBefore(doc3, (IXMLDOMNode*)attr, v, &node);
9592 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9593 ok(node == NULL, "got %p\n", node);
9595 /* cdata to document */
9596 V_VT(&v) = VT_I4;
9597 V_I4(&v) = NODE_CDATA_SECTION;
9599 cdata = NULL;
9600 hr = IXMLDOMDocument_createNode(doc3, v, _bstr_("cdata"), NULL, &cdata);
9601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9602 ok(cdata != NULL, "got %p\n", cdata);
9604 EXPECT_NO_CHILDREN(cdata);
9606 /* attribute to cdata */
9607 V_VT(&v) = VT_NULL;
9608 node = (void*)0xdeadbeef;
9609 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)attr, v, &node);
9610 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9611 ok(node == NULL, "got %p\n", node);
9613 /* document to cdata */
9614 V_VT(&v) = VT_NULL;
9615 node = (void*)0xdeadbeef;
9616 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)doc, v, &node);
9617 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9618 ok(node == NULL, "got %p\n", node);
9620 V_VT(&v) = VT_NULL;
9621 node = (void*)0xdeadbeef;
9622 hr = IXMLDOMDocument_insertBefore(doc3, cdata, v, &node);
9623 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9624 ok(node == NULL, "got %p\n", node);
9626 IXMLDOMNode_Release(cdata);
9627 IXMLDOMDocument_Release(doc3);
9629 /* attribute to attribute */
9630 V_VT(&v) = VT_I4;
9631 V_I4(&v) = NODE_ATTRIBUTE;
9632 newnode = NULL;
9633 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9634 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9635 ok(newnode != NULL, "got %p\n", newnode);
9637 V_VT(&v) = VT_NULL;
9638 node = (void*)0xdeadbeef;
9639 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9640 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9641 ok(node == NULL, "got %p\n", node);
9643 V_VT(&v) = VT_UNKNOWN;
9644 V_UNKNOWN(&v) = (IUnknown*)attr;
9645 node = (void*)0xdeadbeef;
9646 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9647 todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9648 ok(node == NULL, "got %p\n", node);
9649 IXMLDOMNode_Release(newnode);
9651 /* cdata to attribute */
9652 V_VT(&v) = VT_I4;
9653 V_I4(&v) = NODE_CDATA_SECTION;
9654 newnode = NULL;
9655 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9656 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9657 ok(newnode != NULL, "got %p\n", newnode);
9659 V_VT(&v) = VT_NULL;
9660 node = (void*)0xdeadbeef;
9661 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9662 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9663 ok(node == NULL, "got %p\n", node);
9664 IXMLDOMNode_Release(newnode);
9666 /* comment to attribute */
9667 V_VT(&v) = VT_I4;
9668 V_I4(&v) = NODE_COMMENT;
9669 newnode = NULL;
9670 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9671 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9672 ok(newnode != NULL, "got %p\n", newnode);
9674 V_VT(&v) = VT_NULL;
9675 node = (void*)0xdeadbeef;
9676 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9677 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9678 ok(node == NULL, "got %p\n", node);
9679 IXMLDOMNode_Release(newnode);
9681 /* element to attribute */
9682 V_VT(&v) = VT_I4;
9683 V_I4(&v) = NODE_ELEMENT;
9684 newnode = NULL;
9685 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9687 ok(newnode != NULL, "got %p\n", newnode);
9689 V_VT(&v) = VT_NULL;
9690 node = (void*)0xdeadbeef;
9691 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9692 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9693 ok(node == NULL, "got %p\n", node);
9694 IXMLDOMNode_Release(newnode);
9696 /* pi to attribute */
9697 V_VT(&v) = VT_I4;
9698 V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9699 newnode = NULL;
9700 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9701 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9702 ok(newnode != NULL, "got %p\n", newnode);
9704 V_VT(&v) = VT_NULL;
9705 node = (void*)0xdeadbeef;
9706 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9707 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9708 ok(node == NULL, "got %p\n", node);
9709 IXMLDOMNode_Release(newnode);
9710 IXMLDOMAttribute_Release(attr);
9712 /* insertBefore for elements */
9713 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9714 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9716 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9717 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9719 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9720 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9722 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9723 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9725 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9728 EXPECT_NO_CHILDREN(elem1);
9729 EXPECT_NO_CHILDREN(elem2);
9730 EXPECT_NO_CHILDREN(elem3);
9732 todo_wine EXPECT_REF(elem2, 2);
9734 /* NULL to element */
9735 V_VT(&v) = VT_NULL;
9736 node = (void*)0xdeadbeef;
9737 hr = IXMLDOMElement_insertBefore(elem1, NULL, v, &node);
9738 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9739 ok(node == (void*)0xdeadbeef, "got %p\n", node);
9741 /* document to element */
9742 V_VT(&v) = VT_DISPATCH;
9743 V_DISPATCH(&v) = NULL;
9744 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)doc, v, NULL);
9745 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
9747 V_VT(&v) = VT_DISPATCH;
9748 V_DISPATCH(&v) = NULL;
9749 node = NULL;
9750 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9751 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9752 ok(node == (void*)elem4, "got %p\n", node);
9754 EXPECT_CHILDREN(elem1);
9755 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9756 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9757 IXMLDOMElement_Release(elem4);
9759 EXPECT_NO_CHILDREN(elem1);
9761 V_VT(&v) = VT_NULL;
9762 node = NULL;
9763 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9764 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9765 ok(node == (void*)elem2, "got %p\n", node);
9767 EXPECT_CHILDREN(elem1);
9768 todo_wine EXPECT_REF(elem2, 3);
9769 IXMLDOMNode_Release(node);
9771 /* again for already linked node */
9772 V_VT(&v) = VT_NULL;
9773 node = NULL;
9774 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9775 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9776 ok(node == (void*)elem2, "got %p\n", node);
9778 EXPECT_CHILDREN(elem1);
9780 /* increments each time */
9781 todo_wine EXPECT_REF(elem2, 3);
9782 IXMLDOMNode_Release(node);
9784 /* try to add to another element */
9785 V_VT(&v) = VT_NULL;
9786 node = (void*)0xdeadbeef;
9787 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9788 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9789 ok(node == (void*)elem2, "got %p\n", node);
9791 EXPECT_CHILDREN(elem3);
9792 EXPECT_NO_CHILDREN(elem1);
9794 IXMLDOMNode_Release(node);
9796 /* cross document case - try to add as child to a node created with other doc */
9797 doc2 = create_document(&IID_IXMLDOMDocument);
9799 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9800 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9801 todo_wine EXPECT_REF(elem4, 2);
9803 /* same name, another instance */
9804 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9806 todo_wine EXPECT_REF(elem5, 2);
9808 todo_wine EXPECT_REF(elem3, 2);
9809 V_VT(&v) = VT_NULL;
9810 node = NULL;
9811 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9813 ok(node == (void*)elem4, "got %p\n", node);
9814 todo_wine EXPECT_REF(elem4, 3);
9815 todo_wine EXPECT_REF(elem3, 2);
9816 IXMLDOMNode_Release(node);
9818 V_VT(&v) = VT_NULL;
9819 node = NULL;
9820 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9822 ok(node == (void*)elem5, "got %p\n", node);
9823 todo_wine EXPECT_REF(elem4, 2);
9824 todo_wine EXPECT_REF(elem5, 3);
9825 IXMLDOMNode_Release(node);
9827 IXMLDOMDocument_Release(doc2);
9829 IXMLDOMElement_Release(elem1);
9830 IXMLDOMElement_Release(elem2);
9831 IXMLDOMElement_Release(elem3);
9832 IXMLDOMElement_Release(elem4);
9833 IXMLDOMElement_Release(elem5);
9835 /* elements with same default namespace */
9836 V_VT(&v) = VT_I4;
9837 V_I4(&v) = NODE_ELEMENT;
9838 elem1 = NULL;
9839 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9841 ok(elem1 != NULL, "got %p\n", elem1);
9843 V_VT(&v) = VT_I4;
9844 V_I4(&v) = NODE_ELEMENT;
9845 elem2 = NULL;
9846 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9847 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9848 ok(elem2 != NULL, "got %p\n", elem2);
9850 /* check contents so far */
9851 p = NULL;
9852 hr = IXMLDOMElement_get_xml(elem1, &p);
9853 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9854 ok(!lstrcmpW(p, L"<elem1 xmlns=\"http://winehq.org/default\"/>"), "got %s\n", wine_dbgstr_w(p));
9855 SysFreeString(p);
9857 p = NULL;
9858 hr = IXMLDOMElement_get_xml(elem2, &p);
9859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9860 ok(!lstrcmpW(p, L"<elem2 xmlns=\"http://winehq.org/default\"/>"), "got %s\n", wine_dbgstr_w(p));
9861 SysFreeString(p);
9863 V_VT(&v) = VT_NULL;
9864 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9865 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9867 /* get_xml depends on context, for top node it omits child namespace attribute,
9868 but at child level it's still returned */
9869 p = NULL;
9870 hr = IXMLDOMElement_get_xml(elem1, &p);
9871 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9872 todo_wine ok(!lstrcmpW(p, L"<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>"),
9873 "got %s\n", wine_dbgstr_w(p));
9874 SysFreeString(p);
9876 p = NULL;
9877 hr = IXMLDOMElement_get_xml(elem2, &p);
9878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9879 ok(!lstrcmpW(p, L"<elem2 xmlns=\"http://winehq.org/default\"/>"), "got %s\n", wine_dbgstr_w(p));
9880 SysFreeString(p);
9882 IXMLDOMElement_Release(elem1);
9883 IXMLDOMElement_Release(elem2);
9885 /* child without default namespace added to node with default namespace */
9886 V_VT(&v) = VT_I4;
9887 V_I4(&v) = NODE_ELEMENT;
9888 elem1 = NULL;
9889 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9891 ok(elem1 != NULL, "got %p\n", elem1);
9893 V_VT(&v) = VT_I4;
9894 V_I4(&v) = NODE_ELEMENT;
9895 elem2 = NULL;
9896 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9897 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9898 ok(elem2 != NULL, "got %p\n", elem2);
9900 EXPECT_REF(elem2, 1);
9901 V_VT(&v) = VT_NULL;
9902 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9904 EXPECT_REF(elem2, 1);
9906 p = NULL;
9907 hr = IXMLDOMElement_get_xml(elem2, &p);
9908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9909 ok(!lstrcmpW(p, L"<elem2/>"), "got %s\n", wine_dbgstr_w(p));
9910 SysFreeString(p);
9912 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9915 p = NULL;
9916 hr = IXMLDOMElement_get_xml(elem2, &p);
9917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9918 ok(!lstrcmpW(p, L"<elem2/>"), "got %s\n", wine_dbgstr_w(p));
9919 SysFreeString(p);
9921 IXMLDOMElement_Release(elem1);
9922 IXMLDOMElement_Release(elem2);
9923 IXMLDOMDocument_Release(doc);
9926 static void test_appendChild(void)
9928 IXMLDOMDocument *doc, *doc2;
9929 IXMLDOMElement *elem, *elem2;
9930 HRESULT hr;
9932 doc = create_document(&IID_IXMLDOMDocument);
9933 doc2 = create_document(&IID_IXMLDOMDocument);
9935 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9936 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9938 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9941 EXPECT_REF(doc, 1);
9942 todo_wine EXPECT_REF(elem, 2);
9943 EXPECT_REF(doc2, 1);
9944 todo_wine EXPECT_REF(elem2, 2);
9945 EXPECT_NO_CHILDREN(doc);
9946 EXPECT_NO_CHILDREN(doc2);
9948 hr = IXMLDOMDocument_appendChild(doc2, NULL, NULL);
9949 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9951 hr = IXMLDOMElement_appendChild(elem, NULL, NULL);
9952 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9954 /* append from another document */
9955 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9958 EXPECT_REF(doc, 1);
9959 todo_wine EXPECT_REF(elem, 2);
9960 EXPECT_REF(doc2, 1);
9961 todo_wine EXPECT_REF(elem2, 2);
9962 EXPECT_NO_CHILDREN(doc);
9963 EXPECT_CHILDREN(doc2);
9965 IXMLDOMElement_Release(elem);
9966 IXMLDOMElement_Release(elem2);
9967 IXMLDOMDocument_Release(doc);
9968 IXMLDOMDocument_Release(doc2);
9971 static void test_get_doctype(void)
9973 IXMLDOMDocumentType *doctype;
9974 IXMLDOMDocument *doc;
9975 VARIANT_BOOL b;
9976 HRESULT hr;
9977 BSTR s;
9979 doc = create_document(&IID_IXMLDOMDocument);
9981 hr = IXMLDOMDocument_get_doctype(doc, NULL);
9982 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9984 doctype = (void*)0xdeadbeef;
9985 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9986 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
9987 ok(doctype == NULL, "got %p\n", doctype);
9989 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szEmailXML), &b);
9990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9991 ok(b == VARIANT_TRUE, "failed to load XML string\n");
9993 doctype = NULL;
9994 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9996 ok(doctype != NULL, "got %p\n", doctype);
9998 hr = IXMLDOMDocumentType_get_name(doctype, NULL);
9999 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10001 hr = IXMLDOMDocumentType_get_name(doctype, &s);
10002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10003 ok(!lstrcmpW(L"email", s), "got name %s\n", wine_dbgstr_w(s));
10004 SysFreeString(s);
10006 hr = IXMLDOMDocumentType_get_nodeName(doctype, &s);
10007 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10008 ok(!lstrcmpW(L"email", s), "got name %s\n", wine_dbgstr_w(s));
10009 SysFreeString(s);
10011 IXMLDOMDocumentType_Release(doctype);
10012 IXMLDOMDocument_Release(doc);
10015 static void test_get_tagName(void)
10017 IXMLDOMDocument *doc;
10018 IXMLDOMElement *elem, *elem2;
10019 HRESULT hr;
10020 BSTR str;
10022 doc = create_document(&IID_IXMLDOMDocument);
10024 hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
10025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10027 hr = IXMLDOMElement_get_tagName(elem, NULL);
10028 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10030 str = NULL;
10031 hr = IXMLDOMElement_get_tagName(elem, &str);
10032 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10033 ok(!lstrcmpW(str, L"element"), "got %s\n", wine_dbgstr_w(str));
10034 SysFreeString(str);
10036 hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
10037 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10039 str = NULL;
10040 hr = IXMLDOMElement_get_tagName(elem2, &str);
10041 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10042 ok(!lstrcmpW(str, L"s:element"), "got %s\n", wine_dbgstr_w(str));
10043 SysFreeString(str);
10045 IXMLDOMElement_Release(elem);
10046 IXMLDOMElement_Release(elem2);
10047 IXMLDOMDocument_Release(doc);
10048 free_bstrs();
10051 typedef struct {
10052 DOMNodeType type;
10053 const char *name;
10054 VARTYPE vt;
10055 HRESULT hr;
10056 } node_type_t;
10058 static const node_type_t get_datatype[] = {
10059 { NODE_ELEMENT, "element", VT_NULL, S_FALSE },
10060 { NODE_ATTRIBUTE, "attr", VT_NULL, S_FALSE },
10061 { NODE_TEXT, "text", VT_NULL, S_FALSE },
10062 { NODE_CDATA_SECTION , "cdata", VT_NULL, S_FALSE },
10063 { NODE_ENTITY_REFERENCE, "entityref", VT_NULL, S_FALSE },
10064 { NODE_PROCESSING_INSTRUCTION, "pi", VT_NULL, S_FALSE },
10065 { NODE_COMMENT, "comment", VT_NULL, S_FALSE },
10066 { NODE_DOCUMENT_FRAGMENT, "docfrag", VT_NULL, S_FALSE },
10067 { 0 }
10070 static void test_get_dataType(void)
10072 const node_type_t *entry = get_datatype;
10073 IXMLDOMDocument *doc;
10075 doc = create_document(&IID_IXMLDOMDocument);
10077 while (entry->type)
10079 IXMLDOMNode *node = NULL;
10080 VARIANT var, type;
10081 HRESULT hr;
10083 V_VT(&var) = VT_I4;
10084 V_I4(&var) = entry->type;
10085 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
10086 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10088 hr = IXMLDOMNode_get_dataType(node, NULL);
10089 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10091 VariantInit(&type);
10092 hr = IXMLDOMNode_get_dataType(node, &type);
10093 ok(hr == entry->hr, "Unexpected hr %#lx, expected %#lx. node type %d\n",
10094 hr, entry->hr, entry->type);
10095 ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
10096 V_VT(&type), entry->vt, entry->type);
10097 VariantClear(&type);
10099 IXMLDOMNode_Release(node);
10101 entry++;
10104 IXMLDOMDocument_Release(doc);
10105 free_bstrs();
10108 typedef struct _get_node_typestring_t {
10109 DOMNodeType type;
10110 const char *string;
10111 } get_node_typestring_t;
10113 static const get_node_typestring_t get_node_typestring[] = {
10114 { NODE_ELEMENT, "element" },
10115 { NODE_ATTRIBUTE, "attribute" },
10116 { NODE_TEXT, "text" },
10117 { NODE_CDATA_SECTION , "cdatasection" },
10118 { NODE_ENTITY_REFERENCE, "entityreference" },
10119 { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
10120 { NODE_COMMENT, "comment" },
10121 { NODE_DOCUMENT_FRAGMENT, "documentfragment" },
10122 { 0 }
10125 static void test_get_nodeTypeString(void)
10127 const get_node_typestring_t *entry = get_node_typestring;
10128 IXMLDOMDocument *doc;
10129 HRESULT hr;
10130 BSTR str;
10132 doc = create_document(&IID_IXMLDOMDocument);
10134 hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
10135 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10136 ok(!lstrcmpW(str, L"document"), "got string %s\n", wine_dbgstr_w(str));
10137 SysFreeString(str);
10139 while (entry->type)
10141 IXMLDOMNode *node = NULL;
10142 VARIANT var;
10144 V_VT(&var) = VT_I4;
10145 V_I4(&var) = entry->type;
10146 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10147 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10149 hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
10150 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10152 hr = IXMLDOMNode_get_nodeTypeString(node, &str);
10153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10154 ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
10155 wine_dbgstr_w(str), entry->string, entry->type);
10156 SysFreeString(str);
10157 IXMLDOMNode_Release(node);
10159 entry++;
10162 IXMLDOMDocument_Release(doc);
10163 free_bstrs();
10166 typedef struct _get_attributes_t {
10167 DOMNodeType type;
10168 HRESULT hr;
10169 } get_attributes_t;
10171 static const get_attributes_t get_attributes[] = {
10172 { NODE_ATTRIBUTE, S_FALSE },
10173 { NODE_TEXT, S_FALSE },
10174 { NODE_CDATA_SECTION , S_FALSE },
10175 { NODE_ENTITY_REFERENCE, S_FALSE },
10176 { NODE_PROCESSING_INSTRUCTION, S_FALSE },
10177 { NODE_COMMENT, S_FALSE },
10178 { NODE_DOCUMENT_FRAGMENT, S_FALSE },
10179 { 0 }
10182 static void test_get_attributes(void)
10184 const get_attributes_t *entry = get_attributes;
10185 IXMLDOMNamedNodeMap *map;
10186 IXMLDOMDocument *doc, *doc2;
10187 IXMLDOMNode *node, *node2;
10188 IXMLDOMElement *elem;
10189 VARIANT_BOOL b;
10190 HRESULT hr;
10191 VARIANT v;
10192 BSTR str;
10193 LONG length;
10195 doc = create_document(&IID_IXMLDOMDocument);
10197 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
10198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10200 hr = IXMLDOMDocument_get_attributes(doc, NULL);
10201 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10203 map = (void*)0xdeadbeef;
10204 hr = IXMLDOMDocument_get_attributes(doc, &map);
10205 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10206 ok(map == NULL, "got %p\n", map);
10208 /* first child is <?xml ?> */
10209 hr = IXMLDOMDocument_get_firstChild(doc, &node);
10210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10212 hr = IXMLDOMNode_get_attributes(node, &map);
10213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10215 node2 = (void*)0xdeadbeef;
10216 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("attr"), &node2);
10217 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10218 ok(node2 == NULL, "got %p\n", node2);
10220 length = -1;
10221 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10222 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10223 todo_wine ok(length == 1, "got %ld\n", length);
10225 if (hr == S_OK && length == 1)
10227 IXMLDOMAttribute *attr;
10228 DOMNodeType type;
10229 VARIANT v;
10231 node2 = NULL;
10232 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10234 ok(node != NULL, "got %p\n", node2);
10236 hr = IXMLDOMNode_get_nodeName(node2, &str);
10237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10238 ok(!lstrcmpW(str, L"version"), "got %s\n", wine_dbgstr_w(str));
10239 SysFreeString(str);
10241 length = -1;
10242 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10244 ok(length == 1, "got %ld\n", length);
10246 type = -1;
10247 hr = IXMLDOMNode_get_nodeType(node2, &type);
10248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10249 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
10251 hr = IXMLDOMNode_get_xml(node, &str);
10252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10253 ok(!lstrcmpW(str, L"<?xml version=\"1.0\"?>"), "got %s\n", wine_dbgstr_w(str));
10254 SysFreeString(str);
10256 hr = IXMLDOMNode_get_text(node, &str);
10257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10258 ok(!lstrcmpW(str, L"version=\"1.0\""), "got %s\n", wine_dbgstr_w(str));
10259 SysFreeString(str);
10261 hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
10262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10264 length = -1;
10265 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10267 ok(length == 0, "got %ld\n", length);
10269 hr = IXMLDOMNode_get_xml(node, &str);
10270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10271 ok(!lstrcmpW(str, L"<?xml version=\"1.0\"?>"), "got %s\n", wine_dbgstr_w(str));
10272 SysFreeString(str);
10274 hr = IXMLDOMNode_get_text(node, &str);
10275 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10276 ok(!lstrcmpW(str, L""), "got %s\n", wine_dbgstr_w(str));
10277 SysFreeString(str);
10279 IXMLDOMNamedNodeMap_Release(map);
10281 hr = IXMLDOMNode_get_attributes(node, &map);
10282 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10284 length = -1;
10285 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10286 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10287 ok(length == 0, "got %ld\n", length);
10289 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
10290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10292 V_VT(&v) = VT_BSTR;
10293 V_BSTR(&v) = _bstr_("UTF-8");
10294 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
10295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10297 EXPECT_REF(attr, 2);
10298 hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
10299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10300 EXPECT_REF(attr, 2);
10302 hr = IXMLDOMNode_get_attributes(node, &map);
10303 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10305 length = -1;
10306 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10307 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10308 ok(length == 1, "got %ld\n", length);
10310 hr = IXMLDOMNode_get_xml(node, &str);
10311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10312 ok(!lstrcmpW(str, L"<?xml version=\"1.0\"?>"), "got %s\n", wine_dbgstr_w(str));
10313 SysFreeString(str);
10315 hr = IXMLDOMNode_get_text(node, &str);
10316 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10317 ok(!lstrcmpW(str, L"encoding=\"UTF-8\""), "got %s\n", wine_dbgstr_w(str));
10318 SysFreeString(str);
10320 IXMLDOMNamedNodeMap_Release(map);
10321 IXMLDOMNode_Release(node2);
10324 IXMLDOMNode_Release(node);
10326 /* last child is element */
10327 EXPECT_REF(doc, 1);
10328 hr = IXMLDOMDocument_get_lastChild(doc, &node);
10329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10330 EXPECT_REF(doc, 1);
10332 EXPECT_REF(node, 1);
10333 hr = IXMLDOMNode_get_attributes(node, &map);
10334 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10335 EXPECT_REF(node, 1);
10336 EXPECT_REF(doc, 1);
10338 EXPECT_REF(map, 1);
10339 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10340 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10341 EXPECT_REF(node, 1);
10342 EXPECT_REF(node2, 1);
10343 EXPECT_REF(map, 1);
10344 EXPECT_REF(doc, 1);
10345 IXMLDOMNode_Release(node2);
10347 /* release node before map release, map still works */
10348 IXMLDOMNode_Release(node);
10350 length = 0;
10351 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10352 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10353 ok(length == 1, "got %ld\n", length);
10355 node2 = NULL;
10356 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
10357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10358 EXPECT_REF(node2, 1);
10359 IXMLDOMNode_Release(node2);
10361 IXMLDOMNamedNodeMap_Release(map);
10363 /* append created element a different document, map still works */
10364 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
10365 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10367 V_VT(&v) = VT_I4;
10368 V_I4(&v) = 1;
10369 hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v);
10370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10372 hr = IXMLDOMElement_get_attributes(elem, &map);
10373 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10375 length = 0;
10376 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10378 ok(length == 1, "got %ld\n", length);
10380 doc2 = create_document(&IID_IXMLDOMDocument);
10382 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node);
10383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10384 ok(node == (IXMLDOMNode*)elem, "node != elem\n");
10385 IXMLDOMNode_Release(node);
10386 IXMLDOMElement_Release(elem);
10387 IXMLDOMDocument_Release(doc2);
10389 length = 0;
10390 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
10391 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10392 ok(length == 1, "got %ld\n", length);
10394 IXMLDOMNamedNodeMap_Release(map);
10396 while (entry->type)
10398 VARIANT var;
10400 node = NULL;
10402 V_VT(&var) = VT_I4;
10403 V_I4(&var) = entry->type;
10404 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
10405 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
10407 hr = IXMLDOMNode_get_attributes(node, NULL);
10408 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10410 map = (void*)0xdeadbeef;
10411 hr = IXMLDOMNode_get_attributes(node, &map);
10412 ok(hr == entry->hr, "Unexpected hr %#lx, expected %#lx. node type %d\n",
10413 hr, entry->hr, entry->type);
10414 ok(map == NULL, "got %p\n", map);
10416 IXMLDOMNode_Release(node);
10418 entry++;
10421 IXMLDOMDocument_Release(doc);
10422 free_bstrs();
10425 static void test_selection(void)
10427 IXMLDOMSelection *selection, *selection2;
10428 IEnumVARIANT *enum1, *enum2, *enum3;
10429 IXMLDOMNodeList *list;
10430 IUnknown *unk1, *unk2;
10431 IXMLDOMDocument *doc;
10432 IDispatchEx *dispex;
10433 IXMLDOMNode *node;
10434 IDispatch *disp;
10435 VARIANT_BOOL b;
10436 VARIANT v[3];
10437 HRESULT hr;
10438 DISPID did;
10439 BSTR name;
10440 ULONG ret;
10441 LONG len;
10443 doc = create_document(&IID_IXMLDOMDocument);
10445 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10446 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10448 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
10449 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10451 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10452 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10453 IXMLDOMSelection_Release(selection);
10455 /* collection disp id */
10456 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
10457 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10458 did = 0;
10459 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10460 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10461 ok(did == DISPID_DOM_COLLECTION_BASE, "got %ld\n", did);
10462 len = 0;
10463 hr = IXMLDOMSelection_get_length(selection, &len);
10464 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10465 ok(len == 1, "got %ld\n", len);
10466 hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
10467 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10468 ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %ld\n", did);
10469 IDispatchEx_Release(dispex);
10471 /* IEnumVARIANT tests */
10472 enum1 = NULL;
10473 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
10474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10475 ok(enum1 != NULL, "got %p\n", enum1);
10476 EXPECT_REF(enum1, 2);
10478 EXPECT_REF(selection, 1);
10479 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1);
10480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10481 EXPECT_REF(selection, 2);
10482 EXPECT_REF(enum1, 2);
10484 /* enumerator and selection object return same IUnknown* */
10485 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
10486 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10487 EXPECT_REF(selection, 3);
10488 EXPECT_REF(enum1, 2);
10489 ok(unk2 == unk1, "got %p, %p\n", unk1, unk2);
10490 IUnknown_Release(unk2);
10492 EXPECT_REF(selection, 2);
10493 IEnumVARIANT_AddRef(enum1);
10494 EXPECT_REF(selection, 2);
10495 IEnumVARIANT_Release(enum1);
10497 enum3 = NULL;
10498 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
10499 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10500 ok(enum3 != NULL, "got %p\n", enum3);
10501 ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
10502 EXPECT_REF(enum1, 3);
10503 IEnumVARIANT_Release(enum3);
10505 EXPECT_REF(selection, 2);
10506 EXPECT_REF(enum1, 2);
10508 enum2 = NULL;
10509 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10511 ok(enum2 != NULL, "got %p\n", enum2);
10513 EXPECT_REF(selection, 3);
10514 EXPECT_REF(enum1, 2);
10515 EXPECT_REF(enum2, 1);
10517 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10519 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
10520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10521 EXPECT_REF(selection, 3);
10522 EXPECT_REF(enum2, 2);
10523 ok(unk2 != unk1, "got %p, %p\n", unk1, unk2);
10524 IUnknown_Release(unk2);
10525 IUnknown_Release(unk1);
10527 selection2 = NULL;
10528 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
10529 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10530 ok(selection2 == selection, "got %p and %p\n", selection, selection2);
10531 EXPECT_REF(selection, 3);
10532 EXPECT_REF(enum1, 2);
10534 IXMLDOMSelection_Release(selection2);
10536 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
10537 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10538 EXPECT_REF(selection, 3);
10539 IDispatch_Release(disp);
10541 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10543 ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10544 EXPECT_REF(selection, 2);
10545 EXPECT_REF(enum1, 3);
10547 IEnumVARIANT_Release(enum1);
10548 IEnumVARIANT_Release(enum2);
10549 IEnumVARIANT_Release(enum3);
10551 enum1 = NULL;
10552 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10553 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10554 ok(enum1 != NULL, "got %p\n", enum1);
10555 EXPECT_REF(enum1, 1);
10556 EXPECT_REF(selection, 2);
10558 enum2 = NULL;
10559 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10560 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10561 ok(enum2 != NULL, "got %p\n", enum2);
10562 EXPECT_REF(enum2, 1);
10563 EXPECT_REF(selection, 3);
10565 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10567 IEnumVARIANT_AddRef(enum1);
10568 EXPECT_REF(selection, 3);
10569 EXPECT_REF(enum1, 2);
10570 EXPECT_REF(enum2, 1);
10571 IEnumVARIANT_Release(enum1);
10573 IEnumVARIANT_Release(enum1);
10574 IEnumVARIANT_Release(enum2);
10576 EXPECT_REF(selection, 1);
10578 IXMLDOMNodeList_Release(list);
10580 hr = IXMLDOMDocument_get_childNodes(doc, &list);
10581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10583 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10584 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
10586 IXMLDOMNodeList_Release(list);
10588 /* test if IEnumVARIANT touches selection context */
10589 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
10590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10592 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10595 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10598 len = 0;
10599 hr = IXMLDOMSelection_get_length(selection, &len);
10600 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10601 ok(len == 4, "got %ld\n", len);
10603 enum1 = NULL;
10604 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10605 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10607 /* no-op if zero count */
10608 V_VT(&v[0]) = VT_I2;
10609 hr = IEnumVARIANT_Next(enum1, 0, &v[0], NULL);
10610 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10611 ok(V_VT(&v[0]) == VT_I2, "got var type %d\n", V_VT(&v[0]));
10613 /* positive count, null array pointer */
10614 hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10615 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10617 hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10618 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10619 ok(ret == 0, "got %ld\n", ret);
10621 V_VT(&v[0]) = VT_I2;
10622 hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL);
10623 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10624 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
10626 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
10627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10628 hr = IXMLDOMNode_get_nodeName(node, &name);
10629 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10630 ok(!lstrcmpW(name, L"a"), "got node name %s\n", wine_dbgstr_w(name));
10631 SysFreeString(name);
10632 IXMLDOMNode_Release(node);
10633 VariantClear(&v[0]);
10635 /* list cursor is updated */
10636 hr = IXMLDOMSelection_nextNode(selection, &node);
10637 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10638 hr = IXMLDOMNode_get_nodeName(node, &name);
10639 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10640 ok(!lstrcmpW(name, L"c"), "got node name %s\n", wine_dbgstr_w(name));
10641 IXMLDOMNode_Release(node);
10642 SysFreeString(name);
10644 V_VT(&v[0]) = VT_I2;
10645 hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL);
10646 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10647 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
10648 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
10649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10650 hr = IXMLDOMNode_get_nodeName(node, &name);
10651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10652 ok(!lstrcmpW(name, L"b"), "got node name %s\n", wine_dbgstr_w(name));
10653 SysFreeString(name);
10654 IXMLDOMNode_Release(node);
10655 VariantClear(&v[0]);
10657 hr = IXMLDOMSelection_nextNode(selection, &node);
10658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10659 hr = IXMLDOMNode_get_nodeName(node, &name);
10660 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10661 ok(!lstrcmpW(name, L"d"), "got node name %s\n", wine_dbgstr_w(name));
10662 IXMLDOMNode_Release(node);
10663 SysFreeString(name);
10665 hr = IEnumVARIANT_Reset(enum1);
10666 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10668 /* getting multiple elements */
10669 V_VT(&v[1]) = VT_EMPTY;
10670 V_VT(&v[0]) = VT_EMPTY;
10671 hr = IEnumVARIANT_Next(enum1, 2, v, &ret);
10672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10673 ok(ret == 2, "got %ld, expected 2\n", ret);
10674 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
10675 ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1]));
10677 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
10678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10679 hr = IXMLDOMNode_get_nodeName(node, &name);
10680 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10681 ok(!lstrcmpW(name, L"a"), "got node name %s\n", wine_dbgstr_w(name));
10682 SysFreeString(name);
10683 IXMLDOMNode_Release(node);
10685 hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node);
10686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10687 hr = IXMLDOMNode_get_nodeName(node, &name);
10688 ok(!lstrcmpW(name, L"b"), "got node name %s\n", wine_dbgstr_w(name));
10689 SysFreeString(name);
10690 IXMLDOMNode_Release(node);
10692 VariantClear(&v[1]);
10693 VariantClear(&v[0]);
10695 /* IEnumVARIANT_Next makes the IXMLDOMSelection cursor advance one step more */
10696 hr = IXMLDOMSelection_nextNode(selection, &node);
10697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10698 hr = IXMLDOMNode_get_nodeName(node, &name);
10699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10700 ok(!lstrcmpW(name, L"d"), "got node name %s\n", wine_dbgstr_w(name));
10701 SysFreeString(name);
10702 IXMLDOMNode_Release(node);
10704 /* The IEnumVARIANT cursor is still at position '2', */
10705 /* therefore attempting to fetch 4 elements yields 'c' and 'd' */
10706 V_VT(&v[2]) = VT_NULL;
10707 V_VT(&v[1]) = VT_EMPTY;
10708 V_VT(&v[0]) = VT_EMPTY;
10709 hr = IEnumVARIANT_Next(enum1, 4, v, &ret);
10710 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10711 ok(ret == 2, "got %ld, expected 2\n", ret);
10713 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
10714 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
10715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10716 hr = IXMLDOMNode_get_nodeName(node, &name);
10717 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10718 ok(!lstrcmpW(name, L"c"), "got node name %s\n", wine_dbgstr_w(name));
10719 SysFreeString(name);
10720 IXMLDOMNode_Release(node);
10722 ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1]));
10723 hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node);
10724 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10725 hr = IXMLDOMNode_get_nodeName(node, &name);
10726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10727 ok(!lstrcmpW(name, L"d"), "got node name %s\n", wine_dbgstr_w(name));
10728 SysFreeString(name);
10729 IXMLDOMNode_Release(node);
10731 ok(V_VT(&v[2]) == VT_EMPTY, "got var type %d, expected %d (VT_EMPTY)\n", V_VT(&v[2]), VT_EMPTY);
10733 VariantClear(&v[1]);
10734 VariantClear(&v[0]);
10736 IEnumVARIANT_Release(enum1);
10738 IXMLDOMSelection_Release(selection);
10739 IXMLDOMNodeList_Release(list);
10740 IXMLDOMDocument_Release(doc);
10742 free_bstrs();
10745 static void write_to_file(const char *name, const char *data)
10747 DWORD written;
10748 HANDLE hfile;
10749 BOOL ret;
10751 hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10752 ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name);
10754 ret = WriteFile(hfile, data, strlen(data), &written, NULL);
10755 ok(ret, "WriteFile failed: %s, %ld\n", name, GetLastError());
10757 CloseHandle(hfile);
10760 #define TEST_DOC_LOAD_FROM_PATH(doc,path,expected_hr, expected_ret) \
10761 _test_doc_load_from_path(doc, path, expected_hr, expected_ret, __LINE__)
10762 static void _test_doc_load_from_path(IXMLDOMDocument *doc, const char *path,
10763 HRESULT expected_hr, VARIANT_BOOL expected_ret, int line)
10765 IXMLDOMDocument *doc2;
10766 IXMLDOMElement *elem;
10767 BSTR url, url2;
10768 VARIANT_BOOL b;
10769 VARIANT src;
10770 HRESULT hr;
10772 url = _bstr_(path);
10774 V_VT(&src) = VT_BSTR;
10775 V_BSTR(&src) = url;
10776 hr = IXMLDOMDocument_load(doc, src, &b);
10777 ok_(__FILE__, line)(hr == expected_hr, "Failed to load document, %#lx.\n", hr);
10778 ok_(__FILE__, line)(b == expected_ret, "got %d\n", b);
10780 V_VT(&src) = VT_BSTR | VT_BYREF;
10781 V_BSTRREF(&src) = &url;
10782 hr = IXMLDOMDocument_load(doc, src, &b);
10783 ok_(__FILE__, line)(hr == expected_hr, "Failed to load document, %#lx.\n", hr);
10784 ok_(__FILE__, line)(b == expected_ret, "got %d\n", b);
10786 if (expected_hr != S_OK)
10787 return;
10789 url = NULL;
10790 hr = IXMLDOMDocument_get_url(doc, &url);
10791 ok_(__FILE__, line)(hr == S_OK, "Failed to get document url, hr %#lx.\n", hr);
10793 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
10794 ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10796 /* Create another instance for the same document, check url */
10797 hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
10798 ok_(__FILE__, line)(hr == S_OK, "Failed to get owner document, hr %#lx.\n", hr);
10800 hr = IXMLDOMDocument_get_url(doc2, &url2);
10801 ok_(__FILE__, line)(hr == S_OK, "Failed to get document url, hr %#lx.\n", hr);
10802 ok_(__FILE__, line)(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2));
10804 IXMLDOMDocument_Release(doc2);
10805 IXMLDOMElement_Release(elem);
10806 SysFreeString(url2);
10807 SysFreeString(url);
10810 static void url_forward_slash(char *url)
10812 char *p = url;
10814 while (*p)
10816 if (*p == '\\')
10817 *p = '/';
10818 p++;
10822 static void test_load(void)
10824 char path[MAX_PATH], path2[MAX_PATH];
10825 IXMLDOMNodeList *list;
10826 IXMLDOMDocument *doc;
10827 BSTR bstr1, bstr2;
10828 IStream *stream;
10829 VARIANT_BOOL b;
10830 VARIANT src;
10831 HRESULT hr;
10832 void* ptr;
10833 int n;
10834 struct encoding_test
10836 const char *xml;
10837 HRESULT expected_hr;
10838 VARIANT_BOOL expected_ret;
10839 } encoding_tests[] =
10841 { gbkxml, S_OK, VARIANT_TRUE },
10842 { win1252xml, S_OK, VARIANT_TRUE },
10843 { win936xml, S_FALSE, VARIANT_FALSE },
10847 GetTempPathA(MAX_PATH, path);
10848 strcat(path, "winetest.xml");
10850 /* prepare a file */
10851 write_to_file(path, win1252xml);
10853 doc = create_document(&IID_IXMLDOMDocument);
10855 /* null pointer as input */
10856 V_VT(&src) = VT_UNKNOWN;
10857 V_UNKNOWN(&src) = NULL;
10858 hr = IXMLDOMDocument_load(doc, src, &b);
10859 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10860 ok(b == VARIANT_FALSE, "got %d\n", b);
10862 /* "file://" url */
10863 strcpy(path2, "file://");
10864 strcat(path2, path);
10865 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10867 /* file:// url, forward slashes */
10868 url_forward_slash(path2);
10869 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10871 /* "file:/" url */
10872 strcpy(path2, "file:/");
10873 strcat(path2, path);
10874 TEST_DOC_LOAD_FROM_PATH(doc, path, S_OK, VARIANT_TRUE);
10876 /* file:/ with forward slashes. */
10877 url_forward_slash(path2);
10878 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10880 /* Regular local path. */
10881 TEST_DOC_LOAD_FROM_PATH(doc, path, S_OK, VARIANT_TRUE);
10883 /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10884 V_VT(&src) = VT_BSTR | VT_BYREF;
10885 V_BSTRREF(&src) = NULL;
10886 hr = IXMLDOMDocument_load(doc, src, &b);
10887 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
10888 ok(b == VARIANT_FALSE, "got %d\n", b);
10890 bstr1 = NULL;
10891 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10893 SysFreeString(bstr1);
10895 /* Regular local path with some URL encoded characters. */
10896 strcpy(path2, path);
10897 n = strlen(path2);
10898 strcpy(&path2[n-1], "%6C"); /* C:\path\to\winetest.xm%6C */
10899 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10901 /* Both spaces and %20s work. */
10902 GetTempPathA(MAX_PATH, path2);
10903 strcat(path2, "wine test.xml");
10904 write_to_file(path2, win1252xml);
10905 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10906 GetTempPathA(MAX_PATH, path2);
10907 strcat(path2, "wine%20test.xml");
10908 TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
10909 DeleteFileA(path2);
10911 DeleteFileA(path);
10913 /* load from existing path, no xml content */
10914 write_to_file(path, nocontent);
10916 V_VT(&src) = VT_BSTR;
10917 V_BSTR(&src) = _bstr_(path);
10918 b = VARIANT_TRUE;
10919 hr = IXMLDOMDocument_load(doc, src, &b);
10920 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10921 ok(b == VARIANT_FALSE, "got %d\n", b);
10923 bstr1 = (void *)0xdeadbeef;
10924 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10925 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10926 ok(bstr1 == NULL, "got %p\n", bstr1);
10928 DeleteFileA(path);
10929 IXMLDOMDocument_Release(doc);
10931 doc = create_document(&IID_IXMLDOMDocument);
10933 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10935 ok(b == VARIANT_TRUE, "got %d\n", b);
10937 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10938 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10939 bstr1 = _bstr_(list_to_string(list));
10941 hr = IXMLDOMNodeList_reset(list);
10942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10944 IXMLDOMDocument_Release(doc);
10946 doc = create_document(&IID_IXMLDOMDocument);
10948 VariantInit(&src);
10949 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10950 V_VT(&src) = VT_ARRAY|VT_UI1;
10951 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10952 ptr = NULL;
10953 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10955 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10957 memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10958 hr = SafeArrayUnlock(V_ARRAY(&src));
10959 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10961 hr = IXMLDOMDocument_load(doc, src, &b);
10962 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10963 ok(b == VARIANT_TRUE, "got %d\n", b);
10965 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10966 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10967 bstr2 = _bstr_(list_to_string(list));
10969 hr = IXMLDOMNodeList_reset(list);
10970 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10972 ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10973 wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10975 IXMLDOMDocument_Release(doc);
10976 IXMLDOMNodeList_Release(list);
10977 VariantClear(&src);
10979 /* UTF-16 isn't accepted */
10980 doc = create_document(&IID_IXMLDOMDocument);
10982 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10983 V_VT(&src) = VT_ARRAY|VT_UI1;
10984 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10985 ptr = NULL;
10986 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10987 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10988 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10990 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10991 hr = SafeArrayUnlock(V_ARRAY(&src));
10992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
10994 hr = IXMLDOMDocument_load(doc, src, &b);
10995 todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
10996 todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10998 VariantClear(&src);
11000 /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
11001 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
11002 V_VT(&src) = VT_ARRAY|VT_UI2;
11003 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
11004 ptr = NULL;
11005 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
11006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11007 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
11009 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
11010 hr = SafeArrayUnlock(V_ARRAY(&src));
11011 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11013 hr = IXMLDOMDocument_load(doc, src, &b);
11014 todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11015 ok(b == VARIANT_FALSE, "got %d\n", b);
11017 VariantClear(&src);
11019 /* test istream with empty content */
11020 stream = SHCreateMemStream((const BYTE*)nocontent, strlen(nocontent));
11021 V_VT(&src) = VT_UNKNOWN;
11022 V_UNKNOWN(&src) = (IUnknown*)stream;
11023 b = VARIANT_TRUE;
11024 hr = IXMLDOMDocument_load(doc, src, &b);
11025 todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
11026 ok(b == VARIANT_FALSE, "got %d\n", b);
11027 EXPECT_PARSE_ERROR(doc, XML_E_INVALIDATROOTLEVEL, TRUE);
11028 VariantClear(&src);
11030 /* test istream with valid xml */
11031 stream = SHCreateMemStream((const BYTE*)complete4A, strlen(complete4A));
11032 V_VT(&src) = VT_UNKNOWN;
11033 V_UNKNOWN(&src) = (IUnknown*)stream;
11034 b = VARIANT_FALSE;
11035 hr = IXMLDOMDocument_load(doc, src, &b);
11036 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11037 ok(b == VARIANT_TRUE, "got %d\n", b);
11038 EXPECT_PARSE_ERROR(doc, S_OK, FALSE);
11039 VariantClear(&src);
11041 IXMLDOMDocument_Release(doc);
11043 /* Encoding tests. */
11044 for (n = 0; n < ARRAY_SIZE(encoding_tests); n++)
11046 GetTempPathA(MAX_PATH, path);
11047 strcat(path, "codepage_test.xml");
11048 write_to_file(path, encoding_tests[n].xml);
11049 doc = create_document(&IID_IXMLDOMDocument);
11050 TEST_DOC_LOAD_FROM_PATH(doc, path, encoding_tests[n].expected_hr, encoding_tests[n].expected_ret);
11051 DeleteFileA(path);
11052 IXMLDOMDocument_Release(doc);
11055 free_bstrs();
11058 static void test_domobj_dispex(IUnknown *obj)
11060 DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
11061 IDispatchEx *dispex;
11062 IUnknown *unk;
11063 DWORD props;
11064 UINT ticnt;
11065 HRESULT hr;
11066 BSTR name;
11068 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
11069 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11070 if (FAILED(hr)) return;
11072 ticnt = 0;
11073 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
11074 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11075 ok(ticnt == 1, "ticnt=%u\n", ticnt);
11077 name = SysAllocString(L"*");
11078 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
11079 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11080 SysFreeString(name);
11082 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
11083 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11085 props = 0;
11086 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
11087 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11088 ok(props == 0, "expected 0 got %ld\n", props);
11090 hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
11091 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11092 if (SUCCEEDED(hr)) SysFreeString(name);
11094 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
11095 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11097 unk = (IUnknown*)0xdeadbeef;
11098 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
11099 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
11100 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk);
11102 name = SysAllocString(L"testprop");
11103 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid);
11104 ok(hr == DISP_E_UNKNOWNNAME, "Unexpected hr %#lx.\n", hr);
11105 SysFreeString(name);
11107 IDispatchEx_Release(dispex);
11110 static void test_mxnamespacemanager(void)
11112 static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
11113 IMXNamespacePrefixes *prefixes;
11114 IVBMXNamespaceManager *mgr2;
11115 IMXNamespaceManager *nsmgr;
11116 IUnknown *unk1, *unk2;
11117 WCHAR buffW[250];
11118 IUnknown *unk;
11119 HRESULT hr;
11120 INT len;
11122 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11123 &IID_IMXNamespaceManager, (void**)&nsmgr);
11124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11126 check_interface(nsmgr, &IID_IDispatch, TRUE);
11127 check_interface(nsmgr, &IID_IDispatchEx, TRUE);
11128 check_interface(nsmgr, &IID_IMXNamespaceManager, TRUE);
11129 check_interface(nsmgr, &IID_IVBMXNamespaceManager, TRUE);
11131 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
11132 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11134 EXPECT_REF(nsmgr, 2);
11135 EXPECT_REF(mgr2, 2);
11136 prefixes = NULL;
11137 hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
11138 todo_wine
11139 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11140 if (hr == S_OK)
11142 IDispatchEx *dispex;
11143 VARIANT arg, ret;
11144 DISPPARAMS dispparams;
11146 ok(prefixes != NULL, "got %p\n", prefixes);
11147 EXPECT_REF(nsmgr, 2);
11148 EXPECT_REF(mgr2, 2);
11149 EXPECT_REF(prefixes, 1);
11151 IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1);
11152 IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2);
11154 EXPECT_REF(mgr2, 3);
11155 EXPECT_REF(prefixes, 2);
11157 IUnknown_Release(unk1);
11158 IUnknown_Release(unk2);
11160 hr = IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IDispatchEx, (void**)&dispex);
11161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11163 V_VT(&arg) = VT_I4;
11164 V_I4(&arg) = 0;
11165 dispparams.cArgs = 1;
11166 dispparams.cNamedArgs = 0;
11167 dispparams.rgdispidNamedArgs = NULL;
11168 dispparams.rgvarg = &arg;
11170 V_VT(&ret) = VT_EMPTY;
11171 V_DISPATCH(&ret) = (void*)0x1;
11172 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11173 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11174 ok(V_VT(&ret) == VT_BSTR, "got %d\n", V_VT(&ret));
11175 ok(V_BSTR(&ret) != NULL, "got %p\n", V_BSTR(&ret));
11176 VariantClear(&ret);
11178 IDispatchEx_Release(dispex);
11179 IMXNamespacePrefixes_Release(prefixes);
11181 IVBMXNamespaceManager_Release(mgr2);
11183 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
11184 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11186 /* prefix already added */
11187 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
11188 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
11190 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
11191 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11193 /* "xml" and "xmlns" are not allowed here */
11194 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
11195 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11197 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
11198 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11199 todo_wine {
11200 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
11201 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11203 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
11204 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
11206 len = -1;
11207 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
11208 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11209 ok(len == 3, "got %d\n", len);
11211 len = -1;
11212 buffW[0] = 0x1;
11213 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11214 ok(hr == E_XML_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
11215 ok(len == -1, "got %d\n", len);
11216 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11218 len = 10;
11219 buffW[0] = 0x1;
11220 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11221 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11222 ok(len == 3, "got %d\n", len);
11223 ok(!lstrcmpW(buffW, L"xml"), "got prefix %s\n", wine_dbgstr_w(buffW));
11225 /* getURI */
11226 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
11227 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11229 len = -1;
11230 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
11231 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11232 ok(len == -1, "got %d\n", len);
11234 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
11235 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
11237 len = -1;
11238 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
11239 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11240 /* length of "xml" uri is constant */
11241 ok(len == strlen(xmluriA), "got %d\n", len);
11243 len = 100;
11244 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
11245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11246 ok(len == strlen(xmluriA), "got %d\n", len);
11247 ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
11249 len = strlen(xmluriA)-1;
11250 buffW[0] = 0x1;
11251 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
11252 ok(hr == E_XML_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
11253 ok(len == strlen(xmluriA)-1, "got %d\n", len);
11254 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11256 /* prefix xml1 not defined */
11257 len = -1;
11258 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
11259 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
11260 ok(len == 0, "got %d\n", len);
11262 len = 100;
11263 buffW[0] = 0x1;
11264 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
11265 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
11266 ok(buffW[0] == 0, "got %x\n", buffW[0]);
11267 ok(len == 0, "got %d\n", len);
11269 /* IDispatchEx tests */
11270 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
11271 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11272 test_domobj_dispex(unk);
11273 IUnknown_Release(unk);
11275 IMXNamespaceManager_Release(nsmgr);
11277 /* ::getPrefix() */
11278 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11279 &IID_IMXNamespaceManager, (void**)&nsmgr);
11280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11282 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
11283 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11285 len = -1;
11286 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
11287 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11288 ok(len == -1, "got %d\n", len);
11290 len = 100;
11291 buffW[0] = 0x1;
11292 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
11293 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11294 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11295 ok(len == 100, "got %d\n", len);
11297 len = 0;
11298 buffW[0] = 0x1;
11299 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
11300 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11301 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11302 ok(len == 0, "got %d\n", len);
11304 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11305 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11307 len = 100;
11308 buffW[0] = 0x1;
11309 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11311 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11312 ok(len == 3, "got %d\n", len);
11314 len = 100;
11315 buffW[0] = 0x1;
11316 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
11317 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11318 ok(!lstrcmpW(buffW, L"xml"), "got %s\n", wine_dbgstr_w(buffW));
11319 ok(len == 3, "got %d\n", len);
11321 /* with null buffer it's possible to get required length */
11322 len = 100;
11323 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
11324 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11325 ok(len == 3, "got %d\n", len);
11327 len = 0;
11328 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
11329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11330 ok(len == 3, "got %d\n", len);
11332 len = 100;
11333 buffW[0] = 0x1;
11334 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
11335 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11336 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11337 ok(len == 100, "got %d\n", len);
11339 len = 100;
11340 buffW[0] = 0x1;
11341 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
11342 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11343 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11344 ok(len == 100, "got %d\n", len);
11346 len = 100;
11347 buffW[0] = 0x1;
11348 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
11349 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11350 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11351 ok(len == 100, "got %d\n", len);
11353 len = 100;
11354 buffW[0] = 0x1;
11355 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11356 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11357 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11358 ok(len == 100, "got %d\n", len);
11360 len = 100;
11361 buffW[0] = 0x1;
11362 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
11363 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11364 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11365 ok(len == 100, "got %d\n", len);
11367 len = 100;
11368 buffW[0] = 0x1;
11369 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
11370 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11371 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11372 ok(len == 100, "got %d\n", len);
11374 len = 100;
11375 buffW[0] = 0x1;
11376 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11377 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11378 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11379 ok(len == 100, "got %d\n", len);
11381 /* declare another one, indices are shifted */
11382 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
11383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11385 len = 100;
11386 buffW[0] = 0x1;
11387 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11389 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11390 ok(len == 3, "got %d\n", len);
11392 len = 100;
11393 buffW[0] = 0x1;
11394 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11396 ok(!lstrcmpW(buffW, L"ns2"), "got %s\n", wine_dbgstr_w(buffW));
11397 ok(len == 3, "got %d\n", len);
11399 len = 100;
11400 buffW[0] = 0x1;
11401 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
11402 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11403 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11404 ok(len == 100, "got %d\n", len);
11406 len = 100;
11407 buffW[0] = 0x1;
11408 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
11409 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
11410 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11411 ok(len == 100, "got %d\n", len);
11413 IMXNamespaceManager_Release(nsmgr);
11415 /* push/pop tests */
11416 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11417 &IID_IMXNamespaceManager, (void**)&nsmgr);
11418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11420 /* pop with empty stack */
11421 hr = IMXNamespaceManager_popContext(nsmgr);
11422 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11424 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11425 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11427 len = 100;
11428 buffW[0] = 0x1;
11429 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11430 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11431 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11432 ok(len == 3, "got %d\n", len);
11434 hr = IMXNamespaceManager_pushContext(nsmgr);
11435 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11437 len = 100;
11438 buffW[0] = 0x1;
11439 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11440 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11441 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11442 ok(len == 3, "got %d\n", len);
11444 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
11445 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11447 len = 100;
11448 buffW[0] = 0x1;
11449 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11450 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11451 ok(!lstrcmpW(buffW, L"ns2"), "got %s\n", wine_dbgstr_w(buffW));
11452 ok(len == 3, "got %d\n", len);
11454 hr = IMXNamespaceManager_pushContext(nsmgr);
11455 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11456 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
11457 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11459 len = 100;
11460 buffW[0] = 0x1;
11461 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11462 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11463 ok(!lstrcmpW(buffW, L"ns2"), "got %s\n", wine_dbgstr_w(buffW));
11464 ok(len == 3, "got %d\n", len);
11466 len = 100;
11467 buffW[0] = 0x1;
11468 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11469 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11470 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11471 ok(len == 3, "got %d\n", len);
11473 hr = IMXNamespaceManager_popContext(nsmgr);
11474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11476 hr = IMXNamespaceManager_popContext(nsmgr);
11477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11479 len = 100;
11480 buffW[0] = 0x1;
11481 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
11482 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11483 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
11484 ok(len == 100, "got %d\n", len);
11486 len = 100;
11487 buffW[0] = 0x1;
11488 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
11489 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11490 ok(!lstrcmpW(buffW, L"ns1"), "got %s\n", wine_dbgstr_w(buffW));
11491 ok(len == 3, "got %d\n", len);
11493 IMXNamespaceManager_Release(nsmgr);
11495 free_bstrs();
11498 static void test_mxnamespacemanager_override(void)
11500 IMXNamespaceManager *nsmgr;
11501 WCHAR buffW[250];
11502 VARIANT_BOOL b;
11503 HRESULT hr;
11504 INT len;
11506 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
11507 &IID_IMXNamespaceManager, (void**)&nsmgr);
11508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11510 len = ARRAY_SIZE(buffW);
11511 buffW[0] = 0;
11512 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11514 ok(!lstrcmpW(buffW, L"xml"), "got prefix %s\n", wine_dbgstr_w(buffW));
11516 len = ARRAY_SIZE(buffW);
11517 buffW[0] = 0;
11518 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11519 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11521 hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
11522 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
11524 b = VARIANT_FALSE;
11525 hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
11526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11527 ok(b == VARIANT_TRUE, "got %d\n", b);
11529 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
11530 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11532 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
11533 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11535 len = ARRAY_SIZE(buffW);
11536 buffW[0] = 0;
11537 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
11538 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11539 ok(!lstrcmpW(buffW, L"ns0 uri"), "got uri %s\n", wine_dbgstr_w(buffW));
11541 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
11542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11544 len = ARRAY_SIZE(buffW);
11545 buffW[0] = 0;
11546 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
11547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11548 ok(!lstrcmpW(buffW, L"xml"), "got prefix %s\n", wine_dbgstr_w(buffW));
11550 len = ARRAY_SIZE(buffW);
11551 buffW[0] = 0;
11552 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11553 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11554 ok(!lstrcmpW(buffW, L"ns0"), "got prefix %s\n", wine_dbgstr_w(buffW));
11556 len = ARRAY_SIZE(buffW);
11557 buffW[0] = 0;
11558 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
11559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11560 ok(!lstrcmpW(buffW, L""), "got prefix %s\n", wine_dbgstr_w(buffW));
11562 /* new prefix placed at index 1 always */
11563 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
11564 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11566 len = ARRAY_SIZE(buffW);
11567 buffW[0] = 0;
11568 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
11569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11570 ok(!lstrcmpW(buffW, L"ns1"), "got prefix %s\n", wine_dbgstr_w(buffW));
11572 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
11573 todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11575 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
11576 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11578 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
11579 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
11581 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
11582 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11584 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
11585 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
11587 len = ARRAY_SIZE(buffW);
11588 buffW[0] = 0;
11589 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
11590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11591 ok(!lstrcmpW(buffW, L"ns0 uri override"), "got uri %s\n", wine_dbgstr_w(buffW));
11593 len = ARRAY_SIZE(buffW);
11594 buffW[0] = 0;
11595 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
11596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11597 ok(!lstrcmpW(buffW, L""), "got prefix %s\n", wine_dbgstr_w(buffW));
11599 IMXNamespaceManager_Release(nsmgr);
11601 free_bstrs();
11604 static const DOMNodeType nodetypes_test[] =
11606 NODE_ELEMENT,
11607 NODE_ATTRIBUTE,
11608 NODE_TEXT,
11609 NODE_CDATA_SECTION,
11610 NODE_ENTITY_REFERENCE,
11611 NODE_PROCESSING_INSTRUCTION,
11612 NODE_COMMENT,
11613 NODE_DOCUMENT_FRAGMENT,
11614 NODE_INVALID
11617 static void test_dispex(void)
11619 const DOMNodeType *type = nodetypes_test;
11620 IXMLDOMImplementation *impl;
11621 IXMLDOMNodeList *node_list;
11622 IXMLDOMParseError *error;
11623 IXMLDOMNamedNodeMap *map;
11624 IXSLProcessor *processor;
11625 IXSLTemplate *template;
11626 IXMLDOMDocument *doc;
11627 IXMLHTTPRequest *req;
11628 IXMLDOMElement *elem;
11629 IDispatchEx *dispex;
11630 DISPPARAMS dispparams;
11631 IXMLDOMNode *node;
11632 VARIANT arg, ret;
11633 VARIANT_BOOL b;
11634 IUnknown *unk;
11635 HRESULT hr;
11636 DISPID did;
11638 doc = create_document(&IID_IXMLDOMDocument);
11640 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
11641 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11642 test_domobj_dispex(unk);
11643 IUnknown_Release(unk);
11645 for(; *type != NODE_INVALID; type++)
11647 IXMLDOMNode *node;
11648 VARIANT v;
11650 V_VT(&v) = VT_I2;
11651 V_I2(&v) = *type;
11653 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
11654 ok(hr == S_OK, "failed to create node type %d\n", *type);
11656 IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
11658 test_domobj_dispex(unk);
11659 IUnknown_Release(unk);
11660 IXMLDOMNode_Release(node);
11663 /* IXMLDOMNodeList */
11664 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
11665 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11666 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11667 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11668 test_domobj_dispex(unk);
11669 IUnknown_Release(unk);
11670 IXMLDOMNodeList_Release(node_list);
11672 /* IXMLDOMNodeList for children list */
11673 hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
11674 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11675 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
11676 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11677 test_domobj_dispex(unk);
11678 IUnknown_Release(unk);
11680 /* collection dispex test, empty collection */
11681 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
11682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11683 did = 0;
11684 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11686 ok(did == DISPID_DOM_COLLECTION_BASE, "Unexpected value %ld.\n", did);
11687 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11689 ok(did == DISPID_DOM_COLLECTION_BASE+1, "Unexpected value %ld.\n", did);
11690 IDispatchEx_Release(dispex);
11692 did = -1;
11693 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
11694 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11695 ok(did == DISPID_VALUE, "got %ld\n", did);
11697 V_VT(&arg) = VT_I4;
11698 V_I4(&arg) = 0;
11699 dispparams.cArgs = 0;
11700 dispparams.cNamedArgs = 0;
11701 dispparams.rgdispidNamedArgs = NULL;
11702 dispparams.rgvarg = &arg;
11704 V_VT(&ret) = VT_EMPTY;
11705 V_DISPATCH(&ret) = (void*)0x1;
11706 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11707 ok(hr == DISP_E_BADPARAMCOUNT, "Unexpected hr %#lx.\n", hr);
11708 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11709 todo_wine
11710 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11712 V_VT(&arg) = VT_I4;
11713 V_I4(&arg) = 0;
11714 dispparams.cArgs = 2;
11715 dispparams.cNamedArgs = 0;
11716 dispparams.rgdispidNamedArgs = NULL;
11717 dispparams.rgvarg = &arg;
11719 V_VT(&ret) = VT_EMPTY;
11720 V_DISPATCH(&ret) = (void*)0x1;
11721 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11722 ok(hr == DISP_E_BADPARAMCOUNT, "Unexpected hr %#lx.\n", hr);
11723 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11724 todo_wine
11725 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11727 V_VT(&arg) = VT_I4;
11728 V_I4(&arg) = 0;
11729 dispparams.cArgs = 1;
11730 dispparams.cNamedArgs = 0;
11731 dispparams.rgdispidNamedArgs = NULL;
11732 dispparams.rgvarg = &arg;
11734 V_VT(&ret) = VT_EMPTY;
11735 V_DISPATCH(&ret) = (void*)0x1;
11736 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11738 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11739 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11741 V_VT(&ret) = VT_EMPTY;
11742 V_DISPATCH(&ret) = (void*)0x1;
11743 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11744 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11745 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11746 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11748 V_VT(&ret) = VT_EMPTY;
11749 V_DISPATCH(&ret) = (void*)0x1;
11750 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11751 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11752 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11753 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11755 dispparams.cArgs = 0;
11756 dispparams.cNamedArgs = 0;
11757 dispparams.rgdispidNamedArgs = NULL;
11758 dispparams.rgvarg = NULL;
11760 V_VT(&ret) = VT_EMPTY;
11761 V_I4(&ret) = 1;
11762 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11763 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11764 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11765 ok(V_I4(&ret) == 0, "got %ld\n", V_I4(&ret));
11767 dispparams.cArgs = 0;
11768 dispparams.cNamedArgs = 0;
11769 dispparams.rgdispidNamedArgs = NULL;
11770 dispparams.rgvarg = NULL;
11772 V_VT(&ret) = VT_EMPTY;
11773 V_I4(&ret) = 1;
11774 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11775 ok(hr == DISP_E_MEMBERNOTFOUND, "Unexpected hr %#lx.\n", hr);
11776 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11777 todo_wine
11778 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %ld\n", V_I4(&ret));
11780 IXMLDOMNodeList_Release(node_list);
11782 /* IXMLDOMParseError */
11783 hr = IXMLDOMDocument_get_parseError(doc, &error);
11784 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11785 IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11786 test_domobj_dispex(unk);
11788 hr = IXMLDOMParseError_QueryInterface(error, &IID_IDispatchEx, (void**)&dispex);
11789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11791 V_VT(&arg) = VT_I4;
11792 V_I4(&arg) = 0;
11793 dispparams.cArgs = 1;
11794 dispparams.cNamedArgs = 0;
11795 dispparams.rgdispidNamedArgs = NULL;
11796 dispparams.rgvarg = &arg;
11798 V_VT(&ret) = VT_EMPTY;
11799 V_DISPATCH(&ret) = (void*)0x1;
11800 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11801 ok(hr == DISP_E_MEMBERNOTFOUND, "Unexpected hr %#lx.\n", hr);
11802 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11803 todo_wine
11804 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11806 IDispatchEx_Release(dispex);
11808 IUnknown_Release(unk);
11809 IXMLDOMParseError_Release(error);
11811 /* IXMLDOMNamedNodeMap */
11812 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
11813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11815 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11817 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11819 IXMLDOMNodeList_Release(node_list);
11821 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11822 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11823 IXMLDOMNode_Release(node);
11824 hr = IXMLDOMElement_get_attributes(elem, &map);
11825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11826 IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11827 test_domobj_dispex(unk);
11828 IUnknown_Release(unk);
11829 /* collection dispex test */
11830 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11832 did = 0;
11833 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11834 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11835 ok(did == DISPID_DOM_COLLECTION_BASE, "Unexpected value %ld.\n", did);
11836 IDispatchEx_Release(dispex);
11837 IXMLDOMNamedNodeMap_Release(map);
11839 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11841 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11842 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11843 IXMLDOMNodeList_Release(node_list);
11844 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11845 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11846 IXMLDOMNode_Release(node);
11847 hr = IXMLDOMElement_get_attributes(elem, &map);
11848 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11849 /* collection dispex test, empty collection */
11850 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11851 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11852 did = 0;
11853 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11854 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11855 ok(did == DISPID_DOM_COLLECTION_BASE, "Unexpected value %ld\n", did);
11856 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11857 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11858 ok(did == DISPID_DOM_COLLECTION_BASE+1, "Unexpected value %ld.\n", did);
11859 IXMLDOMNamedNodeMap_Release(map);
11861 did = -1;
11862 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
11863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11864 ok(did == DISPID_VALUE, "got %ld\n", did);
11866 V_VT(&arg) = VT_I4;
11867 V_I4(&arg) = 0;
11868 dispparams.cArgs = 0;
11869 dispparams.cNamedArgs = 0;
11870 dispparams.rgdispidNamedArgs = NULL;
11871 dispparams.rgvarg = &arg;
11873 V_VT(&ret) = VT_EMPTY;
11874 V_DISPATCH(&ret) = (void*)0x1;
11875 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11876 todo_wine {
11877 ok(hr == DISP_E_BADPARAMCOUNT, "Unexpected hr %#lx.\n", hr);
11878 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11880 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11882 V_VT(&arg) = VT_I4;
11883 V_I4(&arg) = 0;
11884 dispparams.cArgs = 2;
11885 dispparams.cNamedArgs = 0;
11886 dispparams.rgdispidNamedArgs = NULL;
11887 dispparams.rgvarg = &arg;
11889 V_VT(&ret) = VT_EMPTY;
11890 V_DISPATCH(&ret) = (void*)0x1;
11891 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11892 todo_wine {
11893 ok(hr == DISP_E_BADPARAMCOUNT, "Unexpected hr %#lx.\n", hr);
11894 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11896 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11898 V_VT(&arg) = VT_I4;
11899 V_I4(&arg) = 0;
11900 dispparams.cArgs = 1;
11901 dispparams.cNamedArgs = 0;
11902 dispparams.rgdispidNamedArgs = NULL;
11903 dispparams.rgvarg = &arg;
11905 V_VT(&ret) = VT_EMPTY;
11906 V_DISPATCH(&ret) = (void*)0x1;
11907 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11908 todo_wine
11909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11910 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11911 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11913 V_VT(&ret) = VT_EMPTY;
11914 V_DISPATCH(&ret) = (void*)0x1;
11915 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11916 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11917 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11918 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11920 V_VT(&ret) = VT_EMPTY;
11921 V_DISPATCH(&ret) = (void*)0x1;
11922 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11923 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11924 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11925 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11927 dispparams.cArgs = 0;
11928 dispparams.cNamedArgs = 0;
11929 dispparams.rgdispidNamedArgs = NULL;
11930 dispparams.rgvarg = NULL;
11932 V_VT(&ret) = VT_EMPTY;
11933 V_I4(&ret) = 1;
11934 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11935 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11936 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11937 ok(V_I4(&ret) == 0, "got %ld\n", V_I4(&ret));
11939 dispparams.cArgs = 0;
11940 dispparams.cNamedArgs = 0;
11941 dispparams.rgdispidNamedArgs = NULL;
11942 dispparams.rgvarg = NULL;
11944 V_VT(&ret) = VT_EMPTY;
11945 V_I4(&ret) = 1;
11946 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11947 ok(hr == DISP_E_MEMBERNOTFOUND, "Unexpected hr %#lx.\n", hr);
11948 todo_wine
11949 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11950 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %ld\n", V_I4(&ret));
11952 IDispatchEx_Release(dispex);
11953 IXMLDOMElement_Release(elem);
11955 /* IXMLDOMImplementation */
11956 hr = IXMLDOMDocument_get_implementation(doc, &impl);
11957 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11959 hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11960 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11961 IDispatchEx_Release(dispex);
11962 IXMLDOMImplementation_Release(impl);
11964 IXMLDOMDocument_Release(doc);
11966 /* IXMLHTTPRequest */
11967 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11968 &IID_IXMLHttpRequest, (void**)&req);
11969 if (hr == S_OK)
11971 hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11972 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
11973 IXMLHTTPRequest_Release(req);
11976 /* IXSLTemplate */
11977 template = create_xsltemplate(&IID_IXSLTemplate);
11978 hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11980 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11982 test_domobj_dispex(unk);
11983 IUnknown_Release(unk);
11984 IDispatchEx_Release(dispex);
11986 /* IXSLProcessor */
11987 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11988 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11989 b = VARIANT_FALSE;
11990 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11992 ok(b == VARIANT_TRUE, "got %d\n", b);
11994 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
11996 IXMLDOMDocument_Release(doc);
11998 hr = IXSLTemplate_createProcessor(template, &processor);
11999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12000 hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
12001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12002 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
12003 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12004 test_domobj_dispex(unk);
12005 IUnknown_Release(unk);
12006 IDispatchEx_Release(dispex);
12008 IXSLProcessor_Release(processor);
12009 IXSLTemplate_Release(template);
12011 if (is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument))
12013 doc = create_document_version(60, &IID_IXMLDOMDocument);
12014 test_domobj_dispex((IUnknown*)doc);
12015 IXMLDOMDocument_Release(doc);
12018 free_bstrs();
12021 static void test_parseerror(void)
12023 IXMLDOMParseError2 *error2;
12024 IXMLDOMParseError *error;
12025 IXMLDOMDocument *doc;
12026 HRESULT hr;
12028 doc = create_document(&IID_IXMLDOMDocument);
12030 hr = IXMLDOMDocument_get_parseError(doc, &error);
12031 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12033 hr = IXMLDOMParseError_get_line(error, NULL);
12034 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
12036 hr = IXMLDOMParseError_get_srcText(error, NULL);
12037 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
12039 hr = IXMLDOMParseError_get_linepos(error, NULL);
12040 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
12042 IXMLDOMParseError_Release(error);
12043 IXMLDOMDocument_Release(doc);
12045 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) return;
12046 doc = create_document_version(60, &IID_IXMLDOMDocument);
12048 hr = IXMLDOMDocument_get_parseError(doc, &error);
12049 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12050 hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
12051 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12052 IXMLDOMParseError2_Release(error2);
12053 IXMLDOMParseError_Release(error);
12054 IXMLDOMDocument_Release(doc);
12057 static void test_getAttributeNode(void)
12059 IXMLDOMAttribute *attr;
12060 IXMLDOMDocument *doc;
12061 IXMLDOMElement *elem;
12062 VARIANT_BOOL v;
12063 HRESULT hr;
12064 BSTR str;
12066 doc = create_document(&IID_IXMLDOMDocument);
12068 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
12069 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12071 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12072 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12074 str = SysAllocString(nonexistent_fileW);
12075 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
12076 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12078 attr = (IXMLDOMAttribute*)0xdeadbeef;
12079 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
12080 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12081 ok(attr == NULL, "got %p\n", attr);
12082 SysFreeString(str);
12084 str = SysAllocString(L"nonExistingAttribute");
12085 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
12086 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12088 attr = (IXMLDOMAttribute*)0xdeadbeef;
12089 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
12090 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12091 ok(attr == NULL, "got %p\n", attr);
12092 SysFreeString(str);
12094 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
12095 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12096 IXMLDOMAttribute_Release(attr);
12098 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
12099 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12101 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
12102 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12103 IXMLDOMAttribute_Release(attr);
12105 IXMLDOMElement_Release(elem);
12106 IXMLDOMDocument_Release(doc);
12107 free_bstrs();
12110 static void test_getAttribute(void)
12112 IXMLDOMDocument *doc;
12113 IXMLDOMElement *elem;
12114 VARIANT_BOOL v;
12115 VARIANT var;
12116 HRESULT hr;
12118 doc = create_document(&IID_IXMLDOMDocument);
12120 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
12121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12123 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12126 VariantInit(&var);
12127 hr = IXMLDOMElement_getAttribute( elem, _bstr_("xmlns:foo"), &var );
12128 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12129 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
12130 ok(!lstrcmpW(V_BSTR(&var), L"urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29"), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
12131 VariantClear(&var);
12133 hr = IXMLDOMElement_getAttribute( elem, _bstr_("a"), &var );
12134 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12135 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
12136 ok(!lstrcmpW(V_BSTR(&var), L"attr a"), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
12137 VariantClear(&var);
12139 hr = IXMLDOMElement_getAttribute( elem, _bstr_("foo:b"), &var );
12140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12141 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
12142 ok(!lstrcmpW(V_BSTR(&var), L"attr b"), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
12143 VariantClear(&var);
12145 hr = IXMLDOMElement_getAttribute( elem, _bstr_("b"), &var );
12146 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12147 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
12148 VariantClear(&var);
12150 hr = IXMLDOMElement_getAttribute( elem, _bstr_("non-existent"), &var );
12151 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12152 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
12153 VariantClear(&var);
12155 IXMLDOMElement_Release(elem);
12156 IXMLDOMDocument_Release(doc);
12157 free_bstrs();
12160 typedef struct {
12161 DOMNodeType type;
12162 const char *name;
12163 REFIID iids[3];
12164 } supporterror_t;
12166 static const supporterror_t supporterror_test[] = {
12167 { NODE_ELEMENT, "element", { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
12168 { NODE_ATTRIBUTE, "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
12169 { NODE_CDATA_SECTION, "cdata", { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
12170 { NODE_ENTITY_REFERENCE, "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
12171 { NODE_PROCESSING_INSTRUCTION, "pi", { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
12172 { NODE_COMMENT, "comment", { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
12173 { NODE_DOCUMENT_FRAGMENT, "fragment", { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
12174 { NODE_INVALID }
12177 static void test_supporterrorinfo(void)
12179 static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
12180 &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
12181 const supporterror_t *ptr = supporterror_test;
12182 ISupportErrorInfo *errorinfo, *info2;
12183 IXMLDOMSchemaCollection *schemacache;
12184 IXMLDOMNamedNodeMap *map, *map2;
12185 IXMLDOMDocument *doc;
12186 IXMLDOMElement *elem;
12187 VARIANT_BOOL b;
12188 IUnknown *unk;
12189 REFIID *iid;
12190 void *dummy;
12191 HRESULT hr;
12193 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument3)) return;
12194 doc = create_document_version(60, &IID_IXMLDOMDocument3);
12196 EXPECT_REF(doc, 1);
12197 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
12198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12199 EXPECT_REF(doc, 1);
12200 ISupportErrorInfo_AddRef(errorinfo);
12201 EXPECT_REF(errorinfo, 2);
12202 EXPECT_REF(doc, 1);
12203 ISupportErrorInfo_Release(errorinfo);
12205 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
12206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12207 ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
12209 /* error interface can't be queried back for DOM interface */
12210 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
12211 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
12212 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
12213 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
12215 ISupportErrorInfo_Release(info2);
12217 iid = iids;
12218 while (*iid)
12220 hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
12221 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12222 if (hr == S_OK)
12224 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
12225 ok(hr == S_OK, "Unexpected hr %#lx. for %s\n", hr, wine_dbgstr_guid(*iid));
12226 IUnknown_Release(unk);
12229 iid++;
12232 ISupportErrorInfo_Release(errorinfo);
12234 while (ptr->type != NODE_INVALID)
12236 IXMLDOMNode *node;
12237 VARIANT type;
12239 V_VT(&type) = VT_I1;
12240 V_I1(&type) = ptr->type;
12242 hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
12243 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", ptr->type, hr);
12245 EXPECT_REF(node, 1);
12246 hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
12247 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", ptr->type, hr);
12248 EXPECT_REF(node, 1);
12250 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
12251 ok(hr == E_NOINTERFACE, "%d: Unexpected hr %#lx.\n", ptr->type, hr);
12253 iid = ptr->iids;
12255 while (*iid)
12257 hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
12258 if (hr == S_OK)
12260 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
12261 ok(hr == S_OK, "%d: unexpected hr %#lx for %s\n", ptr->type, hr, wine_dbgstr_guid(*iid));
12262 IUnknown_Release(unk);
12265 iid++;
12268 ISupportErrorInfo_Release(errorinfo);
12269 IXMLDOMNode_Release(node);
12270 ptr++;
12273 /* IXMLDOMNamedNodeMap */
12274 b = VARIANT_FALSE;
12275 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
12276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12277 ok(b == VARIANT_TRUE, "got %d\n", b);
12279 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12282 hr = IXMLDOMElement_get_attributes(elem, &map);
12283 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12285 EXPECT_REF(map, 1);
12286 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
12287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12288 EXPECT_REF(map, 2);
12290 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
12291 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12293 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
12294 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12295 ok(map == map2, "got %p\n", map2);
12296 IXMLDOMNamedNodeMap_Release(map2);
12298 EXPECT_REF(errorinfo, 2);
12299 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
12300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12301 EXPECT_REF(errorinfo, 3);
12302 EXPECT_REF(map, 3);
12303 IUnknown_Release(unk);
12305 ISupportErrorInfo_Release(errorinfo);
12306 IXMLDOMNamedNodeMap_Release(map);
12307 IXMLDOMElement_Release(elem);
12309 IXMLDOMDocument_Release(doc);
12311 /* IXMLDOMSchemaCollection */
12312 hr = CoCreateInstance(&CLSID_XMLSchemaCache, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (void**)&schemacache);
12313 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12315 hr = IXMLDOMSchemaCollection_QueryInterface(schemacache, &IID_ISupportErrorInfo, (void**)&errorinfo);
12316 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12318 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMSchemaCollection);
12319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12321 ISupportErrorInfo_Release(errorinfo);
12322 IXMLDOMSchemaCollection_Release(schemacache);
12324 free_bstrs();
12327 typedef struct {
12328 DOMNodeType type;
12329 const char *name;
12330 const char *put_content;
12331 HRESULT put_hr;
12332 VARTYPE get_vt;
12333 HRESULT get_hr;
12334 } node_value_t;
12336 static const node_value_t nodevalue_test[] = {
12337 { NODE_ELEMENT, "element", "", E_FAIL, VT_NULL, S_FALSE },
12338 { NODE_ATTRIBUTE, "attr", "value", S_OK, VT_BSTR, S_OK },
12339 { NODE_TEXT, "text", "textdata", S_OK, VT_BSTR, S_OK },
12340 { NODE_CDATA_SECTION , "cdata", "cdata data", S_OK, VT_BSTR, S_OK },
12341 { NODE_ENTITY_REFERENCE, "entityref", "ref", E_FAIL, VT_NULL, S_FALSE },
12342 { NODE_PROCESSING_INSTRUCTION, "pi", "instr", S_OK, VT_BSTR, S_OK },
12343 { NODE_COMMENT, "comment", "comment data", S_OK, VT_BSTR, S_OK },
12344 { NODE_DOCUMENT_FRAGMENT, "docfrag", "", E_FAIL, VT_NULL, S_FALSE },
12345 { NODE_INVALID }
12348 static void test_nodeValue(void)
12350 const node_value_t *ptr = nodevalue_test;
12351 IXMLDOMDocument *doc;
12352 HRESULT hr;
12354 doc = create_document(&IID_IXMLDOMDocument);
12356 while (ptr->type != NODE_INVALID)
12358 IXMLDOMNode *node;
12359 VARIANT v;
12361 V_VT(&v) = VT_I2;
12362 V_I2(&v) = ptr->type;
12364 hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
12365 ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
12367 hr = IXMLDOMNode_get_nodeValue(node, NULL);
12368 ok(hr == E_INVALIDARG, "%d: unexpected hr %#lx\n", ptr->type, hr);
12370 V_VT(&v) = VT_BSTR;
12371 V_BSTR(&v) = _bstr_(ptr->put_content);
12372 hr = IXMLDOMNode_put_nodeValue(node, v);
12373 ok(hr == ptr->put_hr, "%d: unexpected hr %#lx\n", ptr->type, hr);
12375 V_VT(&v) = VT_EMPTY;
12376 hr = IXMLDOMNode_get_nodeValue(node, &v);
12377 ok(hr == ptr->get_hr, "%d: unexpected hr %#lx, expected %#lx.\n", ptr->type, hr, ptr->get_hr);
12378 ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
12379 if (hr == S_OK)
12380 ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
12381 wine_dbgstr_w(V_BSTR(&v)));
12382 VariantClear(&v);
12384 IXMLDOMNode_Release(node);
12386 ptr++;
12389 IXMLDOMDocument_Release(doc);
12392 static void test_xmlns_attribute(void)
12394 BSTR str;
12395 IXMLDOMDocument *doc;
12396 IXMLDOMElement *root;
12397 IXMLDOMAttribute *pAttribute;
12398 IXMLDOMElement *elem;
12399 HRESULT hr;
12400 VARIANT v;
12402 doc = create_document(&IID_IXMLDOMDocument);
12404 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
12405 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12407 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
12408 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12410 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("xmlns:dt"), &pAttribute);
12411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
12413 V_VT(&v) = VT_BSTR;
12414 V_BSTR(&v) = _bstr_("urn:schemas-microsoft-com:datatypes");
12415 hr = IXMLDOMAttribute_put_nodeValue(pAttribute, v);
12416 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
12418 hr = IXMLDOMElement_setAttributeNode(root, pAttribute, NULL);
12419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
12421 hr = IXMLDOMNode_put_dataType((IXMLDOMNode*)root, _bstr_("bin.base64"));
12422 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr );
12424 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12425 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12427 str = NULL;
12428 hr = IXMLDOMElement_get_xml(elem, &str);
12429 ok( hr == S_OK, "Unexpected hr %#lx.\n", hr);
12430 todo_wine ok(lstrcmpW(str, L"<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>") == 0,
12431 "got %s\n", wine_dbgstr_w(str));
12432 SysFreeString(str);
12434 IXMLDOMElement_Release(elem);
12435 IXMLDOMAttribute_Release( pAttribute);
12437 IXMLDOMDocument_Release(doc);
12439 free_bstrs();
12442 static const char namespacesA[] =
12443 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
12444 " <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
12445 " <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
12446 " <ns1:elem3/>"
12447 " <ns1:elem4/>"
12448 " <elem5 xmlns=\"http://blahblah.org\"/>"
12449 " <ns1:elem6>true</ns1:elem6>"
12450 " </ns1:elem1>";
12452 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
12453 static const char xsd_schema1_xml[] =
12454 "<?xml version='1.0'?>"
12455 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
12456 " targetNamespace='x-schema:test1.xsd'>"
12457 " <element name='root'>"
12458 " <complexType>"
12459 " <sequence maxOccurs='unbounded'>"
12460 " <any/>"
12461 " </sequence>"
12462 " </complexType>"
12463 " </element>"
12464 "</schema>";
12466 static void test_get_namespaces(void)
12468 IXMLDOMSchemaCollection *collection, *collection2;
12469 IXMLDOMDocument2 *doc, *doc2;
12470 IEnumVARIANT *enumv, *enum2;
12471 IUnknown *unk1, *unk2;
12472 IXMLDOMNode *node;
12473 VARIANT_BOOL b;
12474 ULONG fetched;
12475 VARIANT v[2];
12476 HRESULT hr;
12477 LONG len;
12478 BSTR s;
12480 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
12481 doc = create_document(&IID_IXMLDOMDocument2);
12483 /* null pointer */
12484 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
12485 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
12487 /* no document loaded */
12488 collection = (void*)0xdeadbeef;
12489 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12491 if (hr != S_OK)
12493 IXMLDOMDocument2_Release(doc);
12494 return;
12496 EXPECT_REF(collection, 2);
12498 collection2 = (void*)0xdeadbeef;
12499 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
12500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12501 ok(collection == collection2, "got %p\n", collection2);
12502 EXPECT_REF(collection, 3);
12503 IXMLDOMSchemaCollection_Release(collection);
12505 len = -1;
12506 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12507 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12508 ok(len == 0, "got %ld\n", len);
12509 IXMLDOMSchemaCollection_Release(collection);
12511 /* now with document */
12512 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
12513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12515 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12516 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12518 len = -1;
12519 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12521 ok(len == 2, "got %ld\n", len);
12523 /* try to lookup some uris */
12524 node = (void*)0xdeadbeef;
12525 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
12526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12527 ok(node == NULL, "got %p\n", node);
12529 node = (void*)0xdeadbeef;
12530 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
12531 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12532 ok(node == NULL, "got %p\n", node);
12534 /* load schema and try to add it */
12535 doc2 = create_document(&IID_IXMLDOMDocument2);
12536 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
12537 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12539 V_VT(&v[0]) = VT_DISPATCH;
12540 V_DISPATCH(&v[0]) = (IDispatch*)doc2;
12541 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v[0]);
12542 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12544 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
12545 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12546 ok(!lstrcmpW(s, L"http://blah.org"), "got %s\n", wine_dbgstr_w(s));
12547 SysFreeString(s);
12549 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
12550 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12551 ok(!lstrcmpW(s, L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(s));
12552 SysFreeString(s);
12554 s = (void*)0xdeadbeef;
12555 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
12556 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12557 ok(s == (void*)0xdeadbeef, "got %p\n", s);
12559 /* enumerate */
12560 enumv = (void*)0xdeadbeef;
12561 EXPECT_REF(collection, 2);
12562 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
12563 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12564 EXPECT_REF(collection, 3);
12565 ok(enumv != NULL, "got %p\n", enumv);
12567 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IUnknown, (void**)&unk1);
12568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12569 hr = IEnumVARIANT_QueryInterface(enumv, &IID_IUnknown, (void**)&unk2);
12570 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12571 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
12572 IUnknown_Release(unk1);
12573 IUnknown_Release(unk2);
12575 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2);
12576 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
12578 V_VT(&v[0]) = VT_EMPTY;
12579 hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL);
12580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12581 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12582 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12583 VariantClear(&v[0]);
12585 V_VT(&v[0]) = VT_EMPTY;
12586 hr = IEnumVARIANT_Next(enumv, 1, &v[0], &fetched);
12587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12588 ok(fetched == 1, "got %ld, expected 1\n", fetched);
12589 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12590 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12591 VariantClear(&v[0]);
12593 V_VT(&v[0]) = VT_NULL;
12594 hr = IEnumVARIANT_Next(enumv, 1, &v[0], &fetched);
12595 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12596 ok(fetched == 0, "got %ld, expected 0\n", fetched);
12597 ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
12599 hr = IEnumVARIANT_Reset(enumv);
12600 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12602 V_VT(&v[1]) = VT_EMPTY;
12603 V_VT(&v[0]) = VT_EMPTY;
12604 hr = IEnumVARIANT_Next(enumv, 2, v, &fetched);
12605 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12606 ok(fetched == 2, "got %ld, expected 2\n", fetched);
12607 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12608 ok(V_VT(&v[1]) == VT_BSTR, "got %d\n", V_VT(&v[1]));
12609 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12610 ok(!lstrcmpW(V_BSTR(&v[1]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[1])));
12611 VariantClear(&v[1]);
12612 VariantClear(&v[0]);
12614 V_VT(&v[0]) = VT_NULL;
12615 hr = IEnumVARIANT_Next(enumv, 1, v, &fetched);
12616 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12617 ok(fetched == 0, "got %ld, expected 0\n", fetched);
12618 ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
12620 IEnumVARIANT_Release(enumv);
12621 IXMLDOMSchemaCollection_Release(collection);
12622 IXMLDOMDocument2_Release(doc);
12624 /* now with CLSID_DOMDocument60 */
12625 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) return;
12626 doc = create_document_version(60, &IID_IXMLDOMDocument2);
12628 /* null pointer */
12629 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
12630 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
12632 /* no document loaded */
12633 collection = (void*)0xdeadbeef;
12634 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12636 if (hr != S_OK)
12638 IXMLDOMDocument2_Release(doc);
12639 return;
12641 EXPECT_REF(collection, 2);
12643 collection2 = (void*)0xdeadbeef;
12644 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
12645 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12646 ok(collection == collection2, "got %p\n", collection2);
12647 EXPECT_REF(collection, 3);
12648 IXMLDOMSchemaCollection_Release(collection);
12650 len = -1;
12651 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12652 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12653 ok(len == 0, "got %ld\n", len);
12654 IXMLDOMSchemaCollection_Release(collection);
12656 /* now with document */
12657 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
12658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12660 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
12661 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12663 len = -1;
12664 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
12665 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12666 ok(len == 2, "got %ld\n", len);
12668 /* try to lookup some uris */
12669 node = (void*)0xdeadbeef;
12670 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
12671 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
12672 ok(broken(node == (void*)0xdeadbeef) || (node == NULL), "got %p\n", node);
12674 /* load schema and try to add it */
12675 doc2 = create_document(&IID_IXMLDOMDocument2);
12676 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
12677 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12679 V_VT(&v[0]) = VT_DISPATCH;
12680 V_DISPATCH(&v[0]) = (IDispatch*)doc2;
12681 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v[0]);
12682 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12683 IXMLDOMDocument2_Release(doc2);
12685 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
12686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12687 ok(!lstrcmpW(s, L"http://blah.org"), "got %s\n", wine_dbgstr_w(s));
12688 SysFreeString(s);
12690 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
12691 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12692 ok(!lstrcmpW(s, L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(s));
12693 SysFreeString(s);
12695 s = (void*)0xdeadbeef;
12696 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
12697 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
12698 ok(broken(s == (void*)0xdeadbeef) || (s == NULL), "got %p\n", s);
12700 /* enumerate */
12701 enumv = (void*)0xdeadbeef;
12702 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
12703 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12704 ok(enumv != NULL, "got %p\n", enumv);
12706 V_VT(&v[0]) = VT_EMPTY;
12707 hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL);
12708 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12709 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12710 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12711 VariantClear(&v[0]);
12713 V_VT(&v[0]) = VT_EMPTY;
12714 hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL);
12715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12716 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12717 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12718 VariantClear(&v[0]);
12720 V_VT(&v[0]) = VT_NULL;
12721 hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL);
12722 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12723 ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
12725 hr = IEnumVARIANT_Reset(enumv);
12726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12728 V_VT(&v[1]) = VT_EMPTY;
12729 V_VT(&v[0]) = VT_EMPTY;
12730 hr = IEnumVARIANT_Next(enumv, 2, v, &fetched);
12731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12732 ok(fetched == 2, "got %ld, expected 2\n", fetched);
12733 ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0]));
12734 ok(V_VT(&v[1]) == VT_BSTR, "got %d\n", V_VT(&v[1]));
12735 ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12736 ok(!lstrcmpW(V_BSTR(&v[1]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0])));
12737 VariantClear(&v[1]);
12738 VariantClear(&v[0]);
12740 V_VT(&v[0]) = VT_NULL;
12741 hr = IEnumVARIANT_Next(enumv, 1, v, &fetched);
12742 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
12743 ok(fetched == 0, "got %ld, expected 0\n", fetched);
12744 ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
12746 IEnumVARIANT_Release(enumv);
12747 IXMLDOMSchemaCollection_Release(collection);
12748 IXMLDOMDocument2_Release(doc);
12749 free_bstrs();
12752 static const DOMNodeType put_data_types[] = {
12753 NODE_TEXT,
12754 NODE_CDATA_SECTION,
12755 NODE_PROCESSING_INSTRUCTION,
12756 NODE_COMMENT,
12757 NODE_INVALID
12760 static void test_put_data(void)
12762 WCHAR buff[100], *data;
12763 IXMLDOMDocument *doc;
12764 const DOMNodeType *type;
12765 IXMLDOMText *text;
12766 IXMLDOMNode *node;
12767 VARIANT v;
12768 BSTR get_data;
12769 HRESULT hr;
12771 doc = create_document(&IID_IXMLDOMDocument);
12773 memcpy(&buff[2], L"test node data", 15 * sizeof(WCHAR));
12774 /* just a big length */
12775 *(DWORD*)buff = 0xf0f0;
12776 data = &buff[2];
12778 type = put_data_types;
12779 while (*type != NODE_INVALID)
12781 V_VT(&v) = VT_I2;
12782 V_I2(&v) = *type;
12784 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12785 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12787 /* put_data() is interface-specific */
12788 switch (*type)
12790 case NODE_TEXT:
12792 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12793 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12794 hr = IXMLDOMText_put_data(text, data);
12795 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12797 hr = IXMLDOMText_get_data(text, &get_data);
12798 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12800 IXMLDOMText_Release(text);
12801 break;
12803 case NODE_CDATA_SECTION:
12805 IXMLDOMCDATASection *cdata;
12807 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
12808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12809 hr = IXMLDOMCDATASection_put_data(cdata, data);
12810 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12812 hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
12813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12815 IXMLDOMCDATASection_Release(cdata);
12816 break;
12818 case NODE_PROCESSING_INSTRUCTION:
12820 IXMLDOMProcessingInstruction *pi;
12822 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
12823 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12824 hr = IXMLDOMProcessingInstruction_put_data(pi, data);
12825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12827 hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
12828 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12830 IXMLDOMProcessingInstruction_Release(pi);
12831 break;
12833 case NODE_COMMENT:
12835 IXMLDOMComment *comment;
12837 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
12838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12839 hr = IXMLDOMComment_put_data(comment, data);
12840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12842 hr = IXMLDOMComment_get_data(comment, &get_data);
12843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12845 IXMLDOMComment_Release(comment);
12846 break;
12848 default:
12849 get_data = NULL;
12850 break;
12853 /* compare */
12854 ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
12855 wine_dbgstr_w(data));
12856 SysFreeString(get_data);
12858 IXMLDOMNode_Release(node);
12859 type++;
12862 IXMLDOMDocument_Release(doc);
12863 free_bstrs();
12866 static void test_newline_normalization(void)
12868 const struct msxmlsupported_data_t *table = domdoc_support_data;
12869 IXMLDOMDocument *doc;
12870 IXMLDOMText *text;
12871 IXMLDOMNode *node;
12872 VARIANT v;
12873 VARIANT_BOOL b;
12874 BSTR s;
12875 HRESULT hr;
12876 LONG length;
12878 V_VT(&v) = VT_I2;
12879 V_I2(&v) = NODE_TEXT;
12881 while (table->clsid)
12883 if (!is_clsid_supported(table->clsid, &IID_IXMLDOMDocument))
12885 table++;
12886 continue;
12889 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
12890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12892 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12893 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12895 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12897 /* \r\n is normalized to \n and back to \r\n */
12899 hr = IXMLDOMText_put_data(text, _bstr_("\r\n"));
12900 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12902 hr = IXMLDOMText_get_data(text, &s);
12903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12904 ok(!lstrcmpW(s, L"\n"), "got %s\n", wine_dbgstr_w(s));
12905 SysFreeString(s);
12907 hr = IXMLDOMText_get_length(text, &length);
12908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12909 ok(length == 1, "got %ld, expected 1\n", length);
12911 hr = IXMLDOMText_get_xml(text, &s);
12912 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12913 ok(!lstrcmpW(s, L"\r\n"), "got %s\n", wine_dbgstr_w(s));
12914 SysFreeString(s);
12916 /* \r\r\n is normalized to \n\n and back to \r\n\r\n */
12918 hr = IXMLDOMText_put_data(text, _bstr_("\r\r\n"));
12919 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12921 hr = IXMLDOMText_get_data(text, &s);
12922 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12923 ok(!lstrcmpW(s, L"\n\n"), "got %s\n", wine_dbgstr_w(s));
12924 SysFreeString(s);
12926 hr = IXMLDOMText_get_length(text, &length);
12927 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12928 ok(length == 2, "got %ld, expected 2\n", length);
12930 hr = IXMLDOMText_get_xml(text, &s);
12931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12932 ok(!lstrcmpW(s, L"\r\n\r\n"), "got %s\n", wine_dbgstr_w(s));
12933 SysFreeString(s);
12935 /* the same normalizations are applied when loading a document as a whole */
12937 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?><root>foo\n\r\n\r\r\nbar</root>"), &b);
12938 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12940 hr = IXMLDOMDocument_get_text(doc, &s);
12941 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12942 ok(!lstrcmpW(s, L"foo\n\n\n\nbar"), "got %s\n", wine_dbgstr_w(s));
12943 SysFreeString(s);
12945 hr = IXMLDOMDocument_get_xml(doc, &s);
12946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12947 ok(!lstrcmpW(s, L"<?xml version=\"1.0\"?>\r\n<root>foo\r\n\r\n\r\n\r\nbar</root>\r\n"),
12948 "got %s\n", wine_dbgstr_w(s));
12949 SysFreeString(s);
12951 /* even if xml:space="preserve" */
12953 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?>"
12954 "<root xml:space=\"preserve\">foo\n\r\n\r\r\nbar</root>"), &b);
12955 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12957 hr = IXMLDOMDocument_get_text(doc, &s);
12958 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12959 ok(!lstrcmpW(s, L"foo\n\n\n\nbar"), "got %s\n", wine_dbgstr_w(s));
12960 SysFreeString(s);
12962 hr = IXMLDOMDocument_get_xml(doc, &s);
12963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12964 ok(!lstrcmpW(s, _bstr_("<?xml version=\"1.0\"?>\r\n"
12965 "<root xml:space=\"preserve\">foo\r\n\r\n\r\n\r\nbar</root>\r\n")),
12966 "got %s\n", wine_dbgstr_w(s));
12967 SysFreeString(s);
12969 /* or preserveWhiteSpace is set */
12971 hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE);
12972 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12974 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?><root>foo\n\r\n\r\r\nbar</root>"), &b);
12975 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12977 hr = IXMLDOMDocument_get_text(doc, &s);
12978 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12979 ok(!lstrcmpW(s, L"foo\n\n\n\nbar"), "got %s\n", wine_dbgstr_w(s));
12980 SysFreeString(s);
12982 hr = IXMLDOMDocument_get_xml(doc, &s);
12983 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
12984 if (IsEqualGUID(table->clsid, &CLSID_DOMDocument60))
12986 /* DOMDocument60 does the newline normalization but does not insert line breaks around the root node */
12987 todo_wine
12988 ok(!lstrcmpW(s, L"<?xml version=\"1.0\"?><root>foo\r\n\r\n\r\n\r\nbar</root>"),
12989 "got %s\n", wine_dbgstr_w(s));
12991 else
12993 ok(!lstrcmpW(s, L"<?xml version=\"1.0\"?>\r\n<root>foo\r\n\r\n\r\n\r\nbar</root>\r\n"),
12994 "got %s\n", wine_dbgstr_w(s));
12996 SysFreeString(s);
12998 IXMLDOMText_Release(text);
12999 IXMLDOMNode_Release(node);
13000 IXMLDOMDocument_Release(doc);
13001 free_bstrs();
13002 table++;
13006 static void test_putref_schemas(void)
13008 IXMLDOMSchemaCollection *cache;
13009 IXMLDOMDocument2 *doc;
13010 VARIANT schema;
13011 HRESULT hr;
13013 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
13014 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
13016 doc = create_document(&IID_IXMLDOMDocument2);
13017 cache = create_cache(&IID_IXMLDOMSchemaCollection);
13019 /* set to NULL iface when no schema is set */
13020 V_VT(&schema) = VT_DISPATCH;
13021 V_DISPATCH(&schema) = NULL;
13022 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13023 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13025 V_VT(&schema) = VT_UNKNOWN;
13026 V_UNKNOWN(&schema) = NULL;
13027 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13028 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13030 /* set as VT_DISPATCH, reset with it */
13031 V_VT(&schema) = VT_DISPATCH;
13032 V_DISPATCH(&schema) = (IDispatch*)cache;
13033 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13036 V_DISPATCH(&schema) = NULL;
13037 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
13038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13039 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
13041 V_VT(&schema) = VT_DISPATCH;
13042 V_DISPATCH(&schema) = NULL;
13043 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13044 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13046 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
13047 V_VT(&schema) = VT_I2;
13048 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
13049 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
13050 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
13051 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
13053 /* set as VT_UNKNOWN, reset with it */
13054 V_VT(&schema) = VT_UNKNOWN;
13055 V_UNKNOWN(&schema) = (IUnknown*)cache;
13056 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13059 V_DISPATCH(&schema) = NULL;
13060 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
13061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13062 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
13064 V_VT(&schema) = VT_UNKNOWN;
13065 V_UNKNOWN(&schema) = NULL;
13066 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
13067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13069 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
13070 V_VT(&schema) = VT_I2;
13071 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
13072 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
13073 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
13074 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
13076 IXMLDOMSchemaCollection_Release(cache);
13077 IXMLDOMDocument2_Release(doc);
13080 static void test_namedmap_newenum(void)
13082 IEnumVARIANT *enum1, *enum2, *enum3;
13083 IXMLDOMNamedNodeMap *map;
13084 IUnknown *unk1, *unk2;
13085 IXMLDOMDocument *doc;
13086 IXMLDOMElement *elem;
13087 IXMLDOMNode *node;
13088 VARIANT_BOOL b;
13089 ULONG fetched;
13090 VARIANT v[3];
13091 HRESULT hr;
13092 BSTR str;
13094 doc = create_document(&IID_IXMLDOMDocument);
13096 hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b);
13097 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13099 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
13100 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13102 hr = IXMLDOMElement_get_attributes(elem, &map);
13103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13104 IXMLDOMElement_Release(elem);
13106 enum1 = NULL;
13107 EXPECT_REF(map, 1);
13108 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1);
13109 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13110 ok(enum1 != NULL, "got %p\n", enum1);
13111 EXPECT_REF(map, 1);
13112 EXPECT_REF(enum1, 2);
13114 enum2 = NULL;
13115 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2);
13116 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13117 ok(enum2 == enum1, "got %p\n", enum2);
13119 IEnumVARIANT_Release(enum2);
13121 EXPECT_REF(map, 1);
13122 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2);
13123 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13124 EXPECT_REF(map, 2);
13125 EXPECT_REF(enum2, 1);
13126 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
13128 IEnumVARIANT_Release(enum1);
13130 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
13131 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1);
13132 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13133 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
13134 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13135 EXPECT_REF(map, 3);
13136 EXPECT_REF(enum2, 2);
13137 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
13138 IUnknown_Release(unk1);
13139 IUnknown_Release(unk2);
13141 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3);
13142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13143 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
13144 IEnumVARIANT_Release(enum3);
13146 /* iteration tests */
13147 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
13148 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13149 hr = IXMLDOMNode_get_nodeName(node, &str);
13150 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13151 ok(!lstrcmpW(str, L"attr1"), "got %s\n", wine_dbgstr_w(str));
13152 SysFreeString(str);
13153 IXMLDOMNode_Release(node);
13155 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
13156 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13157 hr = IXMLDOMNode_get_nodeName(node, &str);
13158 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13159 ok(!lstrcmpW(str, L"attr1"), "got %s\n", wine_dbgstr_w(str));
13160 SysFreeString(str);
13161 IXMLDOMNode_Release(node);
13163 V_VT(&v[0]) = VT_EMPTY;
13164 hr = IEnumVARIANT_Next(enum2, 1, &v[0], NULL);
13165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13166 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
13167 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
13168 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13169 hr = IXMLDOMNode_get_nodeName(node, &str);
13170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13171 ok(!lstrcmpW(str, L"attr1"), "got node name %s\n", wine_dbgstr_w(str));
13172 SysFreeString(str);
13173 IXMLDOMNode_Release(node);
13174 VariantClear(&v[0]);
13176 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
13177 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13178 hr = IXMLDOMNode_get_nodeName(node, &str);
13179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13180 ok(!lstrcmpW(str, L"attr2"), "got %s\n", wine_dbgstr_w(str));
13181 SysFreeString(str);
13182 IXMLDOMNode_Release(node);
13184 hr = IEnumVARIANT_Reset(enum2);
13185 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13187 V_VT(&v[1]) = VT_EMPTY;
13188 V_VT(&v[0]) = VT_EMPTY;
13189 hr = IEnumVARIANT_Next(enum2, 2, v, &fetched);
13190 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13191 ok(fetched == 2, "got %ld, expected 2\n", fetched);
13192 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
13193 ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1]));
13194 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
13195 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13196 hr = IXMLDOMNode_get_nodeName(node, &str);
13197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13198 ok(!lstrcmpW(str, L"attr1"), "got node name %s\n", wine_dbgstr_w(str));
13199 SysFreeString(str);
13200 IXMLDOMNode_Release(node);
13201 hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node);
13202 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13203 hr = IXMLDOMNode_get_nodeName(node, &str);
13204 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13205 ok(!lstrcmpW(str, L"attr2"), "got node name %s\n", wine_dbgstr_w(str));
13206 SysFreeString(str);
13207 IXMLDOMNode_Release(node);
13208 VariantClear(&v[1]);
13209 VariantClear(&v[0]);
13211 V_VT(&v[2]) = VT_NULL;
13212 V_VT(&v[1]) = VT_EMPTY;
13213 V_VT(&v[0]) = VT_EMPTY;
13214 hr = IEnumVARIANT_Next(enum2, 3, v, &fetched);
13215 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
13216 ok(fetched == 2, "got %ld, expected 2\n", fetched);
13217 ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
13218 ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1]));
13219 ok(V_VT(&v[2]) == VT_EMPTY, "got var type %d\n", V_VT(&v[2]));
13220 hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node);
13221 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13222 hr = IXMLDOMNode_get_nodeName(node, &str);
13223 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13224 ok(!lstrcmpW(str, L"attr3"), "got node name %s\n", wine_dbgstr_w(str));
13225 SysFreeString(str);
13226 IXMLDOMNode_Release(node);
13227 hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node);
13228 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13229 hr = IXMLDOMNode_get_nodeName(node, &str);
13230 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13231 ok(!lstrcmpW(str, L"attr4"), "got node name %s\n", wine_dbgstr_w(str));
13232 SysFreeString(str);
13233 IXMLDOMNode_Release(node);
13234 VariantClear(&v[1]);
13235 VariantClear(&v[0]);
13236 IEnumVARIANT_Release(enum2);
13238 IXMLDOMNamedNodeMap_Release(map);
13239 IXMLDOMDocument_Release(doc);
13242 static const char xsltext_xsl[] =
13243 "<?xml version=\"1.0\"?>"
13244 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
13245 "<xsl:output method=\"html\" encoding=\"us-ascii\"/>"
13246 "<xsl:template match=\"/\">"
13247 " <xsl:choose>"
13248 " <xsl:when test=\"testkey\">"
13249 " <xsl:text>testdata</xsl:text>"
13250 " </xsl:when>"
13251 " </xsl:choose>"
13252 "</xsl:template>"
13253 "</xsl:stylesheet>";
13255 static const char omitxmldecl_xsl[] =
13256 "<?xml version=\"1.0\"?>"
13257 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
13258 "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>"
13259 "<xsl:template match=\"/\">"
13260 " <xsl:for-each select=\"/a/item\">"
13261 " <xsl:element name=\"node\">"
13262 " <xsl:value-of select=\"@name\"/>"
13263 " </xsl:element>"
13264 " </xsl:for-each>"
13265 "</xsl:template>"
13266 "</xsl:stylesheet>";
13268 static const char omitxmldecl_doc[] =
13269 "<?xml version=\"1.0\"?>"
13270 "<a>"
13271 " <item name=\"item1\"/>"
13272 " <item name=\"item2\"/>"
13273 "</a>";
13275 static void test_xsltext(void)
13277 IXMLDOMDocument *doc, *doc2;
13278 VARIANT_BOOL b;
13279 HRESULT hr;
13280 BSTR ret;
13282 doc = create_document(&IID_IXMLDOMDocument);
13283 doc2 = create_document(&IID_IXMLDOMDocument);
13285 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
13286 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13288 hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b);
13289 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13291 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
13292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13293 ok(!lstrcmpW(ret, L"testdata"), "transform result %s\n", wine_dbgstr_w(ret));
13294 SysFreeString(ret);
13296 /* omit-xml-declaration */
13297 hr = IXMLDOMDocument_loadXML(doc, _bstr_(omitxmldecl_xsl), &b);
13298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13299 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(omitxmldecl_doc), &b);
13300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13302 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
13303 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13304 ok(!lstrcmpW(ret, L"<node>item1</node><node>item2</node>"), "transform result %s\n", wine_dbgstr_w(ret));
13305 SysFreeString(ret);
13307 IXMLDOMDocument_Release(doc2);
13308 IXMLDOMDocument_Release(doc);
13309 free_bstrs();
13312 struct attrtest_t {
13313 const char *name;
13314 const char *uri;
13315 const char *prefix;
13316 const char *href;
13319 static struct attrtest_t attrtests[] = {
13320 { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" },
13321 { "xmlns", "nondefaulturi", "xmlns", "xmlns" },
13322 { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" },
13323 { "c", "nsref1", NULL, "nsref1" },
13324 { "ns:c", "nsref1", "ns", "nsref1" },
13325 { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" },
13326 { "xmlns:c", "nondefaulturi", "xmlns", "" },
13327 { 0 }
13330 /* see dlls/msxml[46]/tests/domdoc.c */
13331 static void test_create_attribute(void)
13333 struct attrtest_t *ptr = attrtests;
13334 IXMLDOMElement *el;
13335 IXMLDOMDocument *doc;
13336 IXMLDOMNode *node, *node2;
13337 VARIANT var;
13338 HRESULT hr;
13339 int i = 0;
13340 BSTR str;
13342 doc = create_document(&IID_IXMLDOMDocument);
13344 while (ptr->name)
13346 V_VT(&var) = VT_I1;
13347 V_I1(&var) = NODE_ATTRIBUTE;
13348 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
13349 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13351 str = NULL;
13352 hr = IXMLDOMNode_get_prefix(node, &str);
13353 if (ptr->prefix)
13355 ok(hr == S_OK, "%d: unexpected hr %#lx\n", i, hr);
13356 ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix);
13358 else
13360 ok(hr == S_FALSE, "%d: unexpected hr %#lx\n", i, hr);
13361 ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str));
13363 SysFreeString(str);
13365 str = NULL;
13366 hr = IXMLDOMNode_get_namespaceURI(node, &str);
13367 ok(hr == S_OK, "%d: unexpected hr %#lx\n", i, hr);
13368 ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href);
13369 SysFreeString(str);
13371 IXMLDOMNode_Release(node);
13372 free_bstrs();
13374 i++;
13375 ptr++;
13378 V_VT(&var) = VT_I1;
13379 V_I1(&var) = NODE_ELEMENT;
13380 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2);
13381 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13383 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el);
13384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13385 IXMLDOMNode_Release(node2);
13387 V_VT(&var) = VT_I1;
13388 V_I1(&var) = NODE_ATTRIBUTE;
13389 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node);
13390 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13392 hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL);
13393 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13395 /* for some reason default namespace uri is not reported */
13396 hr = IXMLDOMNode_get_namespaceURI(node, &str);
13397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13398 ok(!lstrcmpW(str, L""), "got uri %s\n", wine_dbgstr_w(str));
13399 SysFreeString(str);
13401 IXMLDOMNode_Release(node);
13402 IXMLDOMElement_Release(el);
13403 IXMLDOMDocument_Release(doc);
13404 free_bstrs();
13407 static void test_url(void)
13409 IXMLDOMDocument *doc;
13410 HRESULT hr;
13411 BSTR s;
13413 doc = create_document(&IID_IXMLDOMDocument);
13415 hr = IXMLDOMDocument_get_url(doc, NULL);
13416 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
13418 s = (void *)0xdeadbeef;
13419 hr = IXMLDOMDocument_get_url(doc, &s);
13420 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
13421 ok(s == NULL, "got %s\n", wine_dbgstr_w(s));
13423 IXMLDOMDocument_Release(doc);
13426 static void test_merging_text(void)
13428 IXMLDOMText *nodetext;
13429 IXMLDOMText *newtext;
13430 IXMLDOMElement *root;
13431 IXMLDOMDocument *doc;
13432 IXMLDOMNode *first;
13433 HRESULT hr;
13434 VARIANT v;
13435 BSTR str;
13436 int i;
13438 doc = create_document(&IID_IXMLDOMDocument);
13440 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
13441 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13443 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
13444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13446 /* test xmlAddChild */
13447 for (i = 0; i < 10; i++)
13449 str = SysAllocString(L"str1");
13450 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
13451 SysFreeString(str);
13452 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13454 newtext = NULL;
13455 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)nodetext, (IXMLDOMNode**)&newtext);
13456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13457 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
13459 IXMLDOMText_Release(newtext);
13460 IXMLDOMText_Release(nodetext);
13463 /* test xmlAddPrevSibling */
13464 hr = IXMLDOMElement_get_firstChild(root, &first);
13465 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13466 V_VT(&v) = VT_UNKNOWN;
13467 V_UNKNOWN(&v) = (IUnknown*)first;
13468 for (i = 0; i < 10; i++)
13470 str = SysAllocString(L"str2");
13471 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
13472 SysFreeString(str);
13473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13475 newtext = NULL;
13476 hr = IXMLDOMElement_insertBefore(root, (IXMLDOMNode*)nodetext, v, (IXMLDOMNode**)&newtext);
13477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13478 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
13480 IXMLDOMText_Release(newtext);
13481 IXMLDOMText_Release(nodetext);
13484 IXMLDOMNode_Release(first);
13485 IXMLDOMElement_Release(root);
13486 IXMLDOMDocument_Release(doc);
13488 free_bstrs();
13491 static HRESULT WINAPI transformdest_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
13493 BOOL known_iid = IsEqualIID(riid, &IID_IHTMLObjectElement) ||
13494 IsEqualIID(riid, &IID_transformdest_unknown) ||
13495 IsEqualIID(riid, &IID_IServiceProvider) ||
13496 IsEqualIID(riid, &IID_IStream) ||
13497 IsEqualIID(riid, &IID_ISequentialStream) ||
13498 IsEqualIID(riid, &IID_IResponse);
13500 todo_wine_if(IsEqualIID(riid, &IID_IXMLDOMDocument))
13501 ok(known_iid, "Unexpected riid %s\n", wine_dbgstr_guid(riid));
13503 return E_NOINTERFACE;
13506 static ULONG WINAPI transformdest_AddRef(IUnknown *iface)
13508 return 2;
13511 static ULONG WINAPI transformdest_Release(IUnknown *iface)
13513 return 1;
13516 static const IUnknownVtbl transformdestvtbl =
13518 transformdest_QueryInterface,
13519 transformdest_AddRef,
13520 transformdest_Release,
13523 static void test_transformNodeToObject(void)
13525 IUnknown transformdest = { &transformdestvtbl };
13526 IXMLDOMDocument *doc, *doc2, *doc3;
13527 ISequentialStream *sstream;
13528 LARGE_INTEGER off;
13529 WCHAR buffer[256];
13530 IStream *istream;
13531 VARIANT_BOOL b;
13532 ULONG nread;
13533 HRESULT hr;
13534 VARIANT v;
13536 doc = create_document(&IID_IXMLDOMDocument);
13537 doc2 = create_document(&IID_IXMLDOMDocument);
13538 doc3 = create_document(&IID_IXMLDOMDocument);
13540 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &b);
13541 ok(hr == S_OK, "Failed to load document, hr %#lx.\n", hr);
13542 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformSSXML), &b);
13543 ok(hr == S_OK, "Failed to load document, hr %#lx.\n", hr);
13545 V_VT(&v) = VT_UNKNOWN;
13546 V_UNKNOWN(&v) = &transformdest;
13547 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13548 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#lx.\n", hr);
13550 V_VT(&v) = VT_UNKNOWN;
13551 V_UNKNOWN(&v) = NULL;
13552 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13553 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#lx.\n", hr);
13555 V_VT(&v) = VT_DISPATCH;
13556 V_DISPATCH(&v) = NULL;
13557 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13558 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#lx.\n", hr);
13560 V_VT(&v) = VT_DISPATCH;
13561 V_DISPATCH(&v) = (IDispatch *)doc3;
13562 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13563 ok(hr == S_OK, "Failed to transform node, hr %#lx.\n", hr);
13565 /* IStream */
13566 istream = SHCreateMemStream(NULL, 0);
13567 V_VT(&v) = VT_UNKNOWN;
13568 V_UNKNOWN(&v) = (IUnknown *)istream;
13569 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13570 ok(hr == S_OK, "Failed to transform node, hr %#lx.\n", hr);
13572 off.QuadPart = 0;
13573 hr = IStream_Seek(istream, off, STREAM_SEEK_SET, NULL);
13574 ok(hr == S_OK, "Failed to seek, hr %#lx.\n", hr);
13576 nread = 0;
13577 memset(buffer, 0xcc, sizeof(buffer));
13578 hr = IStream_Read(istream, buffer, sizeof(buffer), &nread);
13579 ok(hr == S_OK, "Failed to read, hr %#lx.\n", hr);
13580 buffer[nread/2] = 0;
13581 ok(buffer[0] == 0xfeff, "got %x\n", buffer[0]);
13582 ok(compareIgnoreReturns(&buffer[1], _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(buffer));
13583 IStream_Release(istream);
13585 /* ISequentialStream */
13586 istream = SHCreateMemStream(NULL, 0);
13587 sstream = NULL;
13588 hr = IStream_QueryInterface(istream, &IID_ISequentialStream, (void**)&sstream);
13589 ok(hr == S_OK, "Failed to QI, hr %#lx.\n", hr);
13591 V_VT(&v) = VT_UNKNOWN;
13592 V_UNKNOWN(&v) = (IUnknown *)sstream;
13593 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v);
13594 ok(hr == S_OK, "Failed to transform node, hr %#lx.\n", hr);
13596 off.QuadPart = 0;
13597 hr = IStream_Seek(istream, off, STREAM_SEEK_SET, NULL);
13598 ok(hr == S_OK, "Failed to seek, hr %#lx.\n", hr);
13600 nread = 0;
13601 memset(buffer, 0xcc, sizeof(buffer));
13602 hr = ISequentialStream_Read(sstream, buffer, sizeof(buffer), &nread);
13603 ok(hr == S_OK, "Failed to read, hr %#lx.\n", hr);
13604 buffer[nread/2] = 0;
13605 ok(buffer[0] == 0xfeff, "got %x\n", buffer[0]);
13606 ok(compareIgnoreReturns(&buffer[1], _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(buffer));
13607 ISequentialStream_Release(sstream);
13608 IStream_Release(istream);
13610 IXMLDOMDocument_Release(doc3);
13611 IXMLDOMDocument_Release(doc2);
13612 IXMLDOMDocument_Release(doc);
13613 free_bstrs();
13616 static void test_normalize_attribute_values(void)
13618 IXMLDOMDocument2 *doc;
13619 VARIANT var;
13620 HRESULT hr;
13622 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2))
13624 win_skip("NormalizeAttributeValues is not supported.\n");
13625 return;
13628 doc = create_document_version(60, &IID_IXMLDOMDocument2);
13630 V_VT(&var) = VT_I2;
13631 V_I2(&var) = 10;
13632 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("NormalizeAttributeValues"), &var);
13633 todo_wine {
13634 ok(hr == S_OK, "Failed to get property value, hr %#lx.\n", hr);
13635 ok(V_VT(&var) == VT_BOOL, "Unexpected property value type, vt %d.\n", V_VT(&var));
13636 ok(V_BOOL(&var) == VARIANT_FALSE, "Unexpected property value.\n");
13638 V_VT(&var) = VT_BOOL;
13639 V_BOOL(&var) = VARIANT_TRUE;
13640 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("NormalizeAttributeValues"), var);
13641 ok(hr == S_OK, "Failed to set property, hr %#lx.\n", hr);
13643 V_VT(&var) = VT_I2;
13644 V_I2(&var) = 10;
13645 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("NormalizeAttributeValues"), &var);
13646 todo_wine {
13647 ok(hr == S_OK, "Failed to get property value, hr %#lx.\n", hr);
13648 ok(V_VT(&var) == VT_BOOL, "Unexpected property value type, vt %d.\n", V_VT(&var));
13649 ok(V_BOOL(&var) == VARIANT_TRUE, "Unexpected property value.\n");
13651 IXMLDOMDocument2_Release(doc);
13654 typedef struct _namespace_as_attribute_t {
13655 const GUID *guid;
13656 const char *clsid;
13657 } namespace_as_attribute_t;
13659 static const namespace_as_attribute_t namespace_as_attribute_test_data[] = {
13660 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
13661 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
13662 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
13663 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
13664 { 0 }
13667 /* see dlls/msxml[46]/tests/domdoc.c */
13668 static void test_namespaces_as_attributes(void)
13670 const namespace_as_attribute_t *entry = namespace_as_attribute_test_data;
13671 struct test {
13672 const char *xml;
13673 int explen;
13674 const char *names[3];
13675 const char *prefixes[3];
13676 const char *basenames[3];
13677 const char *uris[3];
13678 const char *texts[3];
13679 const char *xmls[3];
13681 static const struct test tests[] = {
13683 "<a ns:b=\"b attr\" d=\"d attr\" xmlns:ns=\"nshref\" />", 3,
13684 { "ns:b", "d", "xmlns:ns" }, /* nodeName */
13685 { "ns", NULL, "xmlns" }, /* prefix */
13686 { "b", "d", "ns" }, /* baseName */
13687 { "nshref", NULL, "" }, /* namespaceURI */
13688 { "b attr", "d attr", "nshref" }, /* text */
13689 { "ns:b=\"b attr\"", "d=\"d attr\"", "xmlns:ns=\"nshref\"" }, /* xml */
13691 /* property only */
13693 "<a d=\"d attr\" />", 1,
13694 { "d" }, /* nodeName */
13695 { NULL }, /* prefix */
13696 { "d" }, /* baseName */
13697 { NULL }, /* namespaceURI */
13698 { "d attr" }, /* text */
13699 { "d=\"d attr\"" }, /* xml */
13701 /* namespace only */
13703 "<a xmlns:ns=\"nshref\" />", 1,
13704 { "xmlns:ns" }, /* nodeName */
13705 { "xmlns" }, /* prefix */
13706 { "ns" }, /* baseName */
13707 { "" }, /* namespaceURI */
13708 { "nshref" }, /* text */
13709 { "xmlns:ns=\"nshref\"" }, /* xml */
13711 /* default namespace */
13713 "<a xmlns=\"nshref\" />", 1,
13714 { "xmlns" }, /* nodeName */
13715 { "xmlns" }, /* prefix */
13716 { "" }, /* baseName */
13717 { "" }, /* namespaceURI */
13718 { "nshref" }, /* text */
13719 { "xmlns=\"nshref\"" }, /* xml */
13721 /* no properties or namespaces */
13723 "<a />", 0,
13726 { NULL }
13728 const struct test *test;
13729 IXMLDOMNamedNodeMap *map;
13730 IXMLDOMNode *node, *item;
13731 IXMLDOMDocument *doc;
13732 VARIANT_BOOL b;
13733 LONG len, i;
13734 HRESULT hr;
13735 BSTR str;
13737 while (entry->guid)
13739 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
13741 entry++;
13742 continue;
13745 test = tests;
13746 while (test->xml) {
13747 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void **)&doc);
13748 ok(hr == S_OK, "Unexpected hr %#lx for %s.\n", hr, wine_dbgstr_guid(entry->guid));
13750 hr = IXMLDOMDocument_loadXML(doc, _bstr_(test->xml), &b);
13751 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13753 node = NULL;
13754 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
13755 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13757 hr = IXMLDOMNode_get_attributes(node, &map);
13758 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13760 len = -1;
13761 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
13762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13763 ok(len == test->explen, "got %ld\n", len);
13765 item = NULL;
13766 hr = IXMLDOMNamedNodeMap_get_item(map, test->explen+1, &item);
13767 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
13768 ok(!item, "Item should be NULL\n");
13770 for (i = 0; i < len; i++)
13772 item = NULL;
13773 hr = IXMLDOMNamedNodeMap_get_item(map, i, &item);
13774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13776 str = NULL;
13777 hr = IXMLDOMNode_get_nodeName(item, &str);
13778 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13779 ok(!lstrcmpW(str, _bstr_(test->names[i])), "got %s\n", wine_dbgstr_w(str));
13780 SysFreeString(str);
13782 str = NULL;
13783 hr = IXMLDOMNode_get_prefix(item, &str);
13784 if (test->prefixes[i])
13786 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13787 ok(!lstrcmpW(str, _bstr_(test->prefixes[i])), "got %s\n", wine_dbgstr_w(str));
13788 SysFreeString(str);
13790 else
13791 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
13793 str = NULL;
13794 hr = IXMLDOMNode_get_baseName(item, &str);
13795 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13796 ok(!lstrcmpW(str, _bstr_(test->basenames[i])), "got %s\n", wine_dbgstr_w(str));
13797 SysFreeString(str);
13799 str = NULL;
13800 hr = IXMLDOMNode_get_namespaceURI(item, &str);
13801 if (test->uris[i])
13803 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13804 if (test->prefixes[i] && !strcmp(test->prefixes[i], "xmlns"))
13805 ok(!SysStringLen(str), "got %s\n", wine_dbgstr_w(str));
13806 else
13807 ok(!lstrcmpW(str, _bstr_(test->uris[i])), "got %s\n", wine_dbgstr_w(str));
13808 SysFreeString(str);
13810 else
13811 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr );
13813 str = NULL;
13814 hr = IXMLDOMNode_get_text(item, &str);
13815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13816 ok(!lstrcmpW(str, _bstr_(test->texts[i])), "got %s\n", wine_dbgstr_w(str));
13817 SysFreeString(str);
13819 str = NULL;
13820 hr = IXMLDOMNode_get_xml(item, &str);
13821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13822 ok(!lstrcmpW(str, _bstr_(test->xmls[i])), "got %s\n", wine_dbgstr_w(str));
13823 SysFreeString(str);
13825 IXMLDOMNode_Release(item);
13828 IXMLDOMNamedNodeMap_Release(map);
13829 IXMLDOMNode_Release(node);
13830 IXMLDOMDocument_Release(doc);
13832 test++;
13835 entry++;
13837 free_bstrs();
13840 static const IID *qi_list[32];
13841 static int qi_count;
13843 static BOOL qi_list_contains(REFIID iid)
13845 int i;
13847 for (i = 0; i < qi_count; i++)
13849 if (IsEqualGUID(qi_list[i], iid))
13850 return TRUE;
13853 return FALSE;
13856 static BOOL qi_list_contains_service(REFIID service, REFIID iid)
13858 int i;
13860 for (i = 0; i < qi_count; i++)
13862 if (IsEqualGUID(qi_list[i], service) && IsEqualGUID(qi_list[i + 1], iid))
13863 return TRUE;
13866 return FALSE;
13869 static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID iid, void **ppv)
13871 if (qi_count < ARRAY_SIZE(qi_list))
13872 qi_list[qi_count++] = iid;
13873 else
13874 ok(0, "qi_list overflow: %d\n", qi_count);
13876 if (IsEqualGUID(iid, &IID_IUnknown) ||
13877 IsEqualGUID(iid, &IID_IServiceProvider))
13879 *ppv = iface;
13880 return S_OK;
13883 *ppv = NULL;
13884 return E_NOINTERFACE;
13887 static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
13889 return 2;
13892 static ULONG WINAPI sp_Release(IServiceProvider *iface)
13894 return 1;
13897 static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service,
13898 REFIID iid, void **ppv)
13900 if (IsEqualGUID(service, &SID_SContainerDispatch) ||
13901 IsEqualGUID(service, &SID_SInternetHostSecurityManager))
13903 if (qi_count + 1 < ARRAY_SIZE(qi_list))
13905 qi_list[qi_count++] = service;
13906 qi_list[qi_count++] = iid;
13908 else
13909 ok(0, "qi_list overflow: %d\n", qi_count);
13912 *ppv = NULL;
13913 return E_NOINTERFACE;
13916 static const IServiceProviderVtbl sp_vtbl =
13918 sp_QueryInterface,
13919 sp_AddRef,
13920 sp_Release,
13921 sp_QueryService
13924 static IServiceProvider sp = { &sp_vtbl };
13926 static void test_load_with_site(void)
13928 char path[MAX_PATH];
13929 IXMLDOMDocument2 *doc;
13930 IObjectWithSite *site;
13931 VARIANT var;
13932 VARIANT_BOOL b;
13933 HRESULT hr;
13935 GetTempPathA(MAX_PATH, path);
13936 strcat(path, "winetest.xml");
13937 write_to_file(path, win1252xml);
13939 doc = create_document(&IID_IXMLDOMDocument2);
13941 hr = IXMLDOMDocument2_QueryInterface(doc, &IID_IObjectWithSite, (void **)&site);
13942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13944 qi_count = 0;
13945 hr = IObjectWithSite_SetSite(site, (IUnknown *)&sp);
13946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13947 ok(qi_count != 0, "got %d QI calls\n", qi_count);
13948 todo_wine
13949 ok(qi_list_contains(&IID_IXMLDOMDocument), "QI(IID_IXMLDOMDocument) was not called\n");
13950 ok(qi_list_contains(&IID_IHTMLDocument2), "QI(IID_IHTMLDocument2) was not called\n");
13951 ok(qi_list_contains(&IID_IServiceProvider), "QI(IID_IServiceProvider) was not called\n");
13952 todo_wine
13953 ok(qi_list_contains(&IID_IOleClientSite), "QI(IID_IOleClientSite) was not called\n");
13954 ok(qi_list_contains_service(&SID_SContainerDispatch, &IID_IHTMLDocument2),
13955 "QI(SID_SContainerDispatch, IID_IHTMLDocument2) was not called\n");
13956 todo_wine
13957 ok(qi_list_contains_service(&SID_SInternetHostSecurityManager, &IID_IXMLDOMDocument),
13958 "QI(SID_SInternetHostSecurityManager, IID_IXMLDOMDocument) was not called\n");
13960 qi_count = 0;
13961 V_VT(&var) = VT_BSTR;
13962 V_BSTR(&var) = _bstr_(path);
13963 hr = IXMLDOMDocument2_load(doc, var, &b);
13964 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
13965 ok(b == VARIANT_TRUE, "got %d\n", b);
13966 ok(qi_count == 0, "got %d QI calls\n", qi_count);
13968 IXMLDOMDocument2_Release(doc);
13970 DeleteFileA(path);
13971 free_bstrs();
13974 typedef struct _validate_on_parse_test_t
13976 const GUID *guid;
13977 const char *clsid;
13978 HRESULT hr;
13979 } validate_on_parse_test_t;
13981 static const validate_on_parse_test_t validate_on_parse_tests[] =
13983 { &CLSID_DOMDocument, "CLSID_DOMDocument" , E_FAIL },
13984 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", E_FAIL },
13985 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", E_FAIL },
13986 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", E_FAIL },
13987 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", S_OK },
13988 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", S_OK },
13989 { 0 }
13992 static void test_validate_on_parse_values(void)
13994 const validate_on_parse_test_t *entry = validate_on_parse_tests;
13995 int i = 0;
13997 while (entry->guid)
13999 IXMLDOMDocument2 *doc, *doc_clone;
14000 IXMLDOMNode *node_clone;
14001 VARIANT var, var_clone;
14002 VARIANT_BOOL b;
14003 HRESULT hr;
14005 i++;
14006 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
14008 entry++;
14009 continue;
14012 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void **)&doc);
14013 ok(hr == S_OK, "%d: got %#lx.\n", i, hr);
14015 V_VT(&var) = VT_I2;
14016 V_I2(&var) = 0;
14017 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("ValidateOnParse"), &var);
14018 ok(hr == entry->hr || broken(hr == E_FAIL) /* win8 */, "%d: got hr %#lx.\n", i, hr);
14019 if (SUCCEEDED(hr))
14021 ok(V_VT(&var) == VT_BOOL, "%d: got property value type %d.\n", i, V_VT(&var));
14022 ok(V_BOOL(&var) == VARIANT_TRUE, "%d: got property value %d.\n", i, V_BOOL(&var));
14024 else
14026 ok(V_VT(&var) == VT_I2, "%d: got property value type %d.\n", i, V_VT(&var));
14027 ok(V_I2(&var) == 0, "%d: got property value %d.\n", i, V_I2(&var));
14028 if (IsEqualCLSID(entry->guid, &CLSID_DOMDocument40))
14030 win_skip("Skip tests for CLSID_DOMDocument40 on Windows 8.\n");
14031 IXMLDOMDocument2_Release(doc);
14032 entry++;
14033 continue;
14037 b = VARIANT_FALSE;
14038 hr = IXMLDOMDocument2_get_validateOnParse(doc, &b);
14039 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14040 ok(b == VARIANT_TRUE, "%d: got property value %d.\n", i, b);
14042 V_VT(&var) = VT_I2;
14043 V_I2(&var) = 0;
14044 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("ValidateOnParse"), var);
14045 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14046 V_VT(&var) = VT_I2;
14047 V_I2(&var) = 10;
14048 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("ValidateOnParse"), &var);
14049 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14050 if (SUCCEEDED(hr))
14052 ok(V_VT(&var) == VT_BOOL, "%d: got property value type %d.\n", i, V_VT(&var));
14053 ok(V_BOOL(&var) == VARIANT_FALSE, "%d: got property value %d.\n", i, V_BOOL(&var));
14056 V_VT(&var) = VT_BOOL;
14057 V_BOOL(&var) = VARIANT_TRUE;
14058 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("ValidateOnParse"), var);
14059 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14060 b = VARIANT_FALSE;
14061 hr = IXMLDOMDocument2_get_validateOnParse(doc, &b);
14062 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14063 ok(b == VARIANT_TRUE, "%d: got property value %d.\n", i, b);
14065 V_VT(&var) = VT_I2;
14066 V_I2(&var) = 0;
14067 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("ValidateOnParse"), &var);
14068 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14069 if (SUCCEEDED(hr))
14071 ok(V_VT(&var) == VT_BOOL, "%d: got property value type %d.\n", i, V_VT(&var));
14072 ok(V_BOOL(&var) == VARIANT_TRUE, "%d: got property value %d.\n", i, V_BOOL(&var));
14075 b = VARIANT_FALSE;
14076 hr = IXMLDOMDocument2_put_validateOnParse(doc, b);
14077 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14078 V_VT(&var) = VT_I2;
14079 V_I2(&var) = 10;
14080 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("ValidateOnParse"), &var);
14081 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14082 if (SUCCEEDED(hr))
14084 ok(V_VT(&var) == VT_BOOL, "%d: got property value type %d.\n", i, V_VT(&var));
14085 ok(V_BOOL(&var) == VARIANT_FALSE, "%d: got property value %d.\n", i, V_BOOL(&var));
14088 /* Cloned document inherits the property. */
14089 hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node_clone);
14090 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14091 ok(node_clone != NULL, "%d: got node %p.\n", i, node_clone);
14092 hr = IXMLDOMNode_QueryInterface(node_clone, &IID_IXMLDOMDocument2, (void **)&doc_clone);
14093 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14094 V_VT(&var) = VT_I2;
14095 V_I2(&var) = 10;
14096 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("ValidateOnParse"), &var);
14097 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14098 if (SUCCEEDED(hr))
14100 ok(V_VT(&var) == VT_BOOL, "%d: got property value type %d.\n", i, V_VT(&var));
14101 ok(V_BOOL(&var) == VARIANT_FALSE, "%d: got property value %d.\n", i, V_BOOL(&var));
14103 V_VT(&var_clone) = VT_I2;
14104 V_I2(&var_clone) = 10;
14105 hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("ValidateOnParse"), &var_clone);
14106 ok(hr == entry->hr, "%d: got hr %#lx.\n", i, hr);
14107 if (SUCCEEDED(hr))
14109 ok(V_VT(&var_clone) == V_VT(&var), "%d: got property value type %d.\n", i, V_VT(&var_clone));
14110 ok(V_BOOL(&var_clone) == V_BOOL(&var), "%d: got property value %d.\n", i, V_BOOL(&var_clone));
14112 b = VARIANT_TRUE;
14113 hr = IXMLDOMDocument2_get_validateOnParse(doc_clone, &b);
14114 ok(hr == S_OK, "%d: got hr %#lx.\n", i, hr);
14115 ok(b == VARIANT_FALSE, "%d: got property value %d.\n", i, b);
14116 IXMLDOMNode_Release(node_clone);
14117 IXMLDOMDocument2_Release(doc_clone);
14119 IXMLDOMDocument2_Release(doc);
14120 entry++;
14124 START_TEST(domdoc)
14126 HRESULT hr;
14128 hr = CoInitialize( NULL );
14129 ok( hr == S_OK, "failed to init com\n");
14130 if (hr != S_OK) return;
14132 get_class_support_data(domdoc_support_data);
14133 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument))
14135 win_skip("DOMDocument2 is not supported. Skipping all tests.\n");
14136 CoUninitialize();
14137 return;
14140 test_createProcessingInstruction();
14141 test_load_with_site();
14142 test_domdoc();
14143 test_persiststream();
14144 test_domnode();
14145 test_refs();
14146 test_create();
14147 test_getElementsByTagName();
14148 test_get_text();
14149 test_get_childNodes();
14150 test_get_firstChild();
14151 test_get_lastChild();
14152 test_removeChild();
14153 test_replaceChild();
14154 test_removeNamedItem();
14155 test_IXMLDOMDocument2();
14156 test_whitespace();
14157 test_XPath();
14158 test_XSLPattern();
14159 test_cloneNode();
14160 test_xmlTypes();
14161 test_save();
14162 test_testTransforms();
14163 test_namespaces_basic();
14164 test_namespaces_change();
14165 test_FormattingXML();
14166 test_nodeTypedValue();
14167 test_TransformWithLoadingLocalFile();
14168 test_put_nodeValue();
14169 test_IObjectSafety();
14170 test_splitText();
14171 test_getQualifiedItem();
14172 test_removeQualifiedItem();
14173 test_get_ownerDocument();
14174 test_setAttributeNode();
14175 test_put_dataType();
14176 test_createNode();
14177 test_create_attribute();
14178 test_get_prefix();
14179 test_default_properties();
14180 test_selectSingleNode();
14181 test_events();
14182 test_put_nodeTypedValue();
14183 test_get_xml();
14184 test_insertBefore();
14185 test_appendChild();
14186 test_get_doctype();
14187 test_get_tagName();
14188 test_get_dataType();
14189 test_get_nodeTypeString();
14190 test_get_attributes();
14191 test_selection();
14192 test_load();
14193 test_dispex();
14194 test_parseerror();
14195 test_getAttributeNode();
14196 test_getAttribute();
14197 test_supporterrorinfo();
14198 test_nodeValue();
14199 test_get_namespaces();
14200 test_put_data();
14201 test_newline_normalization();
14202 test_putref_schemas();
14203 test_namedmap_newenum();
14204 test_xmlns_attribute();
14205 test_url();
14206 test_merging_text();
14207 test_transformNodeToObject();
14208 test_normalize_attribute_values();
14209 test_namespaces_as_attributes();
14210 test_validate_on_parse_values();
14211 test_xsltemplate();
14212 test_xsltext();
14214 if (is_clsid_supported(&CLSID_MXNamespaceManager40, &IID_IMXNamespaceManager))
14216 test_mxnamespacemanager();
14217 test_mxnamespacemanager_override();
14220 CoUninitialize();