2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
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
33 #include "msxml_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
41 static const xmlChar DT_prefix[] = "dt";
42 static const xmlChar DT_nsURI[] = "urn:schemas-microsoft-com:datatypes";
44 typedef struct _domelem
47 IXMLDOMElement IXMLDOMElement_iface;
51 static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
53 return CONTAINING_RECORD(iface, domelem, IXMLDOMElement_iface);
56 static inline xmlNodePtr get_element( const domelem *This )
58 return This->node.node;
61 static HRESULT WINAPI domelem_QueryInterface(
62 IXMLDOMElement *iface,
66 domelem *This = impl_from_IXMLDOMElement( iface );
68 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
70 if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
71 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
72 IsEqualGUID( riid, &IID_IDispatch ) ||
73 IsEqualGUID( riid, &IID_IUnknown ) )
75 *ppvObject = &This->IXMLDOMElement_iface;
77 else if(node_query_interface(&This->node, riid, ppvObject))
79 return *ppvObject ? S_OK : E_NOINTERFACE;
83 FIXME("interface %s not implemented\n", debugstr_guid(riid));
87 IUnknown_AddRef( (IUnknown*)*ppvObject );
91 static ULONG WINAPI domelem_AddRef(
92 IXMLDOMElement *iface )
94 domelem *This = impl_from_IXMLDOMElement( iface );
95 LONG ref = InterlockedIncrement(&This->ref);
97 TRACE("(%p) ref=%d\n", This, ref);
102 static ULONG WINAPI domelem_Release(
103 IXMLDOMElement *iface )
105 domelem *This = impl_from_IXMLDOMElement( iface );
106 ULONG ref = InterlockedDecrement(&This->ref);
108 TRACE("(%p) ref=%d\n", This, ref);
111 destroy_xmlnode(&This->node);
118 static HRESULT WINAPI domelem_GetTypeInfoCount(
119 IXMLDOMElement *iface,
122 domelem *This = impl_from_IXMLDOMElement( iface );
124 TRACE("(%p)->(%p)\n", This, pctinfo);
131 static HRESULT WINAPI domelem_GetTypeInfo(
132 IXMLDOMElement *iface,
133 UINT iTInfo, LCID lcid,
134 ITypeInfo** ppTInfo )
136 domelem *This = impl_from_IXMLDOMElement( iface );
139 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
141 hr = get_typeinfo(IXMLDOMElement_tid, ppTInfo);
146 static HRESULT WINAPI domelem_GetIDsOfNames(
147 IXMLDOMElement *iface,
148 REFIID riid, LPOLESTR* rgszNames,
149 UINT cNames, LCID lcid, DISPID* rgDispId )
151 domelem *This = impl_from_IXMLDOMElement( iface );
155 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
158 if(!rgszNames || cNames == 0 || !rgDispId)
161 hr = get_typeinfo(IXMLDOMElement_tid, &typeinfo);
164 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
165 ITypeInfo_Release(typeinfo);
171 static HRESULT WINAPI domelem_Invoke(
172 IXMLDOMElement *iface,
173 DISPID dispIdMember, REFIID riid, LCID lcid,
174 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
175 EXCEPINFO* pExcepInfo, UINT* puArgErr )
177 domelem *This = impl_from_IXMLDOMElement( iface );
181 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
182 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
184 hr = get_typeinfo(IXMLDOMElement_tid, &typeinfo);
187 hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMElement_iface, dispIdMember, wFlags,
188 pDispParams, pVarResult, pExcepInfo, puArgErr);
189 ITypeInfo_Release(typeinfo);
195 static HRESULT WINAPI domelem_get_nodeName(
196 IXMLDOMElement *iface,
199 domelem *This = impl_from_IXMLDOMElement( iface );
201 TRACE("(%p)->(%p)\n", This, p);
203 return node_get_nodeName(&This->node, p);
206 static HRESULT WINAPI domelem_get_nodeValue(
207 IXMLDOMElement *iface,
210 domelem *This = impl_from_IXMLDOMElement( iface );
212 TRACE("(%p)->(%p)\n", This, value);
217 V_VT(value) = VT_NULL;
218 V_BSTR(value) = NULL; /* tests show that we should do this */
222 static HRESULT WINAPI domelem_put_nodeValue(
223 IXMLDOMElement *iface,
226 domelem *This = impl_from_IXMLDOMElement( iface );
227 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
231 static HRESULT WINAPI domelem_get_nodeType(
232 IXMLDOMElement *iface,
233 DOMNodeType* domNodeType )
235 domelem *This = impl_from_IXMLDOMElement( iface );
237 TRACE("(%p)->(%p)\n", This, domNodeType);
239 *domNodeType = NODE_ELEMENT;
243 static HRESULT WINAPI domelem_get_parentNode(
244 IXMLDOMElement *iface,
245 IXMLDOMNode** parent )
247 domelem *This = impl_from_IXMLDOMElement( iface );
249 TRACE("(%p)->(%p)\n", This, parent);
251 return node_get_parent(&This->node, parent);
254 static HRESULT WINAPI domelem_get_childNodes(
255 IXMLDOMElement *iface,
256 IXMLDOMNodeList** outList)
258 domelem *This = impl_from_IXMLDOMElement( iface );
260 TRACE("(%p)->(%p)\n", This, outList);
262 return node_get_child_nodes(&This->node, outList);
265 static HRESULT WINAPI domelem_get_firstChild(
266 IXMLDOMElement *iface,
267 IXMLDOMNode** domNode)
269 domelem *This = impl_from_IXMLDOMElement( iface );
271 TRACE("(%p)->(%p)\n", This, domNode);
273 return node_get_first_child(&This->node, domNode);
276 static HRESULT WINAPI domelem_get_lastChild(
277 IXMLDOMElement *iface,
278 IXMLDOMNode** domNode)
280 domelem *This = impl_from_IXMLDOMElement( iface );
282 TRACE("(%p)->(%p)\n", This, domNode);
284 return node_get_last_child(&This->node, domNode);
287 static HRESULT WINAPI domelem_get_previousSibling(
288 IXMLDOMElement *iface,
289 IXMLDOMNode** domNode)
291 domelem *This = impl_from_IXMLDOMElement( iface );
293 TRACE("(%p)->(%p)\n", This, domNode);
295 return node_get_previous_sibling(&This->node, domNode);
298 static HRESULT WINAPI domelem_get_nextSibling(
299 IXMLDOMElement *iface,
300 IXMLDOMNode** domNode)
302 domelem *This = impl_from_IXMLDOMElement( iface );
304 TRACE("(%p)->(%p)\n", This, domNode);
306 return node_get_next_sibling(&This->node, domNode);
309 static HRESULT WINAPI domelem_get_attributes(
310 IXMLDOMElement *iface,
311 IXMLDOMNamedNodeMap** attributeMap)
313 domelem *This = impl_from_IXMLDOMElement( iface );
315 TRACE("(%p)->(%p)\n", This, attributeMap);
317 *attributeMap = create_nodemap((IXMLDOMNode*)&This->IXMLDOMElement_iface);
321 static HRESULT WINAPI domelem_insertBefore(
322 IXMLDOMElement *iface,
323 IXMLDOMNode* newNode, VARIANT refChild,
324 IXMLDOMNode** outOldNode)
326 domelem *This = impl_from_IXMLDOMElement( iface );
328 TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode);
330 return node_insert_before(&This->node, newNode, &refChild, outOldNode);
333 static HRESULT WINAPI domelem_replaceChild(
334 IXMLDOMElement *iface,
335 IXMLDOMNode* newNode,
336 IXMLDOMNode* oldNode,
337 IXMLDOMNode** outOldNode)
339 domelem *This = impl_from_IXMLDOMElement( iface );
341 TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode);
343 return node_replace_child(&This->node, newNode, oldNode, outOldNode);
346 static HRESULT WINAPI domelem_removeChild(
347 IXMLDOMElement *iface,
348 IXMLDOMNode *child, IXMLDOMNode **oldChild)
350 domelem *This = impl_from_IXMLDOMElement( iface );
351 TRACE("(%p)->(%p %p)\n", This, child, oldChild);
352 return node_remove_child(&This->node, child, oldChild);
355 static HRESULT WINAPI domelem_appendChild(
356 IXMLDOMElement *iface,
357 IXMLDOMNode *child, IXMLDOMNode **outChild)
359 domelem *This = impl_from_IXMLDOMElement( iface );
360 TRACE("(%p)->(%p %p)\n", This, child, outChild);
361 return node_append_child(&This->node, child, outChild);
364 static HRESULT WINAPI domelem_hasChildNodes(
365 IXMLDOMElement *iface,
368 domelem *This = impl_from_IXMLDOMElement( iface );
369 TRACE("(%p)->(%p)\n", This, ret);
370 return node_has_childnodes(&This->node, ret);
373 static HRESULT WINAPI domelem_get_ownerDocument(
374 IXMLDOMElement *iface,
375 IXMLDOMDocument **doc)
377 domelem *This = impl_from_IXMLDOMElement( iface );
378 TRACE("(%p)->(%p)\n", This, doc);
379 return node_get_owner_doc(&This->node, doc);
382 static HRESULT WINAPI domelem_cloneNode(
383 IXMLDOMElement *iface,
384 VARIANT_BOOL deep, IXMLDOMNode** outNode)
386 domelem *This = impl_from_IXMLDOMElement( iface );
387 TRACE("(%p)->(%d %p)\n", This, deep, outNode);
388 return node_clone( &This->node, deep, outNode );
391 static HRESULT WINAPI domelem_get_nodeTypeString(
392 IXMLDOMElement *iface,
395 domelem *This = impl_from_IXMLDOMElement( iface );
396 static const WCHAR elementW[] = {'e','l','e','m','e','n','t',0};
398 TRACE("(%p)->(%p)\n", This, p);
400 return return_bstr(elementW, p);
403 static HRESULT WINAPI domelem_get_text(
404 IXMLDOMElement *iface,
407 domelem *This = impl_from_IXMLDOMElement( iface );
408 TRACE("(%p)->(%p)\n", This, p);
409 return node_get_text(&This->node, p);
412 static HRESULT WINAPI domelem_put_text(
413 IXMLDOMElement *iface,
416 domelem *This = impl_from_IXMLDOMElement( iface );
417 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
418 return node_put_text( &This->node, p );
421 static HRESULT WINAPI domelem_get_specified(
422 IXMLDOMElement *iface,
423 VARIANT_BOOL* isSpecified)
425 domelem *This = impl_from_IXMLDOMElement( iface );
426 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
427 *isSpecified = VARIANT_TRUE;
431 static HRESULT WINAPI domelem_get_definition(
432 IXMLDOMElement *iface,
433 IXMLDOMNode** definitionNode)
435 domelem *This = impl_from_IXMLDOMElement( iface );
436 FIXME("(%p)->(%p)\n", This, definitionNode);
440 static inline BYTE hex_to_byte(xmlChar c)
442 if(c <= '9') return c-'0';
443 if(c <= 'F') return c-'A'+10;
447 static inline BYTE base64_to_byte(xmlChar c)
449 if(c == '+') return 62;
450 if(c == '/') return 63;
451 if(c <= '9') return c-'0'+52;
452 if(c <= 'Z') return c-'A';
456 static inline HRESULT VARIANT_from_DT(XDR_DT dt, xmlChar* str, VARIANT* v)
460 BOOL handled = FALSE;
475 V_BSTR(v) = bstr_from_xmlChar(str);
478 return E_OUTOFMEMORY;
496 st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
498 V_VT(&src) = VT_BSTR;
499 V_BSTR(&src) = bstr_from_xmlChar(str);
502 return E_OUTOFMEMORY;
505 e = p + SysStringLen(V_BSTR(&src));
507 if(p+4<e && *(p+4)=='-') /* parse date (yyyy-mm-dd) */
510 st.wMonth = atoiW(p+5);
511 st.wDay = atoiW(p+8);
517 if(p+2<e && *(p+2)==':') /* parse time (hh:mm:ss.?) */
520 st.wMinute = atoiW(p+3);
521 st.wSecond = atoiW(p+6);
527 while(isdigitW(*p)) p++;
531 SystemTimeToVariantTime(&st, &date);
535 if(*p == '+') /* parse timezone offset (+hh:mm) */
536 V_DATE(v) += (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
537 else if(*p == '-') /* parse timezone offset (-hh:mm) */
538 V_DATE(v) -= (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
549 len = xmlStrlen(str)/2;
553 V_VT(v) = (VT_ARRAY|VT_UI1);
554 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
557 return E_OUTOFMEMORY;
560 ((BYTE*)V_ARRAY(v)->pvData)[i] = (hex_to_byte(str[2*i])<<4)
561 + hex_to_byte(str[2*i+1]);
570 len = xmlStrlen(str);
571 if(str[len-2] == '=') i = 2;
572 else if(str[len-1] == '=') i = 1;
576 sab.cElements = len/4*3-i;
578 V_VT(v) = (VT_ARRAY|VT_UI1);
579 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
582 return E_OUTOFMEMORY;
584 for(i=0; i<len/4; i++)
586 ((BYTE*)V_ARRAY(v)->pvData)[3*i] = (base64_to_byte(str[4*i])<<2)
587 + (base64_to_byte(str[4*i+1])>>4);
588 if(3*i+1 < sab.cElements)
589 ((BYTE*)V_ARRAY(v)->pvData)[3*i+1] = (base64_to_byte(str[4*i+1])<<4)
590 + (base64_to_byte(str[4*i+2])>>2);
591 if(3*i+2 < sab.cElements)
592 ((BYTE*)V_ARRAY(v)->pvData)[3*i+2] = (base64_to_byte(str[4*i+2])<<6)
593 + base64_to_byte(str[4*i+3]);
644 FIXME("need to handle dt:%s\n", dt_to_str(dt));
646 V_BSTR(v) = bstr_from_xmlChar(str);
648 return E_OUTOFMEMORY;
655 V_VT(&src) = VT_BSTR;
656 V_BSTR(&src) = bstr_from_xmlChar(str);
659 return E_OUTOFMEMORY;
661 hr = VariantChangeTypeEx(v, &src,
662 MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v));
668 static HRESULT WINAPI domelem_get_nodeTypedValue(
669 IXMLDOMElement *iface,
672 domelem *This = impl_from_IXMLDOMElement( iface );
677 TRACE("(%p)->(%p)\n", This, var1);
682 V_VT(var1) = VT_NULL;
684 dt = element_get_dt(get_element(This));
685 content = xmlNodeGetContent(get_element(This));
686 hr = VARIANT_from_DT(dt, content, var1);
692 static HRESULT WINAPI domelem_put_nodeTypedValue(
693 IXMLDOMElement *iface,
696 domelem *This = impl_from_IXMLDOMElement( iface );
700 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
702 /* for untyped node coerce to BSTR and set */
703 if (IXMLDOMElement_get_dataType(iface, &type) == S_FALSE)
705 if (V_VT(&value) != VT_BSTR)
707 hr = VariantChangeType(&value, &value, 0, VT_BSTR);
710 hr = node_set_content(&This->node, V_BSTR(&value));
711 VariantClear(&value);
715 hr = node_set_content(&This->node, V_BSTR(&value));
719 FIXME("not implemented for typed nodes. type %s\n", debugstr_w(V_BSTR(&value)));
727 XDR_DT element_get_dt(xmlNodePtr node)
729 XDR_DT dt = DT_INVALID;
731 TRACE("(%p)\n", node);
732 if(node->type != XML_ELEMENT_NODE)
734 FIXME("invalid element node\n");
738 if (node->ns && xmlStrEqual(node->ns->href, DT_nsURI))
740 dt = str_to_dt(node->name, -1);
744 xmlChar* pVal = xmlGetNsProp(node, BAD_CAST "dt", DT_nsURI);
747 dt = str_to_dt(pVal, -1);
752 IXMLDOMDocument3* doc = (IXMLDOMDocument3*)create_domdoc((xmlNodePtr)node->doc);
758 if (IXMLDOMDocument3_get_schemas(doc, &v) == S_OK &&
759 V_VT(&v) == VT_DISPATCH)
761 dt = SchemaCache_get_node_dt((IXMLDOMSchemaCollection2*)V_DISPATCH(&v), node);
764 IXMLDOMDocument3_Release(doc);
769 TRACE("=> dt:%s\n", dt_to_str(dt));
773 static HRESULT WINAPI domelem_get_dataType(
774 IXMLDOMElement *iface,
777 domelem *This = impl_from_IXMLDOMElement( iface );
780 TRACE("(%p)->(%p)\n", This, typename);
785 dt = element_get_dt(get_element(This));
814 V_VT(typename) = VT_BSTR;
815 V_BSTR(typename) = SysAllocString(dt_to_bstr(dt));
817 if (!V_BSTR(typename))
818 return E_OUTOFMEMORY;
821 /* Other types (DTD equivalents) do not return anything here,
822 * but the pointer part of the VARIANT is set to NULL */
823 V_VT(typename) = VT_NULL;
824 V_BSTR(typename) = NULL;
827 return (V_VT(typename) != VT_NULL) ? S_OK : S_FALSE;
830 static HRESULT WINAPI domelem_put_dataType(
831 IXMLDOMElement *iface,
834 domelem *This = impl_from_IXMLDOMElement( iface );
839 TRACE("(%p)->(%s)\n", This, debugstr_w(dtName));
844 dt = bstr_to_dt(dtName, -1);
846 /* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
847 This applies to changing types (string->bool) or setting a new one
849 str = xmlNodeGetContent(get_element(This));
850 hr = dt_validate(dt, str);
853 /* Check all supported types. */
888 xmlAttrPtr attr = xmlHasNsProp(get_element(This), DT_prefix, DT_nsURI);
891 attr = xmlSetNsProp(get_element(This), attr->ns, DT_prefix, dt_to_str(dt));
896 xmlNsPtr ns = xmlNewNs(get_element(This), DT_nsURI, DT_prefix);
899 attr = xmlNewNsProp(get_element(This), ns, DT_prefix, dt_to_str(dt));
902 xmlAddChild(get_element(This), (xmlNodePtr)attr);
906 ERR("Failed to create Attribute\n");
909 ERR("Failed to create Namespace\n");
914 FIXME("need to handle dt:%s\n", dt_to_str(dt));
922 static HRESULT WINAPI domelem_get_xml(
923 IXMLDOMElement *iface,
926 domelem *This = impl_from_IXMLDOMElement( iface );
928 TRACE("(%p)->(%p)\n", This, p);
930 return node_get_xml(&This->node, TRUE, FALSE, p);
933 static HRESULT WINAPI domelem_transformNode(
934 IXMLDOMElement *iface,
935 IXMLDOMNode* domNode, BSTR* p)
937 domelem *This = impl_from_IXMLDOMElement( iface );
938 return IXMLDOMNode_transformNode( &This->node.IXMLDOMNode_iface, domNode, p );
941 static HRESULT WINAPI domelem_selectNodes(
942 IXMLDOMElement *iface,
943 BSTR p, IXMLDOMNodeList** outList)
945 domelem *This = impl_from_IXMLDOMElement( iface );
946 return IXMLDOMNode_selectNodes( &This->node.IXMLDOMNode_iface, p, outList );
949 static HRESULT WINAPI domelem_selectSingleNode(
950 IXMLDOMElement *iface,
951 BSTR p, IXMLDOMNode** outNode)
953 domelem *This = impl_from_IXMLDOMElement( iface );
954 return IXMLDOMNode_selectSingleNode( &This->node.IXMLDOMNode_iface, p, outNode );
957 static HRESULT WINAPI domelem_get_parsed(
958 IXMLDOMElement *iface,
959 VARIANT_BOOL* isParsed)
961 domelem *This = impl_from_IXMLDOMElement( iface );
962 FIXME("(%p)->(%p) stub!\n", This, isParsed);
963 *isParsed = VARIANT_TRUE;
967 static HRESULT WINAPI domelem_get_namespaceURI(
968 IXMLDOMElement *iface,
971 domelem *This = impl_from_IXMLDOMElement( iface );
972 TRACE("(%p)->(%p)\n", This, p);
973 return node_get_namespaceURI(&This->node, p);
976 static HRESULT WINAPI domelem_get_prefix(
977 IXMLDOMElement *iface,
980 domelem *This = impl_from_IXMLDOMElement( iface );
981 TRACE("(%p)->(%p)\n", This, prefix);
982 return node_get_prefix( &This->node, prefix );
985 static HRESULT WINAPI domelem_get_baseName(
986 IXMLDOMElement *iface,
989 domelem *This = impl_from_IXMLDOMElement( iface );
990 TRACE("(%p)->(%p)\n", This, name);
991 return node_get_base_name( &This->node, name );
994 static HRESULT WINAPI domelem_transformNodeToObject(
995 IXMLDOMElement *iface,
996 IXMLDOMNode* domNode, VARIANT var1)
998 domelem *This = impl_from_IXMLDOMElement( iface );
999 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
1003 static HRESULT WINAPI domelem_get_tagName(
1004 IXMLDOMElement *iface,
1007 domelem *This = impl_from_IXMLDOMElement( iface );
1009 const xmlChar *prefix;
1012 TRACE("(%p)->(%p)\n", This, p );
1014 if (!p) return E_INVALIDARG;
1016 element = get_element( This );
1020 prefix = element->ns ? element->ns->prefix : NULL;
1021 qname = xmlBuildQName(element->name, prefix, NULL, 0);
1023 *p = bstr_from_xmlChar(qname);
1024 if (qname != element->name) xmlFree(qname);
1026 return *p ? S_OK : E_OUTOFMEMORY;
1029 static HRESULT WINAPI domelem_getAttribute(
1030 IXMLDOMElement *iface,
1031 BSTR name, VARIANT* value)
1033 domelem *This = impl_from_IXMLDOMElement( iface );
1035 xmlChar *xml_name, *xml_value = NULL;
1036 HRESULT hr = S_FALSE;
1038 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value);
1041 return E_INVALIDARG;
1043 element = get_element( This );
1047 V_BSTR(value) = NULL;
1048 V_VT(value) = VT_NULL;
1050 xml_name = xmlChar_from_wchar( name );
1052 if(!xmlValidateNameValue(xml_name))
1055 xml_value = xmlGetNsProp(element, xml_name, NULL);
1057 heap_free(xml_name);
1060 V_VT(value) = VT_BSTR;
1061 V_BSTR(value) = bstr_from_xmlChar( xml_value );
1069 static HRESULT WINAPI domelem_setAttribute(
1070 IXMLDOMElement *iface,
1071 BSTR name, VARIANT value)
1073 domelem *This = impl_from_IXMLDOMElement( iface );
1075 xmlChar *xml_name, *xml_value;
1079 TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_variant(&value));
1081 element = get_element( This );
1086 hr = VariantChangeType(&var, &value, 0, VT_BSTR);
1089 FIXME("VariantChangeType failed\n");
1093 xml_name = xmlChar_from_wchar( name );
1094 xml_value = xmlChar_from_wchar( V_BSTR(&var) );
1096 if(!xmlSetNsProp(element, NULL, xml_name, xml_value))
1099 heap_free(xml_value);
1100 heap_free(xml_name);
1106 static HRESULT WINAPI domelem_removeAttribute(
1107 IXMLDOMElement *iface,
1110 domelem *This = impl_from_IXMLDOMElement( iface );
1111 IXMLDOMNamedNodeMap *attr;
1114 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
1116 hr = IXMLDOMElement_get_attributes(iface, &attr);
1117 if (hr != S_OK) return hr;
1119 hr = IXMLDOMNamedNodeMap_removeNamedItem(attr, p, NULL);
1120 IXMLDOMNamedNodeMap_Release(attr);
1125 static HRESULT WINAPI domelem_getAttributeNode(
1126 IXMLDOMElement *iface,
1127 BSTR p, IXMLDOMAttribute** attributeNode )
1129 domelem *This = impl_from_IXMLDOMElement( iface );
1134 HRESULT hr = S_FALSE;
1136 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode);
1141 *attributeNode = NULL;
1143 element = get_element( This );
1147 xml_name = xmlChar_from_wchar(p);
1149 if(!xmlValidateNameValue(xml_name))
1151 heap_free(xml_name);
1155 attr = xmlHasProp(element, xml_name);
1157 unk = create_attribute((xmlNodePtr)attr);
1158 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode);
1159 IUnknown_Release(unk);
1162 heap_free(xml_name);
1167 static HRESULT WINAPI domelem_setAttributeNode(
1168 IXMLDOMElement *iface,
1169 IXMLDOMAttribute* attribute,
1170 IXMLDOMAttribute** old)
1172 domelem *This = impl_from_IXMLDOMElement( iface );
1173 xmlChar *name, *value;
1179 FIXME("(%p)->(%p %p): semi-stub\n", This, attribute, old);
1181 if (!attribute) return E_INVALIDARG;
1183 if (old) *old = NULL;
1185 hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW);
1186 if (hr != S_OK) return hr;
1188 hr = IXMLDOMAttribute_get_nodeValue(attribute, &valueW);
1191 SysFreeString(nameW);
1195 TRACE("attribute: %s=%s\n", debugstr_w(nameW), debugstr_w(V_BSTR(&valueW)));
1197 hr = IXMLDOMAttribute_get_prefix(attribute, &prefix);
1200 FIXME("namespaces not supported: %s\n", debugstr_w(prefix));
1201 SysFreeString(prefix);
1204 name = xmlChar_from_wchar(nameW);
1205 value = xmlChar_from_wchar(V_BSTR(&valueW));
1207 if (!name || !value)
1209 SysFreeString(nameW);
1210 VariantClear(&valueW);
1213 return E_OUTOFMEMORY;
1216 attr = xmlSetNsProp(get_element(This), NULL, name, value);
1218 SysFreeString(nameW);
1219 VariantClear(&valueW);
1223 return attr ? S_OK : E_FAIL;
1226 static HRESULT WINAPI domelem_removeAttributeNode(
1227 IXMLDOMElement *iface,
1228 IXMLDOMAttribute* domAttribute,
1229 IXMLDOMAttribute** attributeNode)
1231 domelem *This = impl_from_IXMLDOMElement( iface );
1232 FIXME("(%p)->(%p %p)\n", This, domAttribute, attributeNode);
1236 static HRESULT WINAPI domelem_getElementsByTagName(
1237 IXMLDOMElement *iface,
1238 BSTR tagName, IXMLDOMNodeList** resultList)
1240 domelem *This = impl_from_IXMLDOMElement( iface );
1245 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1247 if (!tagName || !resultList) return E_INVALIDARG;
1249 XPath = is_xpathmode(get_element(This)->doc);
1250 set_xpathmode(get_element(This)->doc, TRUE);
1251 query = tagName_to_XPath(tagName);
1252 hr = queryresult_create(get_element(This), query, resultList);
1254 set_xpathmode(get_element(This)->doc, XPath);
1259 static HRESULT WINAPI domelem_normalize(
1260 IXMLDOMElement *iface )
1262 domelem *This = impl_from_IXMLDOMElement( iface );
1263 FIXME("%p\n", This);
1267 static const struct IXMLDOMElementVtbl domelem_vtbl =
1269 domelem_QueryInterface,
1272 domelem_GetTypeInfoCount,
1273 domelem_GetTypeInfo,
1274 domelem_GetIDsOfNames,
1276 domelem_get_nodeName,
1277 domelem_get_nodeValue,
1278 domelem_put_nodeValue,
1279 domelem_get_nodeType,
1280 domelem_get_parentNode,
1281 domelem_get_childNodes,
1282 domelem_get_firstChild,
1283 domelem_get_lastChild,
1284 domelem_get_previousSibling,
1285 domelem_get_nextSibling,
1286 domelem_get_attributes,
1287 domelem_insertBefore,
1288 domelem_replaceChild,
1289 domelem_removeChild,
1290 domelem_appendChild,
1291 domelem_hasChildNodes,
1292 domelem_get_ownerDocument,
1294 domelem_get_nodeTypeString,
1297 domelem_get_specified,
1298 domelem_get_definition,
1299 domelem_get_nodeTypedValue,
1300 domelem_put_nodeTypedValue,
1301 domelem_get_dataType,
1302 domelem_put_dataType,
1304 domelem_transformNode,
1305 domelem_selectNodes,
1306 domelem_selectSingleNode,
1308 domelem_get_namespaceURI,
1310 domelem_get_baseName,
1311 domelem_transformNodeToObject,
1312 domelem_get_tagName,
1313 domelem_getAttribute,
1314 domelem_setAttribute,
1315 domelem_removeAttribute,
1316 domelem_getAttributeNode,
1317 domelem_setAttributeNode,
1318 domelem_removeAttributeNode,
1319 domelem_getElementsByTagName,
1323 static const tid_t domelem_iface_tids[] = {
1328 static dispex_static_data_t domelem_dispex = {
1335 IUnknown* create_element( xmlNodePtr element )
1339 This = heap_alloc( sizeof *This );
1343 This->IXMLDOMElement_iface.lpVtbl = &domelem_vtbl;
1346 init_xmlnode(&This->node, element, (IXMLDOMNode*)&This->IXMLDOMElement_iface, &domelem_dispex);
1348 return (IUnknown*)&This->IXMLDOMElement_iface;