explorer: Don't alter the shell imagelist.
[wine.git] / dlls / msxml3 / tests / domdoc.c
blob4bac5a1ccf249f6fd4086ae3d4aac9d2f0fcbdc0
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 "initguid.h"
40 #include "asptlb.h"
42 #include "wine/test.h"
44 /* undef the #define in msxml2 so that we can access all versions */
45 #undef CLSID_DOMDocument
47 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
49 static int g_unexpectedcall, g_expectedcall;
51 struct msxmlsupported_data_t
53 const GUID *clsid;
54 const char *name;
55 const IID *ifaces[3];
56 BOOL supported[3];
59 static struct msxmlsupported_data_t domdoc_support_data[] =
61 { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
62 { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
63 { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
64 { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
65 { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
66 { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
67 { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
68 { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} },
69 { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
70 { NULL }
73 static const char *debugstr_msxml_guid(REFIID riid)
75 if(!riid)
76 return "(null)";
78 if (IsEqualIID(&IID_IXMLDOMDocument, riid))
79 return "IXMLDOMDocument";
80 else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
81 return "IXMLDOMDocument2";
82 else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
83 return "IXMLDOMDocument3";
84 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
85 return "IXMLDOMSchemaCollection";
86 else if (IsEqualIID(&IID_IXSLTemplate, riid))
87 return "IXSLTemplate";
88 else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
89 return "IMXNamespaceManager";
90 else
91 return wine_dbgstr_guid(riid);
94 static void get_class_support_data(struct msxmlsupported_data_t *table)
96 while (table->clsid)
98 IUnknown *unk;
99 HRESULT hr;
100 int i;
102 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
104 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
105 if (hr == S_OK) IUnknown_Release(unk);
107 table->supported[i] = hr == S_OK;
108 if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
111 table++;
115 static BOOL is_clsid_supported(const GUID *clsid, REFIID riid)
117 const struct msxmlsupported_data_t *table = domdoc_support_data;
118 while (table->clsid)
120 if (table->clsid == clsid)
122 int i;
124 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
125 if (table->ifaces[i] == riid) return table->supported[i];
128 table++;
130 return FALSE;
133 typedef struct
135 IDispatch IDispatch_iface;
136 LONG ref;
137 } dispevent;
139 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
141 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
144 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
146 *ppvObject = NULL;
148 if ( IsEqualGUID( riid, &IID_IDispatch) ||
149 IsEqualGUID( riid, &IID_IUnknown) )
151 *ppvObject = iface;
153 else
154 return E_NOINTERFACE;
156 IDispatch_AddRef( iface );
158 return S_OK;
161 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
163 dispevent *This = impl_from_IDispatch( iface );
164 return InterlockedIncrement( &This->ref );
167 static ULONG WINAPI dispevent_Release(IDispatch *iface)
169 dispevent *This = impl_from_IDispatch( iface );
170 ULONG ref = InterlockedDecrement( &This->ref );
172 if (ref == 0)
173 HeapFree(GetProcessHeap(), 0, This);
175 return ref;
178 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
180 g_unexpectedcall++;
181 *pctinfo = 0;
182 return S_OK;
185 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
186 LCID lcid, ITypeInfo **ppTInfo)
188 g_unexpectedcall++;
189 return S_OK;
192 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
193 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
195 g_unexpectedcall++;
196 return S_OK;
199 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
200 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
201 EXCEPINFO *excepInfo, UINT *argErr)
203 ok(member == 0, "expected 0 member, got %d\n", member);
204 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
205 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
207 ok(params->cArgs == 0, "got %d\n", params->cArgs);
208 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
209 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
210 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
212 ok(result == NULL, "got %p\n", result);
213 ok(excepInfo == NULL, "got %p\n", excepInfo);
214 ok(argErr == NULL, "got %p\n", argErr);
216 g_expectedcall++;
217 return E_FAIL;
220 static const IDispatchVtbl dispeventVtbl =
222 dispevent_QueryInterface,
223 dispevent_AddRef,
224 dispevent_Release,
225 dispevent_GetTypeInfoCount,
226 dispevent_GetTypeInfo,
227 dispevent_GetIDsOfNames,
228 dispevent_Invoke
231 static IDispatch* create_dispevent(void)
233 dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
235 event->IDispatch_iface.lpVtbl = &dispeventVtbl;
236 event->ref = 1;
238 return (IDispatch*)&event->IDispatch_iface;
241 /* IStream */
242 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
244 *ppvObject = NULL;
246 if (IsEqualGUID(riid, &IID_IStream) ||
247 IsEqualGUID(riid, &IID_IUnknown))
248 *ppvObject = iface;
249 else
250 return E_NOINTERFACE;
252 return S_OK;
255 static ULONG WINAPI istream_AddRef(IStream *iface)
257 return 2;
260 static ULONG WINAPI istream_Release(IStream *iface)
262 return 1;
265 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread)
267 ok(0, "unexpected call\n");
268 return E_NOTIMPL;
271 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
273 *written = len/2;
274 return S_OK;
277 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
279 ok(0, "unexpected call\n");
280 return E_NOTIMPL;
283 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size)
285 ok(0, "unexpected call\n");
286 return E_NOTIMPL;
289 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len,
290 ULARGE_INTEGER *pread, ULARGE_INTEGER *written)
292 ok(0, "unexpected call\n");
293 return E_NOTIMPL;
296 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags)
298 ok(0, "unexpected call\n");
299 return E_NOTIMPL;
302 static HRESULT WINAPI istream_Revert(IStream *iface)
304 ok(0, "unexpected call\n");
305 return E_NOTIMPL;
308 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
309 ULARGE_INTEGER len, DWORD locktype)
311 ok(0, "unexpected call\n");
312 return E_NOTIMPL;
315 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
316 ULARGE_INTEGER len, DWORD locktype)
318 ok(0, "unexpected call\n");
319 return E_NOTIMPL;
322 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
324 ok(0, "unexpected call\n");
325 return E_NOTIMPL;
328 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream)
330 ok(0, "unexpected call\n");
331 return E_NOTIMPL;
334 static const IStreamVtbl StreamVtbl = {
335 istream_QueryInterface,
336 istream_AddRef,
337 istream_Release,
338 istream_Read,
339 istream_Write,
340 istream_Seek,
341 istream_SetSize,
342 istream_CopyTo,
343 istream_Commit,
344 istream_Revert,
345 istream_LockRegion,
346 istream_UnlockRegion,
347 istream_Stat,
348 istream_Clone
351 static IStream savestream = { &StreamVtbl };
353 static HRESULT WINAPI response_QI(IResponse *iface, REFIID riid, void **obj)
355 if (IsEqualIID(&IID_IResponse, riid) ||
356 IsEqualIID(&IID_IDispatch, riid) ||
357 IsEqualIID(&IID_IUnknown, riid))
359 *obj = iface;
360 return S_OK;
363 if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid))
364 ok(0, "unexpected call\n");
365 return E_NOINTERFACE;
368 static ULONG WINAPI response_AddRef(IResponse *iface)
370 return 2;
373 static ULONG WINAPI response_Release(IResponse *iface)
375 return 1;
378 static HRESULT WINAPI response_GetTypeInfoCount(IResponse *iface, UINT *count)
380 ok(0, "unexpected call\n");
381 return E_NOTIMPL;
384 static HRESULT WINAPI response_GetTypeInfo(IResponse *iface, UINT ti, LCID lcid, ITypeInfo **tinfo)
386 ok(0, "unexpected call\n");
387 return E_NOTIMPL;
390 static HRESULT WINAPI response_GetIDsOfNames(IResponse *iface, REFIID riid, LPOLESTR *names,
391 UINT cnames, LCID lcid, DISPID *rgDispId)
393 ok(0, "unexpected call\n");
394 return E_NOTIMPL;
397 static HRESULT WINAPI response_Invoke(IResponse *iface, DISPID dispid, REFIID riid, LCID lcid,
398 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr)
400 ok(0, "unexpected call\n");
401 return E_NOTIMPL;
404 static HRESULT WINAPI response_get_Buffer(IResponse *iface, VARIANT_BOOL *fIsBuffering)
406 ok(0, "unexpected call\n");
407 return E_NOTIMPL;
410 static HRESULT WINAPI response_put_Buffer(IResponse *iface, VARIANT_BOOL fIsBuffering)
412 ok(0, "unexpected call\n");
413 return E_NOTIMPL;
416 static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet)
418 ok(0, "unexpected call\n");
419 return E_NOTIMPL;
422 static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType)
424 ok(0, "unexpected call\n");
425 return E_NOTIMPL;
428 static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet)
430 ok(0, "unexpected call\n");
431 return E_NOTIMPL;
434 static HRESULT WINAPI response_put_Expires(IResponse *iface, LONG lExpiresMinutes)
436 ok(0, "unexpected call\n");
437 return E_NOTIMPL;
440 static HRESULT WINAPI response_get_ExpiresAbsolute(IResponse *iface, VARIANT *pvarExpiresRet)
442 ok(0, "unexpected call\n");
443 return E_NOTIMPL;
446 static HRESULT WINAPI response_put_ExpiresAbsolute(IResponse *iface, DATE dtExpires)
448 ok(0, "unexpected call\n");
449 return E_NOTIMPL;
452 static HRESULT WINAPI response_get_Cookies(IResponse *iface, IRequestDictionary **ppCookies)
454 ok(0, "unexpected call\n");
455 return E_NOTIMPL;
458 static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet)
460 ok(0, "unexpected call\n");
461 return E_NOTIMPL;
464 static HRESULT WINAPI response_put_Status(IResponse *iface, BSTR bstrStatus)
466 ok(0, "unexpected call\n");
467 return E_NOTIMPL;
470 static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName)
472 ok(0, "unexpected call\n");
473 return E_NOTIMPL;
476 static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue)
478 ok(0, "unexpected call\n");
479 return E_NOTIMPL;
482 static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry)
484 ok(0, "unexpected call\n");
485 return E_NOTIMPL;
488 static HRESULT WINAPI response_BinaryWrite(IResponse *iface, VARIANT input)
490 HRESULT hr;
491 LONG bound;
492 UINT dim;
494 ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input));
496 dim = SafeArrayGetDim(V_ARRAY(&input));
497 ok(dim == 1, "got wrong array dimensions %u\n", dim);
499 bound = 1;
500 hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound);
501 ok(hr == S_OK, "got %#x\n", hr);
502 ok(bound == 0, "wrong array low bound %d\n", bound);
504 bound = 0;
505 hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound);
506 ok(hr == S_OK, "got %#x\n", hr);
507 ok(bound > 0, "wrong array high bound %d\n", bound);
509 return E_NOTIMPL;
512 static HRESULT WINAPI response_Clear(IResponse *iface)
514 ok(0, "unexpected call\n");
515 return E_NOTIMPL;
518 static HRESULT WINAPI response_End(IResponse *iface)
520 ok(0, "unexpected call\n");
521 return E_NOTIMPL;
524 static HRESULT WINAPI response_Flush(IResponse *iface)
526 ok(0, "unexpected call\n");
527 return E_NOTIMPL;
530 static HRESULT WINAPI response_Redirect(IResponse *iface, BSTR bstrURL)
532 ok(0, "unexpected call\n");
533 return E_NOTIMPL;
536 static HRESULT WINAPI response_Write(IResponse *iface, VARIANT varText)
538 ok(0, "unexpected call\n");
539 return E_NOTIMPL;
542 static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber)
544 ok(0, "unexpected call\n");
545 return E_NOTIMPL;
548 static HRESULT WINAPI response_IsClientConnected(IResponse *iface, VARIANT_BOOL *pfIsClientConnected)
550 ok(0, "unexpected call\n");
551 return E_NOTIMPL;
554 static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet)
556 ok(0, "unexpected call\n");
557 return E_NOTIMPL;
560 static HRESULT WINAPI response_put_CharSet(IResponse *iface, BSTR bstrCharSet)
562 ok(0, "unexpected call\n");
563 return E_NOTIMPL;
566 static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue)
568 ok(0, "unexpected call\n");
569 return E_NOTIMPL;
572 static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl)
574 ok(0, "unexpected call\n");
575 return E_NOTIMPL;
578 static HRESULT WINAPI response_put_CacheControl(IResponse *iface, BSTR bstrCacheControl)
580 ok(0, "unexpected call\n");
581 return E_NOTIMPL;
584 static HRESULT WINAPI response_get_CodePage(IResponse *iface, LONG *plvar)
586 ok(0, "unexpected call\n");
587 return E_NOTIMPL;
590 static HRESULT WINAPI response_put_CodePage(IResponse *iface, LONG codepage)
592 ok(0, "unexpected call\n");
593 return E_NOTIMPL;
596 static HRESULT WINAPI response_get_LCID(IResponse *iface, LONG *lcid)
598 ok(0, "unexpected call\n");
599 return E_NOTIMPL;
602 static HRESULT WINAPI response_put_LCID(IResponse *iface, LONG lcid)
604 ok(0, "unexpected call\n");
605 return E_NOTIMPL;
608 static const IResponseVtbl testresponsevtbl =
610 response_QI,
611 response_AddRef,
612 response_Release,
613 response_GetTypeInfoCount,
614 response_GetTypeInfo,
615 response_GetIDsOfNames,
616 response_Invoke,
617 response_get_Buffer,
618 response_put_Buffer,
619 response_get_ContentType,
620 response_put_ContentType,
621 response_get_Expires,
622 response_put_Expires,
623 response_get_ExpiresAbsolute,
624 response_put_ExpiresAbsolute,
625 response_get_Cookies,
626 response_get_Status,
627 response_put_Status,
628 response_Add,
629 response_AddHeader,
630 response_AppendToLog,
631 response_BinaryWrite,
632 response_Clear,
633 response_End,
634 response_Flush,
635 response_Redirect,
636 response_Write,
637 response_WriteBlock,
638 response_IsClientConnected,
639 response_get_CharSet,
640 response_put_CharSet,
641 response_Pics,
642 response_get_CacheControl,
643 response_put_CacheControl,
644 response_get_CodePage,
645 response_put_CodePage,
646 response_get_LCID,
647 response_put_LCID,
650 static IResponse testresponse = { &testresponsevtbl };
652 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
653 static void _expect_children(IXMLDOMNode *node, int line)
655 VARIANT_BOOL b;
656 HRESULT hr;
658 b = VARIANT_FALSE;
659 hr = IXMLDOMNode_hasChildNodes(node, &b);
660 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
661 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
664 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
665 static void _expect_no_children(IXMLDOMNode *node, int line)
667 VARIANT_BOOL b;
668 HRESULT hr;
670 b = VARIANT_TRUE;
671 hr = IXMLDOMNode_hasChildNodes(node, &b);
672 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
673 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
676 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
677 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
679 ULONG rc;
680 IUnknown_AddRef(obj);
681 rc = IUnknown_Release(obj);
682 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
685 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
686 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
688 LONG length;
689 HRESULT hr;
691 length = 0;
692 hr = IXMLDOMNodeList_get_length(list, &length);
693 ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
694 ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
697 #define EXPECT_HR(hr,hr_exp) \
698 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
700 static const WCHAR szEmpty[] = { 0 };
701 static const WCHAR szIncomplete[] = {
702 '<','?','x','m','l',' ',
703 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
705 static const WCHAR szComplete1[] = {
706 '<','?','x','m','l',' ',
707 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
708 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
710 static const WCHAR szComplete2[] = {
711 '<','?','x','m','l',' ',
712 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
713 '<','a','>','<','/','a','>','\n',0
715 static const char complete4A[] =
716 "<?xml version=\'1.0\'?>\n"
717 "<lc dl=\'str1\'>\n"
718 "<bs vr=\'str2\' sz=\'1234\'>"
719 "fn1.txt\n"
720 "</bs>\n"
721 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
722 "fn2.txt\n"
723 "</pr>\n"
724 "<empty></empty>\n"
725 "<fo>\n"
726 "<ba>\n"
727 "f1\n"
728 "</ba>\n"
729 "</fo>\n"
730 "</lc>\n";
732 static const WCHAR szComplete5[] = {
733 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
734 'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
735 ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
736 '<','S',':','s','c','o','p','e','>',
737 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
738 '<','/','S',':','s','c','o','p','e','>',
739 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
740 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
741 'c','o','m','p','u','t','e','r',
742 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
743 '<','/','S',':','s','e','a','r','c','h','>',0
746 static const WCHAR szComplete6[] = {
747 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
748 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
749 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
752 static const char complete7[] = {
753 "<?xml version=\"1.0\"?>\n\t"
754 "<root>\n"
755 "\t<a/>\n"
756 "\t<b/>\n"
757 "\t<c/>\n"
758 "</root>"
761 #define DECL_WIN_1252 \
762 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
764 static const char win1252xml[] =
765 DECL_WIN_1252
766 "<open></open>";
768 static const char win1252decl[] =
769 DECL_WIN_1252
772 static const char nocontent[] = "no xml content here";
774 static const char szExampleXML[] =
775 "<?xml version='1.0' encoding='utf-8'?>\n"
776 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
777 " <elem>\n"
778 " <a>A1 field</a>\n"
779 " <b>B1 field</b>\n"
780 " <c>C1 field</c>\n"
781 " <d>D1 field</d>\n"
782 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
783 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
784 " <![CDATA[]]> This is<strong> a</strong> <i>description</i><dot>. </dot><bar:x/>\n"
785 " </html>\n"
786 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
787 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
788 " </html>\n"
789 " </description>\n"
790 " </elem>\n"
791 "\n"
792 " <elem a='a'>\n"
793 " <a>A2 field</a>\n"
794 " <b>B2 field</b>\n"
795 " <c type=\"old\">C2 field</c>\n"
796 " <d>D2 field</d>\n"
797 " </elem>\n"
798 "\n"
799 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
800 " <a>A3 field</a>\n"
801 " <b>B3 field</b>\n"
802 " <c>C3 field</c>\n"
803 " </elem>\n"
804 "\n"
805 " <elem>\n"
806 " <a>A4 field</a>\n"
807 " <b>B4 field</b>\n"
808 " <foo:c>C4 field</foo:c>\n"
809 " <d>D4 field</d>\n"
810 " </elem>\n"
811 "</root>\n";
813 static const char charrefsxml[] =
814 "<?xml version='1.0'?>"
815 "<a>"
816 "<b1> Text &#65; end </b1>"
817 "<b2>&#65;&#66; &#67; </b2>"
818 "</a>";
820 static const CHAR szNodeTypesXML[] =
821 "<?xml version='1.0'?>"
822 "<!-- comment node 0 -->"
823 "<root id='0' depth='0'>"
824 " <!-- comment node 1 -->"
825 " text node 0"
826 " <x id='1' depth='1'>"
827 " <?foo value='PI for x'?>"
828 " <!-- comment node 2 -->"
829 " text node 1"
830 " <a id='3' depth='2'/>"
831 " <b id='4' depth='2'/>"
832 " <c id='5' depth='2'/>"
833 " </x>"
834 " <y id='2' depth='1'>"
835 " <?bar value='PI for y'?>"
836 " <!-- comment node 3 -->"
837 " text node 2"
838 " <a id='6' depth='2'/>"
839 " <b id='7' depth='2'/>"
840 " <c id='8' depth='2'/>"
841 " </y>"
842 "</root>";
844 static const CHAR szTransformXML[] =
845 "<?xml version=\"1.0\"?>\n"
846 "<greeting>\n"
847 "Hello World\n"
848 "</greeting>";
850 static const CHAR szTransformSSXML[] =
851 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
852 " <xsl:output method=\"html\"/>\n"
853 " <xsl:template match=\"/\">\n"
854 " <xsl:apply-templates select=\"greeting\"/>\n"
855 " </xsl:template>\n"
856 " <xsl:template match=\"greeting\">\n"
857 " <html>\n"
858 " <body>\n"
859 " <h1>\n"
860 " <xsl:value-of select=\".\"/>\n"
861 " </h1>\n"
862 " </body>\n"
863 " </html>\n"
864 " </xsl:template>\n"
865 "</xsl:stylesheet>";
867 static const CHAR szTransformOutput[] =
868 "<html><body><h1>"
869 "Hello World"
870 "</h1></body></html>";
872 static const CHAR szTypeValueXML[] =
873 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
874 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
875 " <string>Wine</string>\n"
876 " <string2 dt:dt=\"string\">String</string2>\n"
877 " <number dt:dt=\"number\">12.44</number>\n"
878 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
879 " <int dt:dt=\"int\">-13</int>\n"
880 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
881 " <bool dt:dt=\"boolean\">1</bool>\n"
882 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
883 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
884 " <date dt:dt=\"date\">3721-11-01</date>\n"
885 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
886 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
887 " <i1 dt:dt=\"i1\">-13</i1>\n"
888 " <i2 dt:dt=\"i2\">31915</i2>\n"
889 " <i4 dt:dt=\"i4\">-312232</i4>\n"
890 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
891 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
892 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
893 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
894 " <r8 dt:dt=\"r8\">0.412</r8>\n"
895 " <float dt:dt=\"float\">41221.421</float>\n"
896 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
897 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
898 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
899 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
900 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
901 "</root>";
903 static const CHAR szBasicTransformSSXMLPart1[] =
904 "<?xml version=\"1.0\"?>"
905 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
906 "<xsl:output method=\"html\"/>\n"
907 "<xsl:template match=\"/\">"
908 "<HTML><BODY><TABLE>"
909 " <xsl:apply-templates select='document(\"";
911 static const CHAR szBasicTransformSSXMLPart2[] =
912 "\")/bottle/wine'>"
913 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
914 " </xsl:apply-templates>"
915 "</TABLE></BODY></HTML>"
916 "</xsl:template>"
917 "<xsl:template match=\"bottle\">"
918 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
919 "</xsl:template>"
920 "<xsl:template match=\"name\">"
921 " <TD><xsl:apply-templates /></TD>"
922 "</xsl:template>"
923 "<xsl:template match=\"cost\">"
924 " <TD><xsl:apply-templates /></TD>"
925 "</xsl:template>"
926 "</xsl:stylesheet>";
928 static const CHAR szBasicTransformXML[] =
929 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
931 static const CHAR szBasicTransformOutput[] =
932 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
934 #define SZ_EMAIL_DTD \
935 "<!DOCTYPE email ["\
936 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
937 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
938 " <!ATTLIST email sent (yes|no) \"no\">"\
939 " <!ELEMENT recipients (to+,cc*)>"\
940 " <!ELEMENT to (#PCDATA)>"\
941 " <!ATTLIST to name CDATA #IMPLIED>"\
942 " <!ELEMENT cc (#PCDATA)>"\
943 " <!ATTLIST cc name CDATA #IMPLIED>"\
944 " <!ELEMENT from (#PCDATA)>"\
945 " <!ATTLIST from name CDATA #IMPLIED>"\
946 " <!ELEMENT reply-to (#PCDATA)>"\
947 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
948 " <!ELEMENT subject ANY>"\
949 " <!ELEMENT body ANY>"\
950 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
951 " <!ELEMENT attachment (#PCDATA)>"\
952 " <!ATTLIST attachment id ID #REQUIRED>"\
953 "]>"
955 static const CHAR szEmailXML[] =
956 "<?xml version=\"1.0\"?>"
957 SZ_EMAIL_DTD
958 "<email attachments=\"patch1\">"
959 " <recipients>"
960 " <to>wine-patches@winehq.org</to>"
961 " </recipients>"
962 " <from name=\"Anonymous\">user@localhost</from>"
963 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
964 " <body>"
965 " It no longer causes spontaneous combustion..."
966 " </body>"
967 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
968 "</email>";
970 static const CHAR szEmailXML_0D[] =
971 "<?xml version=\"1.0\"?>"
972 SZ_EMAIL_DTD
973 "<email attachments=\"patch1\">"
974 " <recipients>"
975 " <to>wine-patches@winehq.org</to>"
976 " </recipients>"
977 " <from name=\"Anonymous\">user@localhost</from>"
978 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
979 " <body>"
980 " <undecl />"
981 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
982 " </body>"
983 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
984 "</email>";
986 static const CHAR szEmailXML_0E[] =
987 "<?xml version=\"1.0\"?>"
988 SZ_EMAIL_DTD
989 "<email attachments=\"patch1\">"
990 " <recipients>"
991 " <to>wine-patches@winehq.org</to>"
992 " </recipients>"
993 " <from name=\"Anonymous\">user@localhost</from>"
994 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
995 " <body>"
996 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
997 " </body>"
998 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
999 "</email>";
1001 static const CHAR szEmailXML_11[] =
1002 "<?xml version=\"1.0\"?>"
1003 SZ_EMAIL_DTD
1004 "<email attachments=\"patch1\">"
1005 " <recipients>"
1006 " </recipients>"
1007 " <from name=\"Anonymous\">user@localhost</from>"
1008 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
1009 " <body>"
1010 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1011 " </body>"
1012 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1013 "</email>";
1015 static const CHAR szEmailXML_13[] =
1016 "<?xml version=\"1.0\"?>"
1017 SZ_EMAIL_DTD
1018 "<msg attachments=\"patch1\">"
1019 " <recipients>"
1020 " <to>wine-patches@winehq.org</to>"
1021 " </recipients>"
1022 " <from name=\"Anonymous\">user@localhost</from>"
1023 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
1024 " <body>"
1025 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
1026 " </body>"
1027 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1028 "</msg>";
1030 static const CHAR szEmailXML_14[] =
1031 "<?xml version=\"1.0\"?>"
1032 SZ_EMAIL_DTD
1033 "<email attachments=\"patch1\">"
1034 " <to>wine-patches@winehq.org</to>"
1035 " <from name=\"Anonymous\">user@localhost</from>"
1036 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
1037 " <body>"
1038 " XML_INVALID_CONTENT 0xC00CE014"
1039 " </body>"
1040 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1041 "</email>";
1043 static const CHAR szEmailXML_15[] =
1044 "<?xml version=\"1.0\"?>"
1045 SZ_EMAIL_DTD
1046 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1047 " <recipients>"
1048 " <to>wine-patches@winehq.org</to>"
1049 " </recipients>"
1050 " <from name=\"Anonymous\">user@localhost</from>"
1051 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
1052 " <body>"
1053 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1054 " </body>"
1055 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1056 "</email>";
1058 static const CHAR szEmailXML_16[] =
1059 "<?xml version=\"1.0\"?>"
1060 SZ_EMAIL_DTD
1061 "<email attachments=\"patch1\">"
1062 " <recipients>"
1063 " <to>wine-patches@winehq.org</to>"
1064 " </recipients>"
1065 " <from name=\"Anonymous\">user@localhost</from>"
1066 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
1067 " <body enc=\"ASCII\">"
1068 " XML_ATTRIBUTE_FIXED 0xC00CE016"
1069 " </body>"
1070 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1071 "</email>";
1073 static const CHAR szEmailXML_17[] =
1074 "<?xml version=\"1.0\"?>"
1075 SZ_EMAIL_DTD
1076 "<email attachments=\"patch1\" sent=\"true\">"
1077 " <recipients>"
1078 " <to>wine-patches@winehq.org</to>"
1079 " </recipients>"
1080 " <from name=\"Anonymous\">user@localhost</from>"
1081 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
1082 " <body>"
1083 " XML_ATTRIBUTE_VALUE 0xC00CE017"
1084 " </body>"
1085 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1086 "</email>";
1088 static const CHAR szEmailXML_18[] =
1089 "<?xml version=\"1.0\"?>"
1090 SZ_EMAIL_DTD
1091 "<email attachments=\"patch1\">"
1092 " oops"
1093 " <recipients>"
1094 " <to>wine-patches@winehq.org</to>"
1095 " </recipients>"
1096 " <from name=\"Anonymous\">user@localhost</from>"
1097 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
1098 " <body>"
1099 " XML_ILLEGAL_TEXT 0xC00CE018"
1100 " </body>"
1101 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1102 "</email>";
1104 static const CHAR szEmailXML_20[] =
1105 "<?xml version=\"1.0\"?>"
1106 SZ_EMAIL_DTD
1107 "<email>"
1108 " <recipients>"
1109 " <to>wine-patches@winehq.org</to>"
1110 " </recipients>"
1111 " <from name=\"Anonymous\">user@localhost</from>"
1112 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
1113 " <body>"
1114 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1115 " </body>"
1116 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1117 "</email>";
1119 static const char xpath_simple_list[] =
1120 "<?xml version=\"1.0\"?>"
1121 "<root>"
1122 " <a attr1=\"1\" attr2=\"2\" />"
1123 " <b/>"
1124 " <c/>"
1125 " <d/>"
1126 "</root>";
1128 static const char default_ns_doc[] = {
1129 "<?xml version=\"1.0\"?>"
1130 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1131 " d=\"d attr\" />"
1134 static const char attributes_map[] = {
1135 "<?xml version=\"1.0\"?>"
1136 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1139 static const WCHAR nonexistent_fileW[] = {
1140 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1142 static const WCHAR nonexistent_attrW[] = {
1143 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1145 static const WCHAR szDocument[] = {
1146 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1149 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1150 static const WCHAR szdl[] = { 'd','l',0 };
1151 static const WCHAR szvr[] = { 'v','r',0 };
1152 static const WCHAR szlc[] = { 'l','c',0 };
1153 static const WCHAR szbs[] = { 'b','s',0 };
1154 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1155 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1156 static const WCHAR szstar[] = { '*',0 };
1157 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1159 static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1160 static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1161 static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1163 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1164 static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
1165 static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1166 static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1167 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1168 static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1169 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1171 static const WCHAR szAttribute[] = {'A','t','t','r',0 };
1172 static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1174 static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1175 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1176 static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1177 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1178 '!',']',']','>',0};
1179 static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1180 static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1182 static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1183 static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1184 static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1186 #define expect_bstr_eq_and_free(bstr, expect) { \
1187 BSTR bstrExp = alloc_str_from_narrow(expect); \
1188 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1189 SysFreeString(bstr); \
1190 SysFreeString(bstrExp); \
1193 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1195 #define ole_check(expr) { \
1196 HRESULT r = expr; \
1197 ok(r == S_OK, #expr " returned %x\n", r); \
1200 #define ole_expect(expr, expect) { \
1201 HRESULT r = expr; \
1202 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1205 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1207 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1209 void *obj = NULL;
1210 HRESULT hr;
1212 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1213 ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr);
1215 return obj;
1218 #define _create(cls) cls, #cls
1220 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1221 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1222 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1223 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1225 static BSTR alloc_str_from_narrow(const char *str)
1227 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1228 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
1229 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1230 return ret;
1233 static BSTR alloced_bstrs[256];
1234 static int alloced_bstrs_count;
1236 static BSTR _bstr_(const char *str)
1238 assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1239 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
1240 return alloced_bstrs[alloced_bstrs_count++];
1243 static void free_bstrs(void)
1245 int i;
1246 for (i = 0; i < alloced_bstrs_count; i++)
1247 SysFreeString(alloced_bstrs[i]);
1248 alloced_bstrs_count = 0;
1251 static VARIANT _variantbstr_(const char *str)
1253 VARIANT v;
1254 V_VT(&v) = VT_BSTR;
1255 V_BSTR(&v) = _bstr_(str);
1256 return v;
1259 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1261 for (;;)
1263 while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1264 while (*sRight == '\r' || *sRight == '\n') sRight++;
1265 if (*sLeft != *sRight) return FALSE;
1266 if (!*sLeft) return TRUE;
1267 sLeft++;
1268 sRight++;
1272 static void get_str_for_type(DOMNodeType type, char *buf)
1274 switch (type)
1276 case NODE_ATTRIBUTE:
1277 strcpy(buf, "A");
1278 break;
1279 case NODE_ELEMENT:
1280 strcpy(buf, "E");
1281 break;
1282 case NODE_DOCUMENT:
1283 strcpy(buf, "D");
1284 break;
1285 case NODE_TEXT:
1286 strcpy(buf, "T");
1287 break;
1288 case NODE_COMMENT:
1289 strcpy(buf, "C");
1290 break;
1291 case NODE_PROCESSING_INSTRUCTION:
1292 strcpy(buf, "P");
1293 break;
1294 default:
1295 wsprintfA(buf, "[%d]", type);
1299 static int get_node_position(IXMLDOMNode *node)
1301 HRESULT r;
1302 int pos = 0;
1304 IXMLDOMNode_AddRef(node);
1307 IXMLDOMNode *new_node;
1309 pos++;
1310 r = IXMLDOMNode_get_previousSibling(node, &new_node);
1311 ok(SUCCEEDED(r), "get_previousSibling failed\n");
1312 IXMLDOMNode_Release(node);
1313 node = new_node;
1314 } while (r == S_OK);
1315 return pos;
1318 static void node_to_string(IXMLDOMNode *node, char *buf)
1320 HRESULT r = S_OK;
1321 DOMNodeType type;
1323 if (node == NULL)
1325 lstrcpyA(buf, "(null)");
1326 return;
1329 IXMLDOMNode_AddRef(node);
1330 while (r == S_OK)
1332 IXMLDOMNode *new_node;
1334 ole_check(IXMLDOMNode_get_nodeType(node, &type));
1335 get_str_for_type(type, buf);
1336 buf+=strlen(buf);
1338 if (type == NODE_ATTRIBUTE)
1340 BSTR bstr;
1341 ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1342 *(buf++) = '\'';
1343 wsprintfA(buf, "%ws", bstr);
1344 buf += strlen(buf);
1345 *(buf++) = '\'';
1346 SysFreeString(bstr);
1348 r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1350 else
1352 r = IXMLDOMNode_get_parentNode(node, &new_node);
1353 sprintf(buf, "%d", get_node_position(node));
1354 buf += strlen(buf);
1357 ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1358 IXMLDOMNode_Release(node);
1359 node = new_node;
1360 if (r == S_OK)
1361 *(buf++) = '.';
1364 *buf = 0;
1367 static char *list_to_string(IXMLDOMNodeList *list)
1369 static char buf[4096];
1370 char *pos = buf;
1371 LONG len = 0;
1372 HRESULT hr;
1373 int i;
1375 if (list == NULL)
1377 strcpy(buf, "(null)");
1378 return buf;
1380 hr = IXMLDOMNodeList_get_length(list, &len);
1381 ok(hr == S_OK, "got 0x%08x\n", hr);
1382 for (i = 0; i < len; i++)
1384 IXMLDOMNode *node;
1385 if (i > 0)
1386 *(pos++) = ' ';
1387 ole_check(IXMLDOMNodeList_nextNode(list, &node));
1388 node_to_string(node, pos);
1389 pos += strlen(pos);
1390 IXMLDOMNode_Release(node);
1392 *pos = 0;
1393 return buf;
1396 #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); }
1397 #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); }
1399 struct docload_ret_t {
1400 VARIANT_BOOL b;
1401 HRESULT hr;
1404 struct leading_spaces_t {
1405 const CLSID *clsid;
1406 const char *name;
1407 struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
1410 static const struct leading_spaces_t leading_spaces_classdata[] = {
1411 { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1412 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1413 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1414 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1415 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1416 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1417 { NULL }
1420 static const char* leading_spaces_xmldata[] = {
1421 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1422 " <?xml version=\"1.0\"?><root/>",
1423 "\n<?xml version=\"1.0\"?><root/>",
1424 "\t<?xml version=\"1.0\"?><root/>",
1425 "\r\n<?xml version=\"1.0\"?><root/>",
1426 "\r<?xml version=\"1.0\"?><root/>",
1427 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1431 static void test_domdoc( void )
1433 HRESULT r, hr;
1434 IXMLDOMDocument *doc;
1435 IXMLDOMParseError *error;
1436 IXMLDOMElement *element = NULL;
1437 IXMLDOMNode *node;
1438 IXMLDOMText *nodetext = NULL;
1439 IXMLDOMComment *node_comment = NULL;
1440 IXMLDOMAttribute *node_attr = NULL;
1441 IXMLDOMNode *nodeChild = NULL;
1442 IXMLDOMProcessingInstruction *nodePI = NULL;
1443 const struct leading_spaces_t *class_ptr;
1444 const char **data_ptr;
1445 VARIANT_BOOL b;
1446 VARIANT var;
1447 BSTR str;
1448 LONG code, ref;
1449 LONG nLength = 0;
1450 WCHAR buff[100];
1451 char path[MAX_PATH];
1452 int index;
1454 GetTempPathA(MAX_PATH, path);
1455 strcat(path, "leading_spaces.xml");
1457 /* Load document with leading spaces
1459 * Test all CLSIDs with all test data XML strings
1461 class_ptr = leading_spaces_classdata;
1462 index = 0;
1463 while (class_ptr->clsid)
1465 HRESULT hr;
1466 int i;
1468 if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
1470 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
1472 else
1474 class_ptr++;
1475 index++;
1476 continue;
1479 data_ptr = leading_spaces_xmldata;
1480 i = 0;
1481 while (*data_ptr) {
1482 BSTR data = _bstr_(*data_ptr);
1483 DWORD written;
1484 HANDLE file;
1486 file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1487 ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
1489 WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
1490 CloseHandle(file);
1492 b = 0xc;
1493 V_VT(&var) = VT_BSTR;
1494 V_BSTR(&var) = _bstr_(path);
1495 hr = IXMLDOMDocument_load(doc, var, &b);
1496 EXPECT_HR(hr, class_ptr->ret[0].hr);
1497 ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
1499 DeleteFileA(path);
1501 b = 0xc;
1502 hr = IXMLDOMDocument_loadXML(doc, data, &b);
1503 EXPECT_HR(hr, class_ptr->ret[1].hr);
1504 ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
1506 data_ptr++;
1507 i++;
1510 class_ptr++;
1511 index++;
1512 free_bstrs();
1515 doc = create_document(&IID_IXMLDOMDocument);
1516 if (!doc) return;
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 EXPECT_HR(hr, S_FALSE);
1528 b = VARIANT_TRUE;
1529 hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
1530 EXPECT_HR(hr, S_FALSE);
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 r = IXMLDOMDocument_load( doc, var, &b);
1541 ok( r == S_FALSE, "loadXML succeeded\n");
1542 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1543 SysFreeString( str );
1545 str = (BSTR)0x1;
1546 hr = IXMLDOMDocument_get_url(doc, &str);
1547 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1548 ok(str == NULL, "got %p\n", str);
1550 /* try load an empty document */
1551 b = VARIANT_TRUE;
1552 str = SysAllocString( szEmpty );
1553 r = IXMLDOMDocument_loadXML( doc, str, &b );
1554 ok( r == S_FALSE, "loadXML succeeded\n");
1555 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1556 SysFreeString( str );
1558 r = IXMLDOMDocument_get_async( doc, &b );
1559 ok( r == S_OK, "get_async failed (%08x)\n", r);
1560 ok( b == VARIANT_TRUE, "Wrong default value\n");
1562 /* check that there's no document element */
1563 element = NULL;
1564 r = IXMLDOMDocument_get_documentElement( doc, &element );
1565 ok( r == S_FALSE, "should be no document element\n");
1567 /* try finding a node */
1568 node = NULL;
1569 str = SysAllocString( szstr1 );
1570 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1571 ok( r == S_FALSE, "ret %08x\n", r );
1572 SysFreeString( str );
1574 b = VARIANT_TRUE;
1575 str = SysAllocString( szIncomplete );
1576 r = IXMLDOMDocument_loadXML( doc, str, &b );
1577 ok( r == 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 r = IXMLDOMDocument_get_documentElement( doc, &element );
1584 ok( r == 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 r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1593 ok( r == 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( szComplete6 );
1599 r = IXMLDOMDocument_loadXML( doc, str, &b );
1600 ok( r == 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 r = IXMLDOMDocument_loadXML( doc, str, &b );
1608 ok( r == 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 r = IXMLDOMDocument_loadXML( doc, str, &b );
1616 ok( r == 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 r = IXMLDOMDocument_get_nodeName( doc, NULL );
1622 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1624 str = (BSTR)0xdeadbeef;
1625 r = IXMLDOMDocument_get_baseName( doc, &str );
1626 ok ( r == S_FALSE, "got 0x%08x\n", r);
1627 ok (str == NULL, "got %p\n", str);
1629 /* content doesn't matter here */
1630 str = NULL;
1631 r = IXMLDOMDocument_get_nodeName( doc, &str );
1632 ok ( r == S_OK, "get_nodeName wrong code\n");
1633 ok ( str != NULL, "str is null\n");
1634 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1635 SysFreeString( str );
1637 /* test put_text */
1638 r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
1639 ok( r == E_FAIL, "ret %08x\n", r );
1641 /* check that there's a document element */
1642 element = NULL;
1643 r = IXMLDOMDocument_get_documentElement( doc, &element );
1644 ok( r == S_OK, "should be a document element\n");
1645 if( element )
1647 IObjectIdentity *ident;
1649 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1650 ok( r == E_NOINTERFACE, "ret %08x\n", r);
1652 IXMLDOMElement_Release( element );
1653 element = NULL;
1656 /* as soon as we call loadXML again, the document element will disappear */
1657 b = 2;
1658 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1659 ok( r == S_FALSE, "loadXML failed\n");
1660 ok( b == 2, "variant modified\n");
1661 r = IXMLDOMDocument_get_documentElement( doc, &element );
1662 ok( r == S_FALSE, "should be no document element\n");
1664 /* try to load something else simple and valid */
1665 b = VARIANT_FALSE;
1666 str = SysAllocString( szComplete2 );
1667 r = IXMLDOMDocument_loadXML( doc, str, &b );
1668 ok( r == 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 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1675 ok( r == S_OK, "loadXML failed\n");
1676 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1678 r = IXMLDOMDocument_get_parseError( doc, &error );
1679 ok( r == S_OK, "returns %08x\n", r );
1681 r = IXMLDOMParseError_get_errorCode( error, &code );
1682 ok( r == S_FALSE, "returns %08x\n", r );
1683 ok( code == 0, "code %d\n", code );
1684 IXMLDOMParseError_Release( error );
1686 /* test createTextNode */
1687 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1688 ok( r == S_OK, "returns %08x\n", r );
1689 IXMLDOMText_Release(nodetext);
1691 str = SysAllocString( szOpen );
1692 r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1693 ok( r == E_INVALIDARG, "returns %08x\n", r );
1694 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1695 ok( r == S_OK, "returns %08x\n", r );
1696 SysFreeString( str );
1697 if(nodetext)
1699 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1700 ok(r == E_NOINTERFACE, "ret %08x\n", r );
1702 /* Text Last Child Checks */
1703 r = IXMLDOMText_get_lastChild(nodetext, NULL);
1704 ok(r == E_INVALIDARG, "ret %08x\n", r );
1706 nodeChild = (IXMLDOMNode*)0x1;
1707 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1708 ok(r == S_FALSE, "ret %08x\n", r );
1709 ok(nodeChild == NULL, "nodeChild not NULL\n");
1711 /* test length property */
1712 r = IXMLDOMText_get_length(nodetext, NULL);
1713 ok(r == E_INVALIDARG, "ret %08x\n", r );
1715 r = IXMLDOMText_get_length(nodetext, &nLength);
1716 ok(r == S_OK, "ret %08x\n", r );
1717 ok(nLength == 4, "expected 4 got %d\n", nLength);
1719 /* put data Tests */
1720 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1721 ok(r == S_OK, "ret %08x\n", r );
1723 /* get data Tests */
1724 r = IXMLDOMText_get_data(nodetext, &str);
1725 ok(r == S_OK, "ret %08x\n", r );
1726 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1727 SysFreeString(str);
1729 /* Confirm XML text is good */
1730 r = IXMLDOMText_get_xml(nodetext, &str);
1731 ok(r == S_OK, "ret %08x\n", r );
1732 ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
1733 SysFreeString(str);
1735 /* Confirm we get the put_data Text back */
1736 r = IXMLDOMText_get_text(nodetext, &str);
1737 ok(r == S_OK, "ret %08x\n", r );
1738 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1739 SysFreeString(str);
1741 /* test substringData */
1742 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1743 ok(r == E_INVALIDARG, "ret %08x\n", r );
1745 /* test substringData - Invalid offset */
1746 str = (BSTR)&szElement;
1747 r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1748 ok(r == E_INVALIDARG, "ret %08x\n", r );
1749 ok( str == NULL, "incorrect string\n");
1751 /* test substringData - Invalid offset */
1752 str = (BSTR)&szElement;
1753 r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1754 ok(r == S_FALSE, "ret %08x\n", r );
1755 ok( str == NULL, "incorrect string\n");
1757 /* test substringData - Invalid size */
1758 str = (BSTR)&szElement;
1759 r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1760 ok(r == E_INVALIDARG, "ret %08x\n", r );
1761 ok( str == NULL, "incorrect string\n");
1763 /* test substringData - Invalid size */
1764 str = (BSTR)&szElement;
1765 r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1766 ok(r == S_FALSE, "ret %08x\n", r );
1767 ok( str == NULL, "incorrect string\n");
1769 /* test substringData - Start of string */
1770 r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1771 ok(r == S_OK, "ret %08x\n", r );
1772 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1773 SysFreeString(str);
1775 /* test substringData - Middle of string */
1776 r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1777 ok(r == S_OK, "ret %08x\n", r );
1778 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1779 SysFreeString(str);
1781 /* test substringData - End of string */
1782 r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1783 ok(r == S_OK, "ret %08x\n", r );
1784 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1785 SysFreeString(str);
1787 /* test appendData */
1788 r = IXMLDOMText_appendData(nodetext, NULL);
1789 ok(r == S_OK, "ret %08x\n", r );
1791 r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1792 ok(r == S_OK, "ret %08x\n", r );
1794 r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1795 ok(r == S_OK, "ret %08x\n", r );
1797 r = IXMLDOMText_get_text(nodetext, &str);
1798 ok(r == S_OK, "ret %08x\n", r );
1799 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMText_insertData(nodetext, -1, str);
1805 ok(r == S_OK, "ret %08x\n", r );
1807 r = IXMLDOMText_insertData(nodetext, -1, NULL);
1808 ok(r == S_OK, "ret %08x\n", r );
1810 r = IXMLDOMText_insertData(nodetext, 1000, str);
1811 ok(r == S_OK, "ret %08x\n", r );
1813 r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1814 ok(r == S_OK, "ret %08x\n", r );
1816 r = IXMLDOMText_insertData(nodetext, 0, NULL);
1817 ok(r == S_OK, "ret %08x\n", r );
1819 r = IXMLDOMText_insertData(nodetext, 0, str);
1820 ok(r == S_OK, "ret %08x\n", r );
1821 SysFreeString(str);
1823 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1824 ok(r == E_INVALIDARG, "ret %08x\n", r );
1826 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1827 ok(r == E_INVALIDARG, "ret %08x\n", r );
1829 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1830 ok(r == S_OK, "ret %08x\n", r );
1832 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1833 ok(r == S_OK, "ret %08x\n", r );
1835 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1836 ok(r == S_OK, "ret %08x\n", r );
1838 r = IXMLDOMText_get_text(nodetext, &str);
1839 ok(r == S_OK, "ret %08x\n", r );
1840 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMText_deleteData(nodetext, -1, 1);
1846 ok(r == E_INVALIDARG, "ret %08x\n", r );
1848 r = IXMLDOMText_deleteData(nodetext, 0, 0);
1849 ok(r == S_OK, "ret %08x\n", r );
1851 r = IXMLDOMText_deleteData(nodetext, 0, -1);
1852 ok(r == E_INVALIDARG, "ret %08x\n", r );
1854 r = IXMLDOMText_get_length(nodetext, &nLength);
1855 ok(r == S_OK, "ret %08x\n", r );
1856 ok(nLength == 43, "expected 43 got %d\n", nLength);
1858 r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1859 ok(r == S_OK, "ret %08x\n", r );
1861 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1862 ok(r == E_INVALIDARG, "ret %08x\n", r );
1864 /* delete from start */
1865 r = IXMLDOMText_deleteData(nodetext, 0, 5);
1866 ok(r == S_OK, "ret %08x\n", r );
1868 r = IXMLDOMText_get_length(nodetext, &nLength);
1869 ok(r == S_OK, "ret %08x\n", r );
1870 ok(nLength == 38, "expected 38 got %d\n", nLength);
1872 r = IXMLDOMText_get_text(nodetext, &str);
1873 ok(r == S_OK, "ret %08x\n", r );
1874 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMText_deleteData(nodetext, 35, 3);
1879 ok(r == S_OK, "ret %08x\n", r );
1881 r = IXMLDOMText_get_length(nodetext, &nLength);
1882 ok(r == S_OK, "ret %08x\n", r );
1883 ok(nLength == 35, "expected 35 got %d\n", nLength);
1885 r = IXMLDOMText_get_text(nodetext, &str);
1886 ok(r == S_OK, "ret %08x\n", r );
1887 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMText_deleteData(nodetext, 1, 33);
1892 ok(r == S_OK, "ret %08x\n", r );
1894 r = IXMLDOMText_get_length(nodetext, &nLength);
1895 ok(r == S_OK, "ret %08x\n", r );
1896 ok(nLength == 2, "expected 2 got %d\n", nLength);
1898 r = IXMLDOMText_get_text(nodetext, &str);
1899 ok(r == S_OK, "ret %08x\n", r );
1900 ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1901 SysFreeString(str);
1903 /* delete whole data ... */
1904 r = IXMLDOMText_get_length(nodetext, &nLength);
1905 ok(r == S_OK, "ret %08x\n", r );
1907 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1908 ok(r == S_OK, "ret %08x\n", r );
1909 /* ... and try again with empty string */
1910 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1911 ok(r == S_OK, "ret %08x\n", r );
1913 /* test put_data */
1914 V_VT(&var) = VT_BSTR;
1915 V_BSTR(&var) = SysAllocString(szstr1);
1916 r = IXMLDOMText_put_nodeValue(nodetext, var);
1917 ok(r == S_OK, "ret %08x\n", r );
1918 VariantClear(&var);
1920 r = IXMLDOMText_get_text(nodetext, &str);
1921 ok(r == S_OK, "ret %08x\n", r );
1922 ok( !lstrcmpW( str, szstr1 ), "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 r = IXMLDOMText_put_nodeValue(nodetext, var);
1929 ok(r == S_OK, "ret %08x\n", r );
1930 VariantClear(&var);
1932 r = IXMLDOMText_get_text(nodetext, &str);
1933 ok(r == S_OK, "ret %08x\n", r );
1934 ok( !lstrcmpW( str, _bstr_("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(szstr1);
1940 r = IXMLDOMText_put_nodeValue(nodetext, var);
1941 ok(r == S_OK, "ret %08x\n", r );
1942 VariantClear(&var);
1944 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1945 ok(r == E_INVALIDARG, "ret %08x\n", r );
1946 r = IXMLDOMText_get_text(nodetext, &str);
1947 ok(r == S_OK, "ret %08x\n", r );
1948 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1949 SysFreeString(str);
1951 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1952 ok(r == S_OK, "ret %08x\n", r );
1953 r = IXMLDOMText_get_text(nodetext, &str);
1954 ok(r == S_OK, "ret %08x\n", r );
1955 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1956 SysFreeString(str);
1958 /* NULL pointer means delete */
1959 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1960 ok(r == S_OK, "ret %08x\n", r );
1961 r = IXMLDOMText_get_text(nodetext, &str);
1962 ok(r == S_OK, "ret %08x\n", r );
1963 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1964 SysFreeString(str);
1966 /* empty string means delete */
1967 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1968 ok(r == S_OK, "ret %08x\n", r );
1969 r = IXMLDOMText_get_text(nodetext, &str);
1970 ok(r == S_OK, "ret %08x\n", r );
1971 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1972 SysFreeString(str);
1974 /* zero count means insert */
1975 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1976 ok(r == S_OK, "ret %08x\n", r );
1977 r = IXMLDOMText_get_text(nodetext, &str);
1978 ok(r == S_OK, "ret %08x\n", r );
1979 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1980 SysFreeString(str);
1982 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1983 ok(r == S_OK, "ret %08x\n", r );
1985 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1986 ok(r == S_OK, "ret %08x\n", r );
1987 r = IXMLDOMText_get_text(nodetext, &str);
1988 ok(r == S_OK, "ret %08x\n", r );
1989 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1990 SysFreeString(str);
1992 /* nonempty string, count greater than its length */
1993 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1994 ok(r == S_OK, "ret %08x\n", r );
1995 r = IXMLDOMText_get_text(nodetext, &str);
1996 ok(r == S_OK, "ret %08x\n", r );
1997 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2002 ok(r == S_OK, "ret %08x\n", r );
2003 r = IXMLDOMText_get_text(nodetext, &str);
2004 ok(r == S_OK, "ret %08x\n", r );
2005 ok( !lstrcmpW( str, _bstr_("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 r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2013 ok( r == E_INVALIDARG, "returns %08x\n", r );
2014 node_comment = (IXMLDOMComment*)0x1;
2016 /* empty comment */
2017 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2018 ok( r == S_OK, "returns %08x\n", r );
2019 str = (BSTR)0x1;
2020 r = IXMLDOMComment_get_data(node_comment, &str);
2021 ok( r == S_OK, "returns %08x\n", r );
2022 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2023 IXMLDOMComment_Release(node_comment);
2024 SysFreeString(str);
2026 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2027 ok( r == S_OK, "returns %08x\n", r );
2028 str = (BSTR)0x1;
2029 r = IXMLDOMComment_get_data(node_comment, &str);
2030 ok( r == S_OK, "returns %08x\n", r );
2031 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2032 IXMLDOMComment_Release(node_comment);
2033 SysFreeString(str);
2035 str = SysAllocString(szComment);
2036 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2037 SysFreeString(str);
2038 ok( r == S_OK, "returns %08x\n", r );
2039 if(node_comment)
2041 /* Last Child Checks */
2042 r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2043 ok(r == E_INVALIDARG, "ret %08x\n", r );
2045 nodeChild = (IXMLDOMNode*)0x1;
2046 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2047 ok(r == S_FALSE, "ret %08x\n", r );
2048 ok(nodeChild == NULL, "pLastChild not NULL\n");
2050 /* baseName */
2051 str = (BSTR)0xdeadbeef;
2052 r = IXMLDOMComment_get_baseName(node_comment, &str);
2053 ok(r == S_FALSE, "ret %08x\n", r );
2054 ok(str == NULL, "Expected NULL\n");
2056 IXMLDOMComment_Release( node_comment );
2059 /* test Create Attribute */
2060 str = SysAllocString(szAttribute);
2061 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2062 ok( r == E_INVALIDARG, "returns %08x\n", r );
2063 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2064 ok( r == S_OK, "returns %08x\n", r );
2065 IXMLDOMAttribute_Release( node_attr);
2066 SysFreeString(str);
2068 /* test Processing Instruction */
2069 str = SysAllocStringLen(NULL, 0);
2070 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2071 ok( r == E_INVALIDARG, "returns %08x\n", r );
2072 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2073 ok( r == E_FAIL, "returns %08x\n", r );
2074 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2075 ok( r == E_FAIL, "returns %08x\n", r );
2076 SysFreeString(str);
2078 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2079 ok( r == S_OK, "returns %08x\n", r );
2080 if(nodePI)
2082 /* Last Child Checks */
2083 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2084 ok(r == E_INVALIDARG, "ret %08x\n", r );
2086 nodeChild = (IXMLDOMNode*)0x1;
2087 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2088 ok(r == S_FALSE, "ret %08x\n", r );
2089 ok(nodeChild == NULL, "nodeChild not NULL\n");
2091 /* test nodeName */
2092 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2093 ok(r == S_OK, "ret %08x\n", r );
2094 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2095 SysFreeString(str);
2097 /* test baseName */
2098 str = (BSTR)0x1;
2099 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2100 ok(r == S_OK, "ret %08x\n", r );
2101 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2102 SysFreeString(str);
2104 /* test Target */
2105 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2106 ok(r == S_OK, "ret %08x\n", r );
2107 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2108 SysFreeString(str);
2110 /* test get_data */
2111 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2112 ok(r == S_OK, "ret %08x\n", r );
2113 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2114 SysFreeString(str);
2116 /* test put_data */
2117 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2118 ok(r == E_FAIL, "ret %08x\n", r );
2120 /* test put_data */
2121 V_VT(&var) = VT_BSTR;
2122 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
2123 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2124 ok(r == E_FAIL, "ret %08x\n", r );
2125 VariantClear(&var);
2127 /* test get nodeName */
2128 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2129 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2130 ok(r == S_OK, "ret %08x\n", r );
2131 SysFreeString(str);
2133 IXMLDOMProcessingInstruction_Release(nodePI);
2136 ref = IXMLDOMDocument_Release( doc );
2137 ok( ref == 0, "got %d\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 IPersist *persist;
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, "got 0x%08x\n", hr);
2157 hr = IPersistStreamInit_InitNew(streaminit);
2158 ok(hr == S_OK, "got 0x%08x\n", hr);
2160 hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
2161 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
2163 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStream, (void **)&stream);
2164 ok(hr == S_OK, "got 0x%08x\n", hr);
2165 ok((IUnknown *)stream == (IUnknown *)streaminit, "got %p, %p\n", stream, streaminit);
2167 hr = IPersistStream_QueryInterface(stream, &IID_IPersist, (void **)&persist);
2168 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2170 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersist, (void **)&persist);
2171 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2173 hr = IPersistStreamInit_GetClassID(streaminit, NULL);
2174 ok(hr == E_POINTER, "got 0x%08x\n", hr);
2176 memset(&clsid, 0, sizeof(clsid));
2177 hr = IPersistStreamInit_GetClassID(streaminit, &clsid);
2178 ok(hr == S_OK, "got 0x%08x\n", hr);
2179 ok(IsEqualGUID(&clsid, &CLSID_DOMDocument2), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
2181 IPersistStream_Release(stream);
2182 IPersistStreamInit_Release(streaminit);
2183 IXMLDOMDocument_Release(doc);
2186 static void test_domnode( void )
2188 HRESULT r;
2189 IXMLDOMDocument *doc, *owner = NULL;
2190 IXMLDOMElement *element = NULL;
2191 IXMLDOMNamedNodeMap *map = NULL;
2192 IXMLDOMNode *node = NULL, *next = NULL;
2193 IXMLDOMNodeList *list = NULL;
2194 IXMLDOMAttribute *attr = NULL;
2195 DOMNodeType type = NODE_INVALID;
2196 VARIANT_BOOL b;
2197 BSTR str;
2198 VARIANT var;
2199 LONG count;
2201 doc = create_document(&IID_IXMLDOMDocument);
2203 b = FALSE;
2204 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2205 ok( r == S_OK, "loadXML failed\n");
2206 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2208 EXPECT_CHILDREN(doc);
2210 r = IXMLDOMDocument_get_documentElement( doc, &element );
2211 ok( r == S_OK, "should be a document element\n");
2212 ok( element != NULL, "should be an element\n");
2214 VariantInit(&var);
2215 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2217 r = IXMLDOMDocument_get_nodeValue( doc, NULL );
2218 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2220 r = IXMLDOMDocument_get_nodeValue( doc, &var );
2221 ok( r == S_FALSE, "nextNode returned wrong code\n");
2222 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2223 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2225 if (element)
2227 owner = NULL;
2228 r = IXMLDOMElement_get_ownerDocument( element, &owner );
2229 ok( r == S_OK, "get_ownerDocument return code\n");
2230 ok( owner != doc, "get_ownerDocument return\n");
2231 IXMLDOMDocument_Release(owner);
2233 type = NODE_INVALID;
2234 r = IXMLDOMElement_get_nodeType( element, &type);
2235 ok( r == S_OK, "got %08x\n", r);
2236 ok( type == NODE_ELEMENT, "node not an element\n");
2238 str = NULL;
2239 r = IXMLDOMElement_get_baseName( element, &str );
2240 ok( r == S_OK, "get_baseName returned wrong code\n");
2241 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2242 SysFreeString(str);
2244 /* check if nodename is correct */
2245 r = IXMLDOMElement_get_nodeName( element, NULL );
2246 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2248 /* content doesn't matter here */
2249 str = NULL;
2250 r = IXMLDOMElement_get_nodeName( element, &str );
2251 ok ( r == S_OK, "get_nodeName wrong code\n");
2252 ok ( str != NULL, "str is null\n");
2253 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2254 SysFreeString( str );
2256 str = SysAllocString( nonexistent_fileW );
2257 V_VT(&var) = VT_I4;
2258 V_I4(&var) = 0x1234;
2259 r = IXMLDOMElement_getAttribute( element, str, &var );
2260 ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2261 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2262 VariantClear(&var);
2263 SysFreeString(str);
2265 str = SysAllocString( szdl );
2266 V_VT(&var) = VT_I4;
2267 V_I4(&var) = 0x1234;
2268 r = IXMLDOMElement_getAttribute( element, str, &var );
2269 ok( r == S_OK, "getAttribute ret %08x\n", r );
2270 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2271 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2272 VariantClear( &var );
2274 r = IXMLDOMElement_getAttribute( element, NULL, &var );
2275 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2277 r = IXMLDOMElement_getAttribute( element, str, NULL );
2278 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2280 attr = NULL;
2281 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2282 ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2283 ok( attr != NULL, "getAttributeNode returned NULL\n" );
2284 if (attr)
2286 r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2287 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2289 /* attribute doesn't have a parent in msxml interpretation */
2290 node = (IXMLDOMNode*)0xdeadbeef;
2291 r = IXMLDOMAttribute_get_parentNode( attr, &node );
2292 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2293 ok( node == NULL, "Expected NULL, got %p\n", node );
2295 IXMLDOMAttribute_Release(attr);
2298 SysFreeString( str );
2300 r = IXMLDOMElement_get_attributes( element, &map );
2301 ok( r == S_OK, "get_attributes returned wrong code\n");
2302 ok( map != NULL, "should be attributes\n");
2304 EXPECT_CHILDREN(element);
2306 else
2307 ok( FALSE, "no element\n");
2309 if (map)
2311 str = SysAllocString( szdl );
2312 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2313 ok( r == S_OK, "getNamedItem returned wrong code\n");
2314 ok( node != NULL, "should be attributes\n");
2315 IXMLDOMNode_Release(node);
2316 SysFreeString( str );
2318 str = SysAllocString( szdl );
2319 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2320 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2321 SysFreeString( str );
2323 /* something that isn't in complete4A */
2324 str = SysAllocString( szOpen );
2325 node = (IXMLDOMNode *) 1;
2326 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2327 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2328 ok( node == NULL, "getNamedItem should have returned NULL\n");
2329 SysFreeString( str );
2331 /* test indexed access of attributes */
2332 r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2333 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2335 r = IXMLDOMNamedNodeMap_get_length( map, &count );
2336 ok ( r == S_OK, "get_length wrong code\n");
2337 ok ( count == 1, "get_length != 1\n");
2339 node = NULL;
2340 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2341 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2342 ok ( node == NULL, "there is no node\n");
2344 node = NULL;
2345 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2346 ok ( r == S_FALSE, "get_item (1) wrong code\n");
2347 ok ( node == NULL, "there is no attribute\n");
2349 node = NULL;
2350 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2351 ok ( r == S_OK, "get_item (0) wrong code\n");
2352 ok ( node != NULL, "should be attribute\n");
2354 r = IXMLDOMNode_get_nodeName( node, NULL );
2355 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2357 /* content doesn't matter here */
2358 str = NULL;
2359 r = IXMLDOMNode_get_nodeName( node, &str );
2360 ok ( r == S_OK, "get_nodeName wrong code\n");
2361 ok ( str != NULL, "str is null\n");
2362 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2363 SysFreeString( str );
2364 IXMLDOMNode_Release( node );
2366 /* test sequential access of attributes */
2367 node = NULL;
2368 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2369 ok ( r == S_OK, "nextNode (first time) wrong code\n");
2370 ok ( node != NULL, "nextNode, should be attribute\n");
2371 IXMLDOMNode_Release( node );
2373 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2374 ok ( r != S_OK, "nextNode (second time) wrong code\n");
2375 ok ( node == NULL, "nextNode, there is no attribute\n");
2377 r = IXMLDOMNamedNodeMap_reset( map );
2378 ok ( r == S_OK, "reset should return S_OK\n");
2380 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2381 ok ( r == S_OK, "nextNode (third time) wrong code\n");
2382 ok ( node != NULL, "nextNode, should be attribute\n");
2384 else
2385 ok( FALSE, "no map\n");
2387 if (node)
2389 type = NODE_INVALID;
2390 r = IXMLDOMNode_get_nodeType( node, &type);
2391 ok( r == S_OK, "getNamedItem returned wrong code\n");
2392 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2394 str = NULL;
2395 r = IXMLDOMNode_get_baseName( node, NULL );
2396 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2398 str = NULL;
2399 r = IXMLDOMNode_get_baseName( node, &str );
2400 ok( r == S_OK, "get_baseName returned wrong code\n");
2401 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2402 SysFreeString( str );
2404 r = IXMLDOMNode_get_childNodes( node, NULL );
2405 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2407 r = IXMLDOMNode_get_childNodes( node, &list );
2408 ok( r == S_OK, "get_childNodes returned wrong code\n");
2410 if (list)
2412 r = IXMLDOMNodeList_nextNode( list, &next );
2413 ok( r == S_OK, "nextNode returned wrong code\n");
2415 else
2416 ok( FALSE, "no childlist\n");
2418 if (next)
2420 EXPECT_NO_CHILDREN(next);
2422 type = NODE_INVALID;
2423 r = IXMLDOMNode_get_nodeType( next, &type);
2424 ok( r == S_OK, "getNamedItem returned wrong code\n");
2425 ok( type == NODE_TEXT, "node not text\n");
2427 str = (BSTR) 1;
2428 r = IXMLDOMNode_get_baseName( next, &str );
2429 ok( r == S_FALSE, "get_baseName returned wrong code\n");
2430 ok( str == NULL, "basename was wrong\n");
2431 SysFreeString(str);
2433 else
2434 ok( FALSE, "no next\n");
2436 if (next)
2437 IXMLDOMNode_Release( next );
2438 next = NULL;
2439 if (list)
2440 IXMLDOMNodeList_Release( list );
2441 list = NULL;
2442 if (node)
2443 IXMLDOMNode_Release( node );
2445 else
2446 ok( FALSE, "no node\n");
2447 node = NULL;
2449 if (map)
2450 IXMLDOMNamedNodeMap_Release( map );
2452 /* now traverse the tree from the root element */
2453 if (element)
2455 r = IXMLDOMElement_get_childNodes( element, &list );
2456 ok( r == S_OK, "get_childNodes returned wrong code\n");
2458 /* using get_item for child list doesn't advance the position */
2459 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2460 expect_node(node, "E2.E2.D1");
2461 IXMLDOMNode_Release(node);
2462 ole_check(IXMLDOMNodeList_nextNode(list, &node));
2463 expect_node(node, "E1.E2.D1");
2464 IXMLDOMNode_Release(node);
2465 ole_check(IXMLDOMNodeList_reset(list));
2467 IXMLDOMNodeList_AddRef(list);
2468 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2469 ole_check(IXMLDOMNodeList_reset(list));
2471 node = (void*)0xdeadbeef;
2472 str = SysAllocString(szdl);
2473 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2474 SysFreeString(str);
2475 ok( r == S_FALSE, "ret %08x\n", r );
2476 ok( node == NULL, "node %p\n", node );
2478 str = SysAllocString(szbs);
2479 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2480 SysFreeString(str);
2481 ok( r == S_OK, "ret %08x\n", r );
2482 r = IXMLDOMNode_Release( node );
2483 ok( r == 0, "ret %08x\n", r );
2485 else
2486 ok( FALSE, "no element\n");
2488 if (list)
2490 r = IXMLDOMNodeList_get_item(list, 0, NULL);
2491 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2493 r = IXMLDOMNodeList_get_length(list, NULL);
2494 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2496 r = IXMLDOMNodeList_get_length( list, &count );
2497 ok( r == S_OK, "get_length returns %08x\n", r );
2498 ok( count == 4, "get_length got %d\n", count );
2500 r = IXMLDOMNodeList_nextNode(list, NULL);
2501 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2503 r = IXMLDOMNodeList_nextNode( list, &node );
2504 ok( r == S_OK, "nextNode returned wrong code\n");
2506 else
2507 ok( FALSE, "no list\n");
2509 if (node)
2511 type = NODE_INVALID;
2512 r = IXMLDOMNode_get_nodeType( node, &type);
2513 ok( r == S_OK, "getNamedItem returned wrong code\n");
2514 ok( type == NODE_ELEMENT, "node not text\n");
2516 r = IXMLDOMNode_hasChildNodes( node, NULL );
2517 ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
2519 EXPECT_CHILDREN(node);
2521 str = NULL;
2522 r = IXMLDOMNode_get_baseName( node, &str );
2523 ok( r == S_OK, "get_baseName returned wrong code\n");
2524 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
2525 SysFreeString(str);
2527 else
2528 ok( FALSE, "no node\n");
2530 if (node)
2531 IXMLDOMNode_Release( node );
2532 if (list)
2533 IXMLDOMNodeList_Release( list );
2534 if (element)
2535 IXMLDOMElement_Release( element );
2537 b = FALSE;
2538 str = SysAllocString( szComplete5 );
2539 r = IXMLDOMDocument_loadXML( doc, str, &b );
2540 ok( r == S_OK, "loadXML failed\n");
2541 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2542 SysFreeString( str );
2544 EXPECT_CHILDREN(doc);
2546 r = IXMLDOMDocument_get_documentElement( doc, &element );
2547 ok( r == S_OK, "should be a document element\n");
2548 ok( element != NULL, "should be an element\n");
2550 if (element)
2552 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
2553 BSTR tag = NULL;
2555 /* check if the tag is correct */
2556 r = IXMLDOMElement_get_tagName( element, &tag );
2557 ok( r == S_OK, "couldn't get tag name\n");
2558 ok( tag != NULL, "tag was null\n");
2559 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
2560 SysFreeString( tag );
2562 IXMLDOMElement_Release( element );
2564 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2566 free_bstrs();
2569 typedef struct {
2570 DOMNodeType type;
2571 REFIID iid;
2572 } refcount_test_t;
2574 static const refcount_test_t refcount_test[] = {
2575 { NODE_ELEMENT, &IID_IXMLDOMElement },
2576 { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute },
2577 { NODE_TEXT, &IID_IXMLDOMText },
2578 { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection },
2579 { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference },
2580 { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
2581 { NODE_COMMENT, &IID_IXMLDOMComment },
2582 { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment },
2583 { NODE_INVALID, &IID_NULL }
2586 static void test_refs(void)
2588 IXMLDOMImplementation *impl, *impl2;
2589 IXMLDOMElement *element, *elem2;
2590 IXMLDOMNodeList *node_list = NULL;
2591 IXMLDOMNode *node, *node2, *node3;
2592 const refcount_test_t *ptr;
2593 IXMLDOMDocument *doc;
2594 IUnknown *unk, *unk2;
2595 VARIANT_BOOL b;
2596 HRESULT hr;
2597 LONG ref;
2599 doc = create_document(&IID_IXMLDOMDocument);
2601 ptr = refcount_test;
2602 while (ptr->type != NODE_INVALID)
2604 IUnknown *node_typed, *node_typed2;
2605 IDispatchEx *dispex, *dispex2;
2606 IDispatch *disp, *disp2;
2607 VARIANT type;
2609 V_VT(&type) = VT_I1;
2610 V_I1(&type) = ptr->type;
2612 EXPECT_REF(doc, 1);
2613 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
2614 EXPECT_HR(hr, S_OK);
2615 EXPECT_REF(doc, 1);
2616 EXPECT_REF(node, 1);
2618 /* try IDispatch and IUnknown from IXMLDOMNode */
2619 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
2620 EXPECT_HR(hr, S_OK);
2621 EXPECT_REF(unk, 2);
2622 todo_wine {
2623 EXPECT_REF(node, 1);
2624 ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
2626 EXPECT_REF(unk, 2);
2627 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2628 EXPECT_HR(hr, S_OK);
2629 todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
2630 EXPECT_REF(unk, 3);
2631 todo_wine EXPECT_REF(disp, 1);
2633 EXPECT_REF(unk, 3);
2634 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
2635 EXPECT_HR(hr, S_OK);
2636 todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
2637 EXPECT_REF(unk, 4);
2638 todo_wine EXPECT_REF(disp2, 1);
2640 IDispatch_Release(disp);
2641 IDispatch_Release(disp2);
2643 /* get IXMLDOMNode from this IUnknown */
2644 EXPECT_REF(unk, 2);
2645 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
2646 EXPECT_HR(hr, S_OK);
2647 todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
2648 EXPECT_REF(unk, 3);
2649 todo_wine EXPECT_REF(node2, 1);
2651 EXPECT_REF(unk, 3);
2652 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
2653 EXPECT_HR(hr, S_OK);
2654 todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
2655 EXPECT_REF(unk, 4);
2656 todo_wine EXPECT_REF(node3, 1);
2658 IXMLDOMNode_Release(node2);
2659 IXMLDOMNode_Release(node3);
2661 /* try IDispatchEx from IUnknown */
2662 EXPECT_REF(unk, 2);
2663 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
2664 EXPECT_HR(hr, S_OK);
2665 ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
2666 EXPECT_REF(unk, 3);
2667 todo_wine EXPECT_REF(dispex, 1);
2669 EXPECT_REF(unk, 3);
2670 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
2671 EXPECT_HR(hr, S_OK);
2672 todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
2673 EXPECT_REF(unk, 4);
2674 todo_wine EXPECT_REF(dispex2, 1);
2676 IDispatchEx_Release(dispex);
2677 IDispatchEx_Release(dispex2);
2679 /* try corresponding IXMLDOM* */
2680 EXPECT_REF(unk, 2);
2681 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
2682 EXPECT_HR(hr, S_OK);
2683 EXPECT_REF(unk, 3);
2684 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
2685 EXPECT_HR(hr, S_OK);
2686 EXPECT_REF(unk, 4);
2687 todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
2688 IUnknown_Release(node_typed);
2689 IUnknown_Release(node_typed2);
2691 /* try invalid IXMLDOM* */
2692 hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
2693 EXPECT_HR(hr, E_NOINTERFACE);
2695 IUnknown_Release(unk);
2697 EXPECT_REF(node, 1);
2698 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
2699 EXPECT_HR(hr, S_OK);
2700 EXPECT_REF(node, 2);
2701 ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
2703 EXPECT_REF(node, 2);
2704 hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
2705 EXPECT_HR(hr, S_OK);
2706 EXPECT_REF(node, 3);
2707 todo_wine {
2708 EXPECT_REF(node_typed, 2);
2709 ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
2711 IUnknown_Release(node_typed);
2713 IXMLDOMNode_Release(node2);
2714 IXMLDOMNode_Release(node);
2716 ptr++;
2719 EXPECT_REF(doc, 1);
2720 ref = IXMLDOMDocument_Release(doc);
2721 ok( ref == 0, "ref %d\n", ref);
2723 /* check IUnknown after releasing DOM iface */
2724 doc = create_document(&IID_IXMLDOMDocument);
2725 EXPECT_REF(doc, 1);
2726 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2727 EXPECT_HR(hr, S_OK);
2728 todo_wine {
2729 EXPECT_REF(unk, 3);
2730 EXPECT_REF(doc, 1);
2732 IXMLDOMDocument_Release(doc);
2733 EXPECT_REF(unk, 1);
2734 IUnknown_Release(unk);
2736 doc = create_document(&IID_IXMLDOMDocument);
2738 EXPECT_REF(doc, 1);
2739 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2740 EXPECT_HR(hr, S_OK);
2741 todo_wine {
2742 EXPECT_REF(unk, 3);
2743 EXPECT_REF(doc, 1);
2745 IUnknown_Release(unk);
2747 /* IXMLDOMImplementation */
2748 EXPECT_REF(doc, 1);
2749 hr = IXMLDOMDocument_get_implementation(doc, &impl);
2750 EXPECT_HR(hr, S_OK);
2751 EXPECT_REF(doc, 1);
2752 EXPECT_REF(impl, 1);
2753 hr = IXMLDOMDocument_get_implementation(doc, &impl2);
2754 EXPECT_HR(hr, S_OK);
2755 EXPECT_REF(doc, 1);
2756 EXPECT_REF(impl2, 1);
2757 ok(impl != impl2, "got %p, %p\n", impl, impl2);
2758 IXMLDOMImplementation_Release(impl);
2759 IXMLDOMImplementation_Release(impl2);
2761 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2762 EXPECT_HR(hr, S_OK);
2763 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2765 EXPECT_REF(doc, 1);
2766 IXMLDOMDocument_AddRef( doc );
2767 EXPECT_REF(doc, 2);
2768 IXMLDOMDocument_AddRef( doc );
2769 EXPECT_REF(doc, 3);
2771 IXMLDOMDocument_Release( doc );
2772 IXMLDOMDocument_Release( doc );
2774 EXPECT_REF(doc, 1);
2775 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2776 EXPECT_HR(hr, S_OK);
2777 todo_wine {
2778 EXPECT_REF(unk, 3);
2779 EXPECT_REF(doc, 1);
2781 hr = IXMLDOMDocument_get_documentElement(doc, &element);
2782 EXPECT_HR(hr, S_OK);
2783 todo_wine {
2784 EXPECT_REF(doc, 1);
2785 EXPECT_REF(element, 2);
2787 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
2788 EXPECT_HR(hr, S_OK);
2790 todo_wine {
2791 EXPECT_REF(doc, 1);
2792 EXPECT_REF(element, 2);
2793 EXPECT_REF(elem2, 2);
2795 IXMLDOMElement_AddRef(element);
2796 todo_wine EXPECT_REF(element, 3);
2797 IXMLDOMElement_Release(element);
2799 /* get IUnknown from a node doesn't touch node instance refcount */
2800 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2801 EXPECT_HR(hr, S_OK);
2802 EXPECT_REF(element, 2);
2803 todo_wine {
2804 EXPECT_REF(unk, 4);
2805 EXPECT_REF(elem2, 2);
2807 hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
2808 EXPECT_HR(hr, S_OK);
2809 todo_wine {
2810 EXPECT_REF(unk, 5);
2811 EXPECT_REF(unk2, 5);
2813 EXPECT_REF(element, 2);
2814 EXPECT_REF(elem2, 2);
2816 todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
2817 IUnknown_Release(unk);
2819 /* IUnknown refcount is not affected by node refcount */
2820 todo_wine EXPECT_REF(unk2, 4);
2821 IXMLDOMElement_AddRef(elem2);
2822 todo_wine EXPECT_REF(unk2, 4);
2823 IXMLDOMElement_Release(elem2);
2825 IXMLDOMElement_Release(elem2);
2826 todo_wine EXPECT_REF(unk2, 3);
2828 IUnknown_Release(unk2);
2830 hr = IXMLDOMElement_get_childNodes( element, &node_list );
2831 EXPECT_HR(hr, S_OK);
2833 todo_wine EXPECT_REF(element, 2);
2834 EXPECT_REF(node_list, 1);
2836 hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
2837 EXPECT_HR(hr, S_OK);
2838 EXPECT_REF(node_list, 1);
2839 EXPECT_REF(node, 1);
2841 hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2842 EXPECT_HR(hr, S_OK);
2843 EXPECT_REF(node_list, 1);
2844 EXPECT_REF(node2, 1);
2846 ref = IXMLDOMNode_Release( node );
2847 ok( ref == 0, "ref %d\n", ref );
2848 ref = IXMLDOMNode_Release( node2 );
2849 ok( ref == 0, "ref %d\n", ref );
2851 ref = IXMLDOMNodeList_Release( node_list );
2852 ok( ref == 0, "ref %d\n", ref );
2854 ok( node != node2, "node %p node2 %p\n", node, node2 );
2856 ref = IXMLDOMDocument_Release( doc );
2857 todo_wine ok( ref == 0, "ref %d\n", ref );
2859 todo_wine EXPECT_REF(element, 2);
2861 /* IUnknown must be unique however we obtain it */
2862 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2863 EXPECT_HR(hr, S_OK);
2864 EXPECT_REF(element, 2);
2865 hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
2866 EXPECT_HR(hr, S_OK);
2867 todo_wine EXPECT_REF(element, 2);
2868 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2869 EXPECT_HR(hr, S_OK);
2870 todo_wine EXPECT_REF(element, 2);
2871 ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
2872 todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
2874 IUnknown_Release( unk2 );
2875 IUnknown_Release( unk );
2876 IXMLDOMNode_Release( node );
2877 todo_wine EXPECT_REF(element, 2);
2879 IXMLDOMElement_Release( element );
2881 free_bstrs();
2884 static void test_create(void)
2886 static const WCHAR szOne[] = {'1',0};
2887 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2888 HRESULT r;
2889 VARIANT var;
2890 BSTR str, name;
2891 IXMLDOMDocument *doc;
2892 IXMLDOMElement *element;
2893 IXMLDOMComment *comment;
2894 IXMLDOMText *text;
2895 IXMLDOMCDATASection *cdata;
2896 IXMLDOMNode *root, *node, *child;
2897 IXMLDOMNamedNodeMap *attr_map;
2898 IUnknown *unk;
2899 LONG ref;
2900 LONG num;
2902 doc = create_document(&IID_IXMLDOMDocument);
2904 EXPECT_REF(doc, 1);
2906 /* types not supported for creation */
2907 V_VT(&var) = VT_I1;
2908 V_I1(&var) = NODE_DOCUMENT;
2909 node = (IXMLDOMNode*)0x1;
2910 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2911 ok( r == E_INVALIDARG, "returns %08x\n", r );
2912 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2914 V_VT(&var) = VT_I1;
2915 V_I1(&var) = NODE_DOCUMENT_TYPE;
2916 node = (IXMLDOMNode*)0x1;
2917 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2918 ok( r == E_INVALIDARG, "returns %08x\n", r );
2919 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2921 V_VT(&var) = VT_I1;
2922 V_I1(&var) = NODE_ENTITY;
2923 node = (IXMLDOMNode*)0x1;
2924 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2925 ok( r == E_INVALIDARG, "returns %08x\n", r );
2926 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2928 V_VT(&var) = VT_I1;
2929 V_I1(&var) = NODE_NOTATION;
2930 node = (IXMLDOMNode*)0x1;
2931 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2932 ok( r == E_INVALIDARG, "returns %08x\n", r );
2933 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2935 /* NODE_COMMENT */
2936 V_VT(&var) = VT_I1;
2937 V_I1(&var) = NODE_COMMENT;
2938 node = NULL;
2939 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2940 ok( r == S_OK, "returns %08x\n", r );
2941 ok( node != NULL, "\n");
2943 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2944 ok( r == S_OK, "returns %08x\n", r );
2945 IXMLDOMNode_Release(node);
2947 str = NULL;
2948 r = IXMLDOMComment_get_data(comment, &str);
2949 ok( r == S_OK, "returns %08x\n", r );
2950 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2951 IXMLDOMComment_Release(comment);
2952 SysFreeString(str);
2954 node = (IXMLDOMNode*)0x1;
2955 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2956 ok( r == S_OK, "returns %08x\n", r );
2958 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2959 ok( r == S_OK, "returns %08x\n", r );
2960 IXMLDOMNode_Release(node);
2962 str = NULL;
2963 r = IXMLDOMComment_get_data(comment, &str);
2964 ok( r == S_OK, "returns %08x\n", r );
2965 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2966 IXMLDOMComment_Release(comment);
2967 SysFreeString(str);
2969 node = (IXMLDOMNode*)0x1;
2970 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2971 ok( r == S_OK, "returns %08x\n", r );
2973 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2974 ok( r == S_OK, "returns %08x\n", r );
2975 IXMLDOMNode_Release(node);
2977 str = NULL;
2978 r = IXMLDOMComment_get_data(comment, &str);
2979 ok( r == S_OK, "returns %08x\n", r );
2980 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2981 IXMLDOMComment_Release(comment);
2982 SysFreeString(str);
2984 /* NODE_TEXT */
2985 V_VT(&var) = VT_I1;
2986 V_I1(&var) = NODE_TEXT;
2987 node = NULL;
2988 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2989 ok( r == S_OK, "returns %08x\n", r );
2990 ok( node != NULL, "\n");
2992 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2993 ok( r == S_OK, "returns %08x\n", r );
2994 IXMLDOMNode_Release(node);
2996 str = NULL;
2997 r = IXMLDOMText_get_data(text, &str);
2998 ok( r == S_OK, "returns %08x\n", r );
2999 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3000 IXMLDOMText_Release(text);
3001 SysFreeString(str);
3003 node = (IXMLDOMNode*)0x1;
3004 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3005 ok( r == S_OK, "returns %08x\n", r );
3007 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3008 ok( r == S_OK, "returns %08x\n", r );
3009 IXMLDOMNode_Release(node);
3011 str = NULL;
3012 r = IXMLDOMText_get_data(text, &str);
3013 ok( r == S_OK, "returns %08x\n", r );
3014 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3015 IXMLDOMText_Release(text);
3016 SysFreeString(str);
3018 node = (IXMLDOMNode*)0x1;
3019 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3020 ok( r == S_OK, "returns %08x\n", r );
3022 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3023 ok( r == S_OK, "returns %08x\n", r );
3024 IXMLDOMNode_Release(node);
3026 str = NULL;
3027 r = IXMLDOMText_get_data(text, &str);
3028 ok( r == S_OK, "returns %08x\n", r );
3029 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3030 IXMLDOMText_Release(text);
3031 SysFreeString(str);
3033 /* NODE_CDATA_SECTION */
3034 V_VT(&var) = VT_I1;
3035 V_I1(&var) = NODE_CDATA_SECTION;
3036 node = NULL;
3037 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3038 ok( r == S_OK, "returns %08x\n", r );
3039 ok( node != NULL, "\n");
3041 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3042 ok( r == S_OK, "returns %08x\n", r );
3043 IXMLDOMNode_Release(node);
3045 str = NULL;
3046 r = IXMLDOMCDATASection_get_data(cdata, &str);
3047 ok( r == S_OK, "returns %08x\n", r );
3048 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3049 IXMLDOMCDATASection_Release(cdata);
3050 SysFreeString(str);
3052 node = (IXMLDOMNode*)0x1;
3053 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3054 ok( r == S_OK, "returns %08x\n", r );
3056 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3057 ok( r == S_OK, "returns %08x\n", r );
3058 IXMLDOMNode_Release(node);
3060 str = NULL;
3061 r = IXMLDOMCDATASection_get_data(cdata, &str);
3062 ok( r == S_OK, "returns %08x\n", r );
3063 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3064 IXMLDOMCDATASection_Release(cdata);
3065 SysFreeString(str);
3067 node = (IXMLDOMNode*)0x1;
3068 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3069 ok( r == S_OK, "returns %08x\n", r );
3071 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3072 ok( r == S_OK, "returns %08x\n", r );
3073 IXMLDOMNode_Release(node);
3075 str = NULL;
3076 r = IXMLDOMCDATASection_get_data(cdata, &str);
3077 ok( r == S_OK, "returns %08x\n", r );
3078 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3079 IXMLDOMCDATASection_Release(cdata);
3080 SysFreeString(str);
3082 /* NODE_ATTRIBUTE */
3083 V_VT(&var) = VT_I1;
3084 V_I1(&var) = NODE_ATTRIBUTE;
3085 node = (IXMLDOMNode*)0x1;
3086 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3087 ok( r == E_FAIL, "returns %08x\n", r );
3088 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3090 V_VT(&var) = VT_I1;
3091 V_I1(&var) = NODE_ATTRIBUTE;
3092 node = (IXMLDOMNode*)0x1;
3093 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3094 ok( r == E_FAIL, "returns %08x\n", r );
3095 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3097 V_VT(&var) = VT_I1;
3098 V_I1(&var) = NODE_ATTRIBUTE;
3099 str = SysAllocString( szlc );
3100 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3101 ok( r == S_OK, "returns %08x\n", r );
3102 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3103 SysFreeString(str);
3105 /* a name is required for attribute, try a BSTR with first null wchar */
3106 V_VT(&var) = VT_I1;
3107 V_I1(&var) = NODE_ATTRIBUTE;
3108 str = SysAllocString( szstr1 );
3109 str[0] = 0;
3110 node = (IXMLDOMNode*)0x1;
3111 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3112 ok( r == E_FAIL, "returns %08x\n", r );
3113 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3114 SysFreeString(str);
3116 /* NODE_PROCESSING_INSTRUCTION */
3117 V_VT(&var) = VT_I1;
3118 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3119 node = (IXMLDOMNode*)0x1;
3120 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3121 ok( r == E_FAIL, "returns %08x\n", r );
3122 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3124 V_VT(&var) = VT_I1;
3125 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3126 node = (IXMLDOMNode*)0x1;
3127 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3128 ok( r == E_FAIL, "returns %08x\n", r );
3129 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3131 V_VT(&var) = VT_I1;
3132 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
3133 r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3134 ok( r == E_INVALIDARG, "returns %08x\n", r );
3136 /* NODE_ENTITY_REFERENCE */
3137 V_VT(&var) = VT_I1;
3138 V_I1(&var) = NODE_ENTITY_REFERENCE;
3139 node = (IXMLDOMNode*)0x1;
3140 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3141 ok( r == E_FAIL, "returns %08x\n", r );
3142 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3144 V_VT(&var) = VT_I1;
3145 V_I1(&var) = NODE_ENTITY_REFERENCE;
3146 node = (IXMLDOMNode*)0x1;
3147 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3148 ok( r == E_FAIL, "returns %08x\n", r );
3149 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3151 /* NODE_ELEMENT */
3152 V_VT(&var) = VT_I1;
3153 V_I1(&var) = NODE_ELEMENT;
3154 node = (IXMLDOMNode*)0x1;
3155 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3156 ok( r == E_FAIL, "returns %08x\n", r );
3157 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3159 V_VT(&var) = VT_I1;
3160 V_I1(&var) = NODE_ELEMENT;
3161 node = (IXMLDOMNode*)0x1;
3162 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3163 ok( r == E_FAIL, "returns %08x\n", r );
3164 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3166 V_VT(&var) = VT_I1;
3167 V_I1(&var) = NODE_ELEMENT;
3168 str = SysAllocString( szlc );
3169 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3170 ok( r == S_OK, "returns %08x\n", r );
3171 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3173 V_VT(&var) = VT_I1;
3174 V_I1(&var) = NODE_ELEMENT;
3175 r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3176 ok( r == E_INVALIDARG, "returns %08x\n", r );
3178 V_VT(&var) = VT_R4;
3179 V_R4(&var) = NODE_ELEMENT;
3180 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3181 ok( r == S_OK, "returns %08x\n", r );
3182 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3184 V_VT(&var) = VT_BSTR;
3185 V_BSTR(&var) = SysAllocString( szOne );
3186 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3187 ok( r == S_OK, "returns %08x\n", r );
3188 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3189 VariantClear(&var);
3191 V_VT(&var) = VT_BSTR;
3192 V_BSTR(&var) = SysAllocString( szOneGarbage );
3193 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3194 ok( r == E_INVALIDARG, "returns %08x\n", r );
3195 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3196 VariantClear(&var);
3198 V_VT(&var) = VT_I4;
3199 V_I4(&var) = NODE_ELEMENT;
3200 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3201 ok( r == S_OK, "returns %08x\n", r );
3203 EXPECT_REF(doc, 1);
3204 r = IXMLDOMDocument_appendChild( doc, node, &root );
3205 ok( r == S_OK, "returns %08x\n", r );
3206 ok( node == root, "%p %p\n", node, root );
3207 EXPECT_REF(doc, 1);
3209 EXPECT_REF(node, 2);
3211 ref = IXMLDOMNode_Release( node );
3212 ok(ref == 1, "ref %d\n", ref);
3213 SysFreeString( str );
3215 V_VT(&var) = VT_I4;
3216 V_I4(&var) = NODE_ELEMENT;
3217 str = SysAllocString( szbs );
3218 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3219 ok( r == S_OK, "returns %08x\n", r );
3220 SysFreeString( str );
3222 EXPECT_REF(node, 1);
3224 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3225 ok( r == S_OK, "returns %08x\n", r );
3227 EXPECT_REF(unk, 2);
3229 V_VT(&var) = VT_EMPTY;
3230 child = NULL;
3231 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3232 ok( r == S_OK, "returns %08x\n", r );
3233 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3235 todo_wine EXPECT_REF(unk, 4);
3237 IXMLDOMNode_Release( child );
3238 IUnknown_Release( unk );
3240 V_VT(&var) = VT_NULL;
3241 V_DISPATCH(&var) = (IDispatch*)node;
3242 r = IXMLDOMNode_insertBefore( root, node, var, &child );
3243 ok( r == S_OK, "returns %08x\n", r );
3244 ok( node == child, "%p %p\n", node, child );
3245 IXMLDOMNode_Release( child );
3247 V_VT(&var) = VT_NULL;
3248 V_DISPATCH(&var) = (IDispatch*)node;
3249 r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3250 ok( r == S_OK, "returns %08x\n", r );
3251 IXMLDOMNode_Release( node );
3253 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3254 ok( r == S_OK, "returns %08x\n", r );
3256 r = IXMLDOMElement_get_attributes( element, &attr_map );
3257 ok( r == S_OK, "returns %08x\n", r );
3258 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3259 ok( r == S_OK, "returns %08x\n", r );
3260 ok( num == 0, "num %d\n", num );
3261 IXMLDOMNamedNodeMap_Release( attr_map );
3263 V_VT(&var) = VT_BSTR;
3264 V_BSTR(&var) = SysAllocString( szstr1 );
3265 name = SysAllocString( szdl );
3266 r = IXMLDOMElement_setAttribute( element, name, var );
3267 ok( r == S_OK, "returns %08x\n", r );
3268 r = IXMLDOMElement_get_attributes( element, &attr_map );
3269 ok( r == S_OK, "returns %08x\n", r );
3270 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3271 ok( r == S_OK, "returns %08x\n", r );
3272 ok( num == 1, "num %d\n", num );
3273 IXMLDOMNamedNodeMap_Release( attr_map );
3274 VariantClear(&var);
3276 V_VT(&var) = VT_BSTR;
3277 V_BSTR(&var) = SysAllocString( szstr2 );
3278 r = IXMLDOMElement_setAttribute( element, name, var );
3279 ok( r == S_OK, "returns %08x\n", r );
3280 r = IXMLDOMElement_get_attributes( element, &attr_map );
3281 ok( r == S_OK, "returns %08x\n", r );
3282 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3283 ok( r == S_OK, "returns %08x\n", r );
3284 ok( num == 1, "num %d\n", num );
3285 IXMLDOMNamedNodeMap_Release( attr_map );
3286 VariantClear(&var);
3287 r = IXMLDOMElement_getAttribute( element, name, &var );
3288 ok( r == S_OK, "returns %08x\n", r );
3289 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3290 VariantClear(&var);
3291 SysFreeString(name);
3293 V_VT(&var) = VT_BSTR;
3294 V_BSTR(&var) = SysAllocString( szstr1 );
3295 name = SysAllocString( szlc );
3296 r = IXMLDOMElement_setAttribute( element, name, var );
3297 ok( r == S_OK, "returns %08x\n", r );
3298 r = IXMLDOMElement_get_attributes( element, &attr_map );
3299 ok( r == S_OK, "returns %08x\n", r );
3300 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3301 ok( r == S_OK, "returns %08x\n", r );
3302 ok( num == 2, "num %d\n", num );
3303 IXMLDOMNamedNodeMap_Release( attr_map );
3304 VariantClear(&var);
3305 SysFreeString(name);
3307 V_VT(&var) = VT_I4;
3308 V_I4(&var) = 10;
3309 name = SysAllocString( szbs );
3310 r = IXMLDOMElement_setAttribute( element, name, var );
3311 ok( r == S_OK, "returns %08x\n", r );
3312 VariantClear(&var);
3313 r = IXMLDOMElement_getAttribute( element, name, &var );
3314 ok( r == S_OK, "returns %08x\n", r );
3315 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3316 VariantClear(&var);
3317 SysFreeString(name);
3319 /* Create an Attribute */
3320 V_VT(&var) = VT_I4;
3321 V_I4(&var) = NODE_ATTRIBUTE;
3322 str = SysAllocString( szAttribute );
3323 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3324 ok( r == S_OK, "returns %08x\n", r );
3325 ok( node != NULL, "node was null\n");
3326 SysFreeString(str);
3328 IXMLDOMElement_Release( element );
3329 IXMLDOMNode_Release( root );
3330 IXMLDOMDocument_Release( doc );
3333 struct queryresult_t {
3334 const char *query;
3335 const char *result;
3336 int len;
3339 static const struct queryresult_t elementsbytagname[] = {
3340 { "", "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 },
3341 { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
3342 { "bs", "E1.E2.D1", 1 },
3343 { "dl", "", 0 },
3344 { "str1","", 0 },
3345 { NULL }
3348 static void test_getElementsByTagName(void)
3350 const struct queryresult_t *ptr = elementsbytagname;
3351 IXMLDOMNodeList *node_list;
3352 IXMLDOMDocument *doc;
3353 IXMLDOMElement *elem;
3354 WCHAR buff[100];
3355 VARIANT_BOOL b;
3356 HRESULT r;
3357 LONG len;
3358 BSTR str;
3360 doc = create_document(&IID_IXMLDOMDocument);
3362 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3363 ok( r == S_OK, "loadXML failed\n");
3364 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3366 /* null arguments cases */
3367 r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3368 ok( r == E_INVALIDARG, "ret %08x\n", r );
3369 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL);
3370 ok( r == E_INVALIDARG, "ret %08x\n", r );
3372 while (ptr->query)
3374 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list);
3375 ok(r == S_OK, "ret %08x\n", r);
3376 r = IXMLDOMNodeList_get_length(node_list, &len);
3377 ok(r == S_OK, "ret %08x\n", r);
3378 ok(len == ptr->len, "%s: got len %d, expected %d\n", ptr->query, len, ptr->len);
3379 expect_list_and_release(node_list, ptr->result);
3381 free_bstrs();
3382 ptr++;
3385 /* broken query BSTR */
3386 memcpy(&buff[2], szstar, sizeof(szstar));
3387 /* just a big length */
3388 *(DWORD*)buff = 0xf0f0;
3389 r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3390 ok( r == S_OK, "ret %08x\n", r );
3391 r = IXMLDOMNodeList_get_length( node_list, &len );
3392 ok( r == S_OK, "ret %08x\n", r );
3393 ok( len == 6, "len %d\n", len );
3394 IXMLDOMNodeList_Release( node_list );
3396 /* test for element */
3397 r = IXMLDOMDocument_get_documentElement(doc, &elem);
3398 ok( r == S_OK, "ret %08x\n", r );
3400 str = SysAllocString( szstar );
3402 /* null arguments cases */
3403 r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3404 ok( r == E_INVALIDARG, "ret %08x\n", r );
3405 r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3406 ok( r == E_INVALIDARG, "ret %08x\n", r );
3408 r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3409 ok( r == S_OK, "ret %08x\n", r );
3410 r = IXMLDOMNodeList_get_length( node_list, &len );
3411 ok( r == S_OK, "ret %08x\n", r );
3412 ok( len == 5, "len %d\n", len );
3413 expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3414 SysFreeString( str );
3416 /* broken query BSTR */
3417 memcpy(&buff[2], szstar, sizeof(szstar));
3418 /* just a big length */
3419 *(DWORD*)buff = 0xf0f0;
3420 r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3421 ok( r == S_OK, "ret %08x\n", r );
3422 r = IXMLDOMNodeList_get_length( node_list, &len );
3423 ok( r == S_OK, "ret %08x\n", r );
3424 ok( len == 5, "len %d\n", len );
3425 IXMLDOMNodeList_Release( node_list );
3427 IXMLDOMElement_Release(elem);
3429 IXMLDOMDocument_Release( doc );
3431 free_bstrs();
3434 static void test_get_text(void)
3436 HRESULT r;
3437 BSTR str;
3438 VARIANT_BOOL b;
3439 IXMLDOMDocument *doc;
3440 IXMLDOMNode *node, *node2, *node3;
3441 IXMLDOMNode *nodeRoot;
3442 IXMLDOMNodeList *node_list;
3443 IXMLDOMNamedNodeMap *node_map;
3444 LONG len;
3446 doc = create_document(&IID_IXMLDOMDocument);
3448 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3449 ok( r == S_OK, "loadXML failed\n");
3450 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3452 str = SysAllocString( szbs );
3453 r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3454 ok( r == S_OK, "ret %08x\n", r );
3455 SysFreeString(str);
3457 /* Test to get all child node text. */
3458 r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3459 ok( r == S_OK, "ret %08x\n", r );
3460 if(r == S_OK)
3462 r = IXMLDOMNode_get_text( nodeRoot, &str );
3463 ok( r == S_OK, "ret %08x\n", r );
3464 expect_bstr_eq_and_free(str, "fn1.txt\n \nfn2.txt\n \nf1");
3466 IXMLDOMNode_Release(nodeRoot);
3469 r = IXMLDOMNodeList_get_length( node_list, NULL );
3470 ok( r == E_INVALIDARG, "ret %08x\n", r );
3472 r = IXMLDOMNodeList_get_length( node_list, &len );
3473 ok( r == S_OK, "ret %08x\n", r );
3474 ok( len == 1, "expect 1 got %d\n", len );
3476 r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3477 ok( r == E_INVALIDARG, "ret %08x\n", r );
3479 r = IXMLDOMNodeList_nextNode( node_list, NULL );
3480 ok( r == E_INVALIDARG, "ret %08x\n", r );
3482 r = IXMLDOMNodeList_get_item( node_list, 0, &node );
3483 ok( r == S_OK, "ret %08x\n", r );
3484 IXMLDOMNodeList_Release( node_list );
3486 /* Invalid output parameter*/
3487 r = IXMLDOMNode_get_text( node, NULL );
3488 ok( r == E_INVALIDARG, "ret %08x\n", r );
3490 r = IXMLDOMNode_get_text( node, &str );
3491 ok( r == S_OK, "ret %08x\n", r );
3492 ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
3493 SysFreeString(str);
3495 r = IXMLDOMNode_get_attributes( node, &node_map );
3496 ok( r == S_OK, "ret %08x\n", r );
3498 str = SysAllocString( szvr );
3499 r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3500 ok( r == S_OK, "ret %08x\n", r );
3501 SysFreeString(str);
3503 r = IXMLDOMNode_get_text( node2, &str );
3504 ok( r == S_OK, "ret %08x\n", r );
3505 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3506 SysFreeString(str);
3508 r = IXMLDOMNode_get_firstChild( node2, &node3 );
3509 ok( r == S_OK, "ret %08x\n", r );
3511 r = IXMLDOMNode_get_text( node3, &str );
3512 ok( r == S_OK, "ret %08x\n", r );
3513 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3514 SysFreeString(str);
3517 IXMLDOMNode_Release( node3 );
3518 IXMLDOMNode_Release( node2 );
3519 IXMLDOMNamedNodeMap_Release( node_map );
3520 IXMLDOMNode_Release( node );
3521 IXMLDOMDocument_Release( doc );
3523 free_bstrs();
3526 static void test_get_childNodes(void)
3528 IXMLDOMNodeList *node_list, *node_list2;
3529 IEnumVARIANT *enum1, *enum2, *enum3;
3530 VARIANT_BOOL b;
3531 IXMLDOMDocument *doc;
3532 IXMLDOMNode *node, *node2;
3533 IXMLDOMElement *element;
3534 IUnknown *unk1, *unk2;
3535 HRESULT hr;
3536 VARIANT v;
3537 BSTR str;
3538 LONG len;
3540 doc = create_document(&IID_IXMLDOMDocument);
3542 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3543 EXPECT_HR(hr, S_OK);
3544 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3546 hr = IXMLDOMDocument_get_documentElement( doc, &element );
3547 EXPECT_HR(hr, S_OK);
3549 hr = IXMLDOMElement_get_childNodes( element, &node_list );
3550 EXPECT_HR(hr, S_OK);
3552 hr = IXMLDOMNodeList_get_length( node_list, &len );
3553 EXPECT_HR(hr, S_OK);
3554 ok( len == 4, "len %d\n", len);
3556 /* refcount tests for IEnumVARIANT support */
3557 EXPECT_REF(node_list, 1);
3558 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
3559 EXPECT_HR(hr, S_OK);
3560 EXPECT_REF(node_list, 1);
3561 EXPECT_REF(enum1, 2);
3563 EXPECT_REF(node_list, 1);
3564 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
3565 EXPECT_HR(hr, S_OK);
3566 EXPECT_REF(node_list, 1);
3567 ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
3568 IEnumVARIANT_Release(enum2);
3570 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3571 EXPECT_HR(hr, S_OK);
3572 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
3573 EXPECT_HR(hr, S_OK);
3574 EXPECT_REF(node_list, 3);
3575 EXPECT_REF(enum1, 2);
3576 ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
3577 IUnknown_Release(unk1);
3578 IUnknown_Release(unk2);
3580 EXPECT_REF(node_list, 1);
3581 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
3582 EXPECT_HR(hr, S_OK);
3583 EXPECT_REF(node_list, 2);
3584 EXPECT_REF(enum2, 1);
3585 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
3587 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
3588 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3589 EXPECT_HR(hr, S_OK);
3590 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
3591 EXPECT_HR(hr, S_OK);
3592 EXPECT_REF(node_list, 3);
3593 EXPECT_REF(enum2, 2);
3594 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
3595 IUnknown_Release(unk1);
3596 IUnknown_Release(unk2);
3598 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
3599 EXPECT_HR(hr, S_OK);
3600 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
3601 IEnumVARIANT_Release(enum3);
3602 IEnumVARIANT_Release(enum2);
3604 /* iteration tests */
3605 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
3606 EXPECT_HR(hr, S_OK);
3607 hr = IXMLDOMNode_get_nodeName(node, &str);
3608 EXPECT_HR(hr, S_OK);
3609 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3610 SysFreeString(str);
3611 IXMLDOMNode_Release(node);
3613 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3614 EXPECT_HR(hr, S_OK);
3615 hr = IXMLDOMNode_get_nodeName(node, &str);
3616 EXPECT_HR(hr, S_OK);
3617 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3618 SysFreeString(str);
3619 IXMLDOMNode_Release(node);
3621 V_VT(&v) = VT_EMPTY;
3622 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
3623 EXPECT_HR(hr, S_OK);
3624 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
3625 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
3626 EXPECT_HR(hr, S_OK);
3627 hr = IXMLDOMNode_get_nodeName(node, &str);
3628 EXPECT_HR(hr, S_OK);
3629 ok(!lstrcmpW(str, _bstr_("bs")), "got node name %s\n", wine_dbgstr_w(str));
3630 SysFreeString(str);
3631 IXMLDOMNode_Release(node);
3632 VariantClear(&v);
3634 hr = IXMLDOMNodeList_nextNode(node_list, &node);
3635 EXPECT_HR(hr, S_OK);
3636 hr = IXMLDOMNode_get_nodeName(node, &str);
3637 EXPECT_HR(hr, S_OK);
3638 ok(!lstrcmpW(str, _bstr_("pr")), "got %s\n", wine_dbgstr_w(str));
3639 SysFreeString(str);
3640 IXMLDOMNode_Release(node);
3642 IEnumVARIANT_Release(enum1);
3644 hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3645 EXPECT_HR(hr, S_OK);
3647 hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3648 EXPECT_HR(hr, S_OK);
3650 hr = IXMLDOMNodeList_get_length( node_list2, &len );
3651 EXPECT_HR(hr, S_OK);
3652 ok( len == 0, "len %d\n", len);
3654 hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3655 EXPECT_HR(hr, S_FALSE);
3657 IXMLDOMNodeList_Release( node_list2 );
3658 IXMLDOMNode_Release( node );
3659 IXMLDOMNodeList_Release( node_list );
3660 IXMLDOMElement_Release( element );
3662 /* test for children of <?xml ..?> node */
3663 hr = IXMLDOMDocument_get_firstChild(doc, &node);
3664 EXPECT_HR(hr, S_OK);
3666 str = NULL;
3667 hr = IXMLDOMNode_get_nodeName(node, &str);
3668 EXPECT_HR(hr, S_OK);
3669 ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
3670 SysFreeString(str);
3672 /* it returns empty but valid node list */
3673 node_list = (void*)0xdeadbeef;
3674 hr = IXMLDOMNode_get_childNodes(node, &node_list);
3675 EXPECT_HR(hr, S_OK);
3677 len = -1;
3678 hr = IXMLDOMNodeList_get_length(node_list, &len);
3679 EXPECT_HR(hr, S_OK);
3680 ok(len == 0, "got %d\n", len);
3682 IXMLDOMNodeList_Release( node_list );
3683 IXMLDOMNode_Release(node);
3685 IXMLDOMDocument_Release( doc );
3686 free_bstrs();
3689 static void test_get_firstChild(void)
3691 static const WCHAR xmlW[] = {'x','m','l',0};
3692 IXMLDOMDocument *doc;
3693 IXMLDOMNode *node;
3694 VARIANT_BOOL b;
3695 HRESULT r;
3696 BSTR str;
3698 doc = create_document(&IID_IXMLDOMDocument);
3700 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3701 ok( r == S_OK, "loadXML failed\n");
3702 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3704 r = IXMLDOMDocument_get_firstChild( doc, &node );
3705 ok( r == S_OK, "ret %08x\n", r);
3707 r = IXMLDOMNode_get_nodeName( node, &str );
3708 ok( r == S_OK, "ret %08x\n", r);
3710 ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3712 SysFreeString(str);
3713 IXMLDOMNode_Release( node );
3714 IXMLDOMDocument_Release( doc );
3716 free_bstrs();
3719 static void test_get_lastChild(void)
3721 static const WCHAR lcW[] = {'l','c',0};
3722 static const WCHAR foW[] = {'f','o',0};
3723 IXMLDOMDocument *doc;
3724 IXMLDOMNode *node, *child;
3725 VARIANT_BOOL b;
3726 HRESULT r;
3727 BSTR str;
3729 doc = create_document(&IID_IXMLDOMDocument);
3731 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3732 ok( r == S_OK, "loadXML failed\n");
3733 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3735 r = IXMLDOMDocument_get_lastChild( doc, &node );
3736 ok( r == S_OK, "ret %08x\n", r);
3738 r = IXMLDOMNode_get_nodeName( node, &str );
3739 ok( r == S_OK, "ret %08x\n", r);
3741 ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
3742 SysFreeString(str);
3744 r = IXMLDOMNode_get_lastChild( node, &child );
3745 ok( r == S_OK, "ret %08x\n", r);
3747 r = IXMLDOMNode_get_nodeName( child, &str );
3748 ok( r == S_OK, "ret %08x\n", r);
3750 ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
3751 SysFreeString(str);
3753 IXMLDOMNode_Release( child );
3754 IXMLDOMNode_Release( node );
3755 IXMLDOMDocument_Release( doc );
3757 free_bstrs();
3760 static void test_removeChild(void)
3762 HRESULT r;
3763 VARIANT_BOOL b;
3764 IXMLDOMDocument *doc;
3765 IXMLDOMElement *element, *lc_element;
3766 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
3767 IXMLDOMNodeList *root_list, *fo_list;
3769 doc = create_document(&IID_IXMLDOMDocument);
3771 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3772 ok( r == S_OK, "loadXML failed\n");
3773 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3775 r = IXMLDOMDocument_get_documentElement( doc, &element );
3776 ok( r == S_OK, "ret %08x\n", r);
3777 todo_wine EXPECT_REF(element, 2);
3779 r = IXMLDOMElement_get_childNodes( element, &root_list );
3780 ok( r == S_OK, "ret %08x\n", r);
3781 EXPECT_REF(root_list, 1);
3783 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3784 ok( r == S_OK, "ret %08x\n", r);
3785 EXPECT_REF(fo_node, 1);
3787 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3788 ok( r == S_OK, "ret %08x\n", r);
3789 EXPECT_REF(fo_list, 1);
3791 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3792 ok( r == S_OK, "ret %08x\n", r);
3793 EXPECT_REF(ba_node, 1);
3795 /* invalid parameter: NULL ptr */
3796 removed_node = (void*)0xdeadbeef;
3797 r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
3798 ok( r == E_INVALIDARG, "ret %08x\n", r );
3799 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3801 /* ba_node is a descendant of element, but not a direct child. */
3802 removed_node = (void*)0xdeadbeef;
3803 EXPECT_REF(ba_node, 1);
3804 EXPECT_CHILDREN(fo_node);
3805 r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
3806 ok( r == E_INVALIDARG, "ret %08x\n", r );
3807 ok( removed_node == NULL, "%p\n", removed_node );
3808 EXPECT_REF(ba_node, 1);
3809 EXPECT_CHILDREN(fo_node);
3811 EXPECT_REF(ba_node, 1);
3812 EXPECT_REF(fo_node, 1);
3813 r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
3814 ok( r == S_OK, "ret %08x\n", r);
3815 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
3816 EXPECT_REF(fo_node, 2);
3817 EXPECT_REF(ba_node, 1);
3819 /* try removing already removed child */
3820 temp_node = (void*)0xdeadbeef;
3821 r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
3822 ok( r == E_INVALIDARG, "ret %08x\n", r);
3823 ok( temp_node == NULL, "%p\n", temp_node );
3824 IXMLDOMNode_Release( fo_node );
3826 /* the removed node has no parent anymore */
3827 r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
3828 ok( r == S_FALSE, "ret %08x\n", r);
3829 ok( temp_node == NULL, "%p\n", temp_node );
3831 IXMLDOMNode_Release( removed_node );
3832 IXMLDOMNode_Release( ba_node );
3833 IXMLDOMNodeList_Release( fo_list );
3835 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3836 ok( r == S_OK, "ret %08x\n", r);
3838 r = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
3839 ok( r == S_OK, "ret %08x\n", r);
3841 /* MS quirk: passing wrong interface pointer works, too */
3842 r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
3843 ok( r == S_OK, "ret %08x\n", r);
3844 IXMLDOMElement_Release( lc_element );
3846 temp_node = (void*)0xdeadbeef;
3847 r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
3848 ok( r == S_FALSE, "ret %08x\n", r);
3849 ok( temp_node == NULL, "%p\n", temp_node );
3851 IXMLDOMNode_Release( lc_node );
3852 IXMLDOMNodeList_Release( root_list );
3853 IXMLDOMElement_Release( element );
3854 IXMLDOMDocument_Release( doc );
3856 free_bstrs();
3859 static void test_replaceChild(void)
3861 HRESULT r;
3862 VARIANT_BOOL b;
3863 IXMLDOMDocument *doc;
3864 IXMLDOMElement *element, *ba_element;
3865 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
3866 IXMLDOMNodeList *root_list, *fo_list;
3867 IUnknown * unk1, *unk2;
3868 LONG len;
3870 doc = create_document(&IID_IXMLDOMDocument);
3872 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3873 ok( r == S_OK, "loadXML failed\n");
3874 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3876 r = IXMLDOMDocument_get_documentElement( doc, &element );
3877 ok( r == S_OK, "ret %08x\n", r);
3879 r = IXMLDOMElement_get_childNodes( element, &root_list );
3880 ok( r == S_OK, "ret %08x\n", r);
3882 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3883 ok( r == S_OK, "ret %08x\n", r);
3885 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3886 ok( r == S_OK, "ret %08x\n", r);
3888 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3889 ok( r == S_OK, "ret %08x\n", r);
3891 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3892 ok( r == S_OK, "ret %08x\n", r);
3894 IXMLDOMNodeList_Release( fo_list );
3896 /* invalid parameter: NULL ptr for element to remove */
3897 removed_node = (void*)0xdeadbeef;
3898 r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3899 ok( r == E_INVALIDARG, "ret %08x\n", r );
3900 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3902 /* invalid parameter: NULL for replacement element. (Sic!) */
3903 removed_node = (void*)0xdeadbeef;
3904 r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3905 ok( r == E_INVALIDARG, "ret %08x\n", r );
3906 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3908 /* invalid parameter: OldNode is not a child */
3909 removed_node = (void*)0xdeadbeef;
3910 r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3911 ok( r == E_INVALIDARG, "ret %08x\n", r );
3912 ok( removed_node == NULL, "%p\n", removed_node );
3913 IXMLDOMNode_Release( lc_node );
3915 /* invalid parameter: would create loop */
3916 removed_node = (void*)0xdeadbeef;
3917 r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3918 ok( r == E_FAIL, "ret %08x\n", r );
3919 ok( removed_node == NULL, "%p\n", removed_node );
3921 r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
3922 ok( r == S_OK, "ret %08x\n", r );
3924 r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
3925 ok( r == S_OK, "ret %08x\n", r );
3927 /* ba_node and temp_node refer to the same node, yet they
3928 are different interface pointers */
3929 ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
3930 r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
3931 ok( r == S_OK, "ret %08x\n", r );
3932 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
3933 ok( r == S_OK, "ret %08x\n", r );
3934 todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
3936 IUnknown_Release( unk1 );
3937 IUnknown_Release( unk2 );
3939 /* ba_node should have been removed from below fo_node */
3940 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3941 ok( r == S_OK, "ret %08x\n", r );
3943 /* MS quirk: replaceChild also accepts elements instead of nodes */
3944 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
3945 ok( r == S_OK, "ret %08x\n", r );
3946 EXPECT_REF(ba_element, 2);
3948 removed_node = NULL;
3949 r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
3950 ok( r == S_OK, "ret %08x\n", r );
3951 ok( removed_node != NULL, "got %p\n", removed_node);
3952 EXPECT_REF(ba_element, 3);
3953 IXMLDOMElement_Release( ba_element );
3955 r = IXMLDOMNodeList_get_length( fo_list, &len);
3956 ok( r == S_OK, "ret %08x\n", r );
3957 ok( len == 0, "len %d\n", len);
3959 IXMLDOMNodeList_Release( fo_list );
3961 IXMLDOMNode_Release(ba_node);
3962 IXMLDOMNode_Release(fo_node);
3963 IXMLDOMNode_Release(temp_node);
3964 IXMLDOMNodeList_Release( root_list );
3965 IXMLDOMElement_Release( element );
3966 IXMLDOMDocument_Release( doc );
3968 free_bstrs();
3971 static void test_removeNamedItem(void)
3973 IXMLDOMDocument *doc;
3974 IXMLDOMElement *element;
3975 IXMLDOMNode *pr_node, *removed_node, *removed_node2;
3976 IXMLDOMNodeList *root_list;
3977 IXMLDOMNamedNodeMap * pr_attrs;
3978 VARIANT_BOOL b;
3979 BSTR str;
3980 LONG len;
3981 HRESULT r;
3983 doc = create_document(&IID_IXMLDOMDocument);
3985 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3986 ok( r == S_OK, "loadXML failed\n");
3987 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3989 r = IXMLDOMDocument_get_documentElement( doc, &element );
3990 ok( r == S_OK, "ret %08x\n", r);
3992 r = IXMLDOMElement_get_childNodes( element, &root_list );
3993 ok( r == S_OK, "ret %08x\n", r);
3995 r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
3996 ok( r == S_OK, "ret %08x\n", r);
3998 r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
3999 ok( r == S_OK, "ret %08x\n", r);
4001 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4002 ok( r == S_OK, "ret %08x\n", r);
4003 ok( len == 3, "length %d\n", len);
4005 removed_node = (void*)0xdeadbeef;
4006 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4007 ok ( r == E_INVALIDARG, "ret %08x\n", r);
4008 ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4010 removed_node = (void*)0xdeadbeef;
4011 str = SysAllocString(szvr);
4012 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4013 ok ( r == S_OK, "ret %08x\n", r);
4015 removed_node2 = (void*)0xdeadbeef;
4016 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4017 ok ( r == S_FALSE, "ret %08x\n", r);
4018 ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4020 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4021 ok( r == S_OK, "ret %08x\n", r);
4022 ok( len == 2, "length %d\n", len);
4024 r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4025 ok ( r == S_OK, "ret %08x\n", r);
4026 IXMLDOMNode_Release(removed_node);
4028 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4029 ok( r == S_OK, "ret %08x\n", r);
4030 ok( len == 3, "length %d\n", len);
4032 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4033 ok ( r == S_OK, "ret %08x\n", r);
4035 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4036 ok( r == S_OK, "ret %08x\n", r);
4037 ok( len == 2, "length %d\n", len);
4039 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4040 ok ( r == S_FALSE, "ret %08x\n", r);
4042 SysFreeString(str);
4044 IXMLDOMNamedNodeMap_Release( pr_attrs );
4045 IXMLDOMNode_Release( pr_node );
4046 IXMLDOMNodeList_Release( root_list );
4047 IXMLDOMElement_Release( element );
4048 IXMLDOMDocument_Release( doc );
4050 free_bstrs();
4053 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4054 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
4055 HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4056 DWORD expected2)
4058 DWORD enabled, supported;
4059 HRESULT hr;
4061 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4062 if (result == result2)
4063 ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4064 else
4065 ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4066 "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4068 supported = enabled = 0xCAFECAFE;
4069 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4070 ok(hr == S_OK, "ret %08x\n", hr );
4071 if (expected == expected2)
4072 ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4073 else
4074 ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4075 "Expected %08x, got %08x\n", expected2, enabled);
4077 /* reset the safety options */
4079 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4080 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4082 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4084 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4085 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4086 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4089 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4090 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4092 DWORD enabled = 0, supported = 0;
4093 HRESULT hr;
4095 /* get */
4096 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4097 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4098 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4099 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4101 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4102 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4103 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4104 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4105 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4106 "got %08x\n", supported);
4107 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4109 /* set -- individual flags */
4111 test_IObjectSafety_set(safety, S_OK, S_OK,
4112 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4113 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4115 test_IObjectSafety_set(safety, S_OK, S_OK,
4116 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4117 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4119 test_IObjectSafety_set(safety, S_OK, S_OK,
4120 INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4121 0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4123 /* set INTERFACE_USES_DISPEX */
4125 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4126 INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4127 0, 0);
4129 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4130 INTERFACE_USES_DISPEX, 0,
4131 0, 0);
4133 test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4134 0, INTERFACE_USES_DISPEX,
4135 0, 0);
4137 /* set option masking */
4139 test_IObjectSafety_set(safety, S_OK, S_OK,
4140 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4141 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4142 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4143 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4145 test_IObjectSafety_set(safety, S_OK, S_OK,
4146 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4147 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4148 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4149 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4151 test_IObjectSafety_set(safety, S_OK, S_OK,
4152 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4153 INTERFACE_USES_SECURITY_MANAGER,
4157 /* set -- inheriting previous settings */
4159 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4160 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4161 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4162 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4163 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4164 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4165 ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4166 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4167 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4168 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4169 "got %08x\n", supported);
4171 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4172 INTERFACESAFE_FOR_UNTRUSTED_DATA,
4173 INTERFACESAFE_FOR_UNTRUSTED_DATA);
4174 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4175 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4176 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4177 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4178 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4179 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4180 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4181 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4182 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4183 "got %08x\n", supported);
4186 static void test_IXMLDOMDocument2(void)
4188 static const WCHAR emptyW[] = {0};
4189 IXMLDOMDocument2 *doc2, *dtddoc2;
4190 IXMLDOMDocument *doc;
4191 IXMLDOMParseError* err;
4192 IDispatchEx *dispex;
4193 VARIANT_BOOL b;
4194 VARIANT var;
4195 HRESULT r;
4196 LONG res;
4198 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4200 doc = create_document(&IID_IXMLDOMDocument);
4201 dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4203 r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4204 ok( r == S_OK, "ret %08x\n", r );
4205 ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4207 ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4208 ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4209 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4211 err = NULL;
4212 ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4213 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4214 ok(err != NULL, "expected a pointer\n");
4215 if (err)
4217 res = 0;
4218 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4219 /* XML_E_NOTWF */
4220 ok(res == E_XML_NOTWF, "got %08x\n", res);
4221 IXMLDOMParseError_Release(err);
4224 r = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b );
4225 ok( r == S_OK, "loadXML failed\n");
4226 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4228 ole_check(IXMLDOMDocument_get_readyState(doc, &res));
4229 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4231 err = NULL;
4232 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4233 ok(err != NULL, "expected a pointer\n");
4234 if (err)
4236 res = 0;
4237 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4238 /* XML_E_NODTD */
4239 ok(res == E_XML_NODTD, "got %08x\n", res);
4240 IXMLDOMParseError_Release(err);
4243 r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4244 ok( r == S_OK, "ret %08x\n", r );
4245 if(r == S_OK)
4247 IDispatchEx_Release(dispex);
4250 /* we will check if the variant got cleared */
4251 IXMLDOMDocument2_AddRef(doc2);
4252 EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4254 V_VT(&var) = VT_UNKNOWN;
4255 V_UNKNOWN(&var) = (IUnknown *)doc2;
4257 /* invalid calls */
4258 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
4259 expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4260 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
4262 /* valid call */
4263 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4264 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4265 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4266 V_VT(&var) = VT_R4;
4268 /* the variant didn't get cleared*/
4269 expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4271 /* setProperty tests */
4272 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
4273 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
4274 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
4275 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4276 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4277 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4279 V_VT(&var) = VT_BSTR;
4280 V_BSTR(&var) = SysAllocString(emptyW);
4281 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4282 ok(r == S_OK, "got 0x%08x\n", r);
4283 VariantClear(&var);
4285 V_VT(&var) = VT_I2;
4286 V_I2(&var) = 0;
4287 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4288 ok(r == E_FAIL, "got 0x%08x\n", r);
4290 /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4291 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4292 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4293 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4295 IXMLDOMDocument2_Release( doc2 );
4296 IXMLDOMDocument_Release( doc );
4298 /* DTD validation */
4299 ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
4300 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
4301 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4302 err = NULL;
4303 ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
4304 ok(err != NULL, "expected pointer\n");
4305 if (err)
4307 res = 0;
4308 ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
4309 ok(res == 0, "got %08x\n", res);
4310 IXMLDOMParseError_Release(err);
4313 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
4314 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4315 err = NULL;
4316 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4317 ok(err != NULL, "expected pointer\n");
4318 if (err)
4320 res = 0;
4321 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4322 /* XML_ELEMENT_UNDECLARED */
4323 todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
4324 IXMLDOMParseError_Release(err);
4327 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
4328 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4329 err = NULL;
4330 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4331 ok(err != NULL, "expected pointer\n");
4332 if (err)
4334 res = 0;
4335 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4336 /* XML_ELEMENT_ID_NOT_FOUND */
4337 todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
4338 IXMLDOMParseError_Release(err);
4341 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
4342 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4343 err = NULL;
4344 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4345 ok(err != NULL, "expected pointer\n");
4346 if (err)
4348 res = 0;
4349 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4350 /* XML_EMPTY_NOT_ALLOWED */
4351 todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
4352 IXMLDOMParseError_Release(err);
4355 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
4356 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4357 err = NULL;
4358 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4359 ok(err != NULL, "expected pointer\n");
4360 if (err)
4362 res = 0;
4363 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4364 /* XML_ROOT_NAME_MISMATCH */
4365 todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
4366 IXMLDOMParseError_Release(err);
4369 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
4370 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4371 err = NULL;
4372 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4373 ok(err != NULL, "expected pointer\n");
4374 if (err)
4376 res = 0;
4377 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4378 /* XML_INVALID_CONTENT */
4379 todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
4380 IXMLDOMParseError_Release(err);
4383 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
4384 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4385 err = NULL;
4386 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4387 ok(err != NULL, "expected pointer\n");
4388 if (err)
4390 res = 0;
4391 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4392 /* XML_ATTRIBUTE_NOT_DEFINED */
4393 todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
4394 IXMLDOMParseError_Release(err);
4397 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
4398 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4399 err = NULL;
4400 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4401 ok(err != NULL, "expected pointer\n");
4402 if (err)
4404 res = 0;
4405 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4406 /* XML_ATTRIBUTE_FIXED */
4407 todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
4408 IXMLDOMParseError_Release(err);
4411 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
4412 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4413 err = NULL;
4414 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4415 ok(err != NULL, "expected pointer\n");
4416 if (err)
4418 res = 0;
4419 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4420 /* XML_ATTRIBUTE_VALUE */
4421 todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
4422 IXMLDOMParseError_Release(err);
4425 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
4426 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4427 err = NULL;
4428 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4429 ok(err != NULL, "expected pointer\n");
4430 if (err)
4432 res = 0;
4433 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4434 /* XML_ILLEGAL_TEXT */
4435 todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
4436 IXMLDOMParseError_Release(err);
4439 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
4440 ok( b == VARIANT_TRUE, "failed to load XML string\n");
4441 err = NULL;
4442 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4443 ok(err != NULL, "expected pointer\n");
4444 if (err)
4446 res = 0;
4447 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4448 /* XML_REQUIRED_ATTRIBUTE_MISSING */
4449 todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
4450 IXMLDOMParseError_Release(err);
4453 IXMLDOMDocument2_Release( dtddoc2 );
4454 free_bstrs();
4457 #define helper_ole_check(expr) { \
4458 HRESULT r = expr; \
4459 ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
4462 #define helper_ole_check_ver(expr) { \
4463 HRESULT r = expr; \
4464 ok_(__FILE__, line)(r == S_OK, "-> %i (%s): " #expr " returned %08x\n", __LINE__, ver, r); \
4467 #define helper_expect_list_and_release(list, expstr) { \
4468 char *str = list_to_string(list); \
4469 ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i (%s): Invalid node list: %s, expected %s\n", __LINE__, ver, str, expstr); \
4470 if (list) IXMLDOMNodeList_Release(list); \
4473 #define helper_expect_bstr_and_release(bstr, str) { \
4474 ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
4475 "=> %i (%s): got %s\n", __LINE__, ver, wine_dbgstr_w(bstr)); \
4476 SysFreeString(bstr); \
4479 #define check_ws_ignored(ver, doc, str) _check_ws_ignored(__LINE__, ver, doc, str)
4480 static inline void _check_ws_ignored(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4482 IXMLDOMNode *node1, *node2;
4483 IXMLDOMNodeList *list;
4484 BSTR bstr;
4486 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4487 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4488 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4489 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4490 helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1");
4492 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4493 helper_expect_list_and_release(list,
4494 "[4]1.E1.E5.E1.E2.D1 T2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 "
4495 "E4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1 E6.E1.E5.E1.E2.D1");
4496 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4497 if (str)
4499 helper_expect_bstr_and_release(bstr, str);
4501 else
4503 helper_expect_bstr_and_release(bstr, " This is a description.");
4505 IXMLDOMNode_Release(node1);
4507 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4508 helper_expect_list_and_release(list,
4509 "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 "
4510 "E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1");
4511 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4512 helper_expect_bstr_and_release(bstr,
4513 "\n This is a description with preserved whitespace. \n ");
4514 IXMLDOMNode_Release(node2);
4517 #define check_ws_preserved(ver, doc, str) _check_ws_preserved(__LINE__, ver, doc, str)
4518 static inline void _check_ws_preserved(int line, const char *ver, IXMLDOMDocument2* doc, char const* str)
4520 IXMLDOMNode *node1, *node2;
4521 IXMLDOMNodeList *list;
4522 BSTR bstr;
4524 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
4525 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1));
4526 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2));
4527 helper_ole_check_ver(IXMLDOMNodeList_reset(list));
4528 helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1");
4530 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list));
4531 helper_expect_list_and_release(list,
4532 "T1.E2.E10.E2.E2.D1 [4]2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 "
4533 "E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 "
4534 "E7.E2.E10.E2.E2.D1 E8.E2.E10.E2.E2.D1 T9.E2.E10.E2.E2.D1");
4535 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr));
4536 if (str)
4538 helper_expect_bstr_and_release(bstr, str);
4540 else
4542 helper_expect_bstr_and_release(bstr, "\n This is a description. \n ");
4544 IXMLDOMNode_Release(node1);
4546 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list));
4547 helper_expect_list_and_release(list,
4548 "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 "
4549 "E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1");
4550 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr));
4551 helper_expect_bstr_and_release(bstr,
4552 "\n This is a description with preserved whitespace. \n ");
4553 IXMLDOMNode_Release(node2);
4556 static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
4558 static const WCHAR b1_p[] = {' ','T','e','x','t',' ','A',' ','e','n','d',' ',0};
4559 static const WCHAR b1_i[] = {'T','e','x','t',' ','A',' ','e','n','d',0};
4560 static const WCHAR b2_p[] = {'A','B',' ','C',' ',0};
4561 static const WCHAR b2_i[] = {'A','B',' ','C',0};
4562 IXMLDOMNodeList *list;
4563 IXMLDOMElement *root;
4564 IXMLDOMNode *node;
4565 const WCHAR *text;
4566 VARIANT_BOOL b;
4567 HRESULT hr;
4568 BSTR s;
4570 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, preserve);
4571 ok(hr == S_OK, "got 0x%08x\n", hr);
4573 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(charrefsxml), &b);
4574 ok(hr == S_OK, "got 0x%08x\n", hr);
4576 hr = IXMLDOMDocument2_get_documentElement(doc, &root);
4577 ok(hr == S_OK, "got 0x%08x\n", hr);
4579 hr = IXMLDOMElement_get_childNodes(root, &list);
4580 ok(hr == S_OK, "got 0x%08x\n", hr);
4581 IXMLDOMElement_Release(root);
4583 text = preserve == VARIANT_TRUE ? b1_p : b1_i;
4584 hr = IXMLDOMNodeList_get_item(list, 0, &node);
4585 ok(hr == S_OK, "got 0x%08x\n", hr);
4586 hr = IXMLDOMNode_get_text(node, &s);
4587 ok(hr == S_OK, "got 0x%08x\n", hr);
4588 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4589 SysFreeString(s);
4590 IXMLDOMNode_Release(node);
4592 text = preserve == VARIANT_TRUE ? b2_p : b2_i;
4593 hr = IXMLDOMNodeList_get_item(list, 1, &node);
4594 ok(hr == S_OK, "got 0x%08x\n", hr);
4595 hr = IXMLDOMNode_get_text(node, &s);
4596 ok(hr == S_OK, "got 0x%08x\n", hr);
4597 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
4598 SysFreeString(s);
4599 IXMLDOMNode_Release(node);
4601 IXMLDOMNodeList_Release(list);
4604 struct whitespace_t {
4605 const CLSID *clsid;
4606 const char *name;
4609 static const struct whitespace_t whitespace_test_data[] = {
4610 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
4611 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
4612 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
4613 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
4614 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
4615 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
4616 { 0 }
4619 static void test_whitespace(void)
4621 const struct whitespace_t *class_ptr = whitespace_test_data;
4623 while (class_ptr->clsid)
4625 IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
4626 IXMLDOMNodeList *list;
4627 IXMLDOMElement *root;
4628 VARIANT_BOOL b;
4629 HRESULT hr;
4630 LONG len;
4632 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument2))
4634 class_ptr++;
4635 continue;
4638 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4639 &IID_IXMLDOMDocument2, (void**)&doc1);
4640 ok(hr == S_OK, "got 0x%08x\n", hr);
4642 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
4643 &IID_IXMLDOMDocument2, (void**)&doc2);
4644 ok(hr == S_OK, "got 0x%08x\n", hr);
4646 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
4647 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
4648 ok(b == VARIANT_FALSE, "expected false\n");
4649 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
4650 ok(b == VARIANT_TRUE, "expected true\n");
4652 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
4653 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4654 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
4655 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4657 /* switch to XPath */
4658 ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4659 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4661 check_ws_ignored(class_ptr->name, doc1, NULL);
4662 check_ws_preserved(class_ptr->name, doc2, NULL);
4664 /* new instances copy the property */
4665 ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
4666 ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
4668 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
4669 ok(b == VARIANT_FALSE, "expected false\n");
4670 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
4671 ok(b == VARIANT_TRUE, "expected true\n");
4673 check_ws_ignored(class_ptr->name, doc3, NULL);
4674 check_ws_preserved(class_ptr->name, doc4, NULL);
4676 /* setting after loading xml affects trimming of leading/trailing ws only */
4677 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
4678 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
4680 /* the trailing "\n " isn't there, because it was ws-only node */
4681 check_ws_ignored(class_ptr->name, doc1, " This is a description. ");
4682 check_ws_preserved(class_ptr->name, doc2, " This is a description.");
4684 /* it takes effect on reload */
4685 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
4686 ok(b == VARIANT_TRUE, "expected true\n");
4687 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
4688 ok(b == VARIANT_FALSE, "expected false\n");
4690 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
4691 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4692 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
4693 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4695 check_ws_preserved(class_ptr->name, doc1, NULL);
4696 check_ws_ignored(class_ptr->name, doc2, NULL);
4698 /* other instances follow suit */
4699 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
4700 ok(b == VARIANT_TRUE, "expected true\n");
4701 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
4702 ok(b == VARIANT_FALSE, "expected false\n");
4704 check_ws_preserved(class_ptr->name, doc3, NULL);
4705 check_ws_ignored(class_ptr->name, doc4, NULL);
4707 IXMLDOMDocument2_Release(doc2);
4708 IXMLDOMDocument2_Release(doc3);
4709 IXMLDOMDocument2_Release(doc4);
4711 /* text with char references */
4712 test_preserve_charref(doc1, VARIANT_TRUE);
4713 test_preserve_charref(doc1, VARIANT_FALSE);
4715 /* formatting whitespaces */
4716 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
4717 ok(hr == S_OK, "got 0x%08x\n", hr);
4719 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
4720 ok(hr == S_OK, "got 0x%08x\n", hr);
4721 ok(b == VARIANT_TRUE, "for %x\n", b);
4723 hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
4724 ok(hr == S_OK, "got 0x%08x\n", hr);
4725 hr = IXMLDOMElement_get_childNodes(root, &list);
4726 ok(hr == S_OK, "got 0x%08x\n", hr);
4727 len = 0;
4728 hr = IXMLDOMNodeList_get_length(list, &len);
4729 ok(hr == S_OK, "got 0x%08x\n", hr);
4730 ok(len == 3, "got %d\n", len);
4731 IXMLDOMNodeList_Release(list);
4732 IXMLDOMElement_Release(root);
4734 IXMLDOMDocument2_Release(doc1);
4736 free_bstrs();
4738 class_ptr++;
4742 typedef struct {
4743 const GUID *clsid;
4744 const char *name;
4745 const char *ns;
4746 HRESULT hr;
4747 } selection_ns_t;
4749 /* supposed to be tested with szExampleXML */
4750 static const selection_ns_t selection_ns_data[] = {
4751 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4752 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4753 { &CLSID_DOMDocument, "CLSID_DOMDocument", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4754 { &CLSID_DOMDocument, "CLSID_DOMDocument", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4756 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4757 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4758 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4759 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4761 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4762 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4763 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4764 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4766 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4767 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4768 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4769 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4771 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4772 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4773 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
4774 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK },
4776 { NULL }
4779 typedef struct {
4780 const char *query;
4781 const char *list;
4782 } xpath_test_t;
4784 static const xpath_test_t xpath_test[] = {
4785 { "*/a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4786 { "*/b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4787 { "*/c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4788 { "*/d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4789 { "//a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
4790 { "//b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
4791 { "//c", "E3.E1.E2.D1 E3.E2.E2.D1" },
4792 { "//d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
4793 { "//c[@type]", "E3.E2.E2.D1" },
4794 { "//c[@type]/ancestor::node()[1]", "E2.E2.D1" },
4795 { "//c[@type]/ancestor-or-self::node()[1]", "E3.E2.E2.D1" },
4796 { "//c[@type]/attribute::node()[1]", "A'type'.E3.E2.E2.D1" },
4797 { "//c[@type]/child::node()[1]", "T1.E3.E2.E2.D1" },
4798 { "//c[@type]/descendant::node()[1]", "T1.E3.E2.E2.D1" },
4799 { "//c[@type]/descendant-or-self::node()[1]", "E3.E2.E2.D1" },
4800 { "//c[@type]/following::node()[1]", "E4.E2.E2.D1" },
4801 { "//c[@type]/following-sibling::node()[1]", "E4.E2.E2.D1" },
4802 { "//c[@type]/parent::node()[1]", "E2.E2.D1" },
4803 { "//c[@type]/preceding::node()[1]", "T1.E2.E2.E2.D1" },
4804 { "//c[@type]/self::node()[1]", "E3.E2.E2.D1" },
4805 { "child::*", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4806 { "child::node()", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
4807 { "child::text()", "" },
4808 { "child::*/..", "E2.D1" },
4809 { "child::*//@*/..", "E2.E5.E1.E2.D1 E2.E2.D1 E3.E2.E2.D1" },
4810 { "self::node()", "E2.D1" },
4811 { "ancestor::node()", "D1" },
4812 { "elem[c][last()]/a", "E1.E2.E2.D1"},
4813 { "ancestor-or-self::node()[1]", "E2.D1" },
4814 { "((//a)[1])[last()]", "E1.E1.E2.D1" },
4815 { "//elem[@*]", "E2.E2.D1" },
4816 { NULL }
4819 static void test_XPath(void)
4821 const selection_ns_t *ptr = selection_ns_data;
4822 const xpath_test_t *xptest = xpath_test;
4823 VARIANT var;
4824 VARIANT_BOOL b;
4825 IXMLDOMDocument2 *doc;
4826 IXMLDOMDocument *doc2;
4827 IXMLDOMNode *rootNode;
4828 IXMLDOMNode *elem1Node;
4829 IXMLDOMNode *node;
4830 IXMLDOMNodeList *list;
4831 IXMLDOMElement *elem;
4832 IXMLDOMAttribute *attr;
4833 DOMNodeType type;
4834 HRESULT hr;
4835 LONG len;
4836 BSTR str;
4838 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4839 doc = create_document(&IID_IXMLDOMDocument2);
4841 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
4842 EXPECT_HR(hr, S_OK);
4843 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4845 /* switch to XPath */
4846 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4848 /* some simple queries*/
4849 EXPECT_REF(doc, 1);
4850 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4851 EXPECT_HR(hr, S_OK);
4852 EXPECT_REF(doc, 1);
4853 EXPECT_LIST_LEN(list, 1);
4855 EXPECT_REF(list, 1);
4856 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4857 EXPECT_HR(hr, S_OK);
4858 EXPECT_REF(list, 1);
4859 EXPECT_REF(rootNode, 1);
4861 hr = IXMLDOMNodeList_reset(list);
4862 EXPECT_HR(hr, S_OK);
4863 expect_list_and_release(list, "E2.D1");
4865 /* peform xpath tests */
4866 for ( ; xptest->query ; xptest++ )
4868 char *str;
4870 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(xptest->query), &list);
4871 ok(hr == S_OK, "query evaluation failed for query=%s\n", xptest->query);
4873 if (hr != S_OK)
4874 continue;
4876 str = list_to_string(list);
4878 ok(!strcmp(str, xptest->list), "query=%s, invalid node list: \"%s\", expected \"%s\"\n",
4879 xptest->query, str, xptest->list);
4881 if (list)
4882 IXMLDOMNodeList_Release(list);
4885 if (0)
4887 /* namespace:: axis test is disabled until namespace definitions
4888 are supported as attribute nodes, currently it's another node type */
4889 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list);
4890 EXPECT_HR(hr, S_OK);
4891 len = -1;
4892 hr = IXMLDOMNodeList_get_length(list, &len);
4893 EXPECT_HR(hr, S_OK);
4894 ok(len == 2, "got %d\n", len);
4896 hr = IXMLDOMNodeList_nextNode(list, &node);
4897 EXPECT_HR(hr, S_OK);
4898 type = NODE_INVALID;
4899 hr = IXMLDOMNode_get_nodeType(node, &type);
4900 EXPECT_HR(hr, S_OK);
4901 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
4902 IXMLDOMNode_Release(node);
4904 IXMLDOMNodeList_Release(list);
4907 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
4908 expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
4910 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
4911 expect_list_and_release(list, "E3.E2.E2.D1");
4913 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
4914 /* using get_item for query results advances the position */
4915 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
4916 expect_node(node, "E2.E2.D1");
4917 IXMLDOMNode_Release(node);
4918 ole_check(IXMLDOMNodeList_nextNode(list, &node));
4919 expect_node(node, "E4.E2.D1");
4920 IXMLDOMNode_Release(node);
4921 ole_check(IXMLDOMNodeList_reset(list));
4922 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
4924 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
4925 expect_list_and_release(list, "E2.D1");
4927 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
4928 ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
4929 ole_check(IXMLDOMNodeList_reset(list));
4930 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
4932 /* select an attribute */
4933 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
4934 expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
4936 /* would evaluate to a number */
4937 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
4938 /* would evaluate to a boolean */
4939 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
4940 /* would evaluate to a string */
4941 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
4943 /* no results */
4944 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
4945 expect_list_and_release(list, "");
4946 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("elem//c"), &list));
4947 expect_list_and_release(list, "");
4948 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem[4]"), &list));
4949 expect_list_and_release(list, "");
4950 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
4951 expect_list_and_release(list, "");
4953 /* foo undeclared in document node */
4954 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4955 /* undeclared in <root> node */
4956 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
4957 /* undeclared in <elem> node */
4958 ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
4959 /* but this trick can be used */
4960 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
4961 expect_list_and_release(list, "E3.E4.E2.D1");
4963 /* it has to be declared in SelectionNamespaces */
4964 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4965 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
4967 /* now the namespace can be used */
4968 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
4969 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4970 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
4971 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4972 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
4973 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4974 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
4975 expect_list_and_release(list, "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1");
4977 /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
4978 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4979 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
4981 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4983 VariantInit(&var);
4984 ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
4985 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4986 if (V_VT(&var) == VT_BSTR)
4987 expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
4989 /* extra attributes - same thing*/
4990 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4991 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
4992 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4994 IXMLDOMNode_Release(rootNode);
4995 IXMLDOMNode_Release(elem1Node);
4997 /* alter document with already built list */
4998 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4999 EXPECT_HR(hr, S_OK);
5000 EXPECT_LIST_LEN(list, 1);
5002 hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
5003 EXPECT_HR(hr, S_OK);
5004 EXPECT_REF(rootNode, 1);
5005 EXPECT_REF(doc, 1);
5007 hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
5008 EXPECT_HR(hr, S_OK);
5009 IXMLDOMNode_Release(rootNode);
5011 EXPECT_LIST_LEN(list, 1);
5013 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5014 EXPECT_HR(hr, S_OK);
5015 EXPECT_REF(rootNode, 1);
5017 IXMLDOMNodeList_Release(list);
5019 hr = IXMLDOMNode_get_nodeName(rootNode, &str);
5020 EXPECT_HR(hr, S_OK);
5021 ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
5022 SysFreeString(str);
5023 IXMLDOMNode_Release(rootNode);
5025 /* alter node from list and get it another time */
5026 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5027 EXPECT_HR(hr, S_OK);
5028 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5030 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5031 EXPECT_HR(hr, S_OK);
5032 EXPECT_LIST_LEN(list, 1);
5034 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5035 EXPECT_HR(hr, S_OK);
5037 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5038 EXPECT_HR(hr, S_OK);
5040 V_VT(&var) = VT_I2;
5041 V_I2(&var) = 1;
5042 hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
5043 EXPECT_HR(hr, S_OK);
5044 IXMLDOMElement_Release(elem);
5045 IXMLDOMNode_Release(rootNode);
5047 /* now check attribute to be present */
5048 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5049 EXPECT_HR(hr, S_OK);
5051 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
5052 EXPECT_HR(hr, S_OK);
5054 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5055 EXPECT_HR(hr, S_OK);
5056 IXMLDOMAttribute_Release(attr);
5058 IXMLDOMElement_Release(elem);
5059 IXMLDOMNode_Release(rootNode);
5061 /* and now check for attribute in original document */
5062 hr = IXMLDOMDocument2_get_documentElement(doc, &elem);
5063 EXPECT_HR(hr, S_OK);
5065 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
5066 EXPECT_HR(hr, S_OK);
5067 IXMLDOMAttribute_Release(attr);
5069 IXMLDOMElement_Release(elem);
5071 /* attach node from list to another document */
5072 doc2 = create_document(&IID_IXMLDOMDocument);
5074 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5075 EXPECT_HR(hr, S_OK);
5076 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5078 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
5079 EXPECT_HR(hr, S_OK);
5080 EXPECT_LIST_LEN(list, 1);
5082 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
5083 EXPECT_HR(hr, S_OK);
5084 EXPECT_REF(rootNode, 1);
5086 hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
5087 EXPECT_HR(hr, S_OK);
5088 EXPECT_REF(rootNode, 1);
5089 EXPECT_REF(doc2, 1);
5090 EXPECT_REF(list, 1);
5092 EXPECT_LIST_LEN(list, 1);
5094 IXMLDOMNode_Release(rootNode);
5095 IXMLDOMNodeList_Release(list);
5096 IXMLDOMDocument_Release(doc2);
5097 IXMLDOMDocument2_Release(doc);
5099 while (ptr->clsid)
5101 if (is_clsid_supported(ptr->clsid, &IID_IXMLDOMDocument2))
5103 hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
5104 ok(hr == S_OK, "got 0x%08x\n", hr);
5106 else
5108 ptr++;
5109 continue;
5112 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
5113 EXPECT_HR(hr, S_OK);
5114 ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
5116 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
5117 EXPECT_HR(hr, S_OK);
5119 V_VT(&var) = VT_BSTR;
5120 V_BSTR(&var) = _bstr_(ptr->ns);
5122 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
5123 ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
5125 V_VT(&var) = VT_EMPTY;
5126 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
5127 EXPECT_HR(hr, S_OK);
5128 ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
5129 ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
5130 VariantClear(&var);
5132 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
5133 EXPECT_HR(hr, S_OK);
5134 if (hr == S_OK)
5135 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
5137 IXMLDOMDocument2_Release(doc);
5138 ptr++;
5139 free_bstrs();
5142 free_bstrs();
5145 static void test_cloneNode(void )
5147 IXMLDOMDocument2 *doc, *doc_clone;
5148 IXMLDOMDocument *doc2;
5149 VARIANT_BOOL b;
5150 IXMLDOMNodeList *pList;
5151 IXMLDOMNamedNodeMap *mapAttr;
5152 LONG length, length1;
5153 LONG attr_cnt, attr_cnt1;
5154 IXMLDOMNode *node, *attr;
5155 IXMLDOMNode *node_clone;
5156 IXMLDOMNode *node_first;
5157 VARIANT v;
5158 HRESULT hr;
5160 doc = create_document(&IID_IXMLDOMDocument2);
5162 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b);
5163 ok(hr == S_OK, "got 0x%08x\n", hr);
5164 ok(b == VARIANT_TRUE, "failed to load XML string\n");
5166 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v);
5167 ok(hr == S_OK, "got 0x%08x\n", hr);
5168 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XSLPattern")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5169 VariantClear(&v);
5171 V_BSTR(&v) = _bstr_("XPath");
5172 V_VT(&v) = VT_BSTR;
5173 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v);
5174 ok(hr == S_OK, "got 0x%08x\n", hr);
5175 VariantClear(&v);
5177 /* clone document node */
5178 hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node);
5179 ok( hr == S_OK, "ret %08x\n", hr );
5180 ok( node != NULL, "node %p\n", node );
5182 hr = IXMLDOMNode_get_childNodes(node, &pList);
5183 ok( hr == S_OK, "ret %08x\n", hr );
5184 length = 0;
5185 hr = IXMLDOMNodeList_get_length(pList, &length);
5186 ok( hr == S_OK, "ret %08x\n", hr );
5187 ok(length == 2, "got %d\n", length);
5188 IXMLDOMNodeList_Release(pList);
5190 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone);
5191 ok(hr == S_OK, "got 0x%08x\n", hr);
5193 /* cloned document inherits properties */
5194 hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v);
5195 ok(hr == S_OK, "got 0x%08x\n", hr);
5196 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XPath")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v)));
5197 VariantClear(&v);
5199 IXMLDOMDocument2_Release(doc_clone);
5200 IXMLDOMNode_Release(node);
5202 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node);
5203 ok( hr == S_OK, "ret %08x\n", hr );
5204 ok( node != NULL, "node %p\n", node );
5206 /* Check invalid parameter */
5207 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
5208 ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5210 /* All Children */
5211 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
5212 ok( hr == S_OK, "ret %08x\n", hr );
5213 ok( node_clone != NULL, "node %p\n", node );
5215 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5216 ok( hr == S_OK, "ret %08x\n", hr );
5217 hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
5218 ok( hr == S_OK, "ret %08x\n", hr );
5219 IXMLDOMDocument_Release(doc2);
5220 IXMLDOMNode_Release(node_first);
5222 hr = IXMLDOMNode_get_childNodes(node, &pList);
5223 ok( hr == S_OK, "ret %08x\n", hr );
5224 length = 0;
5225 hr = IXMLDOMNodeList_get_length(pList, &length);
5226 ok( hr == S_OK, "ret %08x\n", hr );
5227 ok(length == 1, "got %d\n", length);
5228 IXMLDOMNodeList_Release(pList);
5230 hr = IXMLDOMNode_get_attributes(node, &mapAttr);
5231 ok( hr == S_OK, "ret %08x\n", hr );
5232 attr_cnt = 0;
5233 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
5234 ok( hr == S_OK, "ret %08x\n", hr );
5235 ok(attr_cnt == 3, "got %d\n", attr_cnt);
5236 IXMLDOMNamedNodeMap_Release(mapAttr);
5238 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5239 ok( hr == S_OK, "ret %08x\n", hr );
5240 length1 = 0;
5241 hr = IXMLDOMNodeList_get_length(pList, &length1);
5242 ok(length1 == 1, "got %d\n", length1);
5243 ok( hr == S_OK, "ret %08x\n", hr );
5244 IXMLDOMNodeList_Release(pList);
5246 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5247 ok( hr == S_OK, "ret %08x\n", hr );
5248 attr_cnt1 = 0;
5249 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5250 ok( hr == S_OK, "ret %08x\n", hr );
5251 ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
5252 /* now really get some attributes from cloned element */
5253 attr = NULL;
5254 hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr);
5255 ok(hr == S_OK, "ret %08x\n", hr);
5256 IXMLDOMNode_Release(attr);
5257 IXMLDOMNamedNodeMap_Release(mapAttr);
5259 ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
5260 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5261 IXMLDOMNode_Release(node_clone);
5263 /* No Children */
5264 hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
5265 ok( hr == S_OK, "ret %08x\n", hr );
5266 ok( node_clone != NULL, "node %p\n", node );
5268 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
5269 ok(hr == S_FALSE, "ret %08x\n", hr );
5271 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
5272 ok(hr == S_OK, "ret %08x\n", hr );
5273 hr = IXMLDOMNodeList_get_length(pList, &length1);
5274 ok(hr == S_OK, "ret %08x\n", hr );
5275 ok( length1 == 0, "Length should be 0 (%d)\n", length1);
5276 IXMLDOMNodeList_Release(pList);
5278 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
5279 ok(hr == S_OK, "ret %08x\n", hr );
5280 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
5281 ok(hr == S_OK, "ret %08x\n", hr );
5282 ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
5283 IXMLDOMNamedNodeMap_Release(mapAttr);
5285 ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
5286 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
5287 IXMLDOMNode_Release(node_clone);
5289 IXMLDOMNode_Release(node);
5290 IXMLDOMDocument2_Release(doc);
5291 free_bstrs();
5294 static void test_xmlTypes(void)
5296 IXMLDOMDocument *doc;
5297 IXMLDOMElement *pRoot;
5298 HRESULT hr;
5299 IXMLDOMComment *pComment;
5300 IXMLDOMElement *pElement;
5301 IXMLDOMAttribute *pAttribute;
5302 IXMLDOMNamedNodeMap *pAttribs;
5303 IXMLDOMCDATASection *pCDataSec;
5304 IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
5305 IXMLDOMDocumentFragment *pDocFrag = NULL;
5306 IXMLDOMEntityReference *pEntityRef = NULL;
5307 BSTR str;
5308 IXMLDOMNode *pNextChild;
5309 VARIANT v;
5310 LONG len = 0;
5312 doc = create_document(&IID_IXMLDOMDocument);
5314 hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
5315 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5317 pNextChild = (void*)0xdeadbeef;
5318 hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
5319 ok(hr == S_FALSE, "ret %08x\n", hr );
5320 ok(pNextChild == NULL, "pDocChild not NULL\n");
5322 /* test previous Sibling */
5323 hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
5324 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5326 pNextChild = (void*)0xdeadbeef;
5327 hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
5328 ok(hr == S_FALSE, "ret %08x\n", hr );
5329 ok(pNextChild == NULL, "pNextChild not NULL\n");
5331 /* test get_dataType */
5332 V_VT(&v) = VT_EMPTY;
5333 hr = IXMLDOMDocument_get_dataType(doc, &v);
5334 ok(hr == S_FALSE, "ret %08x\n", hr );
5335 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
5336 VariantClear(&v);
5338 /* test implementation */
5339 hr = IXMLDOMDocument_get_implementation(doc, NULL);
5340 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5342 hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
5343 ok(hr == S_OK, "ret %08x\n", hr );
5344 if(hr == S_OK)
5346 VARIANT_BOOL hasFeature = VARIANT_TRUE;
5347 BSTR sEmpty = SysAllocStringLen(NULL, 0);
5349 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
5350 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5352 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
5353 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5355 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5356 ok(hr == S_OK, "ret %08x\n", hr );
5357 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5359 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
5360 ok(hr == S_OK, "ret %08x\n", hr );
5361 ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
5363 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
5364 ok(hr == S_OK, "ret %08x\n", hr );
5365 ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
5367 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
5368 ok(hr == S_OK, "ret %08x\n", hr );
5369 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5371 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
5372 ok(hr == S_OK, "ret %08x\n", hr );
5373 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5375 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
5376 ok(hr == S_OK, "ret %08x\n", hr );
5377 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5379 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
5380 ok(hr == S_OK, "ret %08x\n", hr );
5381 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
5383 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
5384 ok(hr == S_OK, "ret %08x\n", hr );
5385 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
5387 SysFreeString(sEmpty);
5388 IXMLDOMImplementation_Release(pIXMLDOMImplementation);
5391 pRoot = (IXMLDOMElement*)0x1;
5392 hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
5393 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5394 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5396 pRoot = (IXMLDOMElement*)0x1;
5397 hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
5398 ok(hr == E_FAIL, "ret %08x\n", hr );
5399 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
5401 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5402 ok(hr == S_OK, "ret %08x\n", hr );
5403 if(hr == S_OK)
5405 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5406 ok(hr == S_OK, "ret %08x\n", hr );
5407 if(hr == S_OK)
5409 /* Comment */
5410 str = SysAllocString(szComment);
5411 hr = IXMLDOMDocument_createComment(doc, str, &pComment);
5412 SysFreeString(str);
5413 ok(hr == S_OK, "ret %08x\n", hr );
5414 if(hr == S_OK)
5416 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
5417 ok(hr == S_OK, "ret %08x\n", hr );
5419 hr = IXMLDOMComment_get_nodeName(pComment, &str);
5420 ok(hr == S_OK, "ret %08x\n", hr );
5421 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
5422 SysFreeString(str);
5424 hr = IXMLDOMComment_get_xml(pComment, &str);
5425 ok(hr == S_OK, "ret %08x\n", hr );
5426 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
5427 SysFreeString(str);
5429 /* put data Tests */
5430 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
5431 ok(hr == S_OK, "ret %08x\n", hr );
5433 /* get data Tests */
5434 hr = IXMLDOMComment_get_data(pComment, &str);
5435 ok(hr == S_OK, "ret %08x\n", hr );
5436 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
5437 SysFreeString(str);
5439 /* Confirm XML text is good */
5440 hr = IXMLDOMComment_get_xml(pComment, &str);
5441 ok(hr == S_OK, "ret %08x\n", hr );
5442 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
5443 SysFreeString(str);
5445 /* Confirm we get the put_data Text back */
5446 hr = IXMLDOMComment_get_text(pComment, &str);
5447 ok(hr == S_OK, "ret %08x\n", hr );
5448 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
5449 SysFreeString(str);
5451 /* test length property */
5452 hr = IXMLDOMComment_get_length(pComment, &len);
5453 ok(hr == S_OK, "ret %08x\n", hr );
5454 ok(len == 21, "expected 21 got %d\n", len);
5456 /* test substringData */
5457 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
5458 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5460 /* test substringData - Invalid offset */
5461 str = (BSTR)&szElement;
5462 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
5463 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5464 ok( str == NULL, "incorrect string\n");
5466 /* test substringData - Invalid offset */
5467 str = (BSTR)&szElement;
5468 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
5469 ok(hr == S_FALSE, "ret %08x\n", hr );
5470 ok( str == NULL, "incorrect string\n");
5472 /* test substringData - Invalid size */
5473 str = (BSTR)&szElement;
5474 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
5475 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5476 ok( str == NULL, "incorrect string\n");
5478 /* test substringData - Invalid size */
5479 str = (BSTR)&szElement;
5480 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
5481 ok(hr == S_FALSE, "ret %08x\n", hr );
5482 ok( str == NULL, "incorrect string\n");
5484 /* test substringData - Start of string */
5485 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
5486 ok(hr == S_OK, "ret %08x\n", hr );
5487 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5488 SysFreeString(str);
5490 /* test substringData - Middle of string */
5491 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
5492 ok(hr == S_OK, "ret %08x\n", hr );
5493 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5494 SysFreeString(str);
5496 /* test substringData - End of string */
5497 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
5498 ok(hr == S_OK, "ret %08x\n", hr );
5499 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5500 SysFreeString(str);
5502 /* test appendData */
5503 hr = IXMLDOMComment_appendData(pComment, NULL);
5504 ok(hr == S_OK, "ret %08x\n", hr );
5506 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
5507 ok(hr == S_OK, "ret %08x\n", hr );
5509 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
5510 ok(hr == S_OK, "ret %08x\n", hr );
5512 hr = IXMLDOMComment_get_text(pComment, &str);
5513 ok(hr == S_OK, "ret %08x\n", hr );
5514 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5515 SysFreeString(str);
5517 /* test insertData */
5518 str = SysAllocStringLen(NULL, 0);
5519 hr = IXMLDOMComment_insertData(pComment, -1, str);
5520 ok(hr == S_OK, "ret %08x\n", hr );
5522 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
5523 ok(hr == S_OK, "ret %08x\n", hr );
5525 hr = IXMLDOMComment_insertData(pComment, 1000, str);
5526 ok(hr == S_OK, "ret %08x\n", hr );
5528 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
5529 ok(hr == S_OK, "ret %08x\n", hr );
5531 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
5532 ok(hr == S_OK, "ret %08x\n", hr );
5534 hr = IXMLDOMComment_insertData(pComment, 0, str);
5535 ok(hr == S_OK, "ret %08x\n", hr );
5536 SysFreeString(str);
5538 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
5539 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5541 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
5542 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5544 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
5545 ok(hr == S_OK, "ret %08x\n", hr );
5547 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
5548 ok(hr == S_OK, "ret %08x\n", hr );
5550 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
5551 ok(hr == S_OK, "ret %08x\n", hr );
5553 hr = IXMLDOMComment_get_text(pComment, &str);
5554 ok(hr == S_OK, "ret %08x\n", hr );
5555 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5556 SysFreeString(str);
5558 /* delete data */
5559 /* invalid arguments */
5560 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
5561 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5563 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
5564 ok(hr == S_OK, "ret %08x\n", hr );
5566 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
5567 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5569 hr = IXMLDOMComment_get_length(pComment, &len);
5570 ok(hr == S_OK, "ret %08x\n", hr );
5571 ok(len == 43, "expected 43 got %d\n", len);
5573 hr = IXMLDOMComment_deleteData(pComment, len, 1);
5574 ok(hr == S_OK, "ret %08x\n", hr );
5576 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
5577 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5579 /* delete from start */
5580 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
5581 ok(hr == S_OK, "ret %08x\n", hr );
5583 hr = IXMLDOMComment_get_length(pComment, &len);
5584 ok(hr == S_OK, "ret %08x\n", hr );
5585 ok(len == 38, "expected 38 got %d\n", len);
5587 hr = IXMLDOMComment_get_text(pComment, &str);
5588 ok(hr == S_OK, "ret %08x\n", hr );
5589 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5590 SysFreeString(str);
5592 /* delete from end */
5593 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
5594 ok(hr == S_OK, "ret %08x\n", hr );
5596 hr = IXMLDOMComment_get_length(pComment, &len);
5597 ok(hr == S_OK, "ret %08x\n", hr );
5598 ok(len == 35, "expected 35 got %d\n", len);
5600 hr = IXMLDOMComment_get_text(pComment, &str);
5601 ok(hr == S_OK, "ret %08x\n", hr );
5602 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5603 SysFreeString(str);
5605 /* delete from inside */
5606 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
5607 ok(hr == S_OK, "ret %08x\n", hr );
5609 hr = IXMLDOMComment_get_length(pComment, &len);
5610 ok(hr == S_OK, "ret %08x\n", hr );
5611 ok(len == 2, "expected 2 got %d\n", len);
5613 hr = IXMLDOMComment_get_text(pComment, &str);
5614 ok(hr == S_OK, "ret %08x\n", hr );
5615 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5616 SysFreeString(str);
5618 /* delete whole data ... */
5619 hr = IXMLDOMComment_get_length(pComment, &len);
5620 ok(hr == S_OK, "ret %08x\n", hr );
5622 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5623 ok(hr == S_OK, "ret %08x\n", hr );
5624 /* ... and try again with empty string */
5625 hr = IXMLDOMComment_deleteData(pComment, 0, len);
5626 ok(hr == S_OK, "ret %08x\n", hr );
5628 /* ::replaceData() */
5629 V_VT(&v) = VT_BSTR;
5630 V_BSTR(&v) = SysAllocString(szstr1);
5631 hr = IXMLDOMComment_put_nodeValue(pComment, v);
5632 ok(hr == S_OK, "ret %08x\n", hr );
5633 VariantClear(&v);
5635 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
5636 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5637 hr = IXMLDOMComment_get_text(pComment, &str);
5638 ok(hr == S_OK, "ret %08x\n", hr );
5639 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5640 SysFreeString(str);
5642 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
5643 ok(hr == S_OK, "ret %08x\n", hr );
5644 hr = IXMLDOMComment_get_text(pComment, &str);
5645 ok(hr == S_OK, "ret %08x\n", hr );
5646 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5647 SysFreeString(str);
5649 /* NULL pointer means delete */
5650 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
5651 ok(hr == S_OK, "ret %08x\n", hr );
5652 hr = IXMLDOMComment_get_text(pComment, &str);
5653 ok(hr == S_OK, "ret %08x\n", hr );
5654 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5655 SysFreeString(str);
5657 /* empty string means delete */
5658 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
5659 ok(hr == S_OK, "ret %08x\n", hr );
5660 hr = IXMLDOMComment_get_text(pComment, &str);
5661 ok(hr == S_OK, "ret %08x\n", hr );
5662 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5663 SysFreeString(str);
5665 /* zero count means insert */
5666 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
5667 ok(hr == S_OK, "ret %08x\n", hr );
5668 hr = IXMLDOMComment_get_text(pComment, &str);
5669 ok(hr == S_OK, "ret %08x\n", hr );
5670 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5671 SysFreeString(str);
5673 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
5674 ok(hr == S_OK, "ret %08x\n", hr );
5676 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
5677 ok(hr == S_OK, "ret %08x\n", hr );
5678 hr = IXMLDOMComment_get_text(pComment, &str);
5679 ok(hr == S_OK, "ret %08x\n", hr );
5680 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5681 SysFreeString(str);
5683 /* nonempty string, count greater than its length */
5684 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
5685 ok(hr == S_OK, "ret %08x\n", hr );
5686 hr = IXMLDOMComment_get_text(pComment, &str);
5687 ok(hr == S_OK, "ret %08x\n", hr );
5688 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5689 SysFreeString(str);
5691 /* nonempty string, count less than its length */
5692 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
5693 ok(hr == S_OK, "ret %08x\n", hr );
5694 hr = IXMLDOMComment_get_text(pComment, &str);
5695 ok(hr == S_OK, "ret %08x\n", hr );
5696 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5697 SysFreeString(str);
5699 IXMLDOMComment_Release(pComment);
5702 /* Element */
5703 str = SysAllocString(szElement);
5704 hr = IXMLDOMDocument_createElement(doc, str, &pElement);
5705 SysFreeString(str);
5706 ok(hr == S_OK, "ret %08x\n", hr );
5707 if(hr == S_OK)
5709 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5710 ok(hr == S_OK, "ret %08x\n", hr );
5712 hr = IXMLDOMElement_get_nodeName(pElement, &str);
5713 ok(hr == S_OK, "ret %08x\n", hr );
5714 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
5715 SysFreeString(str);
5717 hr = IXMLDOMElement_get_xml(pElement, &str);
5718 ok(hr == S_OK, "ret %08x\n", hr );
5719 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
5720 SysFreeString(str);
5722 /* Attribute */
5723 pAttribute = (IXMLDOMAttribute*)0x1;
5724 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
5725 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5726 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5728 pAttribute = (IXMLDOMAttribute*)0x1;
5729 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
5730 ok(hr == E_FAIL, "ret %08x\n", hr );
5731 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
5733 str = SysAllocString(szAttribute);
5734 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
5735 SysFreeString(str);
5736 ok(hr == S_OK, "ret %08x\n", hr );
5737 if(hr == S_OK)
5739 IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
5741 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
5742 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5744 pNextChild = (IXMLDOMNode *)0x1;
5745 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
5746 ok(hr == S_FALSE, "ret %08x\n", hr );
5747 ok(pNextChild == NULL, "pNextChild not NULL\n");
5749 /* test Previous Sibling*/
5750 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
5751 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5753 pNextChild = (IXMLDOMNode *)0x1;
5754 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
5755 ok(hr == S_FALSE, "ret %08x\n", hr );
5756 ok(pNextChild == NULL, "pNextChild not NULL\n");
5758 hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
5759 ok(hr == E_FAIL, "ret %08x\n", hr );
5760 ok(pNewChild == NULL, "pNewChild not NULL\n");
5762 hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
5763 ok(hr == S_OK, "ret %08x\n", hr );
5764 if ( hr == S_OK )
5766 hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
5767 ok(hr == S_OK, "ret %08x\n", hr );
5769 IXMLDOMNamedNodeMap_Release(pAttribs);
5772 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5773 ok(hr == S_OK, "ret %08x\n", hr );
5774 ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
5775 SysFreeString(str);
5777 /* test nodeName */
5778 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
5779 ok(hr == S_OK, "ret %08x\n", hr );
5780 ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
5781 SysFreeString(str);
5783 /* test name property */
5784 hr = IXMLDOMAttribute_get_name(pAttribute, &str);
5785 ok(hr == S_OK, "ret %08x\n", hr );
5786 ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
5787 SysFreeString(str);
5789 hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
5790 ok(hr == S_OK, "ret %08x\n", hr );
5791 ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
5792 SysFreeString(str);
5794 IXMLDOMAttribute_Release(pAttribute);
5796 /* Check Element again with the Add Attribute*/
5797 hr = IXMLDOMElement_get_xml(pElement, &str);
5798 ok(hr == S_OK, "ret %08x\n", hr );
5799 ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
5800 SysFreeString(str);
5803 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
5804 ok(hr == S_OK, "ret %08x\n", hr );
5806 hr = IXMLDOMElement_get_xml(pElement, &str);
5807 ok(hr == S_OK, "ret %08x\n", hr );
5808 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
5809 SysFreeString(str);
5811 /* Test for reversible escaping */
5812 str = SysAllocString( szStrangeChars );
5813 hr = IXMLDOMElement_put_text(pElement, str);
5814 ok(hr == S_OK, "ret %08x\n", hr );
5815 SysFreeString( str );
5817 hr = IXMLDOMElement_get_xml(pElement, &str);
5818 ok(hr == S_OK, "ret %08x\n", hr );
5819 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
5820 SysFreeString(str);
5822 hr = IXMLDOMElement_get_text(pElement, &str);
5823 ok(hr == S_OK, "ret %08x\n", hr );
5824 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
5825 SysFreeString(str);
5827 IXMLDOMElement_Release(pElement);
5830 /* CData Section */
5831 str = SysAllocString(szCData);
5832 hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
5833 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5835 hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
5836 SysFreeString(str);
5837 ok(hr == S_OK, "ret %08x\n", hr );
5838 if(hr == S_OK)
5840 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
5841 VARIANT var;
5843 VariantInit(&var);
5845 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
5846 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
5848 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
5849 ok(hr == S_OK, "ret %08x\n", hr );
5851 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
5852 ok(hr == S_OK, "ret %08x\n", hr );
5853 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
5854 SysFreeString(str);
5856 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
5857 ok(hr == S_OK, "ret %08x\n", hr );
5858 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
5859 SysFreeString(str);
5861 /* test lastChild */
5862 pNextChild = (IXMLDOMNode*)0x1;
5863 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
5864 ok(hr == S_FALSE, "ret %08x\n", hr );
5865 ok(pNextChild == NULL, "pNextChild not NULL\n");
5867 /* put data Tests */
5868 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
5869 ok(hr == S_OK, "ret %08x\n", hr );
5871 /* Confirm XML text is good */
5872 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
5873 ok(hr == S_OK, "ret %08x\n", hr );
5874 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
5875 SysFreeString(str);
5877 /* Confirm we get the put_data Text back */
5878 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5879 ok(hr == S_OK, "ret %08x\n", hr );
5880 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
5881 SysFreeString(str);
5883 /* test length property */
5884 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5885 ok(hr == S_OK, "ret %08x\n", hr );
5886 ok(len == 21, "expected 21 got %d\n", len);
5888 /* test get data */
5889 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
5890 ok(hr == S_OK, "ret %08x\n", hr );
5891 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
5892 SysFreeString(str);
5894 /* test substringData */
5895 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
5896 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5898 /* test substringData - Invalid offset */
5899 str = (BSTR)&szElement;
5900 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
5901 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5902 ok( str == NULL, "incorrect string\n");
5904 /* test substringData - Invalid offset */
5905 str = (BSTR)&szElement;
5906 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
5907 ok(hr == S_FALSE, "ret %08x\n", hr );
5908 ok( str == NULL, "incorrect string\n");
5910 /* test substringData - Invalid size */
5911 str = (BSTR)&szElement;
5912 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
5913 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5914 ok( str == NULL, "incorrect string\n");
5916 /* test substringData - Invalid size */
5917 str = (BSTR)&szElement;
5918 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
5919 ok(hr == S_FALSE, "ret %08x\n", hr );
5920 ok( str == NULL, "incorrect string\n");
5922 /* test substringData - Start of string */
5923 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
5924 ok(hr == S_OK, "ret %08x\n", hr );
5925 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
5926 SysFreeString(str);
5928 /* test substringData - Middle of string */
5929 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
5930 ok(hr == S_OK, "ret %08x\n", hr );
5931 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5932 SysFreeString(str);
5934 /* test substringData - End of string */
5935 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
5936 ok(hr == S_OK, "ret %08x\n", hr );
5937 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5938 SysFreeString(str);
5940 /* test appendData */
5941 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
5942 ok(hr == S_OK, "ret %08x\n", hr );
5944 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
5945 ok(hr == S_OK, "ret %08x\n", hr );
5947 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
5948 ok(hr == S_OK, "ret %08x\n", hr );
5950 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5951 ok(hr == S_OK, "ret %08x\n", hr );
5952 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5953 SysFreeString(str);
5955 /* test insertData */
5956 str = SysAllocStringLen(NULL, 0);
5957 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
5958 ok(hr == S_OK, "ret %08x\n", hr );
5960 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
5961 ok(hr == S_OK, "ret %08x\n", hr );
5963 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
5964 ok(hr == S_OK, "ret %08x\n", hr );
5966 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
5967 ok(hr == S_OK, "ret %08x\n", hr );
5969 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
5970 ok(hr == S_OK, "ret %08x\n", hr );
5972 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
5973 ok(hr == S_OK, "ret %08x\n", hr );
5974 SysFreeString(str);
5976 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
5977 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5979 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
5980 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5982 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
5983 ok(hr == S_OK, "ret %08x\n", hr );
5985 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
5986 ok(hr == S_OK, "ret %08x\n", hr );
5988 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
5989 ok(hr == S_OK, "ret %08x\n", hr );
5991 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5992 ok(hr == S_OK, "ret %08x\n", hr );
5993 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5994 SysFreeString(str);
5996 /* delete data */
5997 /* invalid arguments */
5998 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
5999 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6001 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
6002 ok(hr == S_OK, "ret %08x\n", hr );
6004 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
6005 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6007 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6008 ok(hr == S_OK, "ret %08x\n", hr );
6009 ok(len == 43, "expected 43 got %d\n", len);
6011 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
6012 ok(hr == S_OK, "ret %08x\n", hr );
6014 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
6015 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6017 /* delete from start */
6018 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
6019 ok(hr == S_OK, "ret %08x\n", hr );
6021 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6022 ok(hr == S_OK, "ret %08x\n", hr );
6023 ok(len == 38, "expected 38 got %d\n", len);
6025 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6026 ok(hr == S_OK, "ret %08x\n", hr );
6027 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6028 SysFreeString(str);
6030 /* delete from end */
6031 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
6032 ok(hr == S_OK, "ret %08x\n", hr );
6034 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6035 ok(hr == S_OK, "ret %08x\n", hr );
6036 ok(len == 35, "expected 35 got %d\n", len);
6038 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6039 ok(hr == S_OK, "ret %08x\n", hr );
6040 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6041 SysFreeString(str);
6043 /* delete from inside */
6044 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
6045 ok(hr == S_OK, "ret %08x\n", hr );
6047 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6048 ok(hr == S_OK, "ret %08x\n", hr );
6049 ok(len == 2, "expected 2 got %d\n", len);
6051 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6052 ok(hr == S_OK, "ret %08x\n", hr );
6053 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6054 SysFreeString(str);
6056 /* delete whole data ... */
6057 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
6058 ok(hr == S_OK, "ret %08x\n", hr );
6060 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6061 ok(hr == S_OK, "ret %08x\n", hr );
6063 /* ... and try again with empty string */
6064 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
6065 ok(hr == S_OK, "ret %08x\n", hr );
6067 /* ::replaceData() */
6068 V_VT(&v) = VT_BSTR;
6069 V_BSTR(&v) = SysAllocString(szstr1);
6070 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
6071 ok(hr == S_OK, "ret %08x\n", hr );
6072 VariantClear(&v);
6074 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
6075 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6076 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6077 ok(hr == S_OK, "ret %08x\n", hr );
6078 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6079 SysFreeString(str);
6081 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
6082 ok(hr == S_OK, "ret %08x\n", hr );
6083 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6084 ok(hr == S_OK, "ret %08x\n", hr );
6085 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6086 SysFreeString(str);
6088 /* NULL pointer means delete */
6089 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
6090 ok(hr == S_OK, "ret %08x\n", hr );
6091 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6092 ok(hr == S_OK, "ret %08x\n", hr );
6093 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6094 SysFreeString(str);
6096 /* empty string means delete */
6097 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
6098 ok(hr == S_OK, "ret %08x\n", hr );
6099 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6100 ok(hr == S_OK, "ret %08x\n", hr );
6101 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6102 SysFreeString(str);
6104 /* zero count means insert */
6105 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
6106 ok(hr == S_OK, "ret %08x\n", hr );
6107 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6108 ok(hr == S_OK, "ret %08x\n", hr );
6109 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6110 SysFreeString(str);
6112 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
6113 ok(hr == S_OK, "ret %08x\n", hr );
6115 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
6116 ok(hr == S_OK, "ret %08x\n", hr );
6117 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6118 ok(hr == S_OK, "ret %08x\n", hr );
6119 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6120 SysFreeString(str);
6122 /* nonempty string, count greater than its length */
6123 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
6124 ok(hr == S_OK, "ret %08x\n", hr );
6125 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6126 ok(hr == S_OK, "ret %08x\n", hr );
6127 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6128 SysFreeString(str);
6130 /* nonempty string, count less than its length */
6131 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
6132 ok(hr == S_OK, "ret %08x\n", hr );
6133 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
6134 ok(hr == S_OK, "ret %08x\n", hr );
6135 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
6136 SysFreeString(str);
6138 IXMLDOMCDATASection_Release(pCDataSec);
6141 /* Document Fragments */
6142 hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
6143 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6145 hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
6146 ok(hr == S_OK, "ret %08x\n", hr );
6147 if(hr == S_OK)
6149 IXMLDOMNode *node;
6151 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
6152 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6154 node = (IXMLDOMNode *)0x1;
6155 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
6156 ok(hr == S_FALSE, "ret %08x\n", hr );
6157 ok(node == NULL, "expected NULL, got %p\n", node);
6159 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
6160 ok(hr == S_OK, "ret %08x\n", hr );
6162 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
6163 ok(hr == S_OK, "ret %08x\n", hr );
6164 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
6165 SysFreeString(str);
6167 /* test next Sibling*/
6168 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
6169 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6171 node = (IXMLDOMNode *)0x1;
6172 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
6173 ok(hr == S_FALSE, "ret %08x\n", hr );
6174 ok(node == NULL, "next sibling not NULL\n");
6176 /* test Previous Sibling*/
6177 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
6178 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6180 node = (IXMLDOMNode *)0x1;
6181 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
6182 ok(hr == S_FALSE, "ret %08x\n", hr );
6183 ok(node == NULL, "previous sibling not NULL\n");
6185 IXMLDOMDocumentFragment_Release(pDocFrag);
6188 /* Entity References */
6189 hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
6190 ok(hr == E_FAIL, "ret %08x\n", hr );
6191 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
6192 ok(hr == E_FAIL, "ret %08x\n", hr );
6194 str = SysAllocString(szEntityRef);
6195 hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
6196 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6198 hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
6199 SysFreeString(str);
6200 ok(hr == S_OK, "ret %08x\n", hr );
6201 if(hr == S_OK)
6203 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
6204 ok(hr == S_OK, "ret %08x\n", hr );
6206 /* test get_xml*/
6207 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
6208 ok(hr == S_OK, "ret %08x\n", hr );
6209 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
6210 SysFreeString(str);
6212 IXMLDOMEntityReference_Release(pEntityRef);
6215 IXMLDOMElement_Release( pRoot );
6219 IXMLDOMDocument_Release(doc);
6221 free_bstrs();
6224 typedef struct {
6225 const char *name;
6226 const char *type;
6227 HRESULT hr;
6228 } put_datatype_t;
6230 /* Type test for elements only. Name passed into put_dataType is case-insensitive.
6231 So many of the names have been changed to reflect this. */
6232 static put_datatype_t put_datatype_data[] = {
6233 { "test_inval", "abcdefg", E_FAIL },
6234 { "test_bool", "Boolean", S_OK },
6235 { "test_string", "String", S_OK },
6236 { "test_number", "number", S_OK },
6237 { "test_int", "InT", S_OK },
6238 { "test_fixed", "fixed.14.4", S_OK },
6239 { "test_datetime", "DateTime", S_OK },
6240 { "test_datetimetz", "DateTime.tz", S_OK },
6241 { "test_date", "Date", S_OK },
6242 { "test_time", "Time", S_OK },
6243 { "test_timetz", "Time.tz", S_OK },
6244 { "test_I1", "I1", S_OK },
6245 { "test_I2", "I2", S_OK },
6246 { "test_I4", "I4", S_OK },
6247 { "test_UI1", "UI1", S_OK },
6248 { "test_UI2", "UI2", S_OK },
6249 { "test_UI4", "UI4", S_OK },
6250 { "test_r4", "r4", S_OK },
6251 { "test_r8", "r8", S_OK },
6252 { "test_float", "float", S_OK },
6253 { "test_uuid", "UuId", S_OK },
6254 { "test_binhex", "bin.hex", S_OK },
6255 { "test_binbase64", "bin.base64", S_OK },
6256 { NULL }
6259 typedef struct {
6260 DOMNodeType type;
6261 HRESULT hr;
6262 } put_datatype_notype_t;
6264 static put_datatype_notype_t put_dt_notype[] = {
6265 { NODE_PROCESSING_INSTRUCTION, E_FAIL },
6266 { NODE_DOCUMENT_FRAGMENT, E_FAIL },
6267 { NODE_ENTITY_REFERENCE, E_FAIL },
6268 { NODE_CDATA_SECTION, E_FAIL },
6269 { NODE_COMMENT, E_FAIL },
6270 { NODE_INVALID }
6273 static void test_put_dataType( void )
6275 const put_datatype_notype_t *ptr2 = put_dt_notype;
6276 const put_datatype_t *ptr = put_datatype_data;
6277 IXMLDOMElement *root, *element;
6278 BSTR nameW, type1W, type2W;
6279 IXMLDOMDocument *doc;
6280 HRESULT hr;
6282 doc = create_document(&IID_IXMLDOMDocument);
6284 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
6285 EXPECT_HR(hr, E_INVALIDARG);
6287 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6288 EXPECT_HR(hr, S_OK);
6290 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6291 EXPECT_HR(hr, S_OK);
6293 hr = IXMLDOMElement_put_dataType(root, NULL);
6294 EXPECT_HR(hr, E_INVALIDARG);
6296 while (ptr->name)
6298 hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element);
6299 EXPECT_HR(hr, S_OK);
6300 if(hr == S_OK)
6302 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6303 EXPECT_HR(hr, S_OK);
6305 hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type));
6306 ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr);
6308 IXMLDOMElement_Release(element);
6310 ptr++;
6313 /* check changing types */
6314 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element);
6315 EXPECT_HR(hr, S_OK);
6317 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL);
6318 EXPECT_HR(hr, S_OK);
6320 hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz"));
6321 EXPECT_HR(hr, S_OK);
6323 hr = IXMLDOMElement_put_dataType(element, _bstr_("string"));
6324 EXPECT_HR(hr, S_OK);
6326 IXMLDOMElement_Release(element);
6328 /* try to set type for node without a type */
6329 nameW = _bstr_("testname");
6330 type1W = _bstr_("string");
6331 type2W = _bstr_("number");
6332 while (ptr2->type != NODE_INVALID)
6334 IXMLDOMNode *node;
6335 VARIANT type;
6337 V_VT(&type) = VT_I2;
6338 V_I2(&type) = ptr2->type;
6340 hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node);
6341 EXPECT_HR(hr, S_OK);
6342 if(hr == S_OK)
6344 hr = IXMLDOMElement_appendChild(root, node, NULL);
6345 EXPECT_HR(hr, S_OK);
6347 hr = IXMLDOMNode_put_dataType(node, NULL);
6348 EXPECT_HR(hr, E_INVALIDARG);
6350 hr = IXMLDOMNode_put_dataType(node, type1W);
6351 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6352 hr = IXMLDOMNode_put_dataType(node, type2W);
6353 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr);
6355 IXMLDOMNode_Release(node);
6357 ptr2++;
6360 IXMLDOMElement_Release(root);
6361 IXMLDOMDocument_Release(doc);
6362 free_bstrs();
6365 static void test_save(void)
6367 IXMLDOMDocument *doc, *doc2;
6368 IXMLDOMElement *root;
6369 BSTR sOrig, sNew, filename;
6370 char buffer[100];
6371 IStream *stream;
6372 HGLOBAL global;
6373 VARIANT_BOOL b;
6374 DWORD read = 0;
6375 VARIANT dest;
6376 HANDLE hfile;
6377 HRESULT hr;
6378 char *ptr;
6380 doc = create_document(&IID_IXMLDOMDocument);
6381 doc2 = create_document(&IID_IXMLDOMDocument);
6383 /* save to IXMLDOMDocument */
6384 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
6385 EXPECT_HR(hr, S_OK);
6387 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
6388 EXPECT_HR(hr, S_OK);
6390 V_VT(&dest) = VT_UNKNOWN;
6391 V_UNKNOWN(&dest) = (IUnknown*)doc2;
6393 hr = IXMLDOMDocument_save(doc, dest);
6394 EXPECT_HR(hr, S_OK);
6396 hr = IXMLDOMDocument_get_xml(doc, &sOrig);
6397 EXPECT_HR(hr, S_OK);
6399 hr = IXMLDOMDocument_get_xml(doc2, &sNew);
6400 EXPECT_HR(hr, S_OK);
6402 ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n");
6404 SysFreeString(sOrig);
6405 SysFreeString(sNew);
6407 IXMLDOMElement_Release(root);
6408 IXMLDOMDocument_Release(doc2);
6410 /* save to path */
6411 V_VT(&dest) = VT_BSTR;
6412 V_BSTR(&dest) = _bstr_("test.xml");
6414 hr = IXMLDOMDocument_save(doc, dest);
6415 EXPECT_HR(hr, S_OK);
6417 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6418 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6419 if(hfile == INVALID_HANDLE_VALUE) return;
6421 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6422 ok(read != 0, "could not read file\n");
6423 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6425 CloseHandle(hfile);
6426 DeleteFileA("test.xml");
6428 /* save to path VT_BSTR | VT_BYREF */
6429 filename = _bstr_("test.xml");
6430 V_VT(&dest) = VT_BSTR | VT_BYREF;
6431 V_BSTRREF(&dest) = &filename;
6433 hr = IXMLDOMDocument_save(doc, dest);
6434 EXPECT_HR(hr, S_OK);
6436 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
6437 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
6438 if(hfile == INVALID_HANDLE_VALUE) return;
6440 if (hfile != INVALID_HANDLE_VALUE)
6442 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
6443 ok(read != 0, "could not read file\n");
6444 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
6446 CloseHandle(hfile);
6447 DeleteFileA("test.xml");
6450 /* save to stream */
6451 V_VT(&dest) = VT_UNKNOWN;
6452 V_UNKNOWN(&dest) = (IUnknown*)&savestream;
6454 hr = IXMLDOMDocument_save(doc, dest);
6455 EXPECT_HR(hr, S_OK);
6457 /* loaded data contains xml declaration */
6458 hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b);
6459 EXPECT_HR(hr, S_OK);
6461 CreateStreamOnHGlobal(NULL, TRUE, &stream);
6462 V_VT(&dest) = VT_UNKNOWN;
6463 V_UNKNOWN(&dest) = (IUnknown*)stream;
6464 hr = IXMLDOMDocument_save(doc, dest);
6465 EXPECT_HR(hr, S_OK);
6467 hr = GetHGlobalFromStream(stream, &global);
6468 EXPECT_HR(hr, S_OK);
6469 ptr = GlobalLock(global);
6470 ok(!memcmp(ptr, win1252decl, strlen(win1252decl)), "got wrong xml declaration\n");
6471 GlobalUnlock(global);
6472 IStream_Release(stream);
6474 /* loaded data without xml declaration */
6475 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b);
6476 EXPECT_HR(hr, S_OK);
6478 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
6479 ok(hr == S_OK, "got 0x%08x\n", hr);
6480 V_VT(&dest) = VT_UNKNOWN;
6481 V_UNKNOWN(&dest) = (IUnknown*)stream;
6482 hr = IXMLDOMDocument_save(doc, dest);
6483 EXPECT_HR(hr, S_OK);
6485 hr = GetHGlobalFromStream(stream, &global);
6486 EXPECT_HR(hr, S_OK);
6487 ptr = GlobalLock(global);
6488 ok(ptr[0] == '<' && ptr[1] != '?', "got wrong start tag %c%c\n", ptr[0], ptr[1]);
6489 GlobalUnlock(global);
6490 IStream_Release(stream);
6492 IXMLDOMDocument_Release(doc);
6493 free_bstrs();
6496 static void test_testTransforms(void)
6498 IXMLDOMDocument *doc, *docSS;
6499 IXMLDOMNode *pNode;
6500 VARIANT_BOOL bSucc;
6501 HRESULT hr;
6503 doc = create_document(&IID_IXMLDOMDocument);
6504 docSS = create_document(&IID_IXMLDOMDocument);
6506 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
6507 ok(hr == S_OK, "ret %08x\n", hr );
6509 hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
6510 ok(hr == S_OK, "ret %08x\n", hr );
6512 hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
6513 ok(hr == S_OK, "ret %08x\n", hr );
6514 if(hr == S_OK)
6516 BSTR bOut;
6518 hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
6519 ok(hr == S_OK, "ret %08x\n", hr );
6520 if(hr == S_OK)
6522 ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(bOut));
6523 SysFreeString(bOut);
6526 IXMLDOMNode_Release(pNode);
6529 IXMLDOMDocument_Release(docSS);
6530 IXMLDOMDocument_Release(doc);
6532 free_bstrs();
6535 struct namespaces_change_t {
6536 const CLSID *clsid;
6537 const char *name;
6540 static const struct namespaces_change_t namespaces_change_test_data[] = {
6541 { &CLSID_DOMDocument, "CLSID_DOMDocument" },
6542 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" },
6543 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" },
6544 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" },
6545 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" },
6546 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" },
6547 { 0 }
6550 static void test_namespaces_change(void)
6552 const struct namespaces_change_t *class_ptr = namespaces_change_test_data;
6554 while (class_ptr->clsid)
6556 IXMLDOMDocument *doc = NULL;
6557 IXMLDOMElement *elem = NULL;
6558 IXMLDOMNode *node = NULL;
6560 VARIANT var;
6561 HRESULT hr;
6562 BSTR str;
6564 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
6566 class_ptr++;
6567 continue;
6570 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
6571 &IID_IXMLDOMDocument, (void**)&doc);
6572 ok(hr == S_OK, "got 0x%08x\n", hr);
6574 V_VT(&var) = VT_I2;
6575 V_I2(&var) = NODE_ELEMENT;
6577 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node);
6578 EXPECT_HR(hr, S_OK);
6580 hr = IXMLDOMDocument_appendChild(doc, node, NULL);
6581 EXPECT_HR(hr, S_OK);
6583 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
6584 EXPECT_HR(hr, S_OK);
6586 /* try same prefix, different uri */
6587 V_VT(&var) = VT_BSTR;
6588 V_BSTR(&var) = _bstr_("ns/uri2");
6590 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6591 EXPECT_HR(hr, E_INVALIDARG);
6593 /* try same prefix and uri */
6594 V_VT(&var) = VT_BSTR;
6595 V_BSTR(&var) = _bstr_("ns/uri");
6597 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var);
6598 EXPECT_HR(hr, S_OK);
6600 hr = IXMLDOMElement_get_xml(elem, &str);
6601 EXPECT_HR(hr, S_OK);
6602 ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s for %s\n",
6603 wine_dbgstr_w(str), class_ptr->name);
6604 SysFreeString(str);
6606 IXMLDOMElement_Release(elem);
6607 IXMLDOMDocument_Release(doc);
6609 free_bstrs();
6611 class_ptr++;
6615 static void test_namespaces_basic(void)
6617 static const CHAR namespaces_xmlA[] =
6618 "<?xml version=\"1.0\"?>\n"
6619 "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">"
6620 " <XMI.content>"
6621 " <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />"
6622 " </XMI.content>"
6623 "</XMI>";
6625 IXMLDOMDocument *doc;
6626 IXMLDOMElement *elem;
6627 IXMLDOMNode *node;
6629 VARIANT_BOOL b;
6630 HRESULT hr;
6631 BSTR str;
6633 doc = create_document(&IID_IXMLDOMDocument);
6635 hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
6636 EXPECT_HR(hr, S_OK);
6637 ok(b == VARIANT_TRUE, "got %d\n", b);
6639 str = (BSTR)0xdeadbeef;
6640 hr = IXMLDOMDocument_get_namespaceURI(doc, &str);
6641 EXPECT_HR(hr, S_FALSE);
6642 ok(str == NULL, "got %p\n", str);
6644 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node );
6645 EXPECT_HR(hr, S_OK);
6646 if(hr == S_OK)
6648 IXMLDOMAttribute *attr;
6649 IXMLDOMNode *node2;
6651 hr = IXMLDOMNode_get_firstChild(node, &node2);
6652 EXPECT_HR(hr, S_OK);
6653 ok(node2 != NULL, "got %p\n", node2);
6655 /* Test get_prefix */
6656 hr = IXMLDOMNode_get_prefix(node2, NULL);
6657 EXPECT_HR(hr, E_INVALIDARG);
6658 /* NOTE: Need to test that arg2 gets cleared on Error. */
6660 hr = IXMLDOMNode_get_prefix(node2, &str);
6661 EXPECT_HR(hr, S_OK);
6662 ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
6663 SysFreeString(str);
6665 hr = IXMLDOMNode_get_nodeName(node2, &str);
6666 EXPECT_HR(hr, S_OK);
6667 ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str));
6668 SysFreeString(str);
6670 /* Test get_namespaceURI */
6671 hr = IXMLDOMNode_get_namespaceURI(node2, NULL);
6672 EXPECT_HR(hr, E_INVALIDARG);
6673 /* NOTE: Need to test that arg2 gets cleared on Error. */
6675 hr = IXMLDOMNode_get_namespaceURI(node2, &str);
6676 EXPECT_HR(hr, S_OK);
6677 ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str));
6678 SysFreeString(str);
6680 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem);
6681 EXPECT_HR(hr, S_OK);
6683 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr);
6684 EXPECT_HR(hr, S_OK);
6686 hr = IXMLDOMAttribute_get_nodeName(attr, &str);
6687 EXPECT_HR(hr, S_OK);
6688 ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str));
6689 SysFreeString(str);
6691 hr = IXMLDOMAttribute_get_prefix(attr, &str);
6692 EXPECT_HR(hr, S_OK);
6693 ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str));
6694 SysFreeString(str);
6696 IXMLDOMAttribute_Release(attr);
6697 IXMLDOMElement_Release(elem);
6699 IXMLDOMNode_Release(node2);
6700 IXMLDOMNode_Release(node);
6703 IXMLDOMDocument_Release(doc);
6705 free_bstrs();
6708 static void test_FormattingXML(void)
6710 IXMLDOMDocument *doc;
6711 IXMLDOMElement *pElement;
6712 VARIANT_BOOL bSucc;
6713 HRESULT hr;
6714 BSTR str;
6715 static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
6716 static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
6718 doc = create_document(&IID_IXMLDOMDocument);
6720 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
6721 ok(hr == S_OK, "ret %08x\n", hr );
6722 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6724 if(bSucc == VARIANT_TRUE)
6726 hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
6727 ok(hr == S_OK, "ret %08x\n", hr );
6728 if(hr == S_OK)
6730 hr = IXMLDOMElement_get_xml(pElement, &str);
6731 ok(hr == S_OK, "ret %08x\n", hr );
6732 ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
6733 SysFreeString(str);
6735 IXMLDOMElement_Release(pElement);
6739 IXMLDOMDocument_Release(doc);
6741 free_bstrs();
6744 typedef struct _nodetypedvalue_t {
6745 const char *name;
6746 VARTYPE type;
6747 const char *value; /* value in string format */
6748 } nodetypedvalue_t;
6750 static const nodetypedvalue_t get_nodetypedvalue[] = {
6751 { "root/string", VT_BSTR, "Wine" },
6752 { "root/string2", VT_BSTR, "String" },
6753 { "root/number", VT_BSTR, "12.44" },
6754 { "root/number2", VT_BSTR, "-3.71e3" },
6755 { "root/int", VT_I4, "-13" },
6756 { "root/fixed", VT_CY, "7322.9371" },
6757 { "root/bool", VT_BOOL, "-1" },
6758 { "root/datetime", VT_DATE, "40135.14" },
6759 { "root/datetimetz",VT_DATE, "37813.59" },
6760 { "root/date", VT_DATE, "665413" },
6761 { "root/time", VT_DATE, "0.5813889" },
6762 { "root/timetz", VT_DATE, "1.112512" },
6763 { "root/i1", VT_I1, "-13" },
6764 { "root/i2", VT_I2, "31915" },
6765 { "root/i4", VT_I4, "-312232" },
6766 { "root/ui1", VT_UI1, "123" },
6767 { "root/ui2", VT_UI2, "48282" },
6768 { "root/ui4", VT_UI4, "949281" },
6769 { "root/r4", VT_R4, "213124" },
6770 { "root/r8", VT_R8, "0.412" },
6771 { "root/float", VT_R8, "41221.421" },
6772 { "root/uuid", VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
6773 { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
6774 { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
6775 { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
6776 { 0 }
6779 static void test_nodeTypedValue(void)
6781 const nodetypedvalue_t *entry = get_nodetypedvalue;
6782 IXMLDOMDocumentType *doctype, *doctype2;
6783 IXMLDOMProcessingInstruction *pi;
6784 IXMLDOMDocumentFragment *frag;
6785 IXMLDOMDocument *doc, *doc2;
6786 IXMLDOMCDATASection *cdata;
6787 IXMLDOMComment *comment;
6788 IXMLDOMNode *node;
6789 VARIANT_BOOL b;
6790 VARIANT value;
6791 HRESULT hr;
6793 doc = create_document(&IID_IXMLDOMDocument);
6795 b = VARIANT_FALSE;
6796 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
6797 ok(hr == S_OK, "ret %08x\n", hr );
6798 ok(b == VARIANT_TRUE, "got %d\n", b);
6800 hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
6801 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6803 V_VT(&value) = VT_BSTR;
6804 V_BSTR(&value) = NULL;
6805 hr = IXMLDOMDocument_get_nodeValue(doc, &value);
6806 ok(hr == S_FALSE, "ret %08x\n", hr );
6807 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
6809 hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
6810 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6812 V_VT(&value) = VT_EMPTY;
6813 hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
6814 ok(hr == S_FALSE, "ret %08x\n", hr );
6815 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6817 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
6818 ok(hr == S_OK, "ret %08x\n", hr );
6820 V_VT(&value) = VT_BSTR;
6821 V_BSTR(&value) = NULL;
6822 hr = IXMLDOMNode_get_nodeValue(node, &value);
6823 ok(hr == S_FALSE, "ret %08x\n", hr );
6824 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
6826 hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
6827 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
6829 IXMLDOMNode_Release(node);
6831 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
6832 ok(hr == S_OK, "ret %08x\n", hr );
6834 BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
6836 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
6837 ok(hr == S_OK, "ret %08x\n", hr );
6838 ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
6839 ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
6840 if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
6841 ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
6842 VariantClear(&value);
6843 IXMLDOMNode_Release(node);
6846 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
6847 ok(hr == S_OK, "ret %08x\n", hr );
6849 V_VT(&value) = VT_NULL;
6850 V_BSTR(&value) = (void*)0xdeadbeef;
6851 hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
6852 ok(hr == S_OK, "ret %08x\n", hr );
6853 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6854 ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
6855 IXMLDOMProcessingInstruction_Release(pi);
6856 VariantClear(&value);
6859 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata);
6860 ok(hr == S_OK, "ret %08x\n", hr );
6862 V_VT(&value) = VT_NULL;
6863 V_BSTR(&value) = (void*)0xdeadbeef;
6864 hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
6865 ok(hr == S_OK, "ret %08x\n", hr );
6866 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6867 ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n");
6868 IXMLDOMCDATASection_Release(cdata);
6869 VariantClear(&value);
6872 hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
6873 ok(hr == S_OK, "ret %08x\n", hr );
6875 V_VT(&value) = VT_NULL;
6876 V_BSTR(&value) = (void*)0xdeadbeef;
6877 hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
6878 ok(hr == S_OK, "ret %08x\n", hr );
6879 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
6880 ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
6881 IXMLDOMComment_Release(comment);
6882 VariantClear(&value);
6885 hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
6886 ok(hr == S_OK, "ret %08x\n", hr );
6888 V_VT(&value) = VT_EMPTY;
6889 hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
6890 ok(hr == S_FALSE, "ret %08x\n", hr );
6891 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6892 IXMLDOMDocumentFragment_Release(frag);
6895 doc2 = create_document(&IID_IXMLDOMDocument);
6897 b = VARIANT_FALSE;
6898 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
6899 ok(hr == S_OK, "ret %08x\n", hr );
6900 ok(b == VARIANT_TRUE, "got %d\n", b);
6902 EXPECT_REF(doc2, 1);
6904 hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
6905 ok(hr == S_OK, "ret %08x\n", hr );
6907 EXPECT_REF(doc2, 1);
6908 todo_wine EXPECT_REF(doctype, 2);
6911 V_VT(&value) = VT_EMPTY;
6912 hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
6913 ok(hr == S_FALSE, "ret %08x\n", hr );
6914 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6917 hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
6918 ok(hr == S_OK, "ret %08x\n", hr );
6919 ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
6921 IXMLDOMDocumentType_Release(doctype2);
6922 IXMLDOMDocumentType_Release(doctype);
6924 IXMLDOMDocument_Release(doc2);
6926 while (entry->name)
6928 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
6929 ok(hr == S_OK, "ret %08x\n", hr );
6931 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
6932 ok(hr == S_OK, "ret %08x\n", hr );
6933 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
6935 if (entry->type == (VT_ARRAY|VT_UI1))
6937 ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
6938 "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements);
6941 if (entry->type != VT_BSTR)
6943 if (entry->type == VT_DATE ||
6944 entry->type == VT_R8 ||
6945 entry->type == VT_CY)
6947 if (entry->type == VT_DATE)
6949 hr = VariantChangeType(&value, &value, 0, VT_R4);
6950 ok(hr == S_OK, "ret %08x\n", hr );
6952 hr = VariantChangeTypeEx(&value, &value,
6953 MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
6954 VARIANT_NOUSEROVERRIDE, VT_BSTR);
6955 ok(hr == S_OK, "ret %08x\n", hr );
6957 else
6959 hr = VariantChangeType(&value, &value, 0, VT_BSTR);
6960 ok(hr == S_OK, "ret %08x\n", hr );
6963 /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
6964 if (entry->type == (VT_ARRAY|VT_UI1))
6966 ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
6967 "expected %s\n", entry->value);
6969 else
6970 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6971 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6973 else
6974 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6975 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6977 VariantClear( &value );
6978 IXMLDOMNode_Release(node);
6980 entry++;
6983 IXMLDOMDocument_Release(doc);
6984 free_bstrs();
6987 static void test_TransformWithLoadingLocalFile(void)
6989 IXMLDOMDocument *doc;
6990 IXMLDOMDocument *xsl;
6991 IXMLDOMNode *pNode;
6992 VARIANT_BOOL bSucc;
6993 HRESULT hr;
6994 HANDLE file;
6995 DWORD dwWritten;
6996 char lpPathBuffer[MAX_PATH];
6997 int i;
6999 /* Create a Temp File. */
7000 GetTempPathA(MAX_PATH, lpPathBuffer);
7001 strcat(lpPathBuffer, "customers.xml" );
7003 file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
7004 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
7005 if(file == INVALID_HANDLE_VALUE)
7006 return;
7008 WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
7009 CloseHandle(file);
7011 /* Correct path to not include an escape character. */
7012 for(i=0; i < strlen(lpPathBuffer); i++)
7014 if(lpPathBuffer[i] == '\\')
7015 lpPathBuffer[i] = '/';
7018 doc = create_document(&IID_IXMLDOMDocument);
7019 xsl = create_document(&IID_IXMLDOMDocument);
7021 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
7022 ok(hr == S_OK, "ret %08x\n", hr );
7023 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7024 if(bSucc == VARIANT_TRUE)
7026 BSTR sXSL;
7027 BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
7028 BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
7029 BSTR sFileName = _bstr_(lpPathBuffer);
7030 int nLength = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
7032 sXSL = SysAllocStringLen(NULL, nLength);
7033 lstrcpyW(sXSL, sPart1);
7034 lstrcatW(sXSL, sFileName);
7035 lstrcatW(sXSL, sPart2);
7037 hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
7038 ok(hr == S_OK, "ret %08x\n", hr );
7039 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
7040 if(bSucc == VARIANT_TRUE)
7042 BSTR sResult;
7044 hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
7045 ok(hr == S_OK, "ret %08x\n", hr );
7046 if(hr == S_OK)
7048 /* This will load the temp file via the XSL */
7049 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
7050 ok(hr == S_OK, "ret %08x\n", hr );
7051 if(hr == S_OK)
7053 ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
7054 SysFreeString(sResult);
7057 IXMLDOMNode_Release(pNode);
7061 SysFreeString(sXSL);
7064 IXMLDOMDocument_Release(doc);
7065 IXMLDOMDocument_Release(xsl);
7067 DeleteFileA(lpPathBuffer);
7068 free_bstrs();
7071 static void test_put_nodeValue(void)
7073 static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
7074 IXMLDOMDocument *doc;
7075 IXMLDOMText *text;
7076 IXMLDOMEntityReference *entityref;
7077 IXMLDOMAttribute *attr;
7078 IXMLDOMNode *node;
7079 HRESULT hr;
7080 VARIANT data, type;
7082 doc = create_document(&IID_IXMLDOMDocument);
7084 /* test for unsupported types */
7085 /* NODE_DOCUMENT */
7086 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
7087 ok(hr == S_OK, "ret %08x\n", hr );
7088 V_VT(&data) = VT_BSTR;
7089 V_BSTR(&data) = _bstr_("one two three");
7090 hr = IXMLDOMNode_put_nodeValue(node, data);
7091 ok(hr == E_FAIL, "ret %08x\n", hr );
7092 IXMLDOMNode_Release(node);
7094 /* NODE_DOCUMENT_FRAGMENT */
7095 V_VT(&type) = VT_I1;
7096 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
7097 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7098 ok(hr == S_OK, "ret %08x\n", hr );
7099 V_VT(&data) = VT_BSTR;
7100 V_BSTR(&data) = _bstr_("one two three");
7101 hr = IXMLDOMNode_put_nodeValue(node, data);
7102 ok(hr == E_FAIL, "ret %08x\n", hr );
7103 IXMLDOMNode_Release(node);
7105 /* NODE_ELEMENT */
7106 V_VT(&type) = VT_I1;
7107 V_I1(&type) = NODE_ELEMENT;
7108 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
7109 ok(hr == S_OK, "ret %08x\n", hr );
7110 V_VT(&data) = VT_BSTR;
7111 V_BSTR(&data) = _bstr_("one two three");
7112 hr = IXMLDOMNode_put_nodeValue(node, data);
7113 ok(hr == E_FAIL, "ret %08x\n", hr );
7114 IXMLDOMNode_Release(node);
7116 /* NODE_ENTITY_REFERENCE */
7117 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
7118 ok(hr == S_OK, "ret %08x\n", hr );
7120 V_VT(&data) = VT_BSTR;
7121 V_BSTR(&data) = _bstr_("one two three");
7122 hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
7123 ok(hr == E_FAIL, "ret %08x\n", hr );
7125 hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
7126 ok(hr == S_OK, "ret %08x\n", hr );
7127 V_VT(&data) = VT_BSTR;
7128 V_BSTR(&data) = _bstr_("one two three");
7129 hr = IXMLDOMNode_put_nodeValue(node, data);
7130 ok(hr == E_FAIL, "ret %08x\n", hr );
7131 IXMLDOMNode_Release(node);
7132 IXMLDOMEntityReference_Release(entityref);
7134 /* supported types */
7135 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
7136 ok(hr == S_OK, "ret %08x\n", hr );
7137 V_VT(&data) = VT_BSTR;
7138 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7139 hr = IXMLDOMText_put_nodeValue(text, data);
7140 ok(hr == S_OK, "ret %08x\n", hr );
7141 IXMLDOMText_Release(text);
7143 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7144 ok(hr == S_OK, "ret %08x\n", hr );
7145 V_VT(&data) = VT_BSTR;
7146 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
7147 hr = IXMLDOMAttribute_put_nodeValue(attr, data);
7148 ok(hr == S_OK, "ret %08x\n", hr );
7149 hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
7150 ok(hr == S_OK, "ret %08x\n", hr );
7151 ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
7152 wine_dbgstr_w(V_BSTR(&data)));
7153 VariantClear(&data);
7154 IXMLDOMAttribute_Release(attr);
7156 free_bstrs();
7158 IXMLDOMDocument_Release(doc);
7161 static void test_IObjectSafety(void)
7163 IXMLDOMDocument *doc;
7164 IObjectSafety *safety;
7165 HRESULT hr;
7167 doc = create_document(&IID_IXMLDOMDocument);
7169 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
7170 ok(hr == S_OK, "ret %08x\n", hr );
7172 test_IObjectSafety_common(safety);
7174 IObjectSafety_Release(safety);
7175 IXMLDOMDocument_Release(doc);
7177 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
7178 &IID_IObjectSafety, (void**)&safety);
7179 ok(hr == S_OK, "Could not create XMLHTTPRequest instance: %08x\n", hr);
7181 test_IObjectSafety_common(safety);
7183 IObjectSafety_Release(safety);
7187 typedef struct _property_test_t {
7188 const GUID *guid;
7189 const char *clsid;
7190 const char *property;
7191 const char *value;
7192 } property_test_t;
7194 static const property_test_t properties_test_data[] = {
7195 { &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
7196 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
7197 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
7198 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
7199 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
7200 { 0 }
7203 static void test_default_properties(void)
7205 const property_test_t *entry = properties_test_data;
7207 while (entry->guid)
7209 IXMLDOMDocument2 *doc;
7210 VARIANT var;
7211 HRESULT hr;
7213 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
7215 entry++;
7216 continue;
7219 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
7220 ok(hr == S_OK, "got 0x%08x\n", hr);
7222 hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
7223 ok(hr == S_OK, "got 0x%08x\n", hr);
7224 ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
7225 entry->value, entry->clsid);
7226 VariantClear(&var);
7228 IXMLDOMDocument2_Release(doc);
7230 entry++;
7234 typedef struct {
7235 const char *query;
7236 const char *list;
7237 BOOL todo;
7238 } xslpattern_test_t;
7240 static const xslpattern_test_t xslpattern_test[] = {
7241 { "root//elem[0]", "E1.E2.D1" },
7242 { "root//elem[index()=1]", "E2.E2.D1" },
7243 { "root//elem[index() $eq$ 1]", "E2.E2.D1" },
7244 { "root//elem[end()]", "E4.E2.D1" },
7245 { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7246 { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7247 { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7248 { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7249 { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7250 { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7251 { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7252 { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7253 { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7254 { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7255 { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7256 { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7257 { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7258 { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7259 { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7260 { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7261 { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7262 { "root//elem[$any$ *='B2 field']", "E2.E2.D1" },
7263 { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7264 { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7265 { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7266 { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7267 { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7268 { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7269 { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7270 { "root/elem[0]", "E1.E2.D1" },
7271 { "root/elem[index()=1]", "E2.E2.D1" },
7272 { "root/elem[index() $eq$ 1]", "E2.E2.D1" },
7273 { "root/elem[end()]", "E4.E2.D1" },
7274 { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" },
7275 { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7276 { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" },
7277 { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" },
7278 { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" },
7279 { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" },
7280 { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" },
7281 { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" },
7282 { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" },
7283 { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" },
7284 { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" },
7285 { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" },
7286 { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7287 { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" },
7288 { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" },
7289 { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" },
7290 { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" },
7291 { "root/elem[$any$ *='B2 field']", "E2.E2.D1" },
7292 { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" },
7293 { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" },
7294 { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" },
7295 { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" },
7296 { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7297 { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7298 { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
7299 { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
7300 { "root/elem[@*]", "E2.E2.D1 E3.E2.D1", TRUE },
7301 { NULL }
7304 static const xslpattern_test_t xslpattern_test_no_ns[] = {
7305 /* prefixes don't need to be registered, you may use them as they are in the doc */
7306 { "//bar:x", "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" },
7307 /* prefixes must be explicitly specified in the name */
7308 { "//foo:elem", "" },
7309 { "//foo:c", "E3.E4.E2.D1" },
7310 { NULL }
7313 static const xslpattern_test_t xslpattern_test_func[] = {
7314 { "attribute()", "" },
7315 { "attribute('depth')", "" },
7316 { "root/attribute('depth')", "A'depth'.E3.D1" },
7317 { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" },
7318 { "//x//attribute(id)", NULL },
7319 { "//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" },
7320 { "comment()", "C2.D1" },
7321 { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" },
7322 { "element()", "E3.D1" },
7323 { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" },
7324 { "//element(a)", NULL },
7325 { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" },
7326 { "node()", "P1.D1 C2.D1 E3.D1" },
7327 { "//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" },
7328 { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" },
7329 { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" },
7330 { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" },
7331 { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" },
7332 { "pi()", "P1.D1" },
7333 { "//y/pi()", "P1.E4.E3.D1" },
7334 { "root/textnode()", "T2.E3.D1" },
7335 { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" },
7336 { NULL }
7339 static void test_XSLPattern(void)
7341 const xslpattern_test_t *ptr = xslpattern_test;
7342 IXMLDOMDocument2 *doc;
7343 IXMLDOMNodeList *list;
7344 VARIANT_BOOL b;
7345 HRESULT hr;
7346 LONG len;
7348 doc = create_document(&IID_IXMLDOMDocument2);
7350 b = VARIANT_FALSE;
7351 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
7352 EXPECT_HR(hr, S_OK);
7353 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7355 /* switch to XSLPattern */
7356 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"));
7357 EXPECT_HR(hr, S_OK);
7359 /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
7360 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list);
7361 EXPECT_HR(hr, S_OK);
7363 len = 0;
7364 hr = IXMLDOMNodeList_get_length(list, &len);
7365 EXPECT_HR(hr, S_OK);
7366 /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
7367 ok(len == 3, "expected 3 entries in list, got %d\n", len);
7368 IXMLDOMNodeList_Release(list);
7370 while (ptr->query)
7372 list = NULL;
7373 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7374 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7375 len = 0;
7376 hr = IXMLDOMNodeList_get_length(list, &len);
7377 ok(len != 0, "query=%s, empty list\n", ptr->query);
7378 if (len) {
7379 if (ptr->todo) {
7380 char *str = list_to_string(list);
7381 todo_wine
7382 ok(!strcmp(str, ptr->list), "Invalid node list: %s, expected %s\n", str, ptr->list);
7383 IXMLDOMNodeList_Release(list);
7385 else
7386 expect_list_and_release(list, ptr->list);
7389 ptr++;
7392 /* namespace handling */
7393 /* no registered namespaces */
7394 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""));
7395 EXPECT_HR(hr, S_OK);
7397 ptr = xslpattern_test_no_ns;
7398 while (ptr->query)
7400 list = NULL;
7401 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7402 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7404 if (*ptr->list)
7406 len = 0;
7407 hr = IXMLDOMNodeList_get_length(list, &len);
7408 EXPECT_HR(hr, S_OK);
7409 ok(len != 0, "query=%s, empty list\n", ptr->query);
7411 else
7413 len = 1;
7414 hr = IXMLDOMNodeList_get_length(list, &len);
7415 EXPECT_HR(hr, S_OK);
7416 ok(len == 0, "query=%s, empty list\n", ptr->query);
7418 if (len)
7419 expect_list_and_release(list, ptr->list);
7421 ptr++;
7424 /* explicitly register prefix foo */
7425 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
7427 /* now we get the same behavior as XPath */
7428 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7429 EXPECT_HR(hr, S_OK);
7430 len = 0;
7431 hr = IXMLDOMNodeList_get_length(list, &len);
7432 EXPECT_HR(hr, S_OK);
7433 ok(len != 0, "expected filled list\n");
7434 if (len)
7435 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
7437 /* set prefix foo to some nonexistent namespace */
7438 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'"));
7439 EXPECT_HR(hr, S_OK);
7441 /* the registered prefix takes precedence */
7442 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list);
7443 EXPECT_HR(hr, S_OK);
7444 len = 0;
7445 hr = IXMLDOMNodeList_get_length(list, &len);
7446 EXPECT_HR(hr, S_OK);
7447 ok(len == 0, "expected empty list\n");
7448 IXMLDOMNodeList_Release(list);
7450 IXMLDOMDocument2_Release(doc);
7452 doc = create_document(&IID_IXMLDOMDocument2);
7454 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
7455 EXPECT_HR(hr, S_OK);
7456 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7458 ptr = xslpattern_test_func;
7459 while (ptr->query)
7461 list = NULL;
7462 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list);
7463 if (ptr->list)
7465 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7466 len = 0;
7467 hr = IXMLDOMNodeList_get_length(list, &len);
7468 if (*ptr->list)
7470 ok(len != 0, "query=%s, empty list\n", ptr->query);
7471 if (len)
7472 expect_list_and_release(list, ptr->list);
7474 else
7475 ok(len == 0, "query=%s, filled list\n", ptr->query);
7477 else
7478 ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr);
7480 ptr++;
7483 IXMLDOMDocument2_Release(doc);
7484 free_bstrs();
7487 static void test_splitText(void)
7489 IXMLDOMCDATASection *cdata;
7490 IXMLDOMElement *root;
7491 IXMLDOMDocument *doc;
7492 IXMLDOMText *text, *text2;
7493 IXMLDOMNode *node;
7494 VARIANT var;
7495 VARIANT_BOOL success;
7496 LONG length;
7497 HRESULT hr;
7499 doc = create_document(&IID_IXMLDOMDocument);
7501 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
7502 ok(hr == S_OK, "got 0x%08x\n", hr);
7504 hr = IXMLDOMDocument_get_documentElement(doc, &root);
7505 ok(hr == S_OK, "got 0x%08x\n", hr);
7507 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
7508 ok(hr == S_OK, "got 0x%08x\n", hr);
7510 V_VT(&var) = VT_EMPTY;
7511 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
7512 ok(hr == S_OK, "got 0x%08x\n", hr);
7514 length = 0;
7515 hr = IXMLDOMCDATASection_get_length(cdata, &length);
7516 ok(hr == S_OK, "got 0x%08x\n", hr);
7517 ok(length > 0, "got %d\n", length);
7519 hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
7520 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7522 text = (void*)0xdeadbeef;
7523 /* negative offset */
7524 hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
7525 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7526 ok(text == (void*)0xdeadbeef, "got %p\n", text);
7528 text = (void*)0xdeadbeef;
7529 /* offset outside data */
7530 hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
7531 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7532 ok(text == 0, "got %p\n", text);
7534 text = (void*)0xdeadbeef;
7535 /* offset outside data */
7536 hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
7537 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7538 ok(text == 0, "got %p\n", text);
7540 /* no empty node created */
7541 node = (void*)0xdeadbeef;
7542 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7543 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7544 ok(node == 0, "got %p\n", text);
7546 hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
7547 ok(hr == S_OK, "got 0x%08x\n", hr);
7549 length = 0;
7550 hr = IXMLDOMText_get_length(text, &length);
7551 ok(hr == S_OK, "got 0x%08x\n", hr);
7552 ok(length == 7, "got %d\n", length);
7554 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
7555 ok(hr == S_OK, "got 0x%08x\n", hr);
7556 IXMLDOMNode_Release(node);
7558 /* split new text node */
7559 hr = IXMLDOMText_get_length(text, &length);
7560 ok(hr == S_OK, "got 0x%08x\n", hr);
7562 node = (void*)0xdeadbeef;
7563 hr = IXMLDOMText_get_nextSibling(text, &node);
7564 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7565 ok(node == 0, "got %p\n", text);
7567 hr = IXMLDOMText_splitText(text, 0, NULL);
7568 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7570 text2 = (void*)0xdeadbeef;
7571 /* negative offset */
7572 hr = IXMLDOMText_splitText(text, -1, &text2);
7573 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7574 ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
7576 text2 = (void*)0xdeadbeef;
7577 /* offset outside data */
7578 hr = IXMLDOMText_splitText(text, length + 1, &text2);
7579 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7580 ok(text2 == 0, "got %p\n", text2);
7582 text2 = (void*)0xdeadbeef;
7583 /* offset outside data */
7584 hr = IXMLDOMText_splitText(text, length, &text2);
7585 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7586 ok(text2 == 0, "got %p\n", text);
7588 text2 = 0;
7589 hr = IXMLDOMText_splitText(text, 4, &text2);
7590 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7591 if (text2) IXMLDOMText_Release(text2);
7593 node = 0;
7594 hr = IXMLDOMText_get_nextSibling(text, &node);
7595 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
7596 if (node) IXMLDOMNode_Release(node);
7598 IXMLDOMText_Release(text);
7599 IXMLDOMElement_Release(root);
7600 IXMLDOMCDATASection_Release(cdata);
7601 free_bstrs();
7604 typedef struct {
7605 const char *name;
7606 const char *uri;
7607 HRESULT hr;
7608 } ns_item_t;
7610 /* default_ns_doc used */
7611 static const ns_item_t qualified_item_tests[] = {
7612 { "xml:lang", NULL, S_FALSE },
7613 { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE },
7614 { "lang", "http://www.w3.org/XML/1998/namespace", S_OK },
7615 { "ns:b", NULL, S_FALSE },
7616 { "ns:b", "nshref", S_FALSE },
7617 { "b", "nshref", S_OK },
7618 { "d", NULL, S_OK },
7619 { NULL }
7622 static const ns_item_t named_item_tests[] = {
7623 { "xml:lang", NULL, S_OK },
7624 { "lang", NULL, S_FALSE },
7625 { "ns:b", NULL, S_OK },
7626 { "b", NULL, S_FALSE },
7627 { "d", NULL, S_OK },
7628 { NULL }
7631 static void test_getQualifiedItem(void)
7633 IXMLDOMNode *pr_node, *node;
7634 IXMLDOMNodeList *root_list;
7635 IXMLDOMNamedNodeMap *map;
7636 IXMLDOMElement *element;
7637 const ns_item_t* ptr;
7638 IXMLDOMDocument *doc;
7639 VARIANT_BOOL b;
7640 HRESULT hr;
7641 LONG len;
7643 doc = create_document(&IID_IXMLDOMDocument);
7645 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
7646 EXPECT_HR(hr, S_OK);
7647 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7649 hr = IXMLDOMDocument_get_documentElement(doc, &element);
7650 EXPECT_HR(hr, S_OK);
7652 hr = IXMLDOMElement_get_childNodes(element, &root_list);
7653 EXPECT_HR(hr, S_OK);
7655 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
7656 EXPECT_HR(hr, S_OK);
7657 IXMLDOMNodeList_Release(root_list);
7659 hr = IXMLDOMNode_get_attributes(pr_node, &map);
7660 EXPECT_HR(hr, S_OK);
7661 IXMLDOMNode_Release(pr_node);
7663 len = 0;
7664 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7665 EXPECT_HR(hr, S_OK);
7666 ok( len == 3, "length %d\n", len);
7668 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
7669 EXPECT_HR(hr, E_INVALIDARG);
7671 node = (void*)0xdeadbeef;
7672 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
7673 EXPECT_HR(hr, E_INVALIDARG);
7674 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7676 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
7677 EXPECT_HR(hr, E_INVALIDARG);
7679 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
7680 EXPECT_HR(hr, S_OK);
7682 IXMLDOMNode_Release(node);
7683 IXMLDOMNamedNodeMap_Release(map);
7684 IXMLDOMElement_Release(element);
7686 hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b);
7687 EXPECT_HR(hr, S_OK);
7689 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node);
7690 EXPECT_HR(hr, S_OK);
7692 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
7693 EXPECT_HR(hr, S_OK);
7694 IXMLDOMNode_Release(node);
7696 hr = IXMLDOMElement_get_attributes(element, &map);
7697 EXPECT_HR(hr, S_OK);
7699 ptr = qualified_item_tests;
7700 while (ptr->name)
7702 node = (void*)0xdeadbeef;
7703 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
7704 ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr);
7705 if (hr == S_OK)
7706 IXMLDOMNode_Release(node);
7707 else
7708 ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node);
7709 ptr++;
7712 ptr = named_item_tests;
7713 while (ptr->name)
7715 node = (void*)0xdeadbeef;
7716 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node);
7717 ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr);
7718 if (hr == S_OK)
7719 IXMLDOMNode_Release(node);
7720 else
7721 ok(node == NULL, "%s: got %p\n", ptr->name, node);
7722 ptr++;
7725 IXMLDOMNamedNodeMap_Release(map);
7727 IXMLDOMElement_Release(element);
7728 IXMLDOMDocument_Release(doc);
7729 free_bstrs();
7732 static void test_removeQualifiedItem(void)
7734 IXMLDOMDocument *doc;
7735 IXMLDOMElement *element;
7736 IXMLDOMNode *pr_node, *node;
7737 IXMLDOMNodeList *root_list;
7738 IXMLDOMNamedNodeMap *map;
7739 VARIANT_BOOL b;
7740 LONG len;
7741 HRESULT hr;
7743 doc = create_document(&IID_IXMLDOMDocument);
7745 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
7746 ok( hr == S_OK, "loadXML failed\n");
7747 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7749 hr = IXMLDOMDocument_get_documentElement(doc, &element);
7750 ok( hr == S_OK, "ret %08x\n", hr);
7752 hr = IXMLDOMElement_get_childNodes(element, &root_list);
7753 ok( hr == S_OK, "ret %08x\n", hr);
7755 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
7756 ok( hr == S_OK, "ret %08x\n", hr);
7757 IXMLDOMNodeList_Release(root_list);
7759 hr = IXMLDOMNode_get_attributes(pr_node, &map);
7760 ok( hr == S_OK, "ret %08x\n", hr);
7761 IXMLDOMNode_Release(pr_node);
7763 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7764 ok( hr == S_OK, "ret %08x\n", hr);
7765 ok( len == 3, "length %d\n", len);
7767 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
7768 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7770 node = (void*)0xdeadbeef;
7771 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
7772 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7773 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7775 /* out pointer is optional */
7776 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7777 ok( hr == S_OK, "ret %08x\n", hr);
7779 /* already removed */
7780 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7781 ok( hr == S_FALSE, "ret %08x\n", hr);
7783 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
7784 ok( hr == S_OK, "ret %08x\n", hr);
7785 IXMLDOMNode_Release(node);
7787 IXMLDOMNamedNodeMap_Release( map );
7788 IXMLDOMElement_Release( element );
7789 IXMLDOMDocument_Release( doc );
7790 free_bstrs();
7793 #define check_default_props(doc) _check_default_props(__LINE__, doc)
7794 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
7796 VARIANT_BOOL b;
7797 VARIANT var;
7798 HRESULT hr;
7800 VariantInit(&var);
7801 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7802 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
7803 VariantClear(&var);
7805 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7806 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
7807 VariantClear(&var);
7809 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7810 ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
7812 hr = IXMLDOMDocument2_get_schemas(doc, &var);
7813 ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
7814 VariantClear(&var);
7817 #define check_set_props(doc) _check_set_props(__LINE__, doc)
7818 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
7820 VARIANT_BOOL b;
7821 VARIANT var;
7823 VariantInit(&var);
7824 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7825 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
7826 VariantClear(&var);
7828 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7829 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
7830 VariantClear(&var);
7832 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7833 ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
7835 helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
7836 ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
7837 VariantClear(&var);
7840 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
7841 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
7843 VARIANT var;
7845 VariantInit(&var);
7846 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
7847 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
7848 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
7849 V_VT(&var) = VT_DISPATCH;
7850 V_DISPATCH(&var) = NULL;
7851 helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
7852 ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
7853 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7854 VariantClear(&var);
7857 #define unset_props(doc) _unset_props(__LINE__, doc)
7858 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
7860 VARIANT var;
7862 VariantInit(&var);
7863 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
7864 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
7865 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
7866 V_VT(&var) = VT_NULL;
7867 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7868 VariantClear(&var);
7871 static void test_get_ownerDocument(void)
7873 IXMLDOMDocument *doc1, *doc2, *doc3;
7874 IXMLDOMDocument2 *doc, *doc_owner;
7875 IXMLDOMNode *node;
7876 IXMLDOMSchemaCollection *cache;
7877 VARIANT_BOOL b;
7878 VARIANT var;
7879 IXMLDOMElement *element;
7880 IXMLDOMNodeList *node_list;
7881 IXMLDOMAttribute *attr;
7882 LONG i, len;
7883 HRESULT hr;
7884 const CHAR nodeXML[] =
7885 "<root id='0'>"
7886 " <!-- comment node 0 -->"
7887 " text node 0"
7888 " <x attr='val'></x>"
7889 " <?foo value='PI for x'?>"
7890 " <![CDATA[ cdata ]]>"
7891 "</root>";
7893 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
7894 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
7896 doc = create_document(&IID_IXMLDOMDocument2);
7897 cache = create_cache(&IID_IXMLDOMSchemaCollection);
7899 VariantInit(&var);
7901 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
7902 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7904 check_default_props(doc);
7906 /* set properties and check that new instances use them */
7907 set_props(doc, cache);
7908 check_set_props(doc);
7910 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7911 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
7913 /* new interface keeps props */
7914 ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7915 ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
7916 check_set_props(doc_owner);
7917 IXMLDOMDocument2_Release(doc_owner);
7919 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
7920 IXMLDOMNode_Release(node);
7922 ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
7924 /* reload */
7925 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b));
7926 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7928 /* properties retained even after reload */
7929 check_set_props(doc);
7931 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7932 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
7933 IXMLDOMNode_Release(node);
7935 ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7936 ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
7937 check_set_props(doc_owner);
7939 /* changing properties for one instance changes them for all */
7940 unset_props(doc_owner);
7941 check_default_props(doc_owner);
7942 check_default_props(doc);
7944 /* NULL check */
7945 hr = IXMLDOMDocument_loadXML(doc1, _bstr_(nodeXML), &b);
7946 EXPECT_HR(hr, S_OK);
7947 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7949 hr = IXMLDOMDocument_get_documentElement(doc1, &element);
7950 EXPECT_HR(hr, S_OK);
7952 hr = IXMLDOMElement_get_childNodes(element, &node_list);
7953 EXPECT_HR(hr, S_OK);
7955 hr = IXMLDOMNodeList_get_length(node_list, &len);
7956 EXPECT_HR(hr, S_OK);
7958 for(i = 0; i < len; i++) {
7959 hr = IXMLDOMNodeList_get_item(node_list, i, &node);
7960 EXPECT_HR(hr, S_OK);
7962 hr = IXMLDOMNode_get_ownerDocument(node, NULL);
7963 EXPECT_HR(hr, E_INVALIDARG);
7965 IXMLDOMNode_Release(node);
7967 IXMLDOMElement_Release(element);
7969 /* Test Attribute Node */
7970 hr = IXMLDOMNodeList_get_item(node_list, 2, &node);
7971 EXPECT_HR(hr, S_OK);
7972 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element);
7973 EXPECT_HR(hr, S_OK);
7974 IXMLDOMNode_Release(node);
7976 hr = IXMLDOMElement_getAttributeNode(element, _bstr_("attr"), &attr);
7977 EXPECT_HR(hr, S_OK);
7978 ok(attr != NULL, "attr == NULL\n");
7979 IXMLDOMElement_Release(element);
7980 hr = IXMLDOMAttribute_get_ownerDocument(attr, NULL);
7981 EXPECT_HR(hr, E_INVALIDARG);
7982 IXMLDOMAttribute_Release(attr);
7983 IXMLDOMNodeList_Release(node_list);
7985 IXMLDOMSchemaCollection_Release(cache);
7986 IXMLDOMDocument_Release(doc1);
7987 IXMLDOMDocument_Release(doc2);
7988 IXMLDOMDocument_Release(doc3);
7989 IXMLDOMDocument2_Release(doc);
7990 IXMLDOMDocument2_Release(doc_owner);
7991 free_bstrs();
7994 static void test_setAttributeNode(void)
7996 IXMLDOMDocument *doc, *doc2;
7997 IXMLDOMElement *elem, *elem2;
7998 IXMLDOMAttribute *attr, *attr2, *ret_attr;
7999 VARIANT_BOOL b;
8000 HRESULT hr;
8001 VARIANT v;
8002 BSTR str;
8003 ULONG ref1, ref2;
8005 doc = create_document(&IID_IXMLDOMDocument);
8007 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8008 ok( hr == S_OK, "loadXML failed\n");
8009 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8011 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8012 ok( hr == S_OK, "got 0x%08x\n", hr);
8014 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
8015 ok( hr == S_OK, "got 0x%08x\n", hr);
8016 ok( elem2 != elem, "got same instance\n");
8018 ret_attr = (void*)0xdeadbeef;
8019 hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
8020 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8021 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8023 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8024 ok( hr == S_OK, "got 0x%08x\n", hr);
8026 ref1 = IXMLDOMElement_AddRef(elem);
8027 IXMLDOMElement_Release(elem);
8029 ret_attr = (void*)0xdeadbeef;
8030 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8031 ok( hr == S_OK, "got 0x%08x\n", hr);
8032 ok( ret_attr == NULL, "got %p\n", ret_attr);
8034 /* no reference added */
8035 ref2 = IXMLDOMElement_AddRef(elem);
8036 IXMLDOMElement_Release(elem);
8037 ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
8039 EXPECT_CHILDREN(elem);
8040 EXPECT_CHILDREN(elem2);
8042 IXMLDOMElement_Release(elem2);
8044 attr2 = NULL;
8045 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
8046 ok( hr == S_OK, "got 0x%08x\n", hr);
8047 ok( attr2 != attr, "got same instance %p\n", attr2);
8048 IXMLDOMAttribute_Release(attr2);
8050 /* try to add it another time */
8051 ret_attr = (void*)0xdeadbeef;
8052 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8053 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8054 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8056 IXMLDOMElement_Release(elem);
8058 /* initially used element is released, attribute still 'has' a container */
8059 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
8060 ok( hr == S_OK, "got 0x%08x\n", hr);
8061 ret_attr = (void*)0xdeadbeef;
8062 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8063 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8064 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
8065 IXMLDOMElement_Release(elem);
8067 /* add attribute already attached to another document */
8068 doc2 = create_document(&IID_IXMLDOMDocument);
8070 hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b );
8071 ok( hr == S_OK, "loadXML failed\n");
8072 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8074 hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
8075 ok( hr == S_OK, "got 0x%08x\n", hr);
8076 hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
8077 ok( hr == E_FAIL, "got 0x%08x\n", hr);
8078 IXMLDOMElement_Release(elem);
8080 IXMLDOMAttribute_Release(attr);
8082 /* create element, add attribute, see if it's copied or linked */
8083 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
8084 ok( hr == S_OK, "got 0x%08x\n", hr);
8086 attr = NULL;
8087 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8088 ok(hr == S_OK, "got 0x%08x\n", hr);
8089 ok(attr != NULL, "got %p\n", attr);
8091 ref1 = IXMLDOMAttribute_AddRef(attr);
8092 IXMLDOMAttribute_Release(attr);
8094 V_VT(&v) = VT_BSTR;
8095 V_BSTR(&v) = _bstr_("attrvalue1");
8096 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8097 ok( hr == S_OK, "got 0x%08x\n", hr);
8099 str = NULL;
8100 hr = IXMLDOMAttribute_get_xml(attr, &str);
8101 ok( hr == S_OK, "got 0x%08x\n", hr);
8102 ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
8103 "got %s\n", wine_dbgstr_w(str));
8104 SysFreeString(str);
8106 ret_attr = (void*)0xdeadbeef;
8107 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
8108 ok(hr == S_OK, "got 0x%08x\n", hr);
8109 ok(ret_attr == NULL, "got %p\n", ret_attr);
8111 /* attribute reference increased */
8112 ref2 = IXMLDOMAttribute_AddRef(attr);
8113 IXMLDOMAttribute_Release(attr);
8114 ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
8116 hr = IXMLDOMElement_get_xml(elem, &str);
8117 ok( hr == S_OK, "got 0x%08x\n", hr);
8118 ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
8119 "got %s\n", wine_dbgstr_w(str));
8120 SysFreeString(str);
8122 V_VT(&v) = VT_BSTR;
8123 V_BSTR(&v) = _bstr_("attrvalue2");
8124 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
8125 ok( hr == S_OK, "got 0x%08x\n", hr);
8127 hr = IXMLDOMElement_get_xml(elem, &str);
8128 ok( hr == S_OK, "got 0x%08x\n", hr);
8129 todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
8130 "got %s\n", wine_dbgstr_w(str));
8131 SysFreeString(str);
8133 IXMLDOMElement_Release(elem);
8134 IXMLDOMAttribute_Release(attr);
8135 IXMLDOMDocument_Release(doc2);
8136 IXMLDOMDocument_Release(doc);
8137 free_bstrs();
8140 static void test_createNode(void)
8142 IXMLDOMDocument *doc;
8143 IXMLDOMElement *elem;
8144 IXMLDOMNode *node;
8145 VARIANT v, var;
8146 BSTR prefix, str;
8147 HRESULT hr;
8148 ULONG ref;
8150 doc = create_document(&IID_IXMLDOMDocument);
8152 EXPECT_REF(doc, 1);
8154 /* reference count tests */
8155 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8156 ok( hr == S_OK, "got 0x%08x\n", hr);
8158 /* initial reference is 2 */
8159 todo_wine {
8160 EXPECT_REF(elem, 2);
8161 ref = IXMLDOMElement_Release(elem);
8162 ok(ref == 1, "got %d\n", ref);
8163 /* it's released already, attempt to release now will crash it */
8166 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8167 ok( hr == S_OK, "got 0x%08x\n", hr);
8168 todo_wine EXPECT_REF(elem, 2);
8169 IXMLDOMDocument_Release(doc);
8170 todo_wine EXPECT_REF(elem, 2);
8171 IXMLDOMElement_Release(elem);
8173 doc = create_document(&IID_IXMLDOMDocument);
8175 /* NODE_ELEMENT nodes */
8176 /* 1. specified namespace */
8177 V_VT(&v) = VT_I4;
8178 V_I4(&v) = NODE_ELEMENT;
8180 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
8181 ok( hr == S_OK, "got 0x%08x\n", hr);
8182 prefix = NULL;
8183 hr = IXMLDOMNode_get_prefix(node, &prefix);
8184 ok( hr == S_OK, "got 0x%08x\n", hr);
8185 ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
8186 SysFreeString(prefix);
8187 IXMLDOMNode_Release(node);
8189 /* 2. default namespace */
8190 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
8191 ok( hr == S_OK, "got 0x%08x\n", hr);
8192 prefix = (void*)0xdeadbeef;
8193 hr = IXMLDOMNode_get_prefix(node, &prefix);
8194 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8195 ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
8196 /* check dump */
8197 hr = IXMLDOMNode_get_xml(node, &str);
8198 ok( hr == S_OK, "got 0x%08x\n", hr);
8199 ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
8200 "got %s\n", wine_dbgstr_w(str));
8201 SysFreeString(str);
8203 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
8204 ok( hr == S_OK, "got 0x%08x\n", hr);
8206 V_VT(&var) = VT_BSTR;
8207 hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
8208 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8209 ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
8211 str = NULL;
8212 hr = IXMLDOMElement_get_namespaceURI(elem, &str);
8213 ok( hr == S_OK, "got 0x%08x\n", hr);
8214 ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
8215 SysFreeString(str);
8217 IXMLDOMElement_Release(elem);
8218 IXMLDOMNode_Release(node);
8220 IXMLDOMDocument_Release(doc);
8221 free_bstrs();
8224 static const char get_prefix_doc[] =
8225 "<?xml version=\"1.0\" ?>"
8226 "<a xmlns:ns1=\"ns1 href\" />";
8228 static void test_get_prefix(void)
8230 IXMLDOMDocumentFragment *fragment;
8231 IXMLDOMCDATASection *cdata;
8232 IXMLDOMElement *element;
8233 IXMLDOMComment *comment;
8234 IXMLDOMDocument *doc;
8235 VARIANT_BOOL b;
8236 HRESULT hr;
8237 BSTR str;
8239 doc = create_document(&IID_IXMLDOMDocument);
8241 /* nodes that can't support prefix */
8242 /* 1. document */
8243 str = (void*)0xdeadbeef;
8244 hr = IXMLDOMDocument_get_prefix(doc, &str);
8245 EXPECT_HR(hr, S_FALSE);
8246 ok(str == NULL, "got %p\n", str);
8248 hr = IXMLDOMDocument_get_prefix(doc, NULL);
8249 EXPECT_HR(hr, E_INVALIDARG);
8251 /* 2. cdata */
8252 hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
8253 ok(hr == S_OK, "got %08x\n", hr );
8255 str = (void*)0xdeadbeef;
8256 hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
8257 ok(hr == S_FALSE, "got %08x\n", hr);
8258 ok( str == 0, "got %p\n", str);
8260 hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
8261 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8262 IXMLDOMCDATASection_Release(cdata);
8264 /* 3. comment */
8265 hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
8266 ok(hr == S_OK, "got %08x\n", hr );
8268 str = (void*)0xdeadbeef;
8269 hr = IXMLDOMComment_get_prefix(comment, &str);
8270 ok(hr == S_FALSE, "got %08x\n", hr);
8271 ok( str == 0, "got %p\n", str);
8273 hr = IXMLDOMComment_get_prefix(comment, NULL);
8274 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8275 IXMLDOMComment_Release(comment);
8277 /* 4. fragment */
8278 hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
8279 ok(hr == S_OK, "got %08x\n", hr );
8281 str = (void*)0xdeadbeef;
8282 hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
8283 ok(hr == S_FALSE, "got %08x\n", hr);
8284 ok( str == 0, "got %p\n", str);
8286 hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
8287 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8288 IXMLDOMDocumentFragment_Release(fragment);
8290 /* no prefix */
8291 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
8292 ok( hr == S_OK, "got 0x%08x\n", hr);
8294 hr = IXMLDOMElement_get_prefix(element, NULL);
8295 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
8297 str = (void*)0xdeadbeef;
8298 hr = IXMLDOMElement_get_prefix(element, &str);
8299 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8300 ok( str == 0, "got %p\n", str);
8302 IXMLDOMElement_Release(element);
8304 /* with prefix */
8305 hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
8306 ok( hr == S_OK, "got 0x%08x\n", hr);
8308 str = (void*)0xdeadbeef;
8309 hr = IXMLDOMElement_get_prefix(element, &str);
8310 ok( hr == S_OK, "got 0x%08x\n", hr);
8311 ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
8312 SysFreeString(str);
8314 str = (void*)0xdeadbeef;
8315 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8316 ok( hr == S_FALSE, "got 0x%08x\n", hr);
8317 ok( str == 0, "got %p\n", str);
8319 IXMLDOMElement_Release(element);
8321 hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b);
8322 EXPECT_HR(hr, S_OK);
8324 hr = IXMLDOMDocument_get_documentElement(doc, &element);
8325 EXPECT_HR(hr, S_OK);
8327 str = (void*)0xdeadbeef;
8328 hr = IXMLDOMElement_get_prefix(element, &str);
8329 EXPECT_HR(hr, S_FALSE);
8330 ok(str == NULL, "got %p\n", str);
8332 str = (void*)0xdeadbeef;
8333 hr = IXMLDOMElement_get_namespaceURI(element, &str);
8334 EXPECT_HR(hr, S_FALSE);
8335 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
8337 IXMLDOMDocument_Release(doc);
8338 free_bstrs();
8341 static void test_selectSingleNode(void)
8343 IXMLDOMDocument *doc;
8344 IXMLDOMNodeList *list;
8345 IXMLDOMNode *node;
8346 VARIANT_BOOL b;
8347 HRESULT hr;
8348 LONG len;
8350 doc = create_document(&IID_IXMLDOMDocument);
8352 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8353 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8355 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8356 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8358 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
8359 ok( hr == S_OK, "loadXML failed\n");
8360 ok( b == VARIANT_TRUE, "failed to load XML string\n");
8362 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
8363 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8365 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
8366 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8368 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
8369 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8371 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
8372 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8374 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
8375 ok(hr == S_OK, "got 0x%08x\n", hr);
8376 IXMLDOMNode_Release(node);
8378 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
8379 ok(hr == S_OK, "got 0x%08x\n", hr);
8380 IXMLDOMNodeList_Release(list);
8382 list = (void*)0xdeadbeef;
8383 hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
8384 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8385 ok(list == (void*)0xdeadbeef, "got %p\n", list);
8387 node = (void*)0xdeadbeef;
8388 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
8389 ok(hr == S_FALSE, "got 0x%08x\n", hr);
8390 ok(node == 0, "got %p\n", node);
8392 list = (void*)0xdeadbeef;
8393 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
8394 ok(hr == S_OK, "got 0x%08x\n", hr);
8395 len = 1;
8396 hr = IXMLDOMNodeList_get_length(list, &len);
8397 ok(hr == S_OK, "got 0x%08x\n", hr);
8398 ok(len == 0, "got %d\n", len);
8399 IXMLDOMNodeList_Release(list);
8401 IXMLDOMDocument_Release(doc);
8402 free_bstrs();
8405 static void test_events(void)
8407 IConnectionPointContainer *conn;
8408 IConnectionPoint *point;
8409 IXMLDOMDocument *doc;
8410 HRESULT hr;
8411 VARIANT v;
8412 IDispatch *event;
8414 doc = create_document(&IID_IXMLDOMDocument);
8416 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
8417 ok(hr == S_OK, "got 0x%08x\n", hr);
8419 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
8420 ok(hr == S_OK, "got 0x%08x\n", hr);
8421 IConnectionPoint_Release(point);
8422 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
8423 ok(hr == S_OK, "got 0x%08x\n", hr);
8424 IConnectionPoint_Release(point);
8425 hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
8426 ok(hr == S_OK, "got 0x%08x\n", hr);
8427 IConnectionPoint_Release(point);
8429 IConnectionPointContainer_Release(conn);
8431 /* ready state callback */
8432 VariantInit(&v);
8433 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8434 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8436 event = create_dispevent();
8437 V_VT(&v) = VT_UNKNOWN;
8438 V_UNKNOWN(&v) = (IUnknown*)event;
8440 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8441 ok(hr == S_OK, "got 0x%08x\n", hr);
8442 EXPECT_REF(event, 2);
8444 V_VT(&v) = VT_DISPATCH;
8445 V_DISPATCH(&v) = event;
8447 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8448 ok(hr == S_OK, "got 0x%08x\n", hr);
8449 EXPECT_REF(event, 2);
8451 /* VT_NULL doesn't reset event handler */
8452 V_VT(&v) = VT_NULL;
8453 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8454 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
8455 EXPECT_REF(event, 2);
8457 V_VT(&v) = VT_DISPATCH;
8458 V_DISPATCH(&v) = NULL;
8460 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8461 ok(hr == S_OK, "got 0x%08x\n", hr);
8462 EXPECT_REF(event, 1);
8464 V_VT(&v) = VT_UNKNOWN;
8465 V_DISPATCH(&v) = NULL;
8466 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
8467 ok(hr == S_OK, "got 0x%08x\n", hr);
8469 IDispatch_Release(event);
8471 IXMLDOMDocument_Release(doc);
8474 static void test_createProcessingInstruction(void)
8476 static const WCHAR bodyW[] = {'t','e','s','t',0};
8477 IXMLDOMProcessingInstruction *pi;
8478 IXMLDOMDocument *doc;
8479 WCHAR buff[10];
8480 HRESULT hr;
8482 doc = create_document(&IID_IXMLDOMDocument);
8484 /* test for BSTR handling, pass broken BSTR */
8485 memcpy(&buff[2], bodyW, sizeof(bodyW));
8486 /* just a big length */
8487 *(DWORD*)buff = 0xf0f0;
8488 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
8489 ok(hr == S_OK, "got 0x%08x\n", hr);
8491 IXMLDOMProcessingInstruction_Release(pi);
8492 IXMLDOMDocument_Release(doc);
8495 static void test_put_nodeTypedValue(void)
8497 static const BYTE binhexdata[16] =
8498 {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
8499 IXMLDOMDocument *doc;
8500 IXMLDOMElement *elem;
8501 VARIANT type, value;
8502 LONG ubound, lbound;
8503 IXMLDOMNode *node;
8504 SAFEARRAY *array;
8505 HRESULT hr;
8506 BYTE *ptr;
8507 BSTR str;
8509 doc = create_document(&IID_IXMLDOMDocument);
8511 hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
8512 EXPECT_HR(hr, S_OK);
8514 V_VT(&type) = VT_EMPTY;
8515 hr = IXMLDOMElement_get_dataType(elem, &type);
8516 EXPECT_HR(hr, S_FALSE);
8517 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8519 /* set typed value for untyped node */
8520 V_VT(&type) = VT_I1;
8521 V_I1(&type) = 1;
8522 hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
8523 EXPECT_HR(hr, S_OK);
8525 V_VT(&type) = VT_EMPTY;
8526 hr = IXMLDOMElement_get_dataType(elem, &type);
8527 EXPECT_HR(hr, S_FALSE);
8528 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
8530 /* no type info stored */
8531 V_VT(&type) = VT_EMPTY;
8532 hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
8533 EXPECT_HR(hr, S_OK);
8534 ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
8535 ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
8536 "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
8537 VariantClear(&type);
8539 hr = IXMLDOMElement_get_firstChild(elem, &node);
8540 EXPECT_HR(hr, S_OK);
8541 hr = IXMLDOMElement_removeChild(elem, node, NULL);
8542 EXPECT_HR(hr, S_OK);
8543 IXMLDOMNode_Release(node);
8545 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)elem, NULL);
8546 EXPECT_HR(hr, S_OK);
8548 /* bin.base64 */
8549 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.base64"));
8550 EXPECT_HR(hr, S_OK);
8552 V_VT(&value) = VT_BSTR;
8553 V_BSTR(&value) = _bstr_("ABCD");
8554 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8555 EXPECT_HR(hr, S_OK);
8557 V_VT(&value) = VT_EMPTY;
8558 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8559 EXPECT_HR(hr, S_OK);
8560 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8561 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8562 ubound = 0;
8563 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8564 EXPECT_HR(hr, S_OK);
8565 ok(ubound == 2, "got %d\n", ubound);
8566 lbound = 0;
8567 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8568 EXPECT_HR(hr, S_OK);
8569 ok(lbound == 0, "got %d\n", lbound);
8570 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8571 EXPECT_HR(hr, S_OK);
8572 ok(ptr[0] == 0, "got %x\n", ptr[0]);
8573 ok(ptr[1] == 0x10, "got %x\n", ptr[1]);
8574 ok(ptr[2] == 0x83, "got %x\n", ptr[2]);
8575 SafeArrayUnaccessData(V_ARRAY(&value));
8576 VariantClear(&value);
8578 /* when set as VT_BSTR it's stored as is */
8579 hr = IXMLDOMElement_get_firstChild(elem, &node);
8580 EXPECT_HR(hr, S_OK);
8581 hr = IXMLDOMNode_get_text(node, &str);
8582 EXPECT_HR(hr, S_OK);
8583 ok(!lstrcmpW(str, _bstr_("ABCD")), "%s\n", wine_dbgstr_w(str));
8584 IXMLDOMNode_Release(node);
8585 SysFreeString(str);
8587 array = SafeArrayCreateVector(VT_UI1, 0, 7);
8588 hr = SafeArrayAccessData(array, (void*)&ptr);
8589 EXPECT_HR(hr, S_OK);
8590 memcpy(ptr, "dGVzdA=", strlen("dGVzdA="));
8591 SafeArrayUnaccessData(array);
8593 V_VT(&value) = VT_UI1|VT_ARRAY;
8594 V_ARRAY(&value) = array;
8595 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8596 EXPECT_HR(hr, S_OK);
8598 V_VT(&value) = VT_EMPTY;
8599 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8600 EXPECT_HR(hr, S_OK);
8601 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8602 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8603 ubound = 0;
8604 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8605 EXPECT_HR(hr, S_OK);
8606 ok(ubound == 6, "got %d\n", ubound);
8607 lbound = 0;
8608 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8609 EXPECT_HR(hr, S_OK);
8610 ok(lbound == 0, "got %d\n", lbound);
8611 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8612 EXPECT_HR(hr, S_OK);
8613 ok(!memcmp(ptr, "dGVzdA=", strlen("dGVzdA=")), "got wrong data, %s\n", ptr);
8614 SafeArrayUnaccessData(V_ARRAY(&value));
8615 VariantClear(&value);
8617 /* if set with VT_UI1|VT_ARRAY it's encoded */
8618 hr = IXMLDOMElement_get_firstChild(elem, &node);
8619 EXPECT_HR(hr, S_OK);
8620 hr = IXMLDOMNode_get_text(node, &str);
8621 EXPECT_HR(hr, S_OK);
8622 ok(!lstrcmpW(str, _bstr_("ZEdWemRBPQ==")), "%s\n", wine_dbgstr_w(str));
8623 IXMLDOMNode_Release(node);
8624 SafeArrayDestroyData(array);
8625 SysFreeString(str);
8627 /* bin.hex */
8628 V_VT(&value) = VT_BSTR;
8629 V_BSTR(&value) = _bstr_("");
8630 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8631 EXPECT_HR(hr, S_OK);
8633 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.hex"));
8634 EXPECT_HR(hr, S_OK);
8636 array = SafeArrayCreateVector(VT_UI1, 0, 16);
8637 hr = SafeArrayAccessData(array, (void*)&ptr);
8638 EXPECT_HR(hr, S_OK);
8639 memcpy(ptr, binhexdata, sizeof(binhexdata));
8640 SafeArrayUnaccessData(array);
8642 V_VT(&value) = VT_UI1|VT_ARRAY;
8643 V_ARRAY(&value) = array;
8644 hr = IXMLDOMElement_put_nodeTypedValue(elem, value);
8645 EXPECT_HR(hr, S_OK);
8647 V_VT(&value) = VT_EMPTY;
8648 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value);
8649 EXPECT_HR(hr, S_OK);
8650 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value));
8651 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n");
8652 ubound = 0;
8653 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
8654 EXPECT_HR(hr, S_OK);
8655 ok(ubound == 15, "got %d\n", ubound);
8656 lbound = 0;
8657 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);
8658 EXPECT_HR(hr, S_OK);
8659 ok(lbound == 0, "got %d\n", lbound);
8660 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
8661 EXPECT_HR(hr, S_OK);
8662 ok(!memcmp(ptr, binhexdata, sizeof(binhexdata)), "got wrong data\n");
8663 SafeArrayUnaccessData(V_ARRAY(&value));
8664 VariantClear(&value);
8666 /* if set with VT_UI1|VT_ARRAY it's encoded */
8667 hr = IXMLDOMElement_get_firstChild(elem, &node);
8668 EXPECT_HR(hr, S_OK);
8669 hr = IXMLDOMNode_get_text(node, &str);
8670 EXPECT_HR(hr, S_OK);
8671 ok(!lstrcmpW(str, _bstr_("000102030405060708090a0b0c0d0e0f")), "%s\n", wine_dbgstr_w(str));
8672 IXMLDOMNode_Release(node);
8673 SafeArrayDestroyData(array);
8674 SysFreeString(str);
8676 IXMLDOMElement_Release(elem);
8677 IXMLDOMDocument_Release(doc);
8678 free_bstrs();
8681 static void test_get_xml(void)
8683 static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
8684 static const char attrA[] = "attr=\"&quot;a &amp; b&quot;\"";
8685 static const char attr2A[] = "\"a & b\"";
8686 static const char attr3A[] = "attr=\"&amp;quot;a\"";
8687 static const char attr4A[] = "&quot;a";
8688 static const char fooA[] = "<foo/>";
8689 IXMLDOMProcessingInstruction *pi;
8690 IXMLDOMNode *first;
8691 IXMLDOMElement *elem = NULL;
8692 IXMLDOMAttribute *attr;
8693 IXMLDOMDocument *doc;
8694 VARIANT_BOOL b;
8695 VARIANT v;
8696 BSTR xml;
8697 HRESULT hr;
8699 doc = create_document(&IID_IXMLDOMDocument);
8701 b = VARIANT_TRUE;
8702 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8703 ok(hr == S_OK, "got 0x%08x\n", hr);
8704 ok( b == VARIANT_TRUE, "got %d\n", b);
8706 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
8707 _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
8708 ok(hr == S_OK, "got 0x%08x\n", hr);
8710 hr = IXMLDOMDocument_get_firstChild(doc, &first);
8711 ok(hr == S_OK, "got 0x%08x\n", hr);
8713 V_UNKNOWN(&v) = (IUnknown*)first;
8714 V_VT(&v) = VT_UNKNOWN;
8716 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
8717 ok(hr == S_OK, "got 0x%08x\n", hr);
8719 IXMLDOMProcessingInstruction_Release(pi);
8720 IXMLDOMNode_Release(first);
8722 hr = IXMLDOMDocument_get_xml(doc, &xml);
8723 ok(hr == S_OK, "got 0x%08x\n", hr);
8725 ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
8726 "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
8727 SysFreeString(xml);
8729 IXMLDOMDocument_Release(doc);
8731 doc = create_document(&IID_IXMLDOMDocument);
8733 hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem);
8734 ok(hr == S_OK, "got 0x%08x\n", hr);
8736 hr = IXMLDOMDocument_putref_documentElement(doc, elem);
8737 ok(hr == S_OK, "got 0x%08x\n", hr);
8739 hr = IXMLDOMDocument_get_xml(doc, &xml);
8740 ok(hr == S_OK, "got 0x%08x\n", hr);
8742 ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0,
8743 "got %s, expected %s\n", wine_dbgstr_w(xml), fooA);
8744 SysFreeString(xml);
8746 IXMLDOMElement_Release(elem);
8748 /* attribute node */
8749 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
8750 ok(hr == S_OK, "got 0x%08x\n", hr);
8752 V_VT(&v) = VT_BSTR;
8753 V_BSTR(&v) = _bstr_("\"a & b\"");
8754 hr = IXMLDOMAttribute_put_value(attr, v);
8755 ok(hr == S_OK, "got 0x%08x\n", hr);
8757 xml = NULL;
8758 hr = IXMLDOMAttribute_get_xml(attr, &xml);
8759 ok(hr == S_OK, "got 0x%08x\n", hr);
8760 ok(!memcmp(xml, _bstr_(attrA), (sizeof(attrA)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
8761 SysFreeString(xml);
8763 VariantInit(&v);
8764 hr = IXMLDOMAttribute_get_value(attr, &v);
8765 ok(hr == S_OK, "got 0x%08x\n", hr);
8766 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8767 ok(!memcmp(V_BSTR(&v), _bstr_(attr2A), (sizeof(attr2A)-1)*sizeof(WCHAR)),
8768 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8769 VariantClear(&v);
8771 V_VT(&v) = VT_BSTR;
8772 V_BSTR(&v) = _bstr_("&quot;a");
8773 hr = IXMLDOMAttribute_put_value(attr, v);
8774 ok(hr == S_OK, "got 0x%08x\n", hr);
8776 xml = NULL;
8777 hr = IXMLDOMAttribute_get_xml(attr, &xml);
8778 ok(hr == S_OK, "got 0x%08x\n", hr);
8779 ok(!memcmp(xml, _bstr_(attr3A), (sizeof(attr3A)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
8780 SysFreeString(xml);
8782 VariantInit(&v);
8783 hr = IXMLDOMAttribute_get_value(attr, &v);
8784 ok(hr == S_OK, "got 0x%08x\n", hr);
8785 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8786 ok(!memcmp(V_BSTR(&v), _bstr_(attr4A), (sizeof(attr4A)-1)*sizeof(WCHAR)),
8787 "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8788 VariantClear(&v);
8790 IXMLDOMAttribute_Release(attr);
8792 IXMLDOMDocument_Release(doc);
8794 free_bstrs();
8797 static void test_xsltemplate(void)
8799 IXMLDOMDocument *doc, *doc2, *doc3;
8800 IXSLTemplate *template;
8801 IXSLProcessor *processor;
8802 IStream *stream;
8803 VARIANT_BOOL b;
8804 HRESULT hr;
8805 ULONG ref1, ref2;
8806 VARIANT v;
8807 BSTR str;
8809 if (!is_clsid_supported(&CLSID_XSLTemplate, &IID_IXSLTemplate)) return;
8810 template = create_xsltemplate(&IID_IXSLTemplate);
8812 /* works as reset */
8813 hr = IXSLTemplate_putref_stylesheet(template, NULL);
8814 ok(hr == S_OK, "got 0x%08x\n", hr);
8816 doc = create_document(&IID_IXMLDOMDocument);
8818 b = VARIANT_TRUE;
8819 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
8820 ok(hr == S_OK, "got 0x%08x\n", hr);
8821 ok( b == VARIANT_TRUE, "got %d\n", b);
8823 /* putref with non-xsl document */
8824 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8825 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8827 b = VARIANT_TRUE;
8828 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8829 ok(hr == S_OK, "got 0x%08x\n", hr);
8830 ok( b == VARIANT_TRUE, "got %d\n", b);
8832 /* not a freethreaded document */
8833 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8834 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
8836 IXMLDOMDocument_Release(doc);
8838 if (!is_clsid_supported(&CLSID_FreeThreadedDOMDocument, &IID_IXMLDOMDocument))
8840 IXSLTemplate_Release(template);
8841 return;
8844 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
8845 ok(hr == S_OK, "got 0x%08x\n", hr);
8847 b = VARIANT_TRUE;
8848 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
8849 ok(hr == S_OK, "got 0x%08x\n", hr);
8850 ok( b == VARIANT_TRUE, "got %d\n", b);
8852 /* freethreaded document */
8853 ref1 = IXMLDOMDocument_AddRef(doc);
8854 IXMLDOMDocument_Release(doc);
8855 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
8856 ok(hr == S_OK, "got 0x%08x\n", hr);
8857 ref2 = IXMLDOMDocument_AddRef(doc);
8858 IXMLDOMDocument_Release(doc);
8859 ok(ref2 > ref1, "got %d\n", ref2);
8861 /* processor */
8862 hr = IXSLTemplate_createProcessor(template, NULL);
8863 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8865 EXPECT_REF(template, 1);
8866 hr = IXSLTemplate_createProcessor(template, &processor);
8867 ok(hr == S_OK, "got 0x%08x\n", hr);
8868 EXPECT_REF(template, 2);
8870 /* input no set yet */
8871 V_VT(&v) = VT_BSTR;
8872 V_BSTR(&v) = NULL;
8873 hr = IXSLProcessor_get_input(processor, &v);
8874 todo_wine {
8875 ok(hr == S_OK, "got 0x%08x\n", hr);
8876 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
8879 hr = IXSLProcessor_get_output(processor, NULL);
8880 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8882 /* reset before it was set */
8883 V_VT(&v) = VT_EMPTY;
8884 hr = IXSLProcessor_put_output(processor, v);
8885 ok(hr == S_OK, "got 0x%08x\n", hr);
8887 V_VT(&v) = VT_UNKNOWN;
8888 V_UNKNOWN(&v) = NULL;
8889 hr = IXSLProcessor_put_output(processor, v);
8890 ok(hr == S_OK, "got 0x%08x\n", hr);
8892 V_VT(&v) = VT_UNKNOWN;
8893 V_DISPATCH(&v) = NULL;
8894 hr = IXSLProcessor_put_output(processor, v);
8895 ok(hr == S_OK, "got 0x%08x\n", hr);
8897 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
8898 ok(hr == S_OK, "got 0x%08x\n", hr);
8899 EXPECT_REF(stream, 1);
8901 V_VT(&v) = VT_UNKNOWN;
8902 V_UNKNOWN(&v) = (IUnknown*)stream;
8903 hr = IXSLProcessor_put_output(processor, v);
8904 ok(hr == S_OK, "got 0x%08x\n", hr);
8906 /* it seems processor grabs 2 references */
8907 todo_wine EXPECT_REF(stream, 3);
8909 V_VT(&v) = VT_EMPTY;
8910 hr = IXSLProcessor_get_output(processor, &v);
8911 ok(hr == S_OK, "got 0x%08x\n", hr);
8912 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
8913 ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
8915 todo_wine EXPECT_REF(stream, 4);
8916 VariantClear(&v);
8918 hr = IXSLProcessor_transform(processor, NULL);
8919 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8921 /* reset and check stream refcount */
8922 V_VT(&v) = VT_EMPTY;
8923 hr = IXSLProcessor_put_output(processor, v);
8924 ok(hr == S_OK, "got 0x%08x\n", hr);
8926 EXPECT_REF(stream, 1);
8928 IStream_Release(stream);
8930 /* no output interface set, check output */
8931 doc2 = create_document(&IID_IXMLDOMDocument);
8933 b = VARIANT_FALSE;
8934 hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
8935 ok(hr == S_OK, "got 0x%08x\n", hr);
8936 ok( b == VARIANT_TRUE, "got %d\n", b);
8938 V_VT(&v) = VT_UNKNOWN;
8939 V_UNKNOWN(&v) = (IUnknown*)doc2;
8940 hr = IXSLProcessor_put_input(processor, v);
8941 ok(hr == S_OK, "got 0x%08x\n", hr);
8943 hr = IXSLProcessor_transform(processor, &b);
8944 ok(hr == S_OK, "got 0x%08x\n", hr);
8946 V_VT(&v) = VT_EMPTY;
8947 hr = IXSLProcessor_get_output(processor, &v);
8948 ok(hr == S_OK, "got 0x%08x\n", hr);
8949 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
8950 ok(*V_BSTR(&v) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
8951 VariantClear(&v);
8953 /* transform to document */
8954 b = VARIANT_FALSE;
8955 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformXML), &b);
8956 ok(hr == S_OK, "got 0x%08x\n", hr);
8957 ok(b == VARIANT_TRUE, "got %d\n", b);
8959 V_VT(&v) = VT_UNKNOWN;
8960 V_UNKNOWN(&v) = (IUnknown*)doc2;
8961 hr = IXSLProcessor_put_input(processor, v);
8962 ok(hr == S_OK, "got 0x%08x\n", hr);
8964 doc3 = create_document(&IID_IXMLDOMDocument);
8965 V_VT(&v) = VT_UNKNOWN;
8966 V_UNKNOWN(&v) = (IUnknown *)doc3;
8967 hr = IXSLProcessor_put_output(processor, v);
8968 ok(hr == S_OK, "got 0x%08x\n", hr);
8970 hr = IXMLDOMDocument_get_xml(doc3, &str);
8971 ok(hr == S_OK, "got 0x%08x\n", hr);
8972 ok(!*str, "Expected empty document\n");
8973 SysFreeString(str);
8975 hr = IXSLProcessor_transform(processor, &b);
8976 ok(hr == S_OK, "got 0x%08x\n", hr);
8978 V_VT(&v) = VT_EMPTY;
8979 hr = IXSLProcessor_get_output(processor, &v);
8980 ok(hr == S_OK, "got 0x%08x\n", hr);
8981 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
8982 VariantClear(&v);
8984 hr = IXMLDOMDocument_get_xml(doc3, &str);
8985 ok(hr == S_OK, "got 0x%08x\n", hr);
8986 ok(!!*str, "Expected document\n");
8987 SysFreeString(str);
8989 /* transform to IResponse */
8990 V_VT(&v) = VT_EMPTY;
8991 hr = IXSLProcessor_put_output(processor, v);
8992 ok(hr == S_OK, "got 0x%08x\n", hr);
8994 V_VT(&v) = VT_UNKNOWN;
8995 V_UNKNOWN(&v) = (IUnknown *)&testresponse;
8996 hr = IXSLProcessor_put_output(processor, v);
8997 ok(hr == S_OK, "got 0x%08x\n", hr);
8999 b = VARIANT_FALSE;
9000 hr = IXSLProcessor_transform(processor, &b);
9001 ok(hr == S_OK, "got 0x%08x\n", hr);
9002 ok(b == VARIANT_TRUE, "got %x\n", b);
9004 IXSLProcessor_Release(processor);
9005 IXMLDOMDocument_Release(doc2);
9006 IXMLDOMDocument_Release(doc3);
9008 /* drop reference */
9009 hr = IXSLTemplate_putref_stylesheet(template, NULL);
9010 ok(hr == S_OK, "got 0x%08x\n", hr);
9011 ref2 = IXMLDOMDocument_AddRef(doc);
9012 IXMLDOMDocument_Release(doc);
9013 ok(ref2 == ref1, "got %d\n", ref2);
9015 IXMLDOMDocument_Release(doc);
9016 IXSLTemplate_Release(template);
9017 free_bstrs();
9020 static void test_insertBefore(void)
9022 IXMLDOMDocument *doc, *doc2, *doc3;
9023 IXMLDOMAttribute *attr;
9024 IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
9025 IXMLDOMNode *node, *newnode, *cdata;
9026 HRESULT hr;
9027 VARIANT v;
9028 BSTR p;
9030 doc = create_document(&IID_IXMLDOMDocument);
9031 doc3 = create_document(&IID_IXMLDOMDocument);
9033 /* document to document */
9034 V_VT(&v) = VT_NULL;
9035 node = (void*)0xdeadbeef;
9036 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc3, v, &node);
9037 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9038 ok(node == NULL, "got %p\n", node);
9040 /* document to itself */
9041 V_VT(&v) = VT_NULL;
9042 node = (void*)0xdeadbeef;
9043 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc, v, &node);
9044 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9045 ok(node == NULL, "got %p\n", node);
9047 /* insertBefore behaviour for attribute node */
9048 V_VT(&v) = VT_I4;
9049 V_I4(&v) = NODE_ATTRIBUTE;
9051 attr = NULL;
9052 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
9053 ok(hr == S_OK, "got 0x%08x\n", hr);
9054 ok(attr != NULL, "got %p\n", attr);
9056 /* attribute to document */
9057 V_VT(&v) = VT_NULL;
9058 node = (void*)0xdeadbeef;
9059 hr = IXMLDOMDocument_insertBefore(doc3, (IXMLDOMNode*)attr, v, &node);
9060 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9061 ok(node == NULL, "got %p\n", node);
9063 /* cdata to document */
9064 V_VT(&v) = VT_I4;
9065 V_I4(&v) = NODE_CDATA_SECTION;
9067 cdata = NULL;
9068 hr = IXMLDOMDocument_createNode(doc3, v, _bstr_("cdata"), NULL, &cdata);
9069 ok(hr == S_OK, "got 0x%08x\n", hr);
9070 ok(cdata != NULL, "got %p\n", cdata);
9072 EXPECT_NO_CHILDREN(cdata);
9074 /* attribute to cdata */
9075 V_VT(&v) = VT_NULL;
9076 node = (void*)0xdeadbeef;
9077 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)attr, v, &node);
9078 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9079 ok(node == NULL, "got %p\n", node);
9081 /* document to cdata */
9082 V_VT(&v) = VT_NULL;
9083 node = (void*)0xdeadbeef;
9084 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)doc, v, &node);
9085 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9086 ok(node == NULL, "got %p\n", node);
9088 V_VT(&v) = VT_NULL;
9089 node = (void*)0xdeadbeef;
9090 hr = IXMLDOMDocument_insertBefore(doc3, cdata, v, &node);
9091 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9092 ok(node == NULL, "got %p\n", node);
9094 IXMLDOMNode_Release(cdata);
9095 IXMLDOMDocument_Release(doc3);
9097 /* attribute to attribute */
9098 V_VT(&v) = VT_I4;
9099 V_I4(&v) = NODE_ATTRIBUTE;
9100 newnode = NULL;
9101 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
9102 ok(hr == S_OK, "got 0x%08x\n", hr);
9103 ok(newnode != NULL, "got %p\n", newnode);
9105 V_VT(&v) = VT_NULL;
9106 node = (void*)0xdeadbeef;
9107 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9108 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9109 ok(node == NULL, "got %p\n", node);
9111 V_VT(&v) = VT_UNKNOWN;
9112 V_UNKNOWN(&v) = (IUnknown*)attr;
9113 node = (void*)0xdeadbeef;
9114 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9115 todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9116 ok(node == NULL, "got %p\n", node);
9117 IXMLDOMNode_Release(newnode);
9119 /* cdata to attribute */
9120 V_VT(&v) = VT_I4;
9121 V_I4(&v) = NODE_CDATA_SECTION;
9122 newnode = NULL;
9123 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9124 ok(hr == S_OK, "got 0x%08x\n", hr);
9125 ok(newnode != NULL, "got %p\n", newnode);
9127 V_VT(&v) = VT_NULL;
9128 node = (void*)0xdeadbeef;
9129 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9130 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9131 ok(node == NULL, "got %p\n", node);
9132 IXMLDOMNode_Release(newnode);
9134 /* comment to attribute */
9135 V_VT(&v) = VT_I4;
9136 V_I4(&v) = NODE_COMMENT;
9137 newnode = NULL;
9138 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9139 ok(hr == S_OK, "got 0x%08x\n", hr);
9140 ok(newnode != NULL, "got %p\n", newnode);
9142 V_VT(&v) = VT_NULL;
9143 node = (void*)0xdeadbeef;
9144 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9145 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9146 ok(node == NULL, "got %p\n", node);
9147 IXMLDOMNode_Release(newnode);
9149 /* element to attribute */
9150 V_VT(&v) = VT_I4;
9151 V_I4(&v) = NODE_ELEMENT;
9152 newnode = NULL;
9153 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9154 ok(hr == S_OK, "got 0x%08x\n", hr);
9155 ok(newnode != NULL, "got %p\n", newnode);
9157 V_VT(&v) = VT_NULL;
9158 node = (void*)0xdeadbeef;
9159 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9160 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9161 ok(node == NULL, "got %p\n", node);
9162 IXMLDOMNode_Release(newnode);
9164 /* pi to attribute */
9165 V_VT(&v) = VT_I4;
9166 V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
9167 newnode = NULL;
9168 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
9169 ok(hr == S_OK, "got 0x%08x\n", hr);
9170 ok(newnode != NULL, "got %p\n", newnode);
9172 V_VT(&v) = VT_NULL;
9173 node = (void*)0xdeadbeef;
9174 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
9175 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9176 ok(node == NULL, "got %p\n", node);
9177 IXMLDOMNode_Release(newnode);
9178 IXMLDOMAttribute_Release(attr);
9180 /* insertBefore for elements */
9181 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
9182 ok(hr == S_OK, "got 0x%08x\n", hr);
9184 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
9185 ok(hr == S_OK, "got 0x%08x\n", hr);
9187 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9188 ok(hr == S_OK, "got 0x%08x\n", hr);
9190 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
9191 ok(hr == S_OK, "got 0x%08x\n", hr);
9193 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4);
9194 ok(hr == S_OK, "got 0x%08x\n", hr);
9196 EXPECT_NO_CHILDREN(elem1);
9197 EXPECT_NO_CHILDREN(elem2);
9198 EXPECT_NO_CHILDREN(elem3);
9200 todo_wine EXPECT_REF(elem2, 2);
9202 /* document to element */
9203 V_VT(&v) = VT_DISPATCH;
9204 V_DISPATCH(&v) = NULL;
9205 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)doc, v, NULL);
9206 ok(hr == E_FAIL, "got 0x%08x\n", hr);
9208 V_VT(&v) = VT_DISPATCH;
9209 V_DISPATCH(&v) = NULL;
9210 node = NULL;
9211 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node);
9212 ok(hr == S_OK, "got 0x%08x\n", hr);
9213 ok(node == (void*)elem4, "got %p\n", node);
9215 EXPECT_CHILDREN(elem1);
9216 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL);
9217 EXPECT_HR(hr, S_OK);
9218 IXMLDOMElement_Release(elem4);
9220 EXPECT_NO_CHILDREN(elem1);
9222 V_VT(&v) = VT_NULL;
9223 node = NULL;
9224 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9225 ok(hr == S_OK, "got 0x%08x\n", hr);
9226 ok(node == (void*)elem2, "got %p\n", node);
9228 EXPECT_CHILDREN(elem1);
9229 todo_wine EXPECT_REF(elem2, 3);
9230 IXMLDOMNode_Release(node);
9232 /* again for already linked node */
9233 V_VT(&v) = VT_NULL;
9234 node = NULL;
9235 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
9236 ok(hr == S_OK, "got 0x%08x\n", hr);
9237 ok(node == (void*)elem2, "got %p\n", node);
9239 EXPECT_CHILDREN(elem1);
9241 /* increments each time */
9242 todo_wine EXPECT_REF(elem2, 3);
9243 IXMLDOMNode_Release(node);
9245 /* try to add to another element */
9246 V_VT(&v) = VT_NULL;
9247 node = (void*)0xdeadbeef;
9248 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
9249 ok(hr == S_OK, "got 0x%08x\n", hr);
9250 ok(node == (void*)elem2, "got %p\n", node);
9252 EXPECT_CHILDREN(elem3);
9253 EXPECT_NO_CHILDREN(elem1);
9255 IXMLDOMNode_Release(node);
9257 /* cross document case - try to add as child to a node created with other doc */
9258 doc2 = create_document(&IID_IXMLDOMDocument);
9260 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
9261 ok(hr == S_OK, "got 0x%08x\n", hr);
9262 todo_wine EXPECT_REF(elem4, 2);
9264 /* same name, another instance */
9265 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
9266 ok(hr == S_OK, "got 0x%08x\n", hr);
9267 todo_wine EXPECT_REF(elem5, 2);
9269 todo_wine EXPECT_REF(elem3, 2);
9270 V_VT(&v) = VT_NULL;
9271 node = NULL;
9272 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
9273 ok(hr == S_OK, "got 0x%08x\n", hr);
9274 ok(node == (void*)elem4, "got %p\n", node);
9275 todo_wine EXPECT_REF(elem4, 3);
9276 todo_wine EXPECT_REF(elem3, 2);
9277 IXMLDOMNode_Release(node);
9279 V_VT(&v) = VT_NULL;
9280 node = NULL;
9281 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
9282 ok(hr == S_OK, "got 0x%08x\n", hr);
9283 ok(node == (void*)elem5, "got %p\n", node);
9284 todo_wine EXPECT_REF(elem4, 2);
9285 todo_wine EXPECT_REF(elem5, 3);
9286 IXMLDOMNode_Release(node);
9288 IXMLDOMDocument_Release(doc2);
9290 IXMLDOMElement_Release(elem1);
9291 IXMLDOMElement_Release(elem2);
9292 IXMLDOMElement_Release(elem3);
9293 IXMLDOMElement_Release(elem4);
9294 IXMLDOMElement_Release(elem5);
9296 /* elements with same default namespace */
9297 V_VT(&v) = VT_I4;
9298 V_I4(&v) = NODE_ELEMENT;
9299 elem1 = NULL;
9300 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9301 ok(hr == S_OK, "got 0x%08x\n", hr);
9302 ok(elem1 != NULL, "got %p\n", elem1);
9304 V_VT(&v) = VT_I4;
9305 V_I4(&v) = NODE_ELEMENT;
9306 elem2 = NULL;
9307 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
9308 ok(hr == S_OK, "got 0x%08x\n", hr);
9309 ok(elem2 != NULL, "got %p\n", elem2);
9311 /* check contents so far */
9312 p = NULL;
9313 hr = IXMLDOMElement_get_xml(elem1, &p);
9314 ok(hr == S_OK, "got 0x%08x\n", hr);
9315 ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9316 SysFreeString(p);
9318 p = NULL;
9319 hr = IXMLDOMElement_get_xml(elem2, &p);
9320 ok(hr == S_OK, "got 0x%08x\n", hr);
9321 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9322 SysFreeString(p);
9324 V_VT(&v) = VT_NULL;
9325 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9326 ok(hr == S_OK, "got 0x%08x\n", hr);
9328 /* get_xml depends on context, for top node it omits child namespace attribute,
9329 but at child level it's still returned */
9330 p = NULL;
9331 hr = IXMLDOMElement_get_xml(elem1, &p);
9332 ok(hr == S_OK, "got 0x%08x\n", hr);
9333 todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
9334 "got %s\n", wine_dbgstr_w(p));
9335 SysFreeString(p);
9337 p = NULL;
9338 hr = IXMLDOMElement_get_xml(elem2, &p);
9339 ok(hr == S_OK, "got 0x%08x\n", hr);
9340 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
9341 SysFreeString(p);
9343 IXMLDOMElement_Release(elem1);
9344 IXMLDOMElement_Release(elem2);
9346 /* child without default namespace added to node with default namespace */
9347 V_VT(&v) = VT_I4;
9348 V_I4(&v) = NODE_ELEMENT;
9349 elem1 = NULL;
9350 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
9351 ok(hr == S_OK, "got 0x%08x\n", hr);
9352 ok(elem1 != NULL, "got %p\n", elem1);
9354 V_VT(&v) = VT_I4;
9355 V_I4(&v) = NODE_ELEMENT;
9356 elem2 = NULL;
9357 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
9358 ok(hr == S_OK, "got 0x%08x\n", hr);
9359 ok(elem2 != NULL, "got %p\n", elem2);
9361 EXPECT_REF(elem2, 1);
9362 V_VT(&v) = VT_NULL;
9363 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
9364 ok(hr == S_OK, "got 0x%08x\n", hr);
9365 EXPECT_REF(elem2, 1);
9367 p = NULL;
9368 hr = IXMLDOMElement_get_xml(elem2, &p);
9369 ok(hr == S_OK, "got 0x%08x\n", hr);
9370 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9371 SysFreeString(p);
9373 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
9374 ok(hr == S_OK, "got 0x%08x\n", hr);
9376 p = NULL;
9377 hr = IXMLDOMElement_get_xml(elem2, &p);
9378 ok(hr == S_OK, "got 0x%08x\n", hr);
9379 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
9380 SysFreeString(p);
9382 IXMLDOMElement_Release(elem1);
9383 IXMLDOMElement_Release(elem2);
9384 IXMLDOMDocument_Release(doc);
9387 static void test_appendChild(void)
9389 IXMLDOMDocument *doc, *doc2;
9390 IXMLDOMElement *elem, *elem2;
9391 HRESULT hr;
9393 doc = create_document(&IID_IXMLDOMDocument);
9394 doc2 = create_document(&IID_IXMLDOMDocument);
9396 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
9397 ok(hr == S_OK, "got 0x%08x\n", hr);
9399 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
9400 ok(hr == S_OK, "got 0x%08x\n", hr);
9402 EXPECT_REF(doc, 1);
9403 todo_wine EXPECT_REF(elem, 2);
9404 EXPECT_REF(doc2, 1);
9405 todo_wine EXPECT_REF(elem2, 2);
9406 EXPECT_NO_CHILDREN(doc);
9407 EXPECT_NO_CHILDREN(doc2);
9409 hr = IXMLDOMDocument_appendChild(doc2, NULL, NULL);
9410 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9412 hr = IXMLDOMElement_appendChild(elem, NULL, NULL);
9413 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9415 /* append from another document */
9416 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
9417 ok(hr == S_OK, "got 0x%08x\n", hr);
9419 EXPECT_REF(doc, 1);
9420 todo_wine EXPECT_REF(elem, 2);
9421 EXPECT_REF(doc2, 1);
9422 todo_wine EXPECT_REF(elem2, 2);
9423 EXPECT_NO_CHILDREN(doc);
9424 EXPECT_CHILDREN(doc2);
9426 IXMLDOMElement_Release(elem);
9427 IXMLDOMElement_Release(elem2);
9428 IXMLDOMDocument_Release(doc);
9429 IXMLDOMDocument_Release(doc2);
9432 static void test_get_doctype(void)
9434 static const WCHAR emailW[] = {'e','m','a','i','l',0};
9435 IXMLDOMDocumentType *doctype;
9436 IXMLDOMDocument *doc;
9437 VARIANT_BOOL b;
9438 HRESULT hr;
9439 BSTR s;
9441 doc = create_document(&IID_IXMLDOMDocument);
9443 hr = IXMLDOMDocument_get_doctype(doc, NULL);
9444 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9446 doctype = (void*)0xdeadbeef;
9447 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9448 ok(hr == S_FALSE, "got 0x%08x\n", hr);
9449 ok(doctype == NULL, "got %p\n", doctype);
9451 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szEmailXML), &b);
9452 ok(hr == S_OK, "got 0x%08x\n", hr);
9453 ok(b == VARIANT_TRUE, "failed to load XML string\n");
9455 doctype = NULL;
9456 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
9457 ok(hr == S_OK, "got 0x%08x\n", hr);
9458 ok(doctype != NULL, "got %p\n", doctype);
9460 hr = IXMLDOMDocumentType_get_name(doctype, NULL);
9461 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9463 hr = IXMLDOMDocumentType_get_name(doctype, &s);
9464 ok(hr == S_OK, "got 0x%08x\n", hr);
9465 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s));
9466 SysFreeString(s);
9468 hr = IXMLDOMDocumentType_get_nodeName(doctype, &s);
9469 ok(hr == S_OK, "got 0x%08x\n", hr);
9470 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s));
9471 SysFreeString(s);
9473 IXMLDOMDocumentType_Release(doctype);
9474 IXMLDOMDocument_Release(doc);
9477 static void test_get_tagName(void)
9479 IXMLDOMDocument *doc;
9480 IXMLDOMElement *elem, *elem2;
9481 HRESULT hr;
9482 BSTR str;
9484 doc = create_document(&IID_IXMLDOMDocument);
9486 hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
9487 ok(hr == S_OK, "got 0x%08x\n", hr);
9489 hr = IXMLDOMElement_get_tagName(elem, NULL);
9490 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9492 str = NULL;
9493 hr = IXMLDOMElement_get_tagName(elem, &str);
9494 ok(hr == S_OK, "got 0x%08x\n", hr);
9495 ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
9496 SysFreeString(str);
9498 hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
9499 ok(hr == S_OK, "got 0x%08x\n", hr);
9501 str = NULL;
9502 hr = IXMLDOMElement_get_tagName(elem2, &str);
9503 ok(hr == S_OK, "got 0x%08x\n", hr);
9504 ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
9505 SysFreeString(str);
9507 IXMLDOMElement_Release(elem);
9508 IXMLDOMElement_Release(elem2);
9509 IXMLDOMDocument_Release(doc);
9510 free_bstrs();
9513 typedef struct {
9514 DOMNodeType type;
9515 const char *name;
9516 VARTYPE vt;
9517 HRESULT hr;
9518 } node_type_t;
9520 static const node_type_t get_datatype[] = {
9521 { NODE_ELEMENT, "element", VT_NULL, S_FALSE },
9522 { NODE_ATTRIBUTE, "attr", VT_NULL, S_FALSE },
9523 { NODE_TEXT, "text", VT_NULL, S_FALSE },
9524 { NODE_CDATA_SECTION , "cdata", VT_NULL, S_FALSE },
9525 { NODE_ENTITY_REFERENCE, "entityref", VT_NULL, S_FALSE },
9526 { NODE_PROCESSING_INSTRUCTION, "pi", VT_NULL, S_FALSE },
9527 { NODE_COMMENT, "comment", VT_NULL, S_FALSE },
9528 { NODE_DOCUMENT_FRAGMENT, "docfrag", VT_NULL, S_FALSE },
9529 { 0 }
9532 static void test_get_dataType(void)
9534 const node_type_t *entry = get_datatype;
9535 IXMLDOMDocument *doc;
9537 doc = create_document(&IID_IXMLDOMDocument);
9539 while (entry->type)
9541 IXMLDOMNode *node = NULL;
9542 VARIANT var, type;
9543 HRESULT hr;
9545 V_VT(&var) = VT_I4;
9546 V_I4(&var) = entry->type;
9547 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
9548 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9550 hr = IXMLDOMNode_get_dataType(node, NULL);
9551 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9553 VariantInit(&type);
9554 hr = IXMLDOMNode_get_dataType(node, &type);
9555 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9556 hr, entry->hr, entry->type);
9557 ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
9558 V_VT(&type), entry->vt, entry->type);
9559 VariantClear(&type);
9561 IXMLDOMNode_Release(node);
9563 entry++;
9566 IXMLDOMDocument_Release(doc);
9567 free_bstrs();
9570 typedef struct _get_node_typestring_t {
9571 DOMNodeType type;
9572 const char *string;
9573 } get_node_typestring_t;
9575 static const get_node_typestring_t get_node_typestring[] = {
9576 { NODE_ELEMENT, "element" },
9577 { NODE_ATTRIBUTE, "attribute" },
9578 { NODE_TEXT, "text" },
9579 { NODE_CDATA_SECTION , "cdatasection" },
9580 { NODE_ENTITY_REFERENCE, "entityreference" },
9581 { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
9582 { NODE_COMMENT, "comment" },
9583 { NODE_DOCUMENT_FRAGMENT, "documentfragment" },
9584 { 0 }
9587 static void test_get_nodeTypeString(void)
9589 const get_node_typestring_t *entry = get_node_typestring;
9590 IXMLDOMDocument *doc;
9591 HRESULT hr;
9592 BSTR str;
9594 doc = create_document(&IID_IXMLDOMDocument);
9596 hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
9597 ok(hr == S_OK, "got 0x%08x\n", hr);
9598 ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
9599 SysFreeString(str);
9601 while (entry->type)
9603 IXMLDOMNode *node = NULL;
9604 VARIANT var;
9606 V_VT(&var) = VT_I4;
9607 V_I4(&var) = entry->type;
9608 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9609 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9611 hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
9612 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9614 hr = IXMLDOMNode_get_nodeTypeString(node, &str);
9615 ok(hr == S_OK, "got 0x%08x\n", hr);
9616 ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
9617 wine_dbgstr_w(str), entry->string, entry->type);
9618 SysFreeString(str);
9619 IXMLDOMNode_Release(node);
9621 entry++;
9624 IXMLDOMDocument_Release(doc);
9625 free_bstrs();
9628 typedef struct _get_attributes_t {
9629 DOMNodeType type;
9630 HRESULT hr;
9631 } get_attributes_t;
9633 static const get_attributes_t get_attributes[] = {
9634 { NODE_ATTRIBUTE, S_FALSE },
9635 { NODE_TEXT, S_FALSE },
9636 { NODE_CDATA_SECTION , S_FALSE },
9637 { NODE_ENTITY_REFERENCE, S_FALSE },
9638 { NODE_PROCESSING_INSTRUCTION, S_FALSE },
9639 { NODE_COMMENT, S_FALSE },
9640 { NODE_DOCUMENT_FRAGMENT, S_FALSE },
9641 { 0 }
9644 static void test_get_attributes(void)
9646 const get_attributes_t *entry = get_attributes;
9647 IXMLDOMNamedNodeMap *map;
9648 IXMLDOMDocument *doc, *doc2;
9649 IXMLDOMNode *node, *node2;
9650 IXMLDOMElement *elem;
9651 VARIANT_BOOL b;
9652 HRESULT hr;
9653 VARIANT v;
9654 BSTR str;
9655 LONG length;
9657 doc = create_document(&IID_IXMLDOMDocument);
9659 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
9660 ok(hr == S_OK, "got %08x\n", hr);
9662 hr = IXMLDOMDocument_get_attributes(doc, NULL);
9663 ok(hr == E_INVALIDARG, "got %08x\n", hr);
9665 map = (void*)0xdeadbeef;
9666 hr = IXMLDOMDocument_get_attributes(doc, &map);
9667 ok(hr == S_FALSE, "got %08x\n", hr);
9668 ok(map == NULL, "got %p\n", map);
9670 /* first child is <?xml ?> */
9671 hr = IXMLDOMDocument_get_firstChild(doc, &node);
9672 ok(hr == S_OK, "got %08x\n", hr);
9674 hr = IXMLDOMNode_get_attributes(node, &map);
9675 ok(hr == S_OK, "got %08x\n", hr);
9677 node2 = (void*)0xdeadbeef;
9678 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("attr"), &node2);
9679 ok(hr == S_FALSE, "got %08x\n", hr);
9680 ok(node2 == NULL, "got %p\n", node2);
9682 length = -1;
9683 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9684 EXPECT_HR(hr, S_OK);
9685 todo_wine ok(length == 1, "got %d\n", length);
9687 if (hr == S_OK && length == 1)
9689 IXMLDOMAttribute *attr;
9690 DOMNodeType type;
9691 VARIANT v;
9693 node2 = NULL;
9694 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9695 EXPECT_HR(hr, S_OK);
9696 ok(node != NULL, "got %p\n", node2);
9698 hr = IXMLDOMNode_get_nodeName(node2, &str);
9699 EXPECT_HR(hr, S_OK);
9700 ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
9701 SysFreeString(str);
9703 length = -1;
9704 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9705 EXPECT_HR(hr, S_OK);
9706 ok(length == 1, "got %d\n", length);
9708 type = -1;
9709 hr = IXMLDOMNode_get_nodeType(node2, &type);
9710 EXPECT_HR(hr, S_OK);
9711 ok(type == NODE_ATTRIBUTE, "got %d\n", type);
9713 hr = IXMLDOMNode_get_xml(node, &str);
9714 EXPECT_HR(hr, S_OK);
9715 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9716 SysFreeString(str);
9718 hr = IXMLDOMNode_get_text(node, &str);
9719 EXPECT_HR(hr, S_OK);
9720 ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str));
9721 SysFreeString(str);
9723 hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL);
9724 EXPECT_HR(hr, S_OK);
9726 length = -1;
9727 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9728 EXPECT_HR(hr, S_OK);
9729 ok(length == 0, "got %d\n", length);
9731 hr = IXMLDOMNode_get_xml(node, &str);
9732 EXPECT_HR(hr, S_OK);
9733 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9734 SysFreeString(str);
9736 hr = IXMLDOMNode_get_text(node, &str);
9737 EXPECT_HR(hr, S_OK);
9738 ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str));
9739 SysFreeString(str);
9741 IXMLDOMNamedNodeMap_Release(map);
9743 hr = IXMLDOMNode_get_attributes(node, &map);
9744 ok(hr == S_OK, "got %08x\n", hr);
9746 length = -1;
9747 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9748 EXPECT_HR(hr, S_OK);
9749 ok(length == 0, "got %d\n", length);
9751 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr);
9752 EXPECT_HR(hr, S_OK);
9754 V_VT(&v) = VT_BSTR;
9755 V_BSTR(&v) = _bstr_("UTF-8");
9756 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
9757 EXPECT_HR(hr, S_OK);
9759 EXPECT_REF(attr, 2);
9760 hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL);
9761 EXPECT_HR(hr, S_OK);
9762 EXPECT_REF(attr, 2);
9764 hr = IXMLDOMNode_get_attributes(node, &map);
9765 ok(hr == S_OK, "got %08x\n", hr);
9767 length = -1;
9768 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9769 EXPECT_HR(hr, S_OK);
9770 ok(length == 1, "got %d\n", length);
9772 hr = IXMLDOMNode_get_xml(node, &str);
9773 EXPECT_HR(hr, S_OK);
9774 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str));
9775 SysFreeString(str);
9777 hr = IXMLDOMNode_get_text(node, &str);
9778 EXPECT_HR(hr, S_OK);
9779 ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str));
9780 SysFreeString(str);
9782 IXMLDOMNamedNodeMap_Release(map);
9783 IXMLDOMNode_Release(node2);
9786 IXMLDOMNode_Release(node);
9788 /* last child is element */
9789 EXPECT_REF(doc, 1);
9790 hr = IXMLDOMDocument_get_lastChild(doc, &node);
9791 ok(hr == S_OK, "got %08x\n", hr);
9792 EXPECT_REF(doc, 1);
9794 EXPECT_REF(node, 1);
9795 hr = IXMLDOMNode_get_attributes(node, &map);
9796 ok(hr == S_OK, "got %08x\n", hr);
9797 EXPECT_REF(node, 1);
9798 EXPECT_REF(doc, 1);
9800 EXPECT_REF(map, 1);
9801 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9802 ok(hr == S_OK, "got %08x\n", hr);
9803 EXPECT_REF(node, 1);
9804 EXPECT_REF(node2, 1);
9805 EXPECT_REF(map, 1);
9806 EXPECT_REF(doc, 1);
9807 IXMLDOMNode_Release(node2);
9809 /* release node before map release, map still works */
9810 IXMLDOMNode_Release(node);
9812 length = 0;
9813 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9814 ok(hr == S_OK, "got %08x\n", hr);
9815 ok(length == 1, "got %d\n", length);
9817 node2 = NULL;
9818 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
9819 ok(hr == S_OK, "got %08x\n", hr);
9820 EXPECT_REF(node2, 1);
9821 IXMLDOMNode_Release(node2);
9823 IXMLDOMNamedNodeMap_Release(map);
9825 /* append created element a different document, map still works */
9826 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
9827 ok(hr == S_OK, "createElement failed: %08x\n", hr);
9829 V_VT(&v) = VT_I4;
9830 V_I4(&v) = 1;
9831 hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v);
9832 ok(hr == S_OK, "setAttribute failed: %08x\n", hr);
9834 hr = IXMLDOMElement_get_attributes(elem, &map);
9835 ok(hr == S_OK, "get_attributes failed: %08x\n", hr);
9837 length = 0;
9838 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9839 ok(hr == S_OK, "got %08x\n", hr);
9840 ok(length == 1, "got %d\n", length);
9842 doc2 = create_document(&IID_IXMLDOMDocument);
9844 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node);
9845 ok(hr == S_OK, "appendChild failed: %08x\n", hr);
9846 ok(node == (IXMLDOMNode*)elem, "node != elem\n");
9847 IXMLDOMNode_Release(node);
9848 IXMLDOMElement_Release(elem);
9849 IXMLDOMDocument_Release(doc2);
9851 length = 0;
9852 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
9853 ok(hr == S_OK, "got %08x\n", hr);
9854 ok(length == 1, "got %d\n", length);
9856 IXMLDOMNamedNodeMap_Release(map);
9858 while (entry->type)
9860 VARIANT var;
9862 node = NULL;
9864 V_VT(&var) = VT_I4;
9865 V_I4(&var) = entry->type;
9866 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
9867 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
9869 hr = IXMLDOMNode_get_attributes(node, NULL);
9870 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
9872 map = (void*)0xdeadbeef;
9873 hr = IXMLDOMNode_get_attributes(node, &map);
9874 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
9875 hr, entry->hr, entry->type);
9876 ok(map == NULL, "got %p\n", map);
9878 IXMLDOMNode_Release(node);
9880 entry++;
9883 IXMLDOMDocument_Release(doc);
9884 free_bstrs();
9887 static void test_selection(void)
9889 IXMLDOMSelection *selection, *selection2;
9890 IEnumVARIANT *enum1, *enum2, *enum3;
9891 IXMLDOMNodeList *list;
9892 IUnknown *unk1, *unk2;
9893 IXMLDOMDocument *doc;
9894 IDispatchEx *dispex;
9895 IXMLDOMNode *node;
9896 IDispatch *disp;
9897 VARIANT_BOOL b;
9898 HRESULT hr;
9899 DISPID did;
9900 VARIANT v;
9901 BSTR name;
9902 ULONG ret;
9903 LONG len;
9905 doc = create_document(&IID_IXMLDOMDocument);
9907 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
9908 EXPECT_HR(hr, S_OK);
9910 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
9911 EXPECT_HR(hr, S_OK);
9913 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
9914 EXPECT_HR(hr, S_OK);
9915 IXMLDOMSelection_Release(selection);
9917 /* collection disp id */
9918 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex);
9919 EXPECT_HR(hr, S_OK);
9920 did = 0;
9921 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
9922 EXPECT_HR(hr, S_OK);
9923 ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did);
9924 len = 0;
9925 hr = IXMLDOMSelection_get_length(selection, &len);
9926 EXPECT_HR(hr, S_OK);
9927 ok(len == 1, "got %d\n", len);
9928 hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did);
9929 EXPECT_HR(hr, S_OK);
9930 ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did);
9931 IDispatchEx_Release(dispex);
9933 /* IEnumVARIANT tests */
9934 enum1 = NULL;
9935 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
9936 EXPECT_HR(hr, S_OK);
9937 ok(enum1 != NULL, "got %p\n", enum1);
9938 EXPECT_REF(enum1, 2);
9940 EXPECT_REF(selection, 1);
9941 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1);
9942 EXPECT_HR(hr, S_OK);
9943 EXPECT_REF(selection, 2);
9944 EXPECT_REF(enum1, 2);
9946 /* enumerator and selection object return same IUnknown* */
9947 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
9948 EXPECT_HR(hr, S_OK);
9949 EXPECT_REF(selection, 3);
9950 EXPECT_REF(enum1, 2);
9951 ok(unk2 == unk1, "got %p, %p\n", unk1, unk2);
9952 IUnknown_Release(unk2);
9954 EXPECT_REF(selection, 2);
9955 IEnumVARIANT_AddRef(enum1);
9956 EXPECT_REF(selection, 2);
9957 IEnumVARIANT_Release(enum1);
9959 enum3 = NULL;
9960 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
9961 EXPECT_HR(hr, S_OK);
9962 ok(enum3 != NULL, "got %p\n", enum3);
9963 ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
9964 EXPECT_REF(enum1, 3);
9965 IEnumVARIANT_Release(enum3);
9967 EXPECT_REF(selection, 2);
9968 EXPECT_REF(enum1, 2);
9970 enum2 = NULL;
9971 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
9972 EXPECT_HR(hr, S_OK);
9973 ok(enum2 != NULL, "got %p\n", enum2);
9975 EXPECT_REF(selection, 3);
9976 EXPECT_REF(enum1, 2);
9977 EXPECT_REF(enum2, 1);
9979 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
9981 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
9982 EXPECT_HR(hr, S_OK);
9983 EXPECT_REF(selection, 3);
9984 EXPECT_REF(enum2, 2);
9985 ok(unk2 != unk1, "got %p, %p\n", unk1, unk2);
9986 IUnknown_Release(unk2);
9987 IUnknown_Release(unk1);
9989 selection2 = NULL;
9990 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
9991 EXPECT_HR(hr, S_OK);
9992 ok(selection2 == selection, "got %p and %p\n", selection, selection2);
9993 EXPECT_REF(selection, 3);
9994 EXPECT_REF(enum1, 2);
9996 IXMLDOMSelection_Release(selection2);
9998 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
9999 EXPECT_HR(hr, S_OK);
10000 EXPECT_REF(selection, 3);
10001 IDispatch_Release(disp);
10003 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
10004 EXPECT_HR(hr, S_OK);
10005 ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
10006 EXPECT_REF(selection, 2);
10007 EXPECT_REF(enum1, 3);
10009 IEnumVARIANT_Release(enum1);
10010 IEnumVARIANT_Release(enum2);
10011 IEnumVARIANT_Release(enum3);
10013 enum1 = NULL;
10014 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10015 EXPECT_HR(hr, S_OK);
10016 ok(enum1 != NULL, "got %p\n", enum1);
10017 EXPECT_REF(enum1, 1);
10018 EXPECT_REF(selection, 2);
10020 enum2 = NULL;
10021 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
10022 EXPECT_HR(hr, S_OK);
10023 ok(enum2 != NULL, "got %p\n", enum2);
10024 EXPECT_REF(enum2, 1);
10025 EXPECT_REF(selection, 3);
10027 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
10029 IEnumVARIANT_AddRef(enum1);
10030 EXPECT_REF(selection, 3);
10031 EXPECT_REF(enum1, 2);
10032 EXPECT_REF(enum2, 1);
10033 IEnumVARIANT_Release(enum1);
10035 IEnumVARIANT_Release(enum1);
10036 IEnumVARIANT_Release(enum2);
10038 EXPECT_REF(selection, 1);
10040 IXMLDOMNodeList_Release(list);
10042 hr = IXMLDOMDocument_get_childNodes(doc, &list);
10043 EXPECT_HR(hr, S_OK);
10045 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10046 EXPECT_HR(hr, E_NOINTERFACE);
10048 IXMLDOMNodeList_Release(list);
10050 /* test if IEnumVARIANT touches selection context */
10051 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
10052 EXPECT_HR(hr, S_OK);
10054 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
10055 EXPECT_HR(hr, S_OK);
10057 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
10058 EXPECT_HR(hr, S_OK);
10060 len = 0;
10061 hr = IXMLDOMSelection_get_length(selection, &len);
10062 EXPECT_HR(hr, S_OK);
10063 ok(len == 4, "got %d\n", len);
10065 enum1 = NULL;
10066 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
10067 EXPECT_HR(hr, S_OK);
10069 /* no-op if zero count */
10070 V_VT(&v) = VT_I2;
10071 hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
10072 EXPECT_HR(hr, S_OK);
10073 ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
10075 /* positive count, null array pointer */
10076 hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
10077 EXPECT_HR(hr, E_INVALIDARG);
10079 ret = 1;
10080 hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
10081 EXPECT_HR(hr, E_INVALIDARG);
10082 ok(ret == 0, "got %d\n", ret);
10084 V_VT(&v) = VT_I2;
10085 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10086 EXPECT_HR(hr, S_OK);
10087 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10089 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10090 EXPECT_HR(hr, S_OK);
10091 hr = IXMLDOMNode_get_nodeName(node, &name);
10092 EXPECT_HR(hr, S_OK);
10093 ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
10094 SysFreeString(name);
10095 IXMLDOMNode_Release(node);
10096 VariantClear(&v);
10098 /* list cursor is updated */
10099 hr = IXMLDOMSelection_nextNode(selection, &node);
10100 EXPECT_HR(hr, S_OK);
10101 hr = IXMLDOMNode_get_nodeName(node, &name);
10102 EXPECT_HR(hr, S_OK);
10103 ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
10104 IXMLDOMNode_Release(node);
10105 SysFreeString(name);
10107 V_VT(&v) = VT_I2;
10108 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
10109 EXPECT_HR(hr, S_OK);
10110 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
10111 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
10112 EXPECT_HR(hr, S_OK);
10113 hr = IXMLDOMNode_get_nodeName(node, &name);
10114 EXPECT_HR(hr, S_OK);
10115 ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
10116 SysFreeString(name);
10117 IXMLDOMNode_Release(node);
10118 VariantClear(&v);
10119 IEnumVARIANT_Release(enum1);
10121 hr = IXMLDOMSelection_nextNode(selection, &node);
10122 EXPECT_HR(hr, S_OK);
10123 hr = IXMLDOMNode_get_nodeName(node, &name);
10124 EXPECT_HR(hr, S_OK);
10125 ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
10126 IXMLDOMNode_Release(node);
10127 SysFreeString(name);
10129 IXMLDOMSelection_Release(selection);
10130 IXMLDOMNodeList_Release(list);
10131 IXMLDOMDocument_Release(doc);
10133 free_bstrs();
10136 static void write_to_file(const char *name, const char *data)
10138 DWORD written;
10139 HANDLE hfile;
10140 BOOL ret;
10142 hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
10143 ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name);
10145 ret = WriteFile(hfile, data, strlen(data), &written, NULL);
10146 ok(ret, "WriteFile failed: %s, %d\n", name, GetLastError());
10148 CloseHandle(hfile);
10151 static void test_load(void)
10153 IXMLDOMDocument *doc, *doc2;
10154 IXMLDOMNodeList *list;
10155 IXMLDOMElement *elem;
10156 VARIANT_BOOL b;
10157 VARIANT src;
10158 HRESULT hr;
10159 BSTR path, bstr1, bstr2;
10160 void* ptr;
10162 /* prepare a file */
10163 write_to_file("test.xml", win1252xml);
10165 doc = create_document(&IID_IXMLDOMDocument);
10167 /* null pointer as input */
10168 V_VT(&src) = VT_UNKNOWN;
10169 V_UNKNOWN(&src) = NULL;
10170 hr = IXMLDOMDocument_load(doc, src, &b);
10171 EXPECT_HR(hr, E_INVALIDARG);
10172 ok(b == VARIANT_FALSE, "got %d\n", b);
10174 path = _bstr_("test.xml");
10176 /* load from path: VT_BSTR */
10177 V_VT(&src) = VT_BSTR;
10178 V_BSTR(&src) = path;
10179 hr = IXMLDOMDocument_load(doc, src, &b);
10180 EXPECT_HR(hr, S_OK);
10181 ok(b == VARIANT_TRUE, "got %d\n", b);
10183 bstr1 = NULL;
10184 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10185 ok(hr == S_OK, "got 0x%08x\n", hr);
10186 SysFreeString(bstr1);
10188 /* load from a path: VT_BSTR|VT_BYREF */
10189 V_VT(&src) = VT_BSTR | VT_BYREF;
10190 V_BSTRREF(&src) = &path;
10191 hr = IXMLDOMDocument_load(doc, src, &b);
10192 EXPECT_HR(hr, S_OK);
10193 ok(b == VARIANT_TRUE, "got %d\n", b);
10195 bstr1 = NULL;
10196 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10197 ok(hr == S_OK, "got 0x%08x\n", hr);
10199 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
10200 ok(hr == S_OK, "got 0x%08x\n", hr);
10202 /* create another instance for the same document, check url */
10203 hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
10204 ok(hr == S_OK, "got 0x%08x\n", hr);
10206 hr = IXMLDOMDocument_get_url(doc, &bstr2);
10207 ok(hr == S_OK, "got 0x%08x\n", hr);
10208 ok(!lstrcmpW(bstr1, bstr2), "got %s\n", wine_dbgstr_w(bstr2));
10210 IXMLDOMDocument_Release(doc2);
10211 IXMLDOMElement_Release(elem);
10213 SysFreeString(bstr1);
10214 SysFreeString(bstr2);
10216 /* load from a path: VT_BSTR|VT_BYREF, null ptr */
10217 V_VT(&src) = VT_BSTR | VT_BYREF;
10218 V_BSTRREF(&src) = NULL;
10219 hr = IXMLDOMDocument_load(doc, src, &b);
10220 EXPECT_HR(hr, E_INVALIDARG);
10221 ok(b == VARIANT_FALSE, "got %d\n", b);
10223 bstr1 = NULL;
10224 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10225 ok(hr == S_OK, "got 0x%08x\n", hr);
10226 SysFreeString(bstr1);
10228 DeleteFileA("test.xml");
10230 /* load from existing path, no xml content */
10231 write_to_file("test.xml", nocontent);
10233 V_VT(&src) = VT_BSTR;
10234 V_BSTR(&src) = path;
10235 b = VARIANT_TRUE;
10236 hr = IXMLDOMDocument_load(doc, src, &b);
10237 ok(hr == S_FALSE, "got 0x%08x\n", hr);
10238 ok(b == VARIANT_FALSE, "got %d\n", b);
10240 bstr1 = (BSTR)0x1;
10241 hr = IXMLDOMDocument_get_url(doc, &bstr1);
10242 ok(hr == S_FALSE, "got 0x%08x\n", hr);
10243 ok(bstr1 == NULL, "got %p\n", bstr1);
10245 DeleteFileA("test.xml");
10246 IXMLDOMDocument_Release(doc);
10248 doc = create_document(&IID_IXMLDOMDocument);
10250 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b);
10251 EXPECT_HR(hr, S_OK);
10252 ok(b == VARIANT_TRUE, "got %d\n", b);
10254 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10255 EXPECT_HR(hr, S_OK);
10256 bstr1 = _bstr_(list_to_string(list));
10258 hr = IXMLDOMNodeList_reset(list);
10259 EXPECT_HR(hr, S_OK);
10261 IXMLDOMDocument_Release(doc);
10263 doc = create_document(&IID_IXMLDOMDocument);
10265 VariantInit(&src);
10266 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML));
10267 V_VT(&src) = VT_ARRAY|VT_UI1;
10268 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10269 ptr = NULL;
10270 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10271 EXPECT_HR(hr, S_OK);
10272 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10274 memcpy(ptr, szExampleXML, lstrlenA(szExampleXML));
10275 hr = SafeArrayUnlock(V_ARRAY(&src));
10276 EXPECT_HR(hr, S_OK);
10278 hr = IXMLDOMDocument_load(doc, src, &b);
10279 EXPECT_HR(hr, S_OK);
10280 ok(b == VARIANT_TRUE, "got %d\n", b);
10282 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list);
10283 EXPECT_HR(hr, S_OK);
10284 bstr2 = _bstr_(list_to_string(list));
10286 hr = IXMLDOMNodeList_reset(list);
10287 EXPECT_HR(hr, S_OK);
10289 ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n",
10290 wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2));
10292 IXMLDOMDocument_Release(doc);
10293 IXMLDOMNodeList_Release(list);
10294 VariantClear(&src);
10296 /* UTF-16 isn't accepted */
10297 doc = create_document(&IID_IXMLDOMDocument);
10299 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR));
10300 V_VT(&src) = VT_ARRAY|VT_UI1;
10301 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10302 ptr = NULL;
10303 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10304 EXPECT_HR(hr, S_OK);
10305 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10307 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10308 hr = SafeArrayUnlock(V_ARRAY(&src));
10309 EXPECT_HR(hr, S_OK);
10311 hr = IXMLDOMDocument_load(doc, src, &b);
10312 todo_wine EXPECT_HR(hr, S_FALSE);
10313 todo_wine ok(b == VARIANT_FALSE, "got %d\n", b);
10315 VariantClear(&src);
10317 /* it doesn't like it as a VT_ARRAY|VT_UI2 either */
10318 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1));
10319 V_VT(&src) = VT_ARRAY|VT_UI2;
10320 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n");
10321 ptr = NULL;
10322 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr);
10323 EXPECT_HR(hr, S_OK);
10324 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n");
10326 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR));
10327 hr = SafeArrayUnlock(V_ARRAY(&src));
10328 EXPECT_HR(hr, S_OK);
10330 hr = IXMLDOMDocument_load(doc, src, &b);
10331 todo_wine EXPECT_HR(hr, E_INVALIDARG);
10332 ok(b == VARIANT_FALSE, "got %d\n", b);
10334 VariantClear(&src);
10335 IXMLDOMDocument_Release(doc);
10337 free_bstrs();
10340 static void test_domobj_dispex(IUnknown *obj)
10342 static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0};
10343 DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
10344 IDispatchEx *dispex;
10345 IUnknown *unk;
10346 DWORD props;
10347 UINT ticnt;
10348 HRESULT hr;
10349 BSTR name;
10351 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
10352 EXPECT_HR(hr, S_OK);
10353 if (FAILED(hr)) return;
10355 ticnt = 0;
10356 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
10357 EXPECT_HR(hr, S_OK);
10358 ok(ticnt == 1, "ticnt=%u\n", ticnt);
10360 name = SysAllocString(szstar);
10361 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
10362 EXPECT_HR(hr, E_NOTIMPL);
10363 SysFreeString(name);
10365 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
10366 EXPECT_HR(hr, E_NOTIMPL);
10368 props = 0;
10369 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
10370 EXPECT_HR(hr, E_NOTIMPL);
10371 ok(props == 0, "expected 0 got %d\n", props);
10373 hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
10374 EXPECT_HR(hr, E_NOTIMPL);
10375 if (SUCCEEDED(hr)) SysFreeString(name);
10377 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
10378 EXPECT_HR(hr, E_NOTIMPL);
10380 unk = (IUnknown*)0xdeadbeef;
10381 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
10382 EXPECT_HR(hr, E_NOTIMPL);
10383 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk);
10385 name = SysAllocString(testW);
10386 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid);
10387 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
10388 SysFreeString(name);
10390 IDispatchEx_Release(dispex);
10393 static void test_mxnamespacemanager(void)
10395 static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace";
10396 IMXNamespacePrefixes *prefixes;
10397 IVBMXNamespaceManager *mgr2;
10398 IMXNamespaceManager *nsmgr;
10399 IUnknown *unk1, *unk2;
10400 WCHAR buffW[250];
10401 IDispatch *disp;
10402 IUnknown *unk;
10403 HRESULT hr;
10404 INT len;
10406 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10407 &IID_IMXNamespaceManager, (void**)&nsmgr);
10408 EXPECT_HR(hr, S_OK);
10410 /* IMXNamespaceManager inherits from IUnknown */
10411 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp);
10412 EXPECT_HR(hr, S_OK);
10413 IDispatch_Release(disp);
10415 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2);
10416 EXPECT_HR(hr, S_OK);
10418 EXPECT_REF(nsmgr, 2);
10419 EXPECT_REF(mgr2, 2);
10420 prefixes = NULL;
10421 hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
10422 todo_wine
10423 ok(hr == S_OK, "got 0x%08x\n", hr);
10424 if (hr == S_OK)
10426 IDispatchEx *dispex;
10427 VARIANT arg, ret;
10428 DISPPARAMS dispparams;
10430 ok(prefixes != NULL, "got %p\n", prefixes);
10431 EXPECT_REF(nsmgr, 2);
10432 EXPECT_REF(mgr2, 2);
10433 EXPECT_REF(prefixes, 1);
10435 IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1);
10436 IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2);
10438 EXPECT_REF(mgr2, 3);
10439 EXPECT_REF(prefixes, 2);
10441 IUnknown_Release(unk1);
10442 IUnknown_Release(unk2);
10444 hr = IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IDispatchEx, (void**)&dispex);
10445 ok(hr == S_OK, "got 0x%08x\n", hr);
10447 V_VT(&arg) = VT_I4;
10448 V_I4(&arg) = 0;
10449 dispparams.cArgs = 1;
10450 dispparams.cNamedArgs = 0;
10451 dispparams.rgdispidNamedArgs = NULL;
10452 dispparams.rgvarg = &arg;
10454 V_VT(&ret) = VT_EMPTY;
10455 V_DISPATCH(&ret) = (void*)0x1;
10456 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
10457 ok(hr == S_OK, "got 0x%08x\n", hr);
10458 ok(V_VT(&ret) == VT_BSTR, "got %d\n", V_VT(&ret));
10459 ok(V_BSTR(&ret) != NULL, "got %p\n", V_BSTR(&ret));
10460 VariantClear(&ret);
10462 IDispatchEx_Release(dispex);
10463 IMXNamespacePrefixes_Release(prefixes);
10465 IVBMXNamespaceManager_Release(mgr2);
10467 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10468 EXPECT_HR(hr, S_OK);
10470 /* prefix already added */
10471 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10472 EXPECT_HR(hr, S_FALSE);
10474 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL);
10475 EXPECT_HR(hr, E_INVALIDARG);
10477 /* "xml" and "xmlns" are not allowed here */
10478 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1"));
10479 EXPECT_HR(hr, E_INVALIDARG);
10481 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1"));
10482 EXPECT_HR(hr, E_INVALIDARG);
10483 todo_wine {
10484 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL);
10485 EXPECT_HR(hr, E_FAIL);
10487 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL);
10488 EXPECT_HR(hr, E_POINTER);
10490 len = -1;
10491 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len);
10492 EXPECT_HR(hr, S_OK);
10493 ok(len == 3, "got %d\n", len);
10495 len = -1;
10496 buffW[0] = 0x1;
10497 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10498 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10499 ok(len == -1, "got %d\n", len);
10500 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10502 len = 10;
10503 buffW[0] = 0x1;
10504 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10505 EXPECT_HR(hr, S_OK);
10506 ok(len == 3, "got %d\n", len);
10507 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10509 /* getURI */
10510 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL);
10511 EXPECT_HR(hr, E_INVALIDARG);
10513 len = -1;
10514 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len);
10515 EXPECT_HR(hr, E_INVALIDARG);
10516 ok(len == -1, "got %d\n", len);
10518 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL);
10519 EXPECT_HR(hr, E_POINTER);
10521 len = -1;
10522 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len);
10523 EXPECT_HR(hr, S_OK);
10524 /* length of "xml" uri is constant */
10525 ok(len == strlen(xmluriA), "got %d\n", len);
10527 len = 100;
10528 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10529 EXPECT_HR(hr, S_OK);
10530 ok(len == strlen(xmluriA), "got %d\n", len);
10531 ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW));
10533 len = strlen(xmluriA)-1;
10534 buffW[0] = 0x1;
10535 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len);
10536 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL);
10537 ok(len == strlen(xmluriA)-1, "got %d\n", len);
10538 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10540 /* prefix xml1 not defined */
10541 len = -1;
10542 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len);
10543 EXPECT_HR(hr, S_FALSE);
10544 ok(len == 0, "got %d\n", len);
10546 len = 100;
10547 buffW[0] = 0x1;
10548 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len);
10549 EXPECT_HR(hr, S_FALSE);
10550 ok(buffW[0] == 0, "got %x\n", buffW[0]);
10551 ok(len == 0, "got %d\n", len);
10553 /* IDispatchEx tests */
10554 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk);
10555 EXPECT_HR(hr, S_OK);
10556 test_domobj_dispex(unk);
10557 IUnknown_Release(unk);
10559 IMXNamespaceManager_Release(nsmgr);
10561 /* ::getPrefix() */
10562 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10563 &IID_IMXNamespaceManager, (void**)&nsmgr);
10564 EXPECT_HR(hr, S_OK);
10566 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL);
10567 EXPECT_HR(hr, E_INVALIDARG);
10569 len = -1;
10570 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len);
10571 EXPECT_HR(hr, E_INVALIDARG);
10572 ok(len == -1, "got %d\n", len);
10574 len = 100;
10575 buffW[0] = 0x1;
10576 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10577 EXPECT_HR(hr, E_FAIL);
10578 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10579 ok(len == 100, "got %d\n", len);
10581 len = 0;
10582 buffW[0] = 0x1;
10583 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len);
10584 EXPECT_HR(hr, E_FAIL);
10585 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10586 ok(len == 0, "got %d\n", len);
10588 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10589 EXPECT_HR(hr, S_OK);
10591 len = 100;
10592 buffW[0] = 0x1;
10593 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10594 EXPECT_HR(hr, S_OK);
10595 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10596 ok(len == 3, "got %d\n", len);
10598 len = 100;
10599 buffW[0] = 0x1;
10600 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len);
10601 EXPECT_HR(hr, S_OK);
10602 ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW));
10603 ok(len == 3, "got %d\n", len);
10605 /* with null buffer it's possible to get required length */
10606 len = 100;
10607 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10608 EXPECT_HR(hr, S_OK);
10609 ok(len == 3, "got %d\n", len);
10611 len = 0;
10612 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len);
10613 EXPECT_HR(hr, S_OK);
10614 ok(len == 3, "got %d\n", len);
10616 len = 100;
10617 buffW[0] = 0x1;
10618 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len);
10619 EXPECT_HR(hr, E_FAIL);
10620 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10621 ok(len == 100, "got %d\n", len);
10623 len = 100;
10624 buffW[0] = 0x1;
10625 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len);
10626 EXPECT_HR(hr, E_FAIL);
10627 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10628 ok(len == 100, "got %d\n", len);
10630 len = 100;
10631 buffW[0] = 0x1;
10632 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len);
10633 EXPECT_HR(hr, E_INVALIDARG);
10634 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10635 ok(len == 100, "got %d\n", len);
10637 len = 100;
10638 buffW[0] = 0x1;
10639 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10640 EXPECT_HR(hr, E_INVALIDARG);
10641 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10642 ok(len == 100, "got %d\n", len);
10644 len = 100;
10645 buffW[0] = 0x1;
10646 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len);
10647 EXPECT_HR(hr, E_INVALIDARG);
10648 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10649 ok(len == 100, "got %d\n", len);
10651 len = 100;
10652 buffW[0] = 0x1;
10653 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len);
10654 EXPECT_HR(hr, E_FAIL);
10655 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10656 ok(len == 100, "got %d\n", len);
10658 len = 100;
10659 buffW[0] = 0x1;
10660 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10661 EXPECT_HR(hr, E_INVALIDARG);
10662 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10663 ok(len == 100, "got %d\n", len);
10665 /* declare another one, indices are shifted */
10666 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10667 EXPECT_HR(hr, S_OK);
10669 len = 100;
10670 buffW[0] = 0x1;
10671 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10672 EXPECT_HR(hr, S_OK);
10673 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10674 ok(len == 3, "got %d\n", len);
10676 len = 100;
10677 buffW[0] = 0x1;
10678 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10679 EXPECT_HR(hr, S_OK);
10680 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10681 ok(len == 3, "got %d\n", len);
10683 len = 100;
10684 buffW[0] = 0x1;
10685 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len);
10686 EXPECT_HR(hr, E_FAIL);
10687 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10688 ok(len == 100, "got %d\n", len);
10690 len = 100;
10691 buffW[0] = 0x1;
10692 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len);
10693 EXPECT_HR(hr, E_INVALIDARG);
10694 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10695 ok(len == 100, "got %d\n", len);
10697 IMXNamespaceManager_Release(nsmgr);
10699 /* push/pop tests */
10700 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10701 &IID_IMXNamespaceManager, (void**)&nsmgr);
10702 EXPECT_HR(hr, S_OK);
10704 /* pop with empty stack */
10705 hr = IMXNamespaceManager_popContext(nsmgr);
10706 EXPECT_HR(hr, E_FAIL);
10708 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10709 EXPECT_HR(hr, S_OK);
10711 len = 100;
10712 buffW[0] = 0x1;
10713 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10714 EXPECT_HR(hr, S_OK);
10715 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10716 ok(len == 3, "got %d\n", len);
10718 hr = IMXNamespaceManager_pushContext(nsmgr);
10719 EXPECT_HR(hr, S_OK);
10721 len = 100;
10722 buffW[0] = 0x1;
10723 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10724 EXPECT_HR(hr, S_OK);
10725 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10726 ok(len == 3, "got %d\n", len);
10728 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri"));
10729 EXPECT_HR(hr, S_OK);
10731 len = 100;
10732 buffW[0] = 0x1;
10733 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10734 EXPECT_HR(hr, S_OK);
10735 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10736 ok(len == 3, "got %d\n", len);
10738 hr = IMXNamespaceManager_pushContext(nsmgr);
10739 EXPECT_HR(hr, S_OK);
10740 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri"));
10741 EXPECT_HR(hr, S_OK);
10743 len = 100;
10744 buffW[0] = 0x1;
10745 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10746 EXPECT_HR(hr, S_OK);
10747 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW));
10748 ok(len == 3, "got %d\n", len);
10750 len = 100;
10751 buffW[0] = 0x1;
10752 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10753 EXPECT_HR(hr, S_OK);
10754 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10755 ok(len == 3, "got %d\n", len);
10757 hr = IMXNamespaceManager_popContext(nsmgr);
10758 EXPECT_HR(hr, S_OK);
10760 hr = IMXNamespaceManager_popContext(nsmgr);
10761 EXPECT_HR(hr, S_OK);
10763 len = 100;
10764 buffW[0] = 0x1;
10765 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len);
10766 EXPECT_HR(hr, E_FAIL);
10767 ok(buffW[0] == 0x1, "got %x\n", buffW[0]);
10768 ok(len == 100, "got %d\n", len);
10770 len = 100;
10771 buffW[0] = 0x1;
10772 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len);
10773 EXPECT_HR(hr, S_OK);
10774 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW));
10775 ok(len == 3, "got %d\n", len);
10777 IMXNamespaceManager_Release(nsmgr);
10779 free_bstrs();
10782 static void test_mxnamespacemanager_override(void)
10784 IMXNamespaceManager *nsmgr;
10785 WCHAR buffW[250];
10786 VARIANT_BOOL b;
10787 HRESULT hr;
10788 INT len;
10790 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
10791 &IID_IMXNamespaceManager, (void**)&nsmgr);
10792 EXPECT_HR(hr, S_OK);
10794 len = sizeof(buffW)/sizeof(WCHAR);
10795 buffW[0] = 0;
10796 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10797 EXPECT_HR(hr, S_OK);
10798 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10800 len = sizeof(buffW)/sizeof(WCHAR);
10801 buffW[0] = 0;
10802 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10803 EXPECT_HR(hr, E_FAIL);
10805 hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL);
10806 EXPECT_HR(hr, E_POINTER);
10808 b = VARIANT_FALSE;
10809 hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b);
10810 EXPECT_HR(hr, S_OK);
10811 ok(b == VARIANT_TRUE, "got %d\n", b);
10813 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE);
10814 EXPECT_HR(hr, S_OK);
10816 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10817 EXPECT_HR(hr, S_OK);
10819 len = sizeof(buffW)/sizeof(WCHAR);
10820 buffW[0] = 0;
10821 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10822 EXPECT_HR(hr, S_OK);
10823 ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW));
10825 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri"));
10826 EXPECT_HR(hr, S_OK);
10828 len = sizeof(buffW)/sizeof(WCHAR);
10829 buffW[0] = 0;
10830 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len);
10831 EXPECT_HR(hr, S_OK);
10832 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW));
10834 len = sizeof(buffW)/sizeof(WCHAR);
10835 buffW[0] = 0;
10836 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10837 EXPECT_HR(hr, S_OK);
10838 ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW));
10840 len = sizeof(buffW)/sizeof(WCHAR);
10841 buffW[0] = 0;
10842 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len);
10843 EXPECT_HR(hr, S_OK);
10844 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10846 /* new prefix placed at index 1 always */
10847 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri"));
10848 EXPECT_HR(hr, S_OK);
10850 len = sizeof(buffW)/sizeof(WCHAR);
10851 buffW[0] = 0;
10852 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len);
10853 EXPECT_HR(hr, S_OK);
10854 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW));
10856 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL);
10857 todo_wine EXPECT_HR(hr, E_FAIL);
10859 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL);
10860 EXPECT_HR(hr, E_FAIL);
10862 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri"));
10863 EXPECT_HR(hr, E_FAIL);
10865 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE);
10866 EXPECT_HR(hr, S_OK);
10868 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override"));
10869 EXPECT_HR(hr, S_FALSE);
10871 len = sizeof(buffW)/sizeof(WCHAR);
10872 buffW[0] = 0;
10873 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len);
10874 EXPECT_HR(hr, S_OK);
10875 ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW));
10877 len = sizeof(buffW)/sizeof(WCHAR);
10878 buffW[0] = 0;
10879 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len);
10880 EXPECT_HR(hr, S_OK);
10881 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW));
10883 IMXNamespaceManager_Release(nsmgr);
10885 free_bstrs();
10888 static const DOMNodeType nodetypes_test[] =
10890 NODE_ELEMENT,
10891 NODE_ATTRIBUTE,
10892 NODE_TEXT,
10893 NODE_CDATA_SECTION,
10894 NODE_ENTITY_REFERENCE,
10895 NODE_PROCESSING_INSTRUCTION,
10896 NODE_COMMENT,
10897 NODE_DOCUMENT_FRAGMENT,
10898 NODE_INVALID
10901 static void test_dispex(void)
10903 const DOMNodeType *type = nodetypes_test;
10904 IXMLDOMImplementation *impl;
10905 IXMLDOMNodeList *node_list;
10906 IXMLDOMParseError *error;
10907 IXMLDOMNamedNodeMap *map;
10908 IXSLProcessor *processor;
10909 IXSLTemplate *template;
10910 IXMLDOMDocument *doc;
10911 IXMLHTTPRequest *req;
10912 IXMLDOMElement *elem;
10913 IDispatchEx *dispex;
10914 DISPPARAMS dispparams;
10915 IXMLDOMNode *node;
10916 VARIANT arg, ret;
10917 VARIANT_BOOL b;
10918 IUnknown *unk;
10919 HRESULT hr;
10920 DISPID did;
10922 doc = create_document(&IID_IXMLDOMDocument);
10924 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
10925 ok(hr == S_OK, "got 0x%08x\n", hr);
10926 test_domobj_dispex(unk);
10927 IUnknown_Release(unk);
10929 for(; *type != NODE_INVALID; type++)
10931 IXMLDOMNode *node;
10932 VARIANT v;
10934 V_VT(&v) = VT_I2;
10935 V_I2(&v) = *type;
10937 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
10938 ok(hr == S_OK, "failed to create node type %d\n", *type);
10940 IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
10942 test_domobj_dispex(unk);
10943 IUnknown_Release(unk);
10944 IXMLDOMNode_Release(node);
10947 /* IXMLDOMNodeList */
10948 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
10949 EXPECT_HR(hr, S_OK);
10950 IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10951 test_domobj_dispex(unk);
10952 IUnknown_Release(unk);
10953 IXMLDOMNodeList_Release(node_list);
10955 /* IXMLDOMNodeList for children list */
10956 hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
10957 EXPECT_HR(hr, S_OK);
10958 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
10959 ok(hr == S_OK, "got 0x%08x\n", hr);
10960 test_domobj_dispex(unk);
10961 IUnknown_Release(unk);
10963 /* collection dispex test, empty collection */
10964 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex);
10965 EXPECT_HR(hr, S_OK);
10966 did = 0;
10967 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
10968 EXPECT_HR(hr, S_OK);
10969 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
10970 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
10971 EXPECT_HR(hr, S_OK);
10972 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
10973 IDispatchEx_Release(dispex);
10975 did = -1;
10976 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
10977 ok(hr == S_OK, "got 0x%08x\n", hr);
10978 ok(did == DISPID_VALUE, "got %d\n", did);
10980 V_VT(&arg) = VT_I4;
10981 V_I4(&arg) = 0;
10982 dispparams.cArgs = 0;
10983 dispparams.cNamedArgs = 0;
10984 dispparams.rgdispidNamedArgs = NULL;
10985 dispparams.rgvarg = &arg;
10987 V_VT(&ret) = VT_EMPTY;
10988 V_DISPATCH(&ret) = (void*)0x1;
10989 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
10990 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
10991 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
10992 todo_wine
10993 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
10995 V_VT(&arg) = VT_I4;
10996 V_I4(&arg) = 0;
10997 dispparams.cArgs = 2;
10998 dispparams.cNamedArgs = 0;
10999 dispparams.rgdispidNamedArgs = NULL;
11000 dispparams.rgvarg = &arg;
11002 V_VT(&ret) = VT_EMPTY;
11003 V_DISPATCH(&ret) = (void*)0x1;
11004 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11005 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11006 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11007 todo_wine
11008 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11010 V_VT(&arg) = VT_I4;
11011 V_I4(&arg) = 0;
11012 dispparams.cArgs = 1;
11013 dispparams.cNamedArgs = 0;
11014 dispparams.rgdispidNamedArgs = NULL;
11015 dispparams.rgvarg = &arg;
11017 V_VT(&ret) = VT_EMPTY;
11018 V_DISPATCH(&ret) = (void*)0x1;
11019 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11020 ok(hr == S_OK, "got 0x%08x\n", hr);
11021 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11022 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11024 V_VT(&ret) = VT_EMPTY;
11025 V_DISPATCH(&ret) = (void*)0x1;
11026 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11027 ok(hr == S_OK, "got 0x%08x\n", hr);
11028 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11029 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11031 V_VT(&ret) = VT_EMPTY;
11032 V_DISPATCH(&ret) = (void*)0x1;
11033 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11034 ok(hr == S_OK, "got 0x%08x\n", hr);
11035 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11036 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11038 dispparams.cArgs = 0;
11039 dispparams.cNamedArgs = 0;
11040 dispparams.rgdispidNamedArgs = NULL;
11041 dispparams.rgvarg = NULL;
11043 V_VT(&ret) = VT_EMPTY;
11044 V_I4(&ret) = 1;
11045 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11046 ok(hr == S_OK, "got 0x%08x\n", hr);
11047 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11048 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
11050 dispparams.cArgs = 0;
11051 dispparams.cNamedArgs = 0;
11052 dispparams.rgdispidNamedArgs = NULL;
11053 dispparams.rgvarg = NULL;
11055 V_VT(&ret) = VT_EMPTY;
11056 V_I4(&ret) = 1;
11057 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11058 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11059 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11060 todo_wine
11061 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
11063 IXMLDOMNodeList_Release(node_list);
11065 /* IXMLDOMParseError */
11066 hr = IXMLDOMDocument_get_parseError(doc, &error);
11067 EXPECT_HR(hr, S_OK);
11068 IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
11069 test_domobj_dispex(unk);
11071 hr = IXMLDOMParseError_QueryInterface(error, &IID_IDispatchEx, (void**)&dispex);
11072 ok(hr == S_OK, "got 0x%08x\n", hr);
11074 V_VT(&arg) = VT_I4;
11075 V_I4(&arg) = 0;
11076 dispparams.cArgs = 1;
11077 dispparams.cNamedArgs = 0;
11078 dispparams.rgdispidNamedArgs = NULL;
11079 dispparams.rgvarg = &arg;
11081 V_VT(&ret) = VT_EMPTY;
11082 V_DISPATCH(&ret) = (void*)0x1;
11083 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11084 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11085 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11086 todo_wine
11087 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11089 IDispatchEx_Release(dispex);
11091 IUnknown_Release(unk);
11092 IXMLDOMParseError_Release(error);
11094 /* IXMLDOMNamedNodeMap */
11095 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b);
11096 EXPECT_HR(hr, S_OK);
11098 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list);
11099 EXPECT_HR(hr, S_OK);
11100 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11101 EXPECT_HR(hr, S_OK);
11102 IXMLDOMNodeList_Release(node_list);
11104 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11105 EXPECT_HR(hr, S_OK);
11106 IXMLDOMNode_Release(node);
11107 hr = IXMLDOMElement_get_attributes(elem, &map);
11108 EXPECT_HR(hr, S_OK);
11109 IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk);
11110 test_domobj_dispex(unk);
11111 IUnknown_Release(unk);
11112 /* collection dispex test */
11113 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11114 EXPECT_HR(hr, S_OK);
11115 did = 0;
11116 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11117 EXPECT_HR(hr, S_OK);
11118 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11119 IDispatchEx_Release(dispex);
11120 IXMLDOMNamedNodeMap_Release(map);
11122 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
11123 EXPECT_HR(hr, S_OK);
11124 hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
11125 EXPECT_HR(hr, S_OK);
11126 IXMLDOMNodeList_Release(node_list);
11127 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
11128 EXPECT_HR(hr, S_OK);
11129 IXMLDOMNode_Release(node);
11130 hr = IXMLDOMElement_get_attributes(elem, &map);
11131 EXPECT_HR(hr, S_OK);
11132 /* collection dispex test, empty collection */
11133 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex);
11134 EXPECT_HR(hr, S_OK);
11135 did = 0;
11136 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did);
11137 EXPECT_HR(hr, S_OK);
11138 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
11139 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
11140 EXPECT_HR(hr, S_OK);
11141 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
11142 IXMLDOMNamedNodeMap_Release(map);
11144 did = -1;
11145 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
11146 ok(hr == S_OK, "got 0x%08x\n", hr);
11147 ok(did == DISPID_VALUE, "got %d\n", did);
11149 V_VT(&arg) = VT_I4;
11150 V_I4(&arg) = 0;
11151 dispparams.cArgs = 0;
11152 dispparams.cNamedArgs = 0;
11153 dispparams.rgdispidNamedArgs = NULL;
11154 dispparams.rgvarg = &arg;
11156 V_VT(&ret) = VT_EMPTY;
11157 V_DISPATCH(&ret) = (void*)0x1;
11158 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11159 todo_wine {
11160 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11161 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11163 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11165 V_VT(&arg) = VT_I4;
11166 V_I4(&arg) = 0;
11167 dispparams.cArgs = 2;
11168 dispparams.cNamedArgs = 0;
11169 dispparams.rgdispidNamedArgs = NULL;
11170 dispparams.rgvarg = &arg;
11172 V_VT(&ret) = VT_EMPTY;
11173 V_DISPATCH(&ret) = (void*)0x1;
11174 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11175 todo_wine {
11176 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
11177 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11179 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
11181 V_VT(&arg) = VT_I4;
11182 V_I4(&arg) = 0;
11183 dispparams.cArgs = 1;
11184 dispparams.cNamedArgs = 0;
11185 dispparams.rgdispidNamedArgs = NULL;
11186 dispparams.rgvarg = &arg;
11188 V_VT(&ret) = VT_EMPTY;
11189 V_DISPATCH(&ret) = (void*)0x1;
11190 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11191 todo_wine
11192 ok(hr == S_OK, "got 0x%08x\n", hr);
11193 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11194 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11196 V_VT(&ret) = VT_EMPTY;
11197 V_DISPATCH(&ret) = (void*)0x1;
11198 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11199 ok(hr == S_OK, "got 0x%08x\n", hr);
11200 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11201 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11203 V_VT(&ret) = VT_EMPTY;
11204 V_DISPATCH(&ret) = (void*)0x1;
11205 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11206 ok(hr == S_OK, "got 0x%08x\n", hr);
11207 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
11208 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
11210 dispparams.cArgs = 0;
11211 dispparams.cNamedArgs = 0;
11212 dispparams.rgdispidNamedArgs = NULL;
11213 dispparams.rgvarg = NULL;
11215 V_VT(&ret) = VT_EMPTY;
11216 V_I4(&ret) = 1;
11217 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
11218 ok(hr == S_OK, "got 0x%08x\n", hr);
11219 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
11220 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
11222 dispparams.cArgs = 0;
11223 dispparams.cNamedArgs = 0;
11224 dispparams.rgdispidNamedArgs = NULL;
11225 dispparams.rgvarg = NULL;
11227 V_VT(&ret) = VT_EMPTY;
11228 V_I4(&ret) = 1;
11229 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
11230 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
11231 todo_wine
11232 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
11233 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
11235 IDispatchEx_Release(dispex);
11236 IXMLDOMElement_Release(elem);
11238 /* IXMLDOMImplementation */
11239 hr = IXMLDOMDocument_get_implementation(doc, &impl);
11240 EXPECT_HR(hr, S_OK);
11242 hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex);
11243 EXPECT_HR(hr, S_OK);
11244 IDispatchEx_Release(dispex);
11245 IXMLDOMImplementation_Release(impl);
11247 IXMLDOMDocument_Release(doc);
11249 /* IXMLHTTPRequest */
11250 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
11251 &IID_IXMLHttpRequest, (void**)&req);
11252 if (hr == S_OK)
11254 hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex);
11255 EXPECT_HR(hr, E_NOINTERFACE);
11256 IXMLHTTPRequest_Release(req);
11259 /* IXSLTemplate */
11260 template = create_xsltemplate(&IID_IXSLTemplate);
11261 hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex);
11262 EXPECT_HR(hr, S_OK);
11263 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11264 EXPECT_HR(hr, S_OK);
11265 test_domobj_dispex(unk);
11266 IUnknown_Release(unk);
11267 IDispatchEx_Release(dispex);
11269 /* IXSLProcessor */
11270 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
11271 EXPECT_HR(hr, S_OK);
11272 b = VARIANT_FALSE;
11273 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b);
11274 EXPECT_HR(hr, S_OK);
11275 ok(b == VARIANT_TRUE, "got %d\n", b);
11277 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
11278 EXPECT_HR(hr, S_OK);
11279 IXMLDOMDocument_Release(doc);
11281 hr = IXSLTemplate_createProcessor(template, &processor);
11282 EXPECT_HR(hr, S_OK);
11283 hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex);
11284 EXPECT_HR(hr, S_OK);
11285 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
11286 EXPECT_HR(hr, S_OK);
11287 test_domobj_dispex(unk);
11288 IUnknown_Release(unk);
11289 IDispatchEx_Release(dispex);
11291 IXSLProcessor_Release(processor);
11292 IXSLTemplate_Release(template);
11294 if (is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument))
11296 doc = create_document_version(60, &IID_IXMLDOMDocument);
11297 test_domobj_dispex((IUnknown*)doc);
11298 IXMLDOMDocument_Release(doc);
11301 free_bstrs();
11304 static void test_parseerror(void)
11306 IXMLDOMParseError2 *error2;
11307 IXMLDOMParseError *error;
11308 IXMLDOMDocument *doc;
11309 HRESULT hr;
11311 doc = create_document(&IID_IXMLDOMDocument);
11313 hr = IXMLDOMDocument_get_parseError(doc, &error);
11314 EXPECT_HR(hr, S_OK);
11316 hr = IXMLDOMParseError_get_line(error, NULL);
11317 EXPECT_HR(hr, E_INVALIDARG);
11319 hr = IXMLDOMParseError_get_srcText(error, NULL);
11320 EXPECT_HR(hr, E_INVALIDARG);
11322 hr = IXMLDOMParseError_get_linepos(error, NULL);
11323 EXPECT_HR(hr, E_INVALIDARG);
11325 IXMLDOMParseError_Release(error);
11326 IXMLDOMDocument_Release(doc);
11328 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) return;
11329 doc = create_document_version(60, &IID_IXMLDOMDocument);
11331 hr = IXMLDOMDocument_get_parseError(doc, &error);
11332 EXPECT_HR(hr, S_OK);
11333 hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
11334 EXPECT_HR(hr, S_OK);
11335 IXMLDOMParseError2_Release(error2);
11336 IXMLDOMParseError_Release(error);
11337 IXMLDOMDocument_Release(doc);
11340 static void test_getAttributeNode(void)
11342 IXMLDOMAttribute *attr;
11343 IXMLDOMDocument *doc;
11344 IXMLDOMElement *elem;
11345 VARIANT_BOOL v;
11346 HRESULT hr;
11347 BSTR str;
11349 doc = create_document(&IID_IXMLDOMDocument);
11351 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11352 EXPECT_HR(hr, S_OK);
11354 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11355 EXPECT_HR(hr, S_OK);
11357 str = SysAllocString(nonexistent_fileW);
11358 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11359 EXPECT_HR(hr, E_FAIL);
11361 attr = (IXMLDOMAttribute*)0xdeadbeef;
11362 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11363 EXPECT_HR(hr, E_FAIL);
11364 ok(attr == NULL, "got %p\n", attr);
11365 SysFreeString(str);
11367 str = SysAllocString(nonexistent_attrW);
11368 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL);
11369 EXPECT_HR(hr, S_FALSE);
11371 attr = (IXMLDOMAttribute*)0xdeadbeef;
11372 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr);
11373 EXPECT_HR(hr, S_FALSE);
11374 ok(attr == NULL, "got %p\n", attr);
11375 SysFreeString(str);
11377 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr);
11378 EXPECT_HR(hr, S_OK);
11379 IXMLDOMAttribute_Release(attr);
11381 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr);
11382 EXPECT_HR(hr, S_FALSE);
11384 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr);
11385 EXPECT_HR(hr, S_OK);
11386 IXMLDOMAttribute_Release(attr);
11388 IXMLDOMElement_Release(elem);
11389 IXMLDOMDocument_Release(doc);
11390 free_bstrs();
11393 static void test_getAttribute(void)
11395 IXMLDOMDocument *doc;
11396 IXMLDOMElement *elem;
11397 VARIANT_BOOL v;
11398 VARIANT var;
11399 HRESULT hr;
11401 doc = create_document(&IID_IXMLDOMDocument);
11403 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v);
11404 EXPECT_HR(hr, S_OK);
11406 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11407 EXPECT_HR(hr, S_OK);
11409 VariantInit(&var);
11410 hr = IXMLDOMElement_getAttribute( elem, _bstr_("xmlns:foo"), &var );
11411 EXPECT_HR(hr, S_OK);
11412 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11413 ok( !lstrcmpW(V_BSTR(&var), _bstr_("urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11414 VariantClear(&var);
11416 hr = IXMLDOMElement_getAttribute( elem, _bstr_("a"), &var );
11417 EXPECT_HR(hr, S_OK);
11418 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11419 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr a")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11420 VariantClear(&var);
11422 hr = IXMLDOMElement_getAttribute( elem, _bstr_("foo:b"), &var );
11423 EXPECT_HR(hr, S_OK);
11424 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
11425 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr b")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var)));
11426 VariantClear(&var);
11428 hr = IXMLDOMElement_getAttribute( elem, _bstr_("b"), &var );
11429 EXPECT_HR(hr, S_FALSE);
11430 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
11431 VariantClear(&var);
11433 hr = IXMLDOMElement_getAttribute( elem, _bstr_("non-existent"), &var );
11434 EXPECT_HR(hr, S_FALSE);
11435 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var));
11436 VariantClear(&var);
11438 IXMLDOMElement_Release(elem);
11439 IXMLDOMDocument_Release(doc);
11440 free_bstrs();
11443 typedef struct {
11444 DOMNodeType type;
11445 const char *name;
11446 REFIID iids[3];
11447 } supporterror_t;
11449 static const supporterror_t supporterror_test[] = {
11450 { NODE_ELEMENT, "element", { &IID_IXMLDOMNode, &IID_IXMLDOMElement } },
11451 { NODE_ATTRIBUTE, "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } },
11452 { NODE_CDATA_SECTION, "cdata", { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } },
11453 { NODE_ENTITY_REFERENCE, "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } },
11454 { NODE_PROCESSING_INSTRUCTION, "pi", { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } },
11455 { NODE_COMMENT, "comment", { &IID_IXMLDOMNode, &IID_IXMLDOMComment } },
11456 { NODE_DOCUMENT_FRAGMENT, "fragment", { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } },
11457 { NODE_INVALID }
11460 static void test_supporterrorinfo(void)
11462 static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument,
11463 &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
11464 const supporterror_t *ptr = supporterror_test;
11465 ISupportErrorInfo *errorinfo, *info2;
11466 IXMLDOMSchemaCollection *schemacache;
11467 IXMLDOMNamedNodeMap *map, *map2;
11468 IXMLDOMDocument *doc;
11469 IXMLDOMElement *elem;
11470 VARIANT_BOOL b;
11471 IUnknown *unk;
11472 REFIID *iid;
11473 void *dummy;
11474 HRESULT hr;
11476 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument3)) return;
11477 doc = create_document_version(60, &IID_IXMLDOMDocument3);
11479 EXPECT_REF(doc, 1);
11480 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
11481 EXPECT_HR(hr, S_OK);
11482 EXPECT_REF(doc, 1);
11483 ISupportErrorInfo_AddRef(errorinfo);
11484 EXPECT_REF(errorinfo, 2);
11485 EXPECT_REF(doc, 1);
11486 ISupportErrorInfo_Release(errorinfo);
11488 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2);
11489 EXPECT_HR(hr, S_OK);
11490 ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo);
11492 /* error interface can't be queried back for DOM interface */
11493 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy);
11494 EXPECT_HR(hr, E_NOINTERFACE);
11495 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy);
11496 EXPECT_HR(hr, E_NOINTERFACE);
11498 ISupportErrorInfo_Release(info2);
11500 iid = iids;
11501 while (*iid)
11503 hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk);
11504 EXPECT_HR(hr, S_OK);
11505 if (hr == S_OK)
11507 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11508 ok(hr == S_OK, "got 0x%08x for %s\n", hr, wine_dbgstr_guid(*iid));
11509 IUnknown_Release(unk);
11512 iid++;
11515 ISupportErrorInfo_Release(errorinfo);
11517 while (ptr->type != NODE_INVALID)
11519 IXMLDOMNode *node;
11520 VARIANT type;
11522 V_VT(&type) = VT_I1;
11523 V_I1(&type) = ptr->type;
11525 hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node);
11526 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11528 EXPECT_REF(node, 1);
11529 hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo);
11530 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr);
11531 EXPECT_REF(node, 1);
11533 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy);
11534 ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr);
11536 iid = ptr->iids;
11538 while (*iid)
11540 hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk);
11541 if (hr == S_OK)
11543 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
11544 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, wine_dbgstr_guid(*iid));
11545 IUnknown_Release(unk);
11548 iid++;
11551 ISupportErrorInfo_Release(errorinfo);
11552 IXMLDOMNode_Release(node);
11553 ptr++;
11556 /* IXMLDOMNamedNodeMap */
11557 b = VARIANT_FALSE;
11558 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b);
11559 EXPECT_HR(hr, S_OK);
11560 ok(b == VARIANT_TRUE, "got %d\n", b);
11562 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11563 EXPECT_HR(hr, S_OK);
11565 hr = IXMLDOMElement_get_attributes(elem, &map);
11566 EXPECT_HR(hr, S_OK);
11568 EXPECT_REF(map, 1);
11569 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo);
11570 EXPECT_HR(hr, S_OK);
11571 EXPECT_REF(map, 2);
11573 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap);
11574 EXPECT_HR(hr, S_OK);
11576 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2);
11577 EXPECT_HR(hr, S_OK);
11578 ok(map == map2, "got %p\n", map2);
11579 IXMLDOMNamedNodeMap_Release(map2);
11581 EXPECT_REF(errorinfo, 2);
11582 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk);
11583 EXPECT_HR(hr, S_OK);
11584 EXPECT_REF(errorinfo, 3);
11585 EXPECT_REF(map, 3);
11586 IUnknown_Release(unk);
11588 ISupportErrorInfo_Release(errorinfo);
11589 IXMLDOMNamedNodeMap_Release(map);
11590 IXMLDOMElement_Release(elem);
11592 IXMLDOMDocument_Release(doc);
11594 /* IXMLDOMSchemaCollection */
11595 hr = CoCreateInstance(&CLSID_XMLSchemaCache, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (void**)&schemacache);
11596 ok(hr == S_OK, "failed to create schema collection, 0x%08x\n", hr);
11598 hr = IXMLDOMSchemaCollection_QueryInterface(schemacache, &IID_ISupportErrorInfo, (void**)&errorinfo);
11599 ok(hr == S_OK, "got 0x%08x\n", hr);
11601 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMSchemaCollection);
11602 ok(hr == S_OK, "got 0x%08x\n", hr);
11604 ISupportErrorInfo_Release(errorinfo);
11605 IXMLDOMSchemaCollection_Release(schemacache);
11607 free_bstrs();
11610 typedef struct {
11611 DOMNodeType type;
11612 const char *name;
11613 const char *put_content;
11614 HRESULT put_hr;
11615 VARTYPE get_vt;
11616 HRESULT get_hr;
11617 } node_value_t;
11619 static const node_value_t nodevalue_test[] = {
11620 { NODE_ELEMENT, "element", "", E_FAIL, VT_NULL, S_FALSE },
11621 { NODE_ATTRIBUTE, "attr", "value", S_OK, VT_BSTR, S_OK },
11622 { NODE_TEXT, "text", "textdata", S_OK, VT_BSTR, S_OK },
11623 { NODE_CDATA_SECTION , "cdata", "cdata data", S_OK, VT_BSTR, S_OK },
11624 { NODE_ENTITY_REFERENCE, "entityref", "ref", E_FAIL, VT_NULL, S_FALSE },
11625 { NODE_PROCESSING_INSTRUCTION, "pi", "instr", S_OK, VT_BSTR, S_OK },
11626 { NODE_COMMENT, "comment", "comment data", S_OK, VT_BSTR, S_OK },
11627 { NODE_DOCUMENT_FRAGMENT, "docfrag", "", E_FAIL, VT_NULL, S_FALSE },
11628 { NODE_INVALID }
11631 static void test_nodeValue(void)
11633 const node_value_t *ptr = nodevalue_test;
11634 IXMLDOMDocument *doc;
11635 HRESULT hr;
11637 doc = create_document(&IID_IXMLDOMDocument);
11639 while (ptr->type != NODE_INVALID)
11641 IXMLDOMNode *node;
11642 VARIANT v;
11644 V_VT(&v) = VT_I2;
11645 V_I2(&v) = ptr->type;
11647 hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node);
11648 ok(hr == S_OK, "failed to create node type %d\n", ptr->type);
11650 hr = IXMLDOMNode_get_nodeValue(node, NULL);
11651 ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr);
11653 V_VT(&v) = VT_BSTR;
11654 V_BSTR(&v) = _bstr_(ptr->put_content);
11655 hr = IXMLDOMNode_put_nodeValue(node, v);
11656 ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr);
11658 V_VT(&v) = VT_EMPTY;
11659 hr = IXMLDOMNode_get_nodeValue(node, &v);
11660 ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr);
11661 ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt);
11662 if (hr == S_OK)
11663 ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type,
11664 wine_dbgstr_w(V_BSTR(&v)));
11665 VariantClear(&v);
11667 IXMLDOMNode_Release(node);
11669 ptr++;
11672 IXMLDOMDocument_Release(doc);
11675 static void test_xmlns_attribute(void)
11677 BSTR str;
11678 IXMLDOMDocument *doc;
11679 IXMLDOMElement *root;
11680 IXMLDOMAttribute *pAttribute;
11681 IXMLDOMElement *elem;
11682 HRESULT hr;
11683 VARIANT v;
11685 doc = create_document(&IID_IXMLDOMDocument);
11687 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
11688 EXPECT_HR(hr, S_OK);
11690 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
11691 EXPECT_HR(hr, S_OK);
11693 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("xmlns:dt"), &pAttribute);
11694 ok( hr == S_OK, "returns %08x\n", hr );
11696 V_VT(&v) = VT_BSTR;
11697 V_BSTR(&v) = _bstr_("urn:schemas-microsoft-com:datatypes");
11698 hr = IXMLDOMAttribute_put_nodeValue(pAttribute, v);
11699 ok(hr == S_OK, "ret %08x\n", hr );
11701 hr = IXMLDOMElement_setAttributeNode(root, pAttribute, NULL);
11702 ok(hr == S_OK, "ret %08x\n", hr );
11704 hr = IXMLDOMNode_put_dataType((IXMLDOMNode*)root, _bstr_("bin.base64"));
11705 ok(hr == S_OK, "ret %08x\n", hr );
11707 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
11708 EXPECT_HR(hr, S_OK);
11710 str = NULL;
11711 hr = IXMLDOMElement_get_xml(elem, &str);
11712 ok( hr == S_OK, "got 0x%08x\n", hr);
11713 todo_wine ok( lstrcmpW(str, _bstr_("<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>")) == 0,
11714 "got %s\n", wine_dbgstr_w(str));
11715 SysFreeString(str);
11717 IXMLDOMElement_Release(elem);
11718 IXMLDOMAttribute_Release( pAttribute);
11720 IXMLDOMDocument_Release(doc);
11722 free_bstrs();
11725 static const char namespacesA[] =
11726 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
11727 " <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
11728 " <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>"
11729 " <ns1:elem3/>"
11730 " <ns1:elem4/>"
11731 " <elem5 xmlns=\"http://blahblah.org\"/>"
11732 " <ns1:elem6>true</ns1:elem6>"
11733 " </ns1:elem1>";
11735 static const char xsd_schema1_uri[] = "x-schema:test1.xsd";
11736 static const char xsd_schema1_xml[] =
11737 "<?xml version='1.0'?>"
11738 "<schema xmlns='http://www.w3.org/2001/XMLSchema'"
11739 " targetNamespace='x-schema:test1.xsd'>"
11740 " <element name='root'>"
11741 " <complexType>"
11742 " <sequence maxOccurs='unbounded'>"
11743 " <any/>"
11744 " </sequence>"
11745 " </complexType>"
11746 " </element>"
11747 "</schema>";
11749 static void test_get_namespaces(void)
11751 IXMLDOMSchemaCollection *collection, *collection2;
11752 IXMLDOMDocument2 *doc, *doc2;
11753 IEnumVARIANT *enumv, *enum2;
11754 IUnknown *unk1, *unk2;
11755 IXMLDOMNode *node;
11756 VARIANT_BOOL b;
11757 HRESULT hr;
11758 VARIANT v;
11759 LONG len;
11760 BSTR s;
11762 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
11763 doc = create_document(&IID_IXMLDOMDocument2);
11765 /* null pointer */
11766 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11767 EXPECT_HR(hr, E_POINTER);
11769 /* no document loaded */
11770 collection = (void*)0xdeadbeef;
11771 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11772 EXPECT_HR(hr, S_OK);
11773 if (hr != S_OK)
11775 IXMLDOMDocument2_Release(doc);
11776 return;
11778 EXPECT_REF(collection, 2);
11780 collection2 = (void*)0xdeadbeef;
11781 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11782 EXPECT_HR(hr, S_OK);
11783 ok(collection == collection2, "got %p\n", collection2);
11784 EXPECT_REF(collection, 3);
11785 IXMLDOMSchemaCollection_Release(collection);
11787 len = -1;
11788 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11789 EXPECT_HR(hr, S_OK);
11790 ok(len == 0, "got %d\n", len);
11791 IXMLDOMSchemaCollection_Release(collection);
11793 /* now with document */
11794 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11795 EXPECT_HR(hr, S_OK);
11797 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11798 EXPECT_HR(hr, S_OK);
11800 len = -1;
11801 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11802 EXPECT_HR(hr, S_OK);
11803 ok(len == 2, "got %d\n", len);
11805 /* try to lookup some uris */
11806 node = (void*)0xdeadbeef;
11807 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11808 EXPECT_HR(hr, S_OK);
11809 ok(node == NULL, "got %p\n", node);
11811 node = (void*)0xdeadbeef;
11812 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node);
11813 EXPECT_HR(hr, S_OK);
11814 ok(node == NULL, "got %p\n", node);
11816 /* load schema and try to add it */
11817 doc2 = create_document(&IID_IXMLDOMDocument2);
11818 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11819 EXPECT_HR(hr, S_OK);
11821 V_VT(&v) = VT_DISPATCH;
11822 V_DISPATCH(&v) = (IDispatch*)doc2;
11823 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11824 EXPECT_HR(hr, E_FAIL);
11826 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11827 EXPECT_HR(hr, S_OK);
11828 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11829 SysFreeString(s);
11831 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11832 EXPECT_HR(hr, S_OK);
11833 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11834 SysFreeString(s);
11836 s = (void*)0xdeadbeef;
11837 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11838 EXPECT_HR(hr, E_FAIL);
11839 ok(s == (void*)0xdeadbeef, "got %p\n", s);
11841 /* enumerate */
11842 enumv = (void*)0xdeadbeef;
11843 EXPECT_REF(collection, 2);
11844 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11845 EXPECT_HR(hr, S_OK);
11846 EXPECT_REF(collection, 3);
11847 ok(enumv != NULL, "got %p\n", enumv);
11849 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IUnknown, (void**)&unk1);
11850 EXPECT_HR(hr, S_OK);
11851 hr = IEnumVARIANT_QueryInterface(enumv, &IID_IUnknown, (void**)&unk2);
11852 EXPECT_HR(hr, S_OK);
11853 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
11854 IUnknown_Release(unk1);
11855 IUnknown_Release(unk2);
11857 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2);
11858 EXPECT_HR(hr, E_NOINTERFACE);
11860 V_VT(&v) = VT_EMPTY;
11861 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11862 EXPECT_HR(hr, S_OK);
11863 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11864 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11865 VariantClear(&v);
11867 V_VT(&v) = VT_EMPTY;
11868 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11869 EXPECT_HR(hr, S_OK);
11870 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11871 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11872 VariantClear(&v);
11874 V_VT(&v) = VT_NULL;
11875 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11876 EXPECT_HR(hr, S_FALSE);
11877 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11879 IEnumVARIANT_Release(enumv);
11880 IXMLDOMSchemaCollection_Release(collection);
11882 IXMLDOMDocument2_Release(doc);
11884 /* now with CLSID_DOMDocument60 */
11885 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) return;
11886 doc = create_document_version(60, &IID_IXMLDOMDocument2);
11888 /* null pointer */
11889 hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
11890 EXPECT_HR(hr, E_POINTER);
11892 /* no document loaded */
11893 collection = (void*)0xdeadbeef;
11894 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11895 EXPECT_HR(hr, S_OK);
11896 if (hr != S_OK)
11898 IXMLDOMDocument2_Release(doc);
11899 return;
11901 EXPECT_REF(collection, 2);
11903 collection2 = (void*)0xdeadbeef;
11904 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2);
11905 EXPECT_HR(hr, S_OK);
11906 ok(collection == collection2, "got %p\n", collection2);
11907 EXPECT_REF(collection, 3);
11908 IXMLDOMSchemaCollection_Release(collection);
11910 len = -1;
11911 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11912 EXPECT_HR(hr, S_OK);
11913 ok(len == 0, "got %d\n", len);
11914 IXMLDOMSchemaCollection_Release(collection);
11916 /* now with document */
11917 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b);
11918 EXPECT_HR(hr, S_OK);
11920 hr = IXMLDOMDocument2_get_namespaces(doc, &collection);
11921 EXPECT_HR(hr, S_OK);
11923 len = -1;
11924 hr = IXMLDOMSchemaCollection_get_length(collection, &len);
11925 EXPECT_HR(hr, S_OK);
11926 ok(len == 2, "got %d\n", len);
11928 /* try to lookup some uris */
11929 node = (void*)0xdeadbeef;
11930 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
11931 EXPECT_HR(hr, E_NOTIMPL);
11932 ok(broken(node == (void*)0xdeadbeef) || (node == NULL), "got %p\n", node);
11934 /* load schema and try to add it */
11935 doc2 = create_document(&IID_IXMLDOMDocument2);
11936 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b);
11937 EXPECT_HR(hr, S_OK);
11939 V_VT(&v) = VT_DISPATCH;
11940 V_DISPATCH(&v) = (IDispatch*)doc2;
11941 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v);
11942 EXPECT_HR(hr, E_FAIL);
11943 IXMLDOMDocument2_Release(doc2);
11945 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s);
11946 EXPECT_HR(hr, S_OK);
11947 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s));
11948 SysFreeString(s);
11950 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s);
11951 EXPECT_HR(hr, S_OK);
11952 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s));
11953 SysFreeString(s);
11955 s = (void*)0xdeadbeef;
11956 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
11957 EXPECT_HR(hr, E_FAIL);
11958 ok(broken(s == (void*)0xdeadbeef) || (s == NULL), "got %p\n", s);
11960 /* enumerate */
11961 enumv = (void*)0xdeadbeef;
11962 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv);
11963 EXPECT_HR(hr, S_OK);
11964 ok(enumv != NULL, "got %p\n", enumv);
11966 V_VT(&v) = VT_EMPTY;
11967 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11968 EXPECT_HR(hr, S_OK);
11969 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11970 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11971 VariantClear(&v);
11973 V_VT(&v) = VT_EMPTY;
11974 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11975 EXPECT_HR(hr, S_OK);
11976 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
11977 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
11978 VariantClear(&v);
11980 V_VT(&v) = VT_NULL;
11981 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL);
11982 EXPECT_HR(hr, S_FALSE);
11983 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
11985 IEnumVARIANT_Release(enumv);
11986 IXMLDOMSchemaCollection_Release(collection);
11987 IXMLDOMDocument2_Release(doc);
11988 free_bstrs();
11991 static DOMNodeType put_data_types[] = {
11992 NODE_TEXT,
11993 NODE_CDATA_SECTION,
11994 NODE_PROCESSING_INSTRUCTION,
11995 NODE_COMMENT,
11996 NODE_INVALID
11999 static void test_put_data(void)
12001 static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0};
12002 WCHAR buff[100], *data;
12003 IXMLDOMDocument *doc;
12004 DOMNodeType *type;
12005 IXMLDOMText *text;
12006 IXMLDOMNode *node;
12007 VARIANT v;
12008 BSTR get_data;
12009 HRESULT hr;
12011 doc = create_document(&IID_IXMLDOMDocument);
12013 memcpy(&buff[2], test_data, sizeof(test_data));
12014 /* just a big length */
12015 *(DWORD*)buff = 0xf0f0;
12016 data = &buff[2];
12018 type = put_data_types;
12019 while (*type != NODE_INVALID)
12021 V_VT(&v) = VT_I2;
12022 V_I2(&v) = *type;
12024 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12025 EXPECT_HR(hr, S_OK);
12027 /* put_data() is interface-specific */
12028 switch (*type)
12030 case NODE_TEXT:
12032 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12033 EXPECT_HR(hr, S_OK);
12034 hr = IXMLDOMText_put_data(text, data);
12035 EXPECT_HR(hr, S_OK);
12037 hr = IXMLDOMText_get_data(text, &get_data);
12038 EXPECT_HR(hr, S_OK);
12040 IXMLDOMText_Release(text);
12041 break;
12043 case NODE_CDATA_SECTION:
12045 IXMLDOMCDATASection *cdata;
12047 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
12048 EXPECT_HR(hr, S_OK);
12049 hr = IXMLDOMCDATASection_put_data(cdata, data);
12050 EXPECT_HR(hr, S_OK);
12052 hr = IXMLDOMCDATASection_get_data(cdata, &get_data);
12053 EXPECT_HR(hr, S_OK);
12055 IXMLDOMCDATASection_Release(cdata);
12056 break;
12058 case NODE_PROCESSING_INSTRUCTION:
12060 IXMLDOMProcessingInstruction *pi;
12062 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi);
12063 EXPECT_HR(hr, S_OK);
12064 hr = IXMLDOMProcessingInstruction_put_data(pi, data);
12065 EXPECT_HR(hr, S_OK);
12067 hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data);
12068 EXPECT_HR(hr, S_OK);
12070 IXMLDOMProcessingInstruction_Release(pi);
12071 break;
12073 case NODE_COMMENT:
12075 IXMLDOMComment *comment;
12077 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
12078 EXPECT_HR(hr, S_OK);
12079 hr = IXMLDOMComment_put_data(comment, data);
12080 EXPECT_HR(hr, S_OK);
12082 hr = IXMLDOMComment_get_data(comment, &get_data);
12083 EXPECT_HR(hr, S_OK);
12085 IXMLDOMComment_Release(comment);
12086 break;
12088 default:
12089 break;
12092 /* compare */
12093 ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data),
12094 wine_dbgstr_w(data));
12095 SysFreeString(get_data);
12097 IXMLDOMNode_Release(node);
12098 type++;
12101 /* \r\n sequence is never escaped */
12102 V_VT(&v) = VT_I2;
12103 V_I2(&v) = NODE_TEXT;
12105 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
12106 ok(hr == S_OK, "got 0x%08x\n", hr);
12108 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
12110 hr = IXMLDOMText_put_data(text, _bstr_("\r\n"));
12111 ok(hr == S_OK, "got 0x%08x\n", hr);
12113 hr = IXMLDOMText_get_data(text, &get_data);
12114 ok(hr == S_OK, "got 0x%08x\n", hr);
12115 todo_wine
12116 ok(!lstrcmpW(get_data, _bstr_("\n")), "got %s\n", wine_dbgstr_w(get_data));
12117 SysFreeString(get_data);
12119 hr = IXMLDOMText_get_xml(text, &get_data);
12120 ok(hr == S_OK, "got 0x%08x\n", hr);
12121 ok(!lstrcmpW(get_data, _bstr_("\r\n")), "got %s\n", wine_dbgstr_w(get_data));
12122 SysFreeString(get_data);
12124 IXMLDOMText_Release(text);
12125 IXMLDOMNode_Release(node);
12127 IXMLDOMDocument_Release(doc);
12128 free_bstrs();
12131 static void test_putref_schemas(void)
12133 IXMLDOMSchemaCollection *cache;
12134 IXMLDOMDocument2 *doc;
12135 VARIANT schema;
12136 HRESULT hr;
12138 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
12139 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
12141 doc = create_document(&IID_IXMLDOMDocument2);
12142 cache = create_cache(&IID_IXMLDOMSchemaCollection);
12144 /* set to NULL iface when no schema is set */
12145 V_VT(&schema) = VT_DISPATCH;
12146 V_DISPATCH(&schema) = NULL;
12147 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12148 EXPECT_HR(hr, S_OK);
12150 V_VT(&schema) = VT_UNKNOWN;
12151 V_UNKNOWN(&schema) = NULL;
12152 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12153 EXPECT_HR(hr, S_OK);
12155 /* set as VT_DISPATCH, reset with it */
12156 V_VT(&schema) = VT_DISPATCH;
12157 V_DISPATCH(&schema) = (IDispatch*)cache;
12158 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12159 EXPECT_HR(hr, S_OK);
12161 V_DISPATCH(&schema) = NULL;
12162 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12163 EXPECT_HR(hr, S_OK);
12164 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12166 V_VT(&schema) = VT_DISPATCH;
12167 V_DISPATCH(&schema) = NULL;
12168 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12169 EXPECT_HR(hr, S_OK);
12171 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12172 V_VT(&schema) = VT_I2;
12173 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12174 EXPECT_HR(hr, S_FALSE);
12175 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12176 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12178 /* set as VT_UNKNOWN, reset with it */
12179 V_VT(&schema) = VT_UNKNOWN;
12180 V_UNKNOWN(&schema) = (IUnknown*)cache;
12181 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12182 EXPECT_HR(hr, S_OK);
12184 V_DISPATCH(&schema) = NULL;
12185 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12186 EXPECT_HR(hr, S_OK);
12187 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
12189 V_VT(&schema) = VT_UNKNOWN;
12190 V_UNKNOWN(&schema) = NULL;
12191 hr = IXMLDOMDocument2_putref_schemas(doc, schema);
12192 EXPECT_HR(hr, S_OK);
12194 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
12195 V_VT(&schema) = VT_I2;
12196 hr = IXMLDOMDocument2_get_schemas(doc, &schema);
12197 EXPECT_HR(hr, S_FALSE);
12198 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
12199 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
12201 IXMLDOMSchemaCollection_Release(cache);
12202 IXMLDOMDocument2_Release(doc);
12205 static void test_namedmap_newenum(void)
12207 IEnumVARIANT *enum1, *enum2, *enum3;
12208 IXMLDOMNamedNodeMap *map;
12209 IUnknown *unk1, *unk2;
12210 IXMLDOMDocument *doc;
12211 IXMLDOMElement *elem;
12212 IXMLDOMNode *node;
12213 VARIANT_BOOL b;
12214 HRESULT hr;
12215 VARIANT v;
12216 BSTR str;
12218 doc = create_document(&IID_IXMLDOMDocument);
12220 hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b);
12221 EXPECT_HR(hr, S_OK);
12223 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
12224 EXPECT_HR(hr, S_OK);
12226 hr = IXMLDOMElement_get_attributes(elem, &map);
12227 EXPECT_HR(hr, S_OK);
12228 IXMLDOMElement_Release(elem);
12230 enum1 = NULL;
12231 EXPECT_REF(map, 1);
12232 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1);
12233 EXPECT_HR(hr, S_OK);
12234 ok(enum1 != NULL, "got %p\n", enum1);
12235 EXPECT_REF(map, 1);
12236 EXPECT_REF(enum1, 2);
12238 enum2 = NULL;
12239 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2);
12240 EXPECT_HR(hr, S_OK);
12241 ok(enum2 == enum1, "got %p\n", enum2);
12243 IEnumVARIANT_Release(enum2);
12245 EXPECT_REF(map, 1);
12246 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2);
12247 EXPECT_HR(hr, S_OK);
12248 EXPECT_REF(map, 2);
12249 EXPECT_REF(enum2, 1);
12250 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
12252 IEnumVARIANT_Release(enum1);
12254 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
12255 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1);
12256 EXPECT_HR(hr, S_OK);
12257 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
12258 EXPECT_HR(hr, S_OK);
12259 EXPECT_REF(map, 3);
12260 EXPECT_REF(enum2, 2);
12261 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
12262 IUnknown_Release(unk1);
12263 IUnknown_Release(unk2);
12265 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3);
12266 EXPECT_HR(hr, S_OK);
12267 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
12268 IEnumVARIANT_Release(enum3);
12270 /* iteration tests */
12271 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
12272 EXPECT_HR(hr, S_OK);
12273 hr = IXMLDOMNode_get_nodeName(node, &str);
12274 EXPECT_HR(hr, S_OK);
12275 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12276 SysFreeString(str);
12277 IXMLDOMNode_Release(node);
12279 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12280 EXPECT_HR(hr, S_OK);
12281 hr = IXMLDOMNode_get_nodeName(node, &str);
12282 EXPECT_HR(hr, S_OK);
12283 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str));
12284 SysFreeString(str);
12285 IXMLDOMNode_Release(node);
12287 V_VT(&v) = VT_EMPTY;
12288 hr = IEnumVARIANT_Next(enum2, 1, &v, NULL);
12289 EXPECT_HR(hr, S_OK);
12290 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
12291 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
12292 EXPECT_HR(hr, S_OK);
12293 hr = IXMLDOMNode_get_nodeName(node, &str);
12294 EXPECT_HR(hr, S_OK);
12295 ok(!lstrcmpW(str, _bstr_("attr1")), "got node name %s\n", wine_dbgstr_w(str));
12296 SysFreeString(str);
12297 IXMLDOMNode_Release(node);
12298 VariantClear(&v);
12300 hr = IXMLDOMNamedNodeMap_nextNode(map, &node);
12301 EXPECT_HR(hr, S_OK);
12302 hr = IXMLDOMNode_get_nodeName(node, &str);
12303 EXPECT_HR(hr, S_OK);
12304 ok(!lstrcmpW(str, _bstr_("attr2")), "got %s\n", wine_dbgstr_w(str));
12305 SysFreeString(str);
12306 IXMLDOMNode_Release(node);
12308 IEnumVARIANT_Release(enum2);
12309 IXMLDOMNamedNodeMap_Release(map);
12310 IXMLDOMDocument_Release(doc);
12313 static const char xsltext_xsl[] =
12314 "<?xml version=\"1.0\"?>"
12315 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
12316 "<xsl:output method=\"html\" encoding=\"us-ascii\"/>"
12317 "<xsl:template match=\"/\">"
12318 " <xsl:choose>"
12319 " <xsl:when test=\"testkey\">"
12320 " <xsl:text>testdata</xsl:text>"
12321 " </xsl:when>"
12322 " </xsl:choose>"
12323 "</xsl:template>"
12324 "</xsl:stylesheet>";
12326 static const char omitxmldecl_xsl[] =
12327 "<?xml version=\"1.0\"?>"
12328 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
12329 "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>"
12330 "<xsl:template match=\"/\">"
12331 " <xsl:for-each select=\"/a/item\">"
12332 " <xsl:element name=\"node\">"
12333 " <xsl:value-of select=\"@name\"/>"
12334 " </xsl:element>"
12335 " </xsl:for-each>"
12336 "</xsl:template>"
12337 "</xsl:stylesheet>";
12339 static const char omitxmldecl_doc[] =
12340 "<?xml version=\"1.0\"?>"
12341 "<a>"
12342 " <item name=\"item1\"/>"
12343 " <item name=\"item2\"/>"
12344 "</a>";
12346 static void test_xsltext(void)
12348 IXMLDOMDocument *doc, *doc2;
12349 VARIANT_BOOL b;
12350 HRESULT hr;
12351 BSTR ret;
12353 doc = create_document(&IID_IXMLDOMDocument);
12354 doc2 = create_document(&IID_IXMLDOMDocument);
12356 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
12357 EXPECT_HR(hr, S_OK);
12359 hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b);
12360 EXPECT_HR(hr, S_OK);
12362 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
12363 EXPECT_HR(hr, S_OK);
12364 ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret));
12365 SysFreeString(ret);
12367 /* omit-xml-declaration */
12368 hr = IXMLDOMDocument_loadXML(doc, _bstr_(omitxmldecl_xsl), &b);
12369 ok(hr == S_OK, "got 0x%08x\n", hr);
12370 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(omitxmldecl_doc), &b);
12371 ok(hr == S_OK, "got 0x%08x\n", hr);
12373 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
12374 ok(hr == S_OK, "got 0x%08x\n", hr);
12375 ok(!lstrcmpW(ret, _bstr_("<node>item1</node><node>item2</node>")), "transform result %s\n", wine_dbgstr_w(ret));
12376 SysFreeString(ret);
12378 IXMLDOMDocument_Release(doc2);
12379 IXMLDOMDocument_Release(doc);
12380 free_bstrs();
12383 struct attrtest_t {
12384 const char *name;
12385 const char *uri;
12386 const char *prefix;
12387 const char *href;
12390 static struct attrtest_t attrtests[] = {
12391 { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" },
12392 { "xmlns", "nondefaulturi", "xmlns", "xmlns" },
12393 { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" },
12394 { "c", "nsref1", NULL, "nsref1" },
12395 { "ns:c", "nsref1", "ns", "nsref1" },
12396 { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" },
12397 { "xmlns:c", "nondefaulturi", "xmlns", "" },
12398 { 0 }
12401 static void test_create_attribute(void)
12403 struct attrtest_t *ptr = attrtests;
12404 IXMLDOMElement *el;
12405 IXMLDOMDocument *doc;
12406 IXMLDOMNode *node, *node2;
12407 VARIANT var;
12408 HRESULT hr;
12409 int i = 0;
12410 BSTR str;
12412 doc = create_document(&IID_IXMLDOMDocument);
12414 while (ptr->name)
12416 V_VT(&var) = VT_I1;
12417 V_I1(&var) = NODE_ATTRIBUTE;
12418 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
12419 ok(hr == S_OK, "got 0x%08x\n", hr);
12421 str = NULL;
12422 hr = IXMLDOMNode_get_prefix(node, &str);
12423 if (ptr->prefix)
12425 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
12426 ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix);
12428 else
12430 ok(hr == S_FALSE, "%d: got 0x%08x\n", i, hr);
12431 ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str));
12433 SysFreeString(str);
12435 str = NULL;
12436 hr = IXMLDOMNode_get_namespaceURI(node, &str);
12437 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
12438 ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href);
12439 SysFreeString(str);
12441 IXMLDOMNode_Release(node);
12442 free_bstrs();
12444 i++;
12445 ptr++;
12448 V_VT(&var) = VT_I1;
12449 V_I1(&var) = NODE_ELEMENT;
12450 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2);
12451 ok(hr == S_OK, "got 0x%08x\n", hr);
12453 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el);
12454 ok(hr == S_OK, "got 0x%08x\n", hr);
12455 IXMLDOMNode_Release(node2);
12457 V_VT(&var) = VT_I1;
12458 V_I1(&var) = NODE_ATTRIBUTE;
12459 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node);
12460 ok(hr == S_OK, "got 0x%08x\n", hr);
12462 hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL);
12463 ok(hr == S_OK, "got 0x%08x\n", hr);
12465 /* for some reason default namespace uri is not reported */
12466 hr = IXMLDOMNode_get_namespaceURI(node, &str);
12467 ok(hr == S_OK, "got 0x%08x\n", hr);
12468 ok(!lstrcmpW(str, _bstr_("")), "got uri %s\n", wine_dbgstr_w(str));
12469 SysFreeString(str);
12471 IXMLDOMNode_Release(node);
12472 IXMLDOMElement_Release(el);
12473 IXMLDOMDocument_Release(doc);
12474 free_bstrs();
12477 static void test_url(void)
12479 IXMLDOMDocument *doc;
12480 HRESULT hr;
12481 BSTR s;
12483 doc = create_document(&IID_IXMLDOMDocument);
12485 hr = IXMLDOMDocument_get_url(doc, NULL);
12486 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
12488 s = (BSTR)0x1;
12489 hr = IXMLDOMDocument_get_url(doc, &s);
12490 ok(hr == S_FALSE, "got 0x%08x\n", hr);
12491 ok(s == NULL, "got %s\n", wine_dbgstr_w(s));
12493 IXMLDOMDocument_Release(doc);
12496 static void test_merging_text(void)
12498 IXMLDOMText *nodetext;
12499 IXMLDOMText *newtext;
12500 IXMLDOMElement *root;
12501 IXMLDOMDocument *doc;
12502 IXMLDOMNode *first;
12503 HRESULT hr;
12504 VARIANT v;
12505 BSTR str;
12506 int i;
12508 doc = create_document(&IID_IXMLDOMDocument);
12510 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
12511 EXPECT_HR(hr, S_OK);
12513 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
12514 EXPECT_HR(hr, S_OK);
12516 /* test xmlAddChild */
12517 for (i = 0; i < 10; i++)
12519 str = SysAllocString(szstr1);
12520 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
12521 SysFreeString(str);
12522 EXPECT_HR(hr, S_OK);
12524 newtext = NULL;
12525 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)nodetext, (IXMLDOMNode**)&newtext);
12526 EXPECT_HR(hr, S_OK);
12527 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
12529 IXMLDOMText_Release(newtext);
12530 IXMLDOMText_Release(nodetext);
12533 /* test xmlAddPrevSibling */
12534 hr = IXMLDOMElement_get_firstChild(root, &first);
12535 EXPECT_HR(hr, S_OK);
12536 V_VT(&v) = VT_UNKNOWN;
12537 V_UNKNOWN(&v) = (IUnknown*)first;
12538 for (i = 0; i < 10; i++)
12540 str = SysAllocString(szstr2);
12541 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
12542 SysFreeString(str);
12543 EXPECT_HR(hr, S_OK);
12545 newtext = NULL;
12546 hr = IXMLDOMElement_insertBefore(root, (IXMLDOMNode*)nodetext, v, (IXMLDOMNode**)&newtext);
12547 EXPECT_HR(hr, S_OK);
12548 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext);
12550 IXMLDOMText_Release(newtext);
12551 IXMLDOMText_Release(nodetext);
12554 IXMLDOMNode_Release(first);
12555 IXMLDOMElement_Release(root);
12556 IXMLDOMDocument_Release(doc);
12558 free_bstrs();
12561 START_TEST(domdoc)
12563 HRESULT hr;
12565 hr = CoInitialize( NULL );
12566 ok( hr == S_OK, "failed to init com\n");
12567 if (hr != S_OK) return;
12569 get_class_support_data(domdoc_support_data);
12570 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument))
12572 win_skip("DOMDocument2 is not supported. Skipping all tests.\n");
12573 CoUninitialize();
12574 return;
12577 test_domdoc();
12578 test_persiststream();
12579 test_domnode();
12580 test_refs();
12581 test_create();
12582 test_getElementsByTagName();
12583 test_get_text();
12584 test_get_childNodes();
12585 test_get_firstChild();
12586 test_get_lastChild();
12587 test_removeChild();
12588 test_replaceChild();
12589 test_removeNamedItem();
12590 test_IXMLDOMDocument2();
12591 test_whitespace();
12592 test_XPath();
12593 test_XSLPattern();
12594 test_cloneNode();
12595 test_xmlTypes();
12596 test_save();
12597 test_testTransforms();
12598 test_namespaces_basic();
12599 test_namespaces_change();
12600 test_FormattingXML();
12601 test_nodeTypedValue();
12602 test_TransformWithLoadingLocalFile();
12603 test_put_nodeValue();
12604 test_IObjectSafety();
12605 test_splitText();
12606 test_getQualifiedItem();
12607 test_removeQualifiedItem();
12608 test_get_ownerDocument();
12609 test_setAttributeNode();
12610 test_put_dataType();
12611 test_createNode();
12612 test_create_attribute();
12613 test_get_prefix();
12614 test_default_properties();
12615 test_selectSingleNode();
12616 test_events();
12617 test_createProcessingInstruction();
12618 test_put_nodeTypedValue();
12619 test_get_xml();
12620 test_insertBefore();
12621 test_appendChild();
12622 test_get_doctype();
12623 test_get_tagName();
12624 test_get_dataType();
12625 test_get_nodeTypeString();
12626 test_get_attributes();
12627 test_selection();
12628 test_load();
12629 test_dispex();
12630 test_parseerror();
12631 test_getAttributeNode();
12632 test_getAttribute();
12633 test_supporterrorinfo();
12634 test_nodeValue();
12635 test_get_namespaces();
12636 test_put_data();
12637 test_putref_schemas();
12638 test_namedmap_newenum();
12639 test_xmlns_attribute();
12640 test_url();
12641 test_merging_text();
12643 test_xsltemplate();
12644 test_xsltext();
12646 if (is_clsid_supported(&CLSID_MXNamespaceManager40, &IID_IMXNamespaceManager))
12648 test_mxnamespacemanager();
12649 test_mxnamespacemanager_override();
12652 CoUninitialize();