po: Fix trailing full stops errors in the Russian translation.
[wine/multimedia.git] / dlls / msxml3 / xmlelem.c
blob679e159b5dc1d4c5fe9a4192b49e20b18b3334d7
1 /*
2 * XML Element implementation
4 * Copyright 2007 James Hawkins
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "ole2.h"
35 #include "msxml6.h"
36 #include "ocidl.h"
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44 #ifdef HAVE_LIBXML2
46 static HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
48 /**********************************************************************
49 * IXMLElement
51 typedef struct _xmlelem
53 IXMLElement IXMLElement_iface;
54 LONG ref;
55 xmlNodePtr node;
56 BOOL own;
57 } xmlelem;
59 static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface)
61 return CONTAINING_RECORD(iface, xmlelem, IXMLElement_iface);
64 static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement *iface, REFIID riid, void** ppvObject)
66 xmlelem *This = impl_from_IXMLElement(iface);
68 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
70 if (IsEqualGUID(riid, &IID_IUnknown) ||
71 IsEqualGUID(riid, &IID_IDispatch) ||
72 IsEqualGUID(riid, &IID_IXMLElement))
74 *ppvObject = iface;
76 else
78 FIXME("interface %s not implemented\n", debugstr_guid(riid));
79 *ppvObject = NULL;
80 return E_NOINTERFACE;
83 IXMLElement_AddRef(iface);
85 return S_OK;
88 static ULONG WINAPI xmlelem_AddRef(IXMLElement *iface)
90 xmlelem *This = impl_from_IXMLElement(iface);
91 TRACE("%p\n", This);
92 return InterlockedIncrement(&This->ref);
95 static ULONG WINAPI xmlelem_Release(IXMLElement *iface)
97 xmlelem *This = impl_from_IXMLElement(iface);
98 LONG ref;
100 TRACE("%p\n", This);
102 ref = InterlockedDecrement(&This->ref);
103 if (ref == 0)
105 if (This->own) xmlFreeNode(This->node);
106 heap_free(This);
109 return ref;
112 static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement *iface, UINT* pctinfo)
114 xmlelem *This = impl_from_IXMLElement(iface);
116 TRACE("(%p)->(%p)\n", This, pctinfo);
118 *pctinfo = 1;
120 return S_OK;
123 static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement *iface, UINT iTInfo,
124 LCID lcid, ITypeInfo** ppTInfo)
126 xmlelem *This = impl_from_IXMLElement(iface);
127 HRESULT hr;
129 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
131 hr = get_typeinfo(IXMLElement_tid, ppTInfo);
133 return hr;
136 static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement *iface, REFIID riid,
137 LPOLESTR* rgszNames, UINT cNames,
138 LCID lcid, DISPID* rgDispId)
140 xmlelem *This = impl_from_IXMLElement(iface);
141 ITypeInfo *typeinfo;
142 HRESULT hr;
144 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
145 lcid, rgDispId);
147 if(!rgszNames || cNames == 0 || !rgDispId)
148 return E_INVALIDARG;
150 hr = get_typeinfo(IXMLElement_tid, &typeinfo);
151 if(SUCCEEDED(hr))
153 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
154 ITypeInfo_Release(typeinfo);
157 return hr;
160 static HRESULT WINAPI xmlelem_Invoke(IXMLElement *iface, DISPID dispIdMember,
161 REFIID riid, LCID lcid, WORD wFlags,
162 DISPPARAMS* pDispParams, VARIANT* pVarResult,
163 EXCEPINFO* pExcepInfo, UINT* puArgErr)
165 xmlelem *This = impl_from_IXMLElement(iface);
166 ITypeInfo *typeinfo;
167 HRESULT hr;
169 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
170 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
172 hr = get_typeinfo(IXMLElement_tid, &typeinfo);
173 if(SUCCEEDED(hr))
175 hr = ITypeInfo_Invoke(typeinfo, &This->IXMLElement_iface, dispIdMember, wFlags, pDispParams,
176 pVarResult, pExcepInfo, puArgErr);
177 ITypeInfo_Release(typeinfo);
180 return hr;
183 static HRESULT WINAPI xmlelem_get_tagName(IXMLElement *iface, BSTR *p)
185 xmlelem *This = impl_from_IXMLElement(iface);
187 TRACE("(%p)->(%p)\n", This, p);
189 if (!p)
190 return E_INVALIDARG;
192 *p = bstr_from_xmlChar(This->node->name);
193 CharUpperBuffW(*p, SysStringLen(*p));
195 TRACE("returning %s\n", debugstr_w(*p));
197 return S_OK;
200 static HRESULT WINAPI xmlelem_put_tagName(IXMLElement *iface, BSTR p)
202 xmlelem *This = impl_from_IXMLElement(iface);
204 FIXME("(%p)->(%s): stub\n", This, debugstr_w(p));
206 if (!p)
207 return E_INVALIDARG;
209 return E_NOTIMPL;
212 static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **parent)
214 xmlelem *This = impl_from_IXMLElement(iface);
216 TRACE("(%p)->(%p)\n", This, parent);
218 if (!parent)
219 return E_INVALIDARG;
221 *parent = NULL;
223 if (!This->node->parent)
224 return S_FALSE;
226 return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent, FALSE);
229 static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName,
230 VARIANT PropertyValue)
232 xmlelem *This = impl_from_IXMLElement(iface);
233 xmlChar *name, *value;
234 xmlAttrPtr attr;
236 TRACE("(%p)->(%s %s)\n", This, debugstr_w(strPropertyName), debugstr_variant(&PropertyValue));
238 if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR)
239 return E_INVALIDARG;
241 name = xmlchar_from_wchar(strPropertyName);
242 value = xmlchar_from_wchar(V_BSTR(&PropertyValue));
243 attr = xmlSetProp(This->node, name, value);
245 heap_free(name);
246 heap_free(value);
247 return (attr) ? S_OK : S_FALSE;
250 static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR name,
251 VARIANT *value)
253 static const WCHAR xmllangW[] = { 'x','m','l',':','l','a','n','g',0 };
254 xmlelem *This = impl_from_IXMLElement(iface);
255 xmlChar *val = NULL;
257 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(name), value);
259 if (!value)
260 return E_INVALIDARG;
262 VariantInit(value);
263 V_BSTR(value) = NULL;
265 if (!name)
266 return E_INVALIDARG;
268 /* case for xml:lang attribute */
269 if (!lstrcmpiW(name, xmllangW))
271 xmlNsPtr ns;
272 ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml");
273 val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href);
275 else
277 xmlAttrPtr attr;
278 xmlChar *xml_name;
280 xml_name = xmlchar_from_wchar(name);
281 attr = This->node->properties;
282 while (attr)
284 BSTR attr_name;
286 attr_name = bstr_from_xmlChar(attr->name);
287 if (!lstrcmpiW(name, attr_name))
289 val = xmlNodeListGetString(attr->doc, attr->children, 1);
290 SysFreeString(attr_name);
291 break;
294 attr = attr->next;
295 SysFreeString(attr_name);
298 heap_free(xml_name);
301 if (val)
303 V_VT(value) = VT_BSTR;
304 V_BSTR(value) = bstr_from_xmlChar(val);
307 xmlFree(val);
308 TRACE("returning %s\n", debugstr_w(V_BSTR(value)));
309 return (val) ? S_OK : S_FALSE;
312 static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName)
314 xmlelem *This = impl_from_IXMLElement(iface);
315 xmlChar *name;
316 xmlAttrPtr attr;
317 int res;
318 HRESULT hr = S_FALSE;
320 TRACE("(%p)->(%s)\n", This, debugstr_w(strPropertyName));
322 if (!strPropertyName)
323 return E_INVALIDARG;
325 name = xmlchar_from_wchar(strPropertyName);
326 attr = xmlHasProp(This->node, name);
327 if (!attr)
328 goto done;
330 res = xmlRemoveProp(attr);
332 if (res == 0)
333 hr = S_OK;
335 done:
336 heap_free(name);
337 return hr;
340 static HRESULT WINAPI xmlelem_get_children(IXMLElement *iface, IXMLElementCollection **p)
342 xmlelem *This = impl_from_IXMLElement(iface);
344 TRACE("(%p)->(%p)\n", This, p);
346 if (!p)
347 return E_INVALIDARG;
349 return XMLElementCollection_create((IUnknown *)iface, This->node, (LPVOID *)p);
352 static LONG type_libxml_to_msxml(xmlElementType type)
354 switch (type)
356 case XML_ELEMENT_NODE:
357 return XMLELEMTYPE_ELEMENT;
358 case XML_TEXT_NODE:
359 return XMLELEMTYPE_TEXT;
360 case XML_COMMENT_NODE:
361 return XMLELEMTYPE_COMMENT;
362 case XML_DOCUMENT_NODE:
363 return XMLELEMTYPE_DOCUMENT;
364 case XML_DTD_NODE:
365 return XMLELEMTYPE_DTD;
366 case XML_PI_NODE:
367 return XMLELEMTYPE_PI;
368 default:
369 break;
372 return XMLELEMTYPE_OTHER;
375 static HRESULT WINAPI xmlelem_get_type(IXMLElement *iface, LONG *p)
377 xmlelem *This = impl_from_IXMLElement(iface);
379 TRACE("(%p)->(%p)\n", This, p);
381 if (!p)
382 return E_INVALIDARG;
384 *p = type_libxml_to_msxml(This->node->type);
385 TRACE("returning %d\n", *p);
386 return S_OK;
389 static HRESULT WINAPI xmlelem_get_text(IXMLElement *iface, BSTR *p)
391 xmlelem *This = impl_from_IXMLElement(iface);
392 xmlChar *content;
394 TRACE("(%p)->(%p)\n", This, p);
396 if (!p)
397 return E_INVALIDARG;
399 content = xmlNodeGetContent(This->node);
400 *p = bstr_from_xmlChar(content);
401 TRACE("returning %s\n", debugstr_w(*p));
403 xmlFree(content);
404 return S_OK;
407 static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p)
409 xmlelem *This = impl_from_IXMLElement(iface);
410 xmlChar *content;
412 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
414 /* FIXME: test which types can be used */
415 if (This->node->type == XML_ELEMENT_NODE)
416 return E_NOTIMPL;
418 content = xmlchar_from_wchar(p);
419 xmlNodeSetContent(This->node, content);
421 heap_free(content);
423 return S_OK;
426 static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildElem,
427 LONG lIndex, LONG lreserved)
429 xmlelem *This = impl_from_IXMLElement(iface);
430 xmlelem *childElem = impl_from_IXMLElement(pChildElem);
431 xmlNodePtr child;
433 TRACE("(%p)->(%p %d %d)\n", This, pChildElem, lIndex, lreserved);
435 if (lIndex == 0)
436 child = xmlAddChild(This->node, childElem->node);
437 else
438 child = xmlAddNextSibling(This->node, childElem->node->last);
440 /* parent is responsible for child data */
441 if (child) childElem->own = FALSE;
443 return (child) ? S_OK : S_FALSE;
446 static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChildElem)
448 xmlelem *This = impl_from_IXMLElement(iface);
449 xmlelem *childElem = impl_from_IXMLElement(pChildElem);
451 TRACE("(%p)->(%p)\n", This, childElem);
453 if (!pChildElem)
454 return E_INVALIDARG;
456 /* only supported for This is childElem parent case */
457 if (This->node != childElem->node->parent)
458 return E_INVALIDARG;
460 xmlUnlinkNode(childElem->node);
461 /* standalone element now */
462 childElem->own = TRUE;
464 return S_OK;
467 static const struct IXMLElementVtbl xmlelem_vtbl =
469 xmlelem_QueryInterface,
470 xmlelem_AddRef,
471 xmlelem_Release,
472 xmlelem_GetTypeInfoCount,
473 xmlelem_GetTypeInfo,
474 xmlelem_GetIDsOfNames,
475 xmlelem_Invoke,
476 xmlelem_get_tagName,
477 xmlelem_put_tagName,
478 xmlelem_get_parent,
479 xmlelem_setAttribute,
480 xmlelem_getAttribute,
481 xmlelem_removeAttribute,
482 xmlelem_get_children,
483 xmlelem_get_type,
484 xmlelem_get_text,
485 xmlelem_put_text,
486 xmlelem_addChild,
487 xmlelem_removeChild
490 HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own)
492 xmlelem *elem;
494 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
496 if (!ppObj)
497 return E_INVALIDARG;
499 *ppObj = NULL;
501 elem = heap_alloc(sizeof (*elem));
502 if(!elem)
503 return E_OUTOFMEMORY;
505 elem->IXMLElement_iface.lpVtbl = &xmlelem_vtbl;
506 elem->ref = 1;
507 elem->node = node;
508 elem->own = own;
510 *ppObj = &elem->IXMLElement_iface;
512 TRACE("returning iface %p\n", *ppObj);
513 return S_OK;
516 /************************************************************************
517 * IXMLElementCollection
519 typedef struct _xmlelem_collection
521 IXMLElementCollection IXMLElementCollection_iface;
522 IEnumVARIANT IEnumVARIANT_iface;
523 LONG ref;
524 LONG length;
525 xmlNodePtr node;
527 /* IEnumVARIANT members */
528 xmlNodePtr current;
529 } xmlelem_collection;
531 static inline LONG xmlelem_collection_updatelength(xmlelem_collection *collection)
533 xmlNodePtr ptr = collection->node->children;
535 collection->length = 0;
536 while (ptr)
538 collection->length++;
539 ptr = ptr->next;
541 return collection->length;
544 static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface)
546 return CONTAINING_RECORD(iface, xmlelem_collection, IXMLElementCollection_iface);
549 static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
551 return CONTAINING_RECORD(iface, xmlelem_collection, IEnumVARIANT_iface);
554 static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject)
556 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
558 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
560 if (IsEqualGUID(riid, &IID_IUnknown) ||
561 IsEqualGUID(riid, &IID_IXMLElementCollection))
563 *ppvObject = iface;
565 else if (IsEqualGUID(riid, &IID_IEnumVARIANT))
567 *ppvObject = &This->IEnumVARIANT_iface;
569 else
571 FIXME("interface %s not implemented\n", debugstr_guid(riid));
572 return E_NOINTERFACE;
575 IXMLElementCollection_AddRef(iface);
577 return S_OK;
580 static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface)
582 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
583 TRACE("(%p)\n", This);
584 return InterlockedIncrement(&This->ref);
587 static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface)
589 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
590 LONG ref;
592 TRACE("(%p)\n", This);
594 ref = InterlockedDecrement(&This->ref);
595 if (ref == 0)
597 heap_free(This);
600 return ref;
603 static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo)
605 FIXME("\n");
606 return E_NOTIMPL;
609 static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo,
610 LCID lcid, ITypeInfo** ppTInfo)
612 FIXME("\n");
613 return E_NOTIMPL;
616 static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid,
617 LPOLESTR* rgszNames, UINT cNames,
618 LCID lcid, DISPID* rgDispId)
620 FIXME("\n");
621 return E_NOTIMPL;
624 static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember,
625 REFIID riid, LCID lcid, WORD wFlags,
626 DISPPARAMS* pDispParams, VARIANT* pVarResult,
627 EXCEPINFO* pExcepInfo, UINT* puArgErr)
629 FIXME("\n");
630 return E_NOTIMPL;
633 static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, LONG v)
635 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
636 TRACE("(%p)->(%d)\n", This, v);
637 return E_FAIL;
640 static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, LONG *p)
642 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
644 TRACE("(%p)->(%p)\n", This, p);
646 if (!p)
647 return E_INVALIDARG;
649 *p = xmlelem_collection_updatelength(This);
650 return S_OK;
653 static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk)
655 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
657 TRACE("(%p)->(%p)\n", This, ppUnk);
659 if (!ppUnk)
660 return E_INVALIDARG;
662 *ppUnk = (IUnknown *)This;
663 IUnknown_AddRef(*ppUnk);
664 return S_OK;
667 static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1,
668 VARIANT var2, IDispatch **ppDisp)
670 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
671 xmlNodePtr ptr = This->node->children;
672 int index, i;
674 TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&var1), debugstr_variant(&var2), ppDisp);
676 if (!ppDisp)
677 return E_INVALIDARG;
679 *ppDisp = NULL;
681 index = V_I4(&var1);
682 if (index < 0)
683 return E_INVALIDARG;
685 xmlelem_collection_updatelength(This);
686 if (index >= This->length)
687 return E_FAIL;
689 for (i = 0; i < index; i++)
690 ptr = ptr->next;
692 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp, FALSE);
695 static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl =
697 xmlelem_collection_QueryInterface,
698 xmlelem_collection_AddRef,
699 xmlelem_collection_Release,
700 xmlelem_collection_GetTypeInfoCount,
701 xmlelem_collection_GetTypeInfo,
702 xmlelem_collection_GetIDsOfNames,
703 xmlelem_collection_Invoke,
704 xmlelem_collection_put_length,
705 xmlelem_collection_get_length,
706 xmlelem_collection_get__newEnum,
707 xmlelem_collection_item
710 /************************************************************************
711 * xmlelem_collection implementation of IEnumVARIANT.
713 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface(
714 IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj)
716 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
717 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
720 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef(
721 IEnumVARIANT *iface)
723 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
724 return IXMLDocument_AddRef((IXMLDocument *)this);
727 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release(
728 IEnumVARIANT *iface)
730 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
731 return IXMLDocument_Release((IXMLDocument *)this);
734 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
735 IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched)
737 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
738 xmlNodePtr ptr = This->current;
740 TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, fetched);
742 if (!rgVar)
743 return E_INVALIDARG;
745 /* FIXME: handle celt */
746 if (fetched)
747 *fetched = 1;
749 if (This->current)
750 This->current = This->current->next;
751 else
753 V_VT(rgVar) = VT_EMPTY;
754 if (fetched) *fetched = 0;
755 return S_FALSE;
758 V_VT(rgVar) = VT_DISPATCH;
759 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE);
762 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(
763 IEnumVARIANT *iface, ULONG celt)
765 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
766 FIXME("(%p)->(%d): stub\n", This, celt);
767 return E_NOTIMPL;
770 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset(
771 IEnumVARIANT *iface)
773 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
774 TRACE("(%p)\n", This);
775 This->current = This->node->children;
776 return S_OK;
779 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone(
780 IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
782 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
783 FIXME("(%p)->(%p): stub\n", This, ppEnum);
784 return E_NOTIMPL;
787 static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl =
789 xmlelem_collection_IEnumVARIANT_QueryInterface,
790 xmlelem_collection_IEnumVARIANT_AddRef,
791 xmlelem_collection_IEnumVARIANT_Release,
792 xmlelem_collection_IEnumVARIANT_Next,
793 xmlelem_collection_IEnumVARIANT_Skip,
794 xmlelem_collection_IEnumVARIANT_Reset,
795 xmlelem_collection_IEnumVARIANT_Clone
798 static HRESULT XMLElementCollection_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
800 xmlelem_collection *collection;
802 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
804 *ppObj = NULL;
806 if (!node->children)
807 return S_FALSE;
809 collection = heap_alloc(sizeof (*collection));
810 if(!collection)
811 return E_OUTOFMEMORY;
813 collection->IXMLElementCollection_iface.lpVtbl = &xmlelem_collection_vtbl;
814 collection->IEnumVARIANT_iface.lpVtbl = &xmlelem_collection_IEnumVARIANTvtbl;
815 collection->ref = 1;
816 collection->length = 0;
817 collection->node = node;
818 collection->current = node->children;
819 xmlelem_collection_updatelength(collection);
821 *ppObj = &collection->IXMLElementCollection_iface;
823 TRACE("returning iface %p\n", *ppObj);
824 return S_OK;
827 #endif