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
34 #include "msxml_private.h"
37 # include <libxml/HTMLtree.h>
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46 static const WCHAR szBinBase64[] = {'b','i','n','.','b','a','s','e','6','4',0};
47 static const WCHAR szString[] = {'s','t','r','i','n','g',0};
48 static const WCHAR szNumber[] = {'n','u','m','b','e','r',0};
49 static const WCHAR szInt[] = {'I','n','t',0};
50 static const WCHAR szFixed[] = {'F','i','x','e','d','.','1','4','.','4',0};
51 static const WCHAR szBoolean[] = {'B','o','o','l','e','a','n',0};
52 static const WCHAR szDateTime[] = {'d','a','t','e','T','i','m','e',0};
53 static const WCHAR szDateTimeTZ[] = {'d','a','t','e','T','i','m','e','.','t','z',0};
54 static const WCHAR szDate[] = {'D','a','t','e',0};
55 static const WCHAR szTime[] = {'T','i','m','e',0};
56 static const WCHAR szTimeTZ[] = {'T','i','m','e','.','t','z',0};
57 static const WCHAR szI1[] = {'i','1',0};
58 static const WCHAR szI2[] = {'i','2',0};
59 static const WCHAR szI4[] = {'i','4',0};
60 static const WCHAR szIU1[] = {'u','i','1',0};
61 static const WCHAR szIU2[] = {'u','i','2',0};
62 static const WCHAR szIU4[] = {'u','i','4',0};
63 static const WCHAR szR4[] = {'r','4',0};
64 static const WCHAR szR8[] = {'r','8',0};
65 static const WCHAR szFloat[] = {'f','l','o','a','t',0};
66 static const WCHAR szUUID[] = {'u','u','i','d',0};
67 static const WCHAR szBinHex[] = {'b','i','n','.','h','e','x',0};
69 static const IID IID_xmlnode = {0x4f2f4ba2,0xb822,0x11df,{0x8b,0x8a,0x68,0x50,0xdf,0xd7,0x20,0x85}};
71 xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type )
77 This = get_node_obj( iface );
78 if ( !This || !This->node )
80 if ( type && This->node->type != type )
85 BOOL node_query_interface(xmlnode *This, REFIID riid, void **ppv)
87 if(IsEqualGUID(&IID_xmlnode, riid)) {
88 TRACE("(%p)->(IID_xmlnode %p)\n", This, ppv);
93 if(This->dispex.outer)
94 return dispex_query_interface(&This->dispex, riid, ppv);
99 xmlnode *get_node_obj(IXMLDOMNode *node)
104 hres = IXMLDOMNode_QueryInterface(node, &IID_xmlnode, (void**)&obj);
105 return SUCCEEDED(hres) ? obj : NULL;
108 static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
110 return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
113 static HRESULT WINAPI xmlnode_QueryInterface(
118 xmlnode *This = impl_from_IXMLDOMNode( iface );
120 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
123 return IXMLDOMNode_QueryInterface(This->iface, riid, ppvObject);
125 if (IsEqualGUID(riid, &IID_IUnknown)) {
127 }else if (IsEqualGUID( riid, &IID_IDispatch) ||
128 IsEqualGUID( riid, &IID_IXMLDOMNode)) {
129 *ppvObject = &This->lpVtbl;
130 }else if(node_query_interface(This, riid, ppvObject)) {
131 return *ppvObject ? S_OK : E_NOINTERFACE;
133 FIXME("interface %s not implemented\n", debugstr_guid(riid));
135 return E_NOINTERFACE;
138 IUnknown_AddRef( (IUnknown*)*ppvObject );
142 static ULONG WINAPI xmlnode_AddRef(
145 xmlnode *This = impl_from_IXMLDOMNode( iface );
146 return IXMLDOMNode_AddRef(This->iface);
149 static ULONG WINAPI xmlnode_Release(
152 xmlnode *This = impl_from_IXMLDOMNode( iface );
153 return IXMLDOMNode_Release(This->iface);
156 static HRESULT WINAPI xmlnode_GetTypeInfoCount(
160 xmlnode *This = impl_from_IXMLDOMNode( iface );
162 TRACE("(%p)->(%p)\n", This, pctinfo);
169 static HRESULT WINAPI xmlnode_GetTypeInfo(
173 ITypeInfo** ppTInfo )
175 xmlnode *This = impl_from_IXMLDOMNode( iface );
178 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
180 hr = get_typeinfo(IXMLDOMNode_tid, ppTInfo);
185 static HRESULT WINAPI xmlnode_GetIDsOfNames(
193 xmlnode *This = impl_from_IXMLDOMNode( iface );
198 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
201 if(!rgszNames || cNames == 0 || !rgDispId)
204 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
207 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
208 ITypeInfo_Release(typeinfo);
214 static HRESULT WINAPI xmlnode_Invoke(
220 DISPPARAMS* pDispParams,
222 EXCEPINFO* pExcepInfo,
225 xmlnode *This = impl_from_IXMLDOMNode( iface );
229 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
230 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
232 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
235 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
236 pVarResult, pExcepInfo, puArgErr);
237 ITypeInfo_Release(typeinfo);
243 static HRESULT WINAPI xmlnode_get_nodeName(
247 xmlnode *This = impl_from_IXMLDOMNode( iface );
250 TRACE("(%p)->(%p)\n", This, name );
258 switch( This->node->type )
260 case XML_CDATA_SECTION_NODE:
261 str = (const xmlChar*) "#cdata-section";
263 case XML_COMMENT_NODE:
264 str = (const xmlChar*) "#comment";
266 case XML_DOCUMENT_FRAG_NODE:
267 str = (const xmlChar*) "#document-fragment";
270 str = (const xmlChar*) "#text";
272 case XML_DOCUMENT_NODE:
273 str = (const xmlChar*) "#document";
275 case XML_ATTRIBUTE_NODE:
276 case XML_ELEMENT_NODE:
278 str = This->node->name;
281 FIXME("nodeName not mapped correctly (%d)\n", This->node->type);
282 str = This->node->name;
286 *name = bstr_from_xmlChar( str );
293 static HRESULT WINAPI xmlnode_get_nodeValue(
297 xmlnode *This = impl_from_IXMLDOMNode( iface );
300 TRACE("(%p)->(%p)\n", This, value);
305 V_BSTR(value) = NULL;
306 V_VT(value) = VT_NULL;
308 switch ( This->node->type )
310 case XML_CDATA_SECTION_NODE:
311 case XML_COMMENT_NODE:
313 case XML_ATTRIBUTE_NODE:
315 xmlChar *content = xmlNodeGetContent(This->node);
316 V_VT(value) = VT_BSTR;
317 V_BSTR(value) = bstr_from_xmlChar( content );
323 V_VT(value) = VT_BSTR;
324 V_BSTR(value) = bstr_from_xmlChar( This->node->content );
327 case XML_ELEMENT_NODE:
328 case XML_DOCUMENT_NODE:
329 /* these seem to return NULL */
333 FIXME("node %p type %d\n", This, This->node->type);
336 TRACE("%p returned %s\n", This, debugstr_w( V_BSTR(value) ) );
341 static HRESULT WINAPI xmlnode_put_nodeValue(
345 xmlnode *This = impl_from_IXMLDOMNode( iface );
348 TRACE("%p type(%d)\n", This, This->node->type);
350 /* Document, Document Fragment, Document Type, Element,
351 Entity, Entity Reference, Notation aren't supported. */
352 switch ( This->node->type )
354 case XML_ATTRIBUTE_NODE:
355 case XML_CDATA_SECTION_NODE:
356 case XML_COMMENT_NODE:
360 VARIANT string_value;
363 VariantInit(&string_value);
364 hr = VariantChangeType(&string_value, &value, 0, VT_BSTR);
367 VariantClear(&string_value);
368 WARN("Couldn't convert to VT_BSTR\n");
372 str = xmlChar_from_wchar(V_BSTR(&string_value));
373 VariantClear(&string_value);
375 xmlNodeSetContent(This->node, str);
381 /* Do nothing for unsupported types. */
389 static HRESULT WINAPI xmlnode_get_nodeType(
393 xmlnode *This = impl_from_IXMLDOMNode( iface );
395 TRACE("(%p)->(%p)\n", This, type);
397 assert( (int)NODE_ELEMENT == (int)XML_ELEMENT_NODE );
398 assert( (int)NODE_NOTATION == (int)XML_NOTATION_NODE );
400 *type = This->node->type;
405 static HRESULT get_node(
411 TRACE("(%p)->(%s %p %p)\n", This, name, node, out );
416 /* if we don't have a doc, use our parent. */
417 if(node && !node->doc && node->parent)
418 node->doc = node->parent->doc;
420 *out = create_node( node );
426 static HRESULT WINAPI xmlnode_get_parentNode(
428 IXMLDOMNode** parent)
430 xmlnode *This = impl_from_IXMLDOMNode( iface );
431 return get_node( This, "parent", This->node->parent, parent );
434 static HRESULT WINAPI xmlnode_get_childNodes(
436 IXMLDOMNodeList** childList)
438 xmlnode *This = impl_from_IXMLDOMNode( iface );
440 TRACE("(%p)->(%p)\n", This, childList );
445 *childList = create_children_nodelist(This->node);
446 if (*childList == NULL)
447 return E_OUTOFMEMORY;
452 static HRESULT WINAPI xmlnode_get_firstChild(
454 IXMLDOMNode** firstChild)
456 xmlnode *This = impl_from_IXMLDOMNode( iface );
457 TRACE("(%p)->(%p)\n", This, firstChild);
458 return get_node( This, "firstChild", This->node->children, firstChild );
461 static HRESULT WINAPI xmlnode_get_lastChild(
463 IXMLDOMNode** lastChild)
465 xmlnode *This = impl_from_IXMLDOMNode( iface );
467 TRACE("(%p)->(%p)\n", This, lastChild );
472 switch( This->node->type )
474 /* CDATASection, Comment, PI and Text Nodes do not support lastChild */
476 case XML_CDATA_SECTION_NODE:
478 case XML_COMMENT_NODE:
482 return get_node( This, "lastChild", This->node->last, lastChild );
486 static HRESULT WINAPI xmlnode_get_previousSibling(
488 IXMLDOMNode** previousSibling)
490 xmlnode *This = impl_from_IXMLDOMNode( iface );
492 TRACE("(%p)->(%p)\n", This, previousSibling );
494 if (!previousSibling)
497 switch( This->node->type )
499 /* Attribute, Document and Document Fragment Nodes do not support previousSibling */
500 case XML_DOCUMENT_NODE:
501 case XML_DOCUMENT_FRAG_NODE:
502 case XML_ATTRIBUTE_NODE:
503 *previousSibling = NULL;
506 return get_node( This, "previous", This->node->prev, previousSibling );
510 static HRESULT WINAPI xmlnode_get_nextSibling(
512 IXMLDOMNode** nextSibling)
514 xmlnode *This = impl_from_IXMLDOMNode( iface );
516 TRACE("(%p)->(%p)\n", This, nextSibling );
521 switch( This->node->type )
523 /* Attribute, Document and Document Fragment Nodes do not support nextSibling */
524 case XML_DOCUMENT_NODE:
525 case XML_DOCUMENT_FRAG_NODE:
526 case XML_ATTRIBUTE_NODE:
530 return get_node( This, "next", This->node->next, nextSibling );
534 static HRESULT WINAPI xmlnode_get_attributes(
536 IXMLDOMNamedNodeMap** attributeMap)
538 xmlnode *This = impl_from_IXMLDOMNode( iface );
539 TRACE("(%p)->(%p)\n", This, attributeMap);
544 switch( This->node->type )
546 /* Attribute, CDataSection, Comment, Documents, Documents Fragments,
547 Entity and Text Nodes does not support get_attributes */
548 case XML_ATTRIBUTE_NODE:
549 case XML_CDATA_SECTION_NODE:
550 case XML_COMMENT_NODE:
551 case XML_DOCUMENT_NODE:
552 case XML_DOCUMENT_FRAG_NODE:
553 case XML_ENTITY_NODE:
554 case XML_ENTITY_REF_NODE:
556 *attributeMap = NULL;
559 *attributeMap = create_nodemap( iface );
564 static HRESULT WINAPI xmlnode_insertBefore(
566 IXMLDOMNode* newChild,
568 IXMLDOMNode** outNewChild)
570 xmlnode *This = impl_from_IXMLDOMNode( iface );
571 xmlNodePtr before_node, new_child_node;
572 IXMLDOMNode *before = NULL;
576 TRACE("(%p)->(%p var %p)\n",This,newChild,outNewChild);
581 switch(V_VT(&refChild))
588 hr = IUnknown_QueryInterface(V_UNKNOWN(&refChild), &IID_IXMLDOMNode, (LPVOID)&before);
589 if(FAILED(hr)) return hr;
593 hr = IDispatch_QueryInterface(V_DISPATCH(&refChild), &IID_IXMLDOMNode, (LPVOID)&before);
594 if(FAILED(hr)) return hr;
598 FIXME("refChild var type %x\n", V_VT(&refChild));
602 node_obj = get_node_obj(newChild);
604 FIXME("newChild is not our node implementation\n");
608 new_child_node = node_obj->node;
609 TRACE("new_child_node %p This->node %p\n", new_child_node, This->node);
611 if(!new_child_node->parent)
612 if(xmldoc_remove_orphan(new_child_node->doc, new_child_node) != S_OK)
613 WARN("%p is not an orphan of %p\n", new_child_node, new_child_node->doc);
617 node_obj = get_node_obj(before);
618 IXMLDOMNode_Release(before);
620 FIXME("before node is not our node implementation\n");
624 before_node = node_obj->node;
625 xmlAddPrevSibling(before_node, new_child_node);
629 xmlAddChild(This->node, new_child_node);
632 IXMLDOMNode_AddRef(newChild);
634 *outNewChild = newChild;
640 static HRESULT WINAPI xmlnode_replaceChild(
642 IXMLDOMNode* newChild,
643 IXMLDOMNode* oldChild,
644 IXMLDOMNode** outOldChild)
646 xmlnode *This = impl_from_IXMLDOMNode( iface );
647 xmlNode *old_child_ptr, *new_child_ptr;
648 xmlDocPtr leaving_doc;
649 xmlNode *my_ancestor;
650 IXMLDOMNode *realOldChild;
653 TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, outOldChild);
655 /* Do not believe any documentation telling that newChild == NULL
656 means removal. It does certainly *not* apply to msxml3! */
657 if(!newChild || !oldChild)
663 hr = IXMLDOMNode_QueryInterface(oldChild,&IID_IXMLDOMNode,(LPVOID*)&realOldChild);
667 old_child_ptr = impl_from_IXMLDOMNode(realOldChild)->node;
668 IXMLDOMNode_Release(realOldChild);
669 if(old_child_ptr->parent != This->node)
671 WARN("childNode %p is not a child of %p\n", oldChild, iface);
675 new_child_ptr = impl_from_IXMLDOMNode(newChild)->node;
676 my_ancestor = This->node;
679 if(my_ancestor == new_child_ptr)
681 WARN("tried to create loop\n");
684 my_ancestor = my_ancestor->parent;
687 if(!new_child_ptr->parent)
688 if(xmldoc_remove_orphan(new_child_ptr->doc, new_child_ptr) != S_OK)
689 WARN("%p is not an orphan of %p\n", new_child_ptr, new_child_ptr->doc);
691 leaving_doc = new_child_ptr->doc;
692 xmldoc_add_ref(old_child_ptr->doc);
693 xmlReplaceNode(old_child_ptr, new_child_ptr);
694 xmldoc_release(leaving_doc);
696 xmldoc_add_orphan(old_child_ptr->doc, old_child_ptr);
700 IXMLDOMNode_AddRef(oldChild);
701 *outOldChild = oldChild;
707 static HRESULT WINAPI xmlnode_removeChild(
709 IXMLDOMNode* childNode,
710 IXMLDOMNode** oldChild)
712 xmlnode *This = impl_from_IXMLDOMNode( iface );
715 TRACE("(%p)->(%p %p)\n", This, childNode, oldChild);
717 if(!childNode) return E_INVALIDARG;
722 child_node = get_node_obj(childNode);
724 FIXME("childNode is not our node implementation\n");
728 if(child_node->node->parent != This->node)
730 WARN("childNode %p is not a child of %p\n", childNode, iface);
734 xmlUnlinkNode(child_node->node);
738 IXMLDOMNode_AddRef(childNode);
739 *oldChild = childNode;
745 static HRESULT WINAPI xmlnode_appendChild(
747 IXMLDOMNode* newChild,
748 IXMLDOMNode** outNewChild)
750 xmlnode *This = impl_from_IXMLDOMNode( iface );
755 TRACE("(%p)->(%p %p)\n", This, newChild, outNewChild);
757 hr = IXMLDOMNode_get_nodeType(newChild, &type);
758 if(FAILED(hr) || type == NODE_ATTRIBUTE) {
759 if(outNewChild) *outNewChild = NULL;
764 return IXMLDOMNode_insertBefore(iface, newChild, var, outNewChild);
767 static HRESULT WINAPI xmlnode_hasChildNodes(
769 VARIANT_BOOL* hasChild)
771 xmlnode *This = impl_from_IXMLDOMNode( iface );
773 TRACE("(%p)->(%p)\n", This, hasChild);
777 if (!This->node->children)
779 *hasChild = VARIANT_FALSE;
783 *hasChild = VARIANT_TRUE;
787 static HRESULT WINAPI xmlnode_get_ownerDocument(
789 IXMLDOMDocument** DOMDocument)
791 xmlnode *This = impl_from_IXMLDOMNode( iface );
793 TRACE("(%p)->(%p)\n", This, DOMDocument);
795 return DOMDocument_create_from_xmldoc(This->node->doc, (IXMLDOMDocument3**)DOMDocument);
798 static HRESULT WINAPI xmlnode_cloneNode(
801 IXMLDOMNode** cloneRoot)
803 xmlnode *This = impl_from_IXMLDOMNode( iface );
804 xmlNodePtr pClone = NULL;
805 IXMLDOMNode *pNode = NULL;
807 TRACE("(%p)->(%d %p)\n", This, deep, cloneRoot);
812 pClone = xmlCopyNode(This->node, deep ? 1 : 2);
815 pClone->doc = This->node->doc;
816 xmldoc_add_orphan(pClone->doc, pClone);
818 pNode = create_node(pClone);
821 ERR("Copy failed\n");
829 ERR("Copy failed\n");
836 static HRESULT WINAPI xmlnode_get_nodeTypeString(
840 xmlnode *This = impl_from_IXMLDOMNode( iface );
843 TRACE("(%p)->(%p)\n", This, xmlnodeType );
851 switch( This->node->type )
853 case XML_ATTRIBUTE_NODE:
854 str = (const xmlChar*) "attribute";
856 case XML_CDATA_SECTION_NODE:
857 str = (const xmlChar*) "cdatasection";
859 case XML_COMMENT_NODE:
860 str = (const xmlChar*) "comment";
862 case XML_DOCUMENT_NODE:
863 str = (const xmlChar*) "document";
865 case XML_DOCUMENT_FRAG_NODE:
866 str = (const xmlChar*) "documentfragment";
868 case XML_ELEMENT_NODE:
869 str = (const xmlChar*) "element";
871 case XML_ENTITY_NODE:
872 str = (const xmlChar*) "entity";
874 case XML_ENTITY_REF_NODE:
875 str = (const xmlChar*) "entityreference";
877 case XML_NOTATION_NODE:
878 str = (const xmlChar*) "notation";
881 str = (const xmlChar*) "processinginstruction";
884 str = (const xmlChar*) "text";
887 FIXME("Unknown node type (%d)\n", This->node->type);
888 str = This->node->name;
892 *xmlnodeType = bstr_from_xmlChar( str );
899 static HRESULT WINAPI xmlnode_get_text(
903 xmlnode *This = impl_from_IXMLDOMNode( iface );
907 TRACE("(%p, type %d)->(%p)\n", This, This->node->type, text);
912 pContent = xmlNodeGetContent((xmlNodePtr)This->node);
915 str = bstr_from_xmlChar(pContent);
919 /* Always return a string. */
920 if (!str) str = SysAllocStringLen( NULL, 0 );
922 TRACE("%p %s\n", This, debugstr_w(str) );
928 static HRESULT WINAPI xmlnode_put_text(
932 xmlnode *This = impl_from_IXMLDOMNode( iface );
935 TRACE("(%p)->(%s)\n", This, debugstr_w(text));
937 switch(This->node->type)
939 case XML_DOCUMENT_NODE:
945 str = xmlChar_from_wchar(text);
947 /* Escape the string. */
948 str2 = xmlEncodeEntitiesReentrant(This->node->doc, str);
951 xmlNodeSetContent(This->node, str2);
957 static HRESULT WINAPI xmlnode_get_specified(
959 VARIANT_BOOL* isSpecified)
961 xmlnode *This = impl_from_IXMLDOMNode( iface );
962 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
963 *isSpecified = VARIANT_TRUE;
967 static HRESULT WINAPI xmlnode_get_definition(
969 IXMLDOMNode** definitionNode)
971 xmlnode *This = impl_from_IXMLDOMNode( iface );
972 FIXME("(%p)->(%p)\n", This, definitionNode);
976 static inline BYTE hex_to_byte(xmlChar c)
978 if(c <= '9') return c-'0';
979 if(c <= 'F') return c-'A'+10;
983 static inline BYTE base64_to_byte(xmlChar c)
985 if(c == '+') return 62;
986 if(c == '/') return 63;
987 if(c <= '9') return c-'0'+52;
988 if(c <= 'Z') return c-'A';
992 static inline HRESULT VARIANT_from_xmlChar(xmlChar *str, VARIANT *v, BSTR type)
994 if(!type || !lstrcmpiW(type, szString) ||
995 !lstrcmpiW(type, szNumber) || !lstrcmpiW(type, szUUID))
998 V_BSTR(v) = bstr_from_xmlChar(str);
1001 return E_OUTOFMEMORY;
1003 else if(!lstrcmpiW(type, szDateTime) || !lstrcmpiW(type, szDateTimeTZ) ||
1004 !lstrcmpiW(type, szDate) || !lstrcmpiW(type, szTime) ||
1005 !lstrcmpiW(type, szTimeTZ))
1015 st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
1017 V_VT(&src) = VT_BSTR;
1018 V_BSTR(&src) = bstr_from_xmlChar(str);
1021 return E_OUTOFMEMORY;
1024 e = p + SysStringLen(V_BSTR(&src));
1026 if(p+4<e && *(p+4)=='-') /* parse date (yyyy-mm-dd) */
1028 st.wYear = atoiW(p);
1029 st.wMonth = atoiW(p+5);
1030 st.wDay = atoiW(p+8);
1036 if(p+2<e && *(p+2)==':') /* parse time (hh:mm:ss.?) */
1038 st.wHour = atoiW(p);
1039 st.wMinute = atoiW(p+3);
1040 st.wSecond = atoiW(p+6);
1046 while(isdigitW(*p)) p++;
1050 SystemTimeToVariantTime(&st, &date);
1054 if(*p == '+') /* parse timezone offset (+hh:mm) */
1055 V_DATE(v) += (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
1056 else if(*p == '-') /* parse timezone offset (-hh:mm) */
1057 V_DATE(v) -= (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
1061 else if(!lstrcmpiW(type, szBinHex))
1066 len = xmlStrlen(str)/2;
1068 sab.cElements = len;
1070 V_VT(v) = (VT_ARRAY|VT_UI1);
1071 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
1074 return E_OUTOFMEMORY;
1076 for(i=0; i<len; i++)
1077 ((BYTE*)V_ARRAY(v)->pvData)[i] = (hex_to_byte(str[2*i])<<4)
1078 + hex_to_byte(str[2*i+1]);
1080 else if(!lstrcmpiW(type, szBinBase64))
1085 len = xmlStrlen(str);
1086 if(str[len-2] == '=') i = 2;
1087 else if(str[len-1] == '=') i = 1;
1091 sab.cElements = len/4*3-i;
1093 V_VT(v) = (VT_ARRAY|VT_UI1);
1094 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
1097 return E_OUTOFMEMORY;
1099 for(i=0; i<len/4; i++)
1101 ((BYTE*)V_ARRAY(v)->pvData)[3*i] = (base64_to_byte(str[4*i])<<2)
1102 + (base64_to_byte(str[4*i+1])>>4);
1103 if(3*i+1 < sab.cElements)
1104 ((BYTE*)V_ARRAY(v)->pvData)[3*i+1] = (base64_to_byte(str[4*i+1])<<4)
1105 + (base64_to_byte(str[4*i+2])>>2);
1106 if(3*i+2 < sab.cElements)
1107 ((BYTE*)V_ARRAY(v)->pvData)[3*i+2] = (base64_to_byte(str[4*i+2])<<6)
1108 + base64_to_byte(str[4*i+3]);
1116 if(!lstrcmpiW(type, szInt) || !lstrcmpiW(type, szI4))
1118 else if(!lstrcmpiW(type, szFixed))
1120 else if(!lstrcmpiW(type, szBoolean))
1122 else if(!lstrcmpiW(type, szI1))
1124 else if(!lstrcmpiW(type, szI2))
1126 else if(!lstrcmpiW(type, szIU1))
1128 else if(!lstrcmpiW(type, szIU2))
1130 else if(!lstrcmpiW(type, szIU4))
1132 else if(!lstrcmpiW(type, szR4))
1134 else if(!lstrcmpiW(type, szR8) || !lstrcmpiW(type, szFloat))
1138 FIXME("Type handling not yet implemented\n");
1142 V_VT(&src) = VT_BSTR;
1143 V_BSTR(&src) = bstr_from_xmlChar(str);
1146 return E_OUTOFMEMORY;
1148 hres = VariantChangeTypeEx(v, &src, MAKELCID(MAKELANGID(
1149 LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v));
1157 static HRESULT WINAPI xmlnode_get_nodeTypedValue(
1159 VARIANT* typedValue)
1161 xmlnode *This = impl_from_IXMLDOMNode( iface );
1164 HRESULT hres = S_FALSE;
1166 TRACE("(%p)->(%p)\n", This, typedValue);
1169 return E_INVALIDARG;
1171 V_VT(typedValue) = VT_NULL;
1173 if(This->node->type == XML_ELEMENT_NODE ||
1174 This->node->type == XML_TEXT_NODE ||
1175 This->node->type == XML_ENTITY_REF_NODE)
1176 hres = IXMLDOMNode_get_dataType(iface, &type);
1178 if(hres != S_OK && This->node->type != XML_ELEMENT_NODE)
1179 return IXMLDOMNode_get_nodeValue(iface, typedValue);
1181 content = xmlNodeGetContent(This->node);
1182 hres = VARIANT_from_xmlChar(content, typedValue,
1183 hres==S_OK ? V_BSTR(&type) : NULL);
1185 VariantClear(&type);
1190 static HRESULT WINAPI xmlnode_put_nodeTypedValue(
1194 xmlnode *This = impl_from_IXMLDOMNode( iface );
1195 FIXME("%p\n", This);
1199 static HRESULT WINAPI xmlnode_get_dataType(
1201 VARIANT* dataTypeName)
1203 xmlnode *This = impl_from_IXMLDOMNode( iface );
1206 TRACE("(%p)->(%p)\n", This, dataTypeName);
1209 return E_INVALIDARG;
1211 /* Attribute, CDATA Section, Comment, Document, Document Fragment,
1212 Entity, Notation, PI, and Text Node are non-typed. */
1213 V_BSTR(dataTypeName) = NULL;
1214 V_VT(dataTypeName) = VT_NULL;
1216 switch ( This->node->type )
1218 case XML_ELEMENT_NODE:
1219 pVal = xmlGetNsProp(This->node, (const xmlChar*)"dt",
1220 (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
1223 V_VT(dataTypeName) = VT_BSTR;
1224 V_BSTR(dataTypeName) = bstr_from_xmlChar( pVal );
1228 case XML_ENTITY_REF_NODE:
1229 FIXME("XML_ENTITY_REF_NODE should return a valid value.\n");
1232 TRACE("Type %d returning NULL\n", This->node->type);
1235 /* non-typed nodes return S_FALSE */
1236 if(V_VT(dataTypeName) == VT_NULL)
1244 static HRESULT WINAPI xmlnode_put_dataType(
1248 xmlnode *This = impl_from_IXMLDOMNode( iface );
1249 HRESULT hr = E_FAIL;
1251 TRACE("(%p)->(%s)\n", This, debugstr_w(dataTypeName));
1253 if(dataTypeName == NULL)
1254 return E_INVALIDARG;
1256 /* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
1257 This applies to changing types (string->bool) or setting a new one
1259 FIXME("Need to Validate the data before allowing a type to be set.\n");
1261 /* Check all supported types. */
1262 if(lstrcmpiW(dataTypeName,szString) == 0 ||
1263 lstrcmpiW(dataTypeName,szNumber) == 0 ||
1264 lstrcmpiW(dataTypeName,szUUID) == 0 ||
1265 lstrcmpiW(dataTypeName,szInt) == 0 ||
1266 lstrcmpiW(dataTypeName,szI4) == 0 ||
1267 lstrcmpiW(dataTypeName,szFixed) == 0 ||
1268 lstrcmpiW(dataTypeName,szBoolean) == 0 ||
1269 lstrcmpiW(dataTypeName,szDateTime) == 0 ||
1270 lstrcmpiW(dataTypeName,szDateTimeTZ) == 0 ||
1271 lstrcmpiW(dataTypeName,szDate) == 0 ||
1272 lstrcmpiW(dataTypeName,szTime) == 0 ||
1273 lstrcmpiW(dataTypeName,szTimeTZ) == 0 ||
1274 lstrcmpiW(dataTypeName,szI1) == 0 ||
1275 lstrcmpiW(dataTypeName,szI2) == 0 ||
1276 lstrcmpiW(dataTypeName,szIU1) == 0 ||
1277 lstrcmpiW(dataTypeName,szIU2) == 0 ||
1278 lstrcmpiW(dataTypeName,szIU4) == 0 ||
1279 lstrcmpiW(dataTypeName,szR4) == 0 ||
1280 lstrcmpiW(dataTypeName,szR8) == 0 ||
1281 lstrcmpiW(dataTypeName,szFloat) == 0 ||
1282 lstrcmpiW(dataTypeName,szBinHex) == 0 ||
1283 lstrcmpiW(dataTypeName,szBinBase64) == 0)
1285 xmlNsPtr pNS = NULL;
1286 xmlAttrPtr pAttr = NULL;
1287 xmlChar* str = xmlChar_from_wchar(dataTypeName);
1289 pAttr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
1290 (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
1293 pAttr = xmlSetNsProp(This->node, pAttr->ns, (const xmlChar*)"dt", str);
1299 pNS = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
1302 pAttr = xmlNewNsProp(This->node, pNS, (const xmlChar*)"dt", str);
1305 xmlAddChild(This->node, (xmlNodePtr)pAttr);
1310 ERR("Failed to create Attribute\n");
1313 ERR("Failed to Create Namepsace\n");
1321 static BSTR EnsureCorrectEOL(BSTR sInput)
1328 nLen = lstrlenW(sInput);
1329 /* Count line endings */
1330 for(i=0; i < nLen; i++)
1332 if(sInput[i] == '\n')
1336 TRACE("len=%d, num=%d\n", nLen, nNum);
1338 /* Add linefeed as needed */
1342 sNew = SysAllocStringLen(NULL, nLen + nNum+1);
1343 for(i=0; i < nLen; i++)
1345 if(sInput[i] == '\n')
1347 sNew[i+nPlace] = '\r';
1350 sNew[i+nPlace] = sInput[i];
1353 SysFreeString(sInput);
1360 TRACE("len %d\n", lstrlenW(sNew));
1365 /* Removes encoding information and last character (nullbyte) */
1366 static BSTR EnsureNoEncoding(BSTR sInput)
1368 static const WCHAR wszEncoding[] = {'e','n','c','o','d','i','n','g','='};
1373 while(*pBeg != '\n' && memcmp(pBeg, wszEncoding, sizeof(wszEncoding)))
1378 SysReAllocStringLen(&sInput, sInput, SysStringLen(sInput)-1);
1383 pEnd = pBeg + sizeof(wszEncoding)/sizeof(WCHAR) + 2;
1384 while(*pEnd != '\"') pEnd++;
1387 sNew = SysAllocStringLen(NULL,
1388 pBeg-sInput + SysStringLen(sInput)-(pEnd-sInput)-1);
1389 memcpy(sNew, sInput, (pBeg-sInput)*sizeof(WCHAR));
1390 memcpy(&sNew[pBeg-sInput], pEnd, (SysStringLen(sInput)-(pEnd-sInput)-1)*sizeof(WCHAR));
1392 SysFreeString(sInput);
1397 * We are trying to replicate the same behaviour as msxml by converting
1398 * line endings to \r\n and using indents as \t. The problem is that msxml
1399 * only formats nodes that have a line ending. Using libxml we cannot
1400 * reproduce behaviour exactly.
1403 static HRESULT WINAPI xmlnode_get_xml(
1407 xmlnode *This = impl_from_IXMLDOMNode( iface );
1408 xmlBufferPtr pXmlBuf;
1412 TRACE("(%p %d)->(%p)\n", This, This->node->type, xmlString);
1415 return E_INVALIDARG;
1419 xmldecl = xmldoc_unlink_xmldecl( This->node->doc );
1421 pXmlBuf = xmlBufferCreate();
1424 nSize = xmlNodeDump(pXmlBuf, This->node->doc, This->node, 0, 1);
1427 const xmlChar *pContent;
1430 /* Attribute Nodes return a space in front of their name */
1431 pContent = xmlBufferContent(pXmlBuf);
1432 if( ((const char*)pContent)[0] == ' ')
1433 bstrContent = bstr_from_xmlChar(pContent+1);
1435 bstrContent = bstr_from_xmlChar(pContent);
1437 switch(This->node->type)
1439 case XML_ELEMENT_NODE:
1440 *xmlString = EnsureCorrectEOL(bstrContent);
1442 case XML_DOCUMENT_NODE:
1443 *xmlString = EnsureCorrectEOL(bstrContent);
1444 *xmlString = EnsureNoEncoding(*xmlString);
1447 *xmlString = bstrContent;
1451 xmlBufferFree(pXmlBuf);
1454 xmldoc_link_xmldecl( This->node->doc, xmldecl );
1456 /* Always returns a string. */
1457 if(*xmlString == NULL) *xmlString = SysAllocStringLen( NULL, 0 );
1462 static HRESULT WINAPI xmlnode_transformNode(
1464 IXMLDOMNode* styleSheet,
1467 #ifdef SONAME_LIBXSLT
1468 xmlnode *This = impl_from_IXMLDOMNode( iface );
1469 xmlnode *pStyleSheet = NULL;
1470 xsltStylesheetPtr xsltSS = NULL;
1471 xmlDocPtr result = NULL;
1473 TRACE("(%p)->(%p %p)\n", This, styleSheet, xmlString);
1475 if (!libxslt_handle)
1477 if(!styleSheet || !xmlString)
1478 return E_INVALIDARG;
1482 pStyleSheet = get_node_obj(styleSheet);
1484 FIXME("styleSheet is not our xmlnode implementation\n");
1488 xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc);
1491 result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL);
1494 const xmlChar *pContent;
1496 if(result->type == XML_HTML_DOCUMENT_NODE)
1498 xmlOutputBufferPtr pOutput = xmlAllocOutputBuffer(NULL);
1501 htmlDocContentDumpOutput(pOutput, result->doc, NULL);
1502 pContent = xmlBufferContent(pOutput->buffer);
1503 *xmlString = bstr_from_xmlChar(pContent);
1504 xmlOutputBufferClose(pOutput);
1509 xmlBufferPtr pXmlBuf;
1512 pXmlBuf = xmlBufferCreate();
1515 nSize = xmlNodeDump(pXmlBuf, NULL, (xmlNodePtr)result, 0, 0);
1518 pContent = xmlBufferContent(pXmlBuf);
1519 *xmlString = bstr_from_xmlChar(pContent);
1521 xmlBufferFree(pXmlBuf);
1526 /* libxslt "helpfully" frees the XML document the stylesheet was
1527 generated from, too */
1529 pxsltFreeStylesheet(xsltSS);
1532 if(*xmlString == NULL)
1533 *xmlString = SysAllocStringLen(NULL, 0);
1537 FIXME("libxslt headers were not found at compile time\n");
1542 static HRESULT WINAPI xmlnode_selectNodes(
1545 IXMLDOMNodeList** resultList)
1547 xmlnode *This = impl_from_IXMLDOMNode( iface );
1549 TRACE("(%p)->(%s %p)\n", This, debugstr_w(queryString), resultList );
1551 return queryresult_create( This->node, queryString, resultList );
1554 static HRESULT WINAPI xmlnode_selectSingleNode(
1557 IXMLDOMNode** resultNode)
1559 xmlnode *This = impl_from_IXMLDOMNode( iface );
1560 IXMLDOMNodeList *list;
1563 TRACE("(%p)->(%s %p)\n", This, debugstr_w(queryString), resultNode );
1566 r = IXMLDOMNode_selectNodes(iface, queryString, &list);
1569 r = IXMLDOMNodeList_nextNode(list, resultNode);
1570 IXMLDOMNodeList_Release(list);
1575 static HRESULT WINAPI xmlnode_get_parsed(
1577 VARIANT_BOOL* isParsed)
1579 xmlnode *This = impl_from_IXMLDOMNode( iface );
1580 FIXME("(%p)->(%p) stub!\n", This, isParsed);
1581 *isParsed = VARIANT_TRUE;
1585 static HRESULT WINAPI xmlnode_get_namespaceURI(
1589 xmlnode *This = impl_from_IXMLDOMNode( iface );
1590 HRESULT hr = S_FALSE;
1593 TRACE("(%p)->(%p)\n", This, namespaceURI );
1596 return E_INVALIDARG;
1598 *namespaceURI = NULL;
1600 pNSList = xmlGetNsList(This->node->doc, This->node);
1603 *namespaceURI = bstr_from_xmlChar( pNSList[0]->href );
1612 static HRESULT WINAPI xmlnode_get_prefix(
1616 xmlnode *This = impl_from_IXMLDOMNode( iface );
1617 HRESULT hr = S_FALSE;
1620 TRACE("(%p)->(%p)\n", This, prefixString );
1623 return E_INVALIDARG;
1625 *prefixString = NULL;
1627 pNSList = xmlGetNsList(This->node->doc, This->node);
1630 *prefixString = bstr_from_xmlChar( pNSList[0]->prefix );
1639 static HRESULT WINAPI xmlnode_get_baseName(
1643 xmlnode *This = impl_from_IXMLDOMNode( iface );
1645 HRESULT r = S_FALSE;
1647 TRACE("(%p)->(%p)\n", This, nameString );
1650 return E_INVALIDARG;
1652 switch ( This->node->type )
1654 case XML_ELEMENT_NODE:
1655 case XML_ATTRIBUTE_NODE:
1657 str = bstr_from_xmlChar( This->node->name );
1661 case XML_COMMENT_NODE:
1662 case XML_DOCUMENT_NODE:
1665 ERR("Unhandled type %d\n", This->node->type );
1669 TRACE("returning %08x str = %s\n", r, debugstr_w( str ) );
1675 static HRESULT WINAPI xmlnode_transformNodeToObject(
1677 IXMLDOMNode* stylesheet,
1678 VARIANT outputObject)
1680 xmlnode *This = impl_from_IXMLDOMNode( iface );
1681 FIXME("(%p)->(%p)\n", This, stylesheet);
1685 static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
1687 xmlnode_QueryInterface,
1690 xmlnode_GetTypeInfoCount,
1691 xmlnode_GetTypeInfo,
1692 xmlnode_GetIDsOfNames,
1694 xmlnode_get_nodeName,
1695 xmlnode_get_nodeValue,
1696 xmlnode_put_nodeValue,
1697 xmlnode_get_nodeType,
1698 xmlnode_get_parentNode,
1699 xmlnode_get_childNodes,
1700 xmlnode_get_firstChild,
1701 xmlnode_get_lastChild,
1702 xmlnode_get_previousSibling,
1703 xmlnode_get_nextSibling,
1704 xmlnode_get_attributes,
1705 xmlnode_insertBefore,
1706 xmlnode_replaceChild,
1707 xmlnode_removeChild,
1708 xmlnode_appendChild,
1709 xmlnode_hasChildNodes,
1710 xmlnode_get_ownerDocument,
1712 xmlnode_get_nodeTypeString,
1715 xmlnode_get_specified,
1716 xmlnode_get_definition,
1717 xmlnode_get_nodeTypedValue,
1718 xmlnode_put_nodeTypedValue,
1719 xmlnode_get_dataType,
1720 xmlnode_put_dataType,
1722 xmlnode_transformNode,
1723 xmlnode_selectNodes,
1724 xmlnode_selectSingleNode,
1726 xmlnode_get_namespaceURI,
1728 xmlnode_get_baseName,
1729 xmlnode_transformNodeToObject,
1732 void destroy_xmlnode(xmlnode *This)
1735 xmldoc_release(This->node->doc);
1738 void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data)
1741 xmldoc_add_ref( node->doc );
1743 This->lpVtbl = &xmlnode_vtbl;
1745 This->iface = node_iface;
1748 init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data);
1750 This->dispex.outer = NULL;
1755 const IXMLDOMNodeVtbl *lpVtbl;
1759 static inline unknode *impl_from_unkIXMLDOMNode(IXMLDOMNode *iface)
1761 return (unknode *)((char*)iface - FIELD_OFFSET(unknode, lpVtbl));
1764 static HRESULT WINAPI unknode_QueryInterface(
1769 unknode *This = impl_from_unkIXMLDOMNode( iface );
1771 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
1773 if (IsEqualGUID(riid, &IID_IUnknown)) {
1775 }else if (IsEqualGUID( riid, &IID_IDispatch) ||
1776 IsEqualGUID( riid, &IID_IXMLDOMNode)) {
1777 *ppvObject = &This->lpVtbl;
1778 }else if(node_query_interface(&This->node, riid, ppvObject)) {
1779 return *ppvObject ? S_OK : E_NOINTERFACE;
1781 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1783 return E_NOINTERFACE;
1786 IUnknown_AddRef((IUnknown*)*ppvObject);
1790 static ULONG WINAPI unknode_AddRef(
1791 IXMLDOMNode *iface )
1793 unknode *This = impl_from_unkIXMLDOMNode( iface );
1795 return InterlockedIncrement(&This->ref);
1798 static ULONG WINAPI unknode_Release(
1799 IXMLDOMNode *iface )
1801 unknode *This = impl_from_unkIXMLDOMNode( iface );
1804 ref = InterlockedDecrement( &This->ref );
1806 destroy_xmlnode(&This->node);
1813 static HRESULT WINAPI unknode_GetTypeInfoCount(
1817 unknode *This = impl_from_unkIXMLDOMNode( iface );
1819 TRACE("(%p)->(%p)\n", This, pctinfo);
1826 static HRESULT WINAPI unknode_GetTypeInfo(
1830 ITypeInfo** ppTInfo )
1832 unknode *This = impl_from_unkIXMLDOMNode( iface );
1835 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1837 hr = get_typeinfo(IXMLDOMNode_tid, ppTInfo);
1842 static HRESULT WINAPI unknode_GetIDsOfNames(
1845 LPOLESTR* rgszNames,
1850 unknode *This = impl_from_unkIXMLDOMNode( iface );
1852 ITypeInfo *typeinfo;
1855 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1858 if(!rgszNames || cNames == 0 || !rgDispId)
1859 return E_INVALIDARG;
1861 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
1864 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1865 ITypeInfo_Release(typeinfo);
1871 static HRESULT WINAPI unknode_Invoke(
1873 DISPID dispIdMember,
1877 DISPPARAMS* pDispParams,
1878 VARIANT* pVarResult,
1879 EXCEPINFO* pExcepInfo,
1882 unknode *This = impl_from_unkIXMLDOMNode( iface );
1883 ITypeInfo *typeinfo;
1886 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1887 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1889 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
1892 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
1893 pVarResult, pExcepInfo, puArgErr);
1894 ITypeInfo_Release(typeinfo);
1900 static HRESULT WINAPI unknode_get_nodeName(
1904 unknode *This = impl_from_unkIXMLDOMNode( iface );
1905 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), p );
1908 static HRESULT WINAPI unknode_get_nodeValue(
1912 unknode *This = impl_from_unkIXMLDOMNode( iface );
1913 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
1916 static HRESULT WINAPI unknode_put_nodeValue(
1920 unknode *This = impl_from_unkIXMLDOMNode( iface );
1921 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
1924 static HRESULT WINAPI unknode_get_nodeType(
1926 DOMNodeType* domNodeType )
1928 unknode *This = impl_from_unkIXMLDOMNode( iface );
1929 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), domNodeType );
1932 static HRESULT WINAPI unknode_get_parentNode(
1934 IXMLDOMNode** parent )
1936 unknode *This = impl_from_unkIXMLDOMNode( iface );
1937 TRACE("(%p)->(%p)\n", This, parent);
1938 if (!parent) return E_INVALIDARG;
1943 static HRESULT WINAPI unknode_get_childNodes(
1945 IXMLDOMNodeList** outList)
1947 unknode *This = impl_from_unkIXMLDOMNode( iface );
1948 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), outList );
1951 static HRESULT WINAPI unknode_get_firstChild(
1953 IXMLDOMNode** domNode)
1955 unknode *This = impl_from_unkIXMLDOMNode( iface );
1956 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), domNode );
1959 static HRESULT WINAPI unknode_get_lastChild(
1961 IXMLDOMNode** domNode)
1963 unknode *This = impl_from_unkIXMLDOMNode( iface );
1964 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), domNode );
1967 static HRESULT WINAPI unknode_get_previousSibling(
1969 IXMLDOMNode** domNode)
1971 unknode *This = impl_from_unkIXMLDOMNode( iface );
1972 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), domNode );
1975 static HRESULT WINAPI unknode_get_nextSibling(
1977 IXMLDOMNode** domNode)
1979 unknode *This = impl_from_unkIXMLDOMNode( iface );
1980 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), domNode );
1983 static HRESULT WINAPI unknode_get_attributes(
1985 IXMLDOMNamedNodeMap** attributeMap)
1987 unknode *This = impl_from_unkIXMLDOMNode( iface );
1988 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
1991 static HRESULT WINAPI unknode_insertBefore(
1993 IXMLDOMNode* newNode, VARIANT var1,
1994 IXMLDOMNode** outOldNode)
1996 unknode *This = impl_from_unkIXMLDOMNode( iface );
1997 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newNode, var1, outOldNode );
2000 static HRESULT WINAPI unknode_replaceChild(
2002 IXMLDOMNode* newNode,
2003 IXMLDOMNode* oldNode,
2004 IXMLDOMNode** outOldNode)
2006 unknode *This = impl_from_unkIXMLDOMNode( iface );
2007 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newNode, oldNode, outOldNode );
2010 static HRESULT WINAPI unknode_removeChild(
2012 IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
2014 unknode *This = impl_from_unkIXMLDOMNode( iface );
2015 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), domNode, oldNode );
2018 static HRESULT WINAPI unknode_appendChild(
2020 IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
2022 unknode *This = impl_from_unkIXMLDOMNode( iface );
2023 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newNode, outNewNode );
2026 static HRESULT WINAPI unknode_hasChildNodes(
2028 VARIANT_BOOL* pbool)
2030 unknode *This = impl_from_unkIXMLDOMNode( iface );
2031 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), pbool );
2034 static HRESULT WINAPI unknode_get_ownerDocument(
2036 IXMLDOMDocument** domDocument)
2038 unknode *This = impl_from_unkIXMLDOMNode( iface );
2039 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), domDocument );
2042 static HRESULT WINAPI unknode_cloneNode(
2044 VARIANT_BOOL pbool, IXMLDOMNode** outNode)
2046 unknode *This = impl_from_unkIXMLDOMNode( iface );
2047 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), pbool, outNode );
2050 static HRESULT WINAPI unknode_get_nodeTypeString(
2054 unknode *This = impl_from_unkIXMLDOMNode( iface );
2055 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), p );
2058 static HRESULT WINAPI unknode_get_text(
2062 unknode *This = impl_from_unkIXMLDOMNode( iface );
2063 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), p );
2066 static HRESULT WINAPI unknode_put_text(
2070 unknode *This = impl_from_unkIXMLDOMNode( iface );
2071 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), p );
2074 static HRESULT WINAPI unknode_get_specified(
2076 VARIANT_BOOL* pbool)
2078 unknode *This = impl_from_unkIXMLDOMNode( iface );
2079 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), pbool );
2082 static HRESULT WINAPI unknode_get_definition(
2084 IXMLDOMNode** domNode)
2086 unknode *This = impl_from_unkIXMLDOMNode( iface );
2087 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), domNode );
2090 static HRESULT WINAPI unknode_get_nodeTypedValue(
2094 unknode *This = impl_from_unkIXMLDOMNode( iface );
2095 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
2098 static HRESULT WINAPI unknode_put_nodeTypedValue(
2102 unknode *This = impl_from_unkIXMLDOMNode( iface );
2103 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
2106 static HRESULT WINAPI unknode_get_dataType(
2110 unknode *This = impl_from_unkIXMLDOMNode( iface );
2111 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), var1 );
2114 static HRESULT WINAPI unknode_put_dataType(
2118 unknode *This = impl_from_unkIXMLDOMNode( iface );
2119 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
2122 static HRESULT WINAPI unknode_get_xml(
2126 unknode *This = impl_from_unkIXMLDOMNode( iface );
2127 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), p );
2130 static HRESULT WINAPI unknode_transformNode(
2132 IXMLDOMNode* domNode, BSTR* p)
2134 unknode *This = impl_from_unkIXMLDOMNode( iface );
2135 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), domNode, p );
2138 static HRESULT WINAPI unknode_selectNodes(
2140 BSTR p, IXMLDOMNodeList** outList)
2142 unknode *This = impl_from_unkIXMLDOMNode( iface );
2143 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), p, outList );
2146 static HRESULT WINAPI unknode_selectSingleNode(
2148 BSTR p, IXMLDOMNode** outNode)
2150 unknode *This = impl_from_unkIXMLDOMNode( iface );
2151 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), p, outNode );
2154 static HRESULT WINAPI unknode_get_parsed(
2156 VARIANT_BOOL* pbool)
2158 unknode *This = impl_from_unkIXMLDOMNode( iface );
2159 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), pbool );
2162 static HRESULT WINAPI unknode_get_namespaceURI(
2166 unknode *This = impl_from_unkIXMLDOMNode( iface );
2167 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), p );
2170 static HRESULT WINAPI unknode_get_prefix(
2174 unknode *This = impl_from_unkIXMLDOMNode( iface );
2175 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), p );
2178 static HRESULT WINAPI unknode_get_baseName(
2182 unknode *This = impl_from_unkIXMLDOMNode( iface );
2183 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), p );
2186 static HRESULT WINAPI unknode_transformNodeToObject(
2188 IXMLDOMNode* domNode, VARIANT var1)
2190 unknode *This = impl_from_unkIXMLDOMNode( iface );
2191 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), domNode, var1 );
2194 static const struct IXMLDOMNodeVtbl unknode_vtbl =
2196 unknode_QueryInterface,
2199 unknode_GetTypeInfoCount,
2200 unknode_GetTypeInfo,
2201 unknode_GetIDsOfNames,
2203 unknode_get_nodeName,
2204 unknode_get_nodeValue,
2205 unknode_put_nodeValue,
2206 unknode_get_nodeType,
2207 unknode_get_parentNode,
2208 unknode_get_childNodes,
2209 unknode_get_firstChild,
2210 unknode_get_lastChild,
2211 unknode_get_previousSibling,
2212 unknode_get_nextSibling,
2213 unknode_get_attributes,
2214 unknode_insertBefore,
2215 unknode_replaceChild,
2216 unknode_removeChild,
2217 unknode_appendChild,
2218 unknode_hasChildNodes,
2219 unknode_get_ownerDocument,
2221 unknode_get_nodeTypeString,
2224 unknode_get_specified,
2225 unknode_get_definition,
2226 unknode_get_nodeTypedValue,
2227 unknode_put_nodeTypedValue,
2228 unknode_get_dataType,
2229 unknode_put_dataType,
2231 unknode_transformNode,
2232 unknode_selectNodes,
2233 unknode_selectSingleNode,
2235 unknode_get_namespaceURI,
2237 unknode_get_baseName,
2238 unknode_transformNodeToObject
2241 IXMLDOMNode *create_node( xmlNodePtr node )
2250 TRACE("type %d\n", node->type);
2253 case XML_ELEMENT_NODE:
2254 pUnk = create_element( node );
2256 case XML_ATTRIBUTE_NODE:
2257 pUnk = create_attribute( node );
2260 pUnk = create_text( node );
2262 case XML_CDATA_SECTION_NODE:
2263 pUnk = create_cdata( node );
2265 case XML_ENTITY_REF_NODE:
2266 pUnk = create_doc_entity_ref( node );
2269 pUnk = create_pi( node );
2271 case XML_COMMENT_NODE:
2272 pUnk = create_comment( node );
2274 case XML_DOCUMENT_NODE:
2275 pUnk = create_domdoc( node );
2277 case XML_DOCUMENT_FRAG_NODE:
2278 pUnk = create_doc_fragment( node );
2283 FIXME("only creating basic node for type %d\n", node->type);
2285 new_node = heap_alloc(sizeof(unknode));
2289 new_node->lpVtbl = &unknode_vtbl;
2291 init_xmlnode(&new_node->node, node, (IXMLDOMNode*)&new_node->lpVtbl, NULL);
2292 pUnk = (IUnknown*)&new_node->lpVtbl;
2296 hr = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMNode, (LPVOID*)&ret);
2297 IUnknown_Release(pUnk);
2298 if(FAILED(hr)) return NULL;