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, *new_child;
648 xmlDocPtr leaving_doc;
649 xmlNode *my_ancestor;
651 TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, outOldChild);
653 /* Do not believe any documentation telling that newChild == NULL
654 means removal. It does certainly *not* apply to msxml3! */
655 if(!newChild || !oldChild)
661 old_child = get_node_obj(oldChild);
663 FIXME("oldChild is not our node implementation\n");
667 if(old_child->node->parent != This->node)
669 WARN("childNode %p is not a child of %p\n", oldChild, iface);
673 new_child = get_node_obj(newChild);
675 FIXME("newChild is not our node implementation\n");
679 my_ancestor = This->node;
682 if(my_ancestor == new_child->node)
684 WARN("tried to create loop\n");
687 my_ancestor = my_ancestor->parent;
690 if(!new_child->node->parent)
691 if(xmldoc_remove_orphan(new_child->node->doc, new_child->node) != S_OK)
692 WARN("%p is not an orphan of %p\n", new_child->node, new_child->node->doc);
694 leaving_doc = new_child->node->doc;
695 xmldoc_add_ref(old_child->node->doc);
696 xmlReplaceNode(old_child->node, new_child->node);
697 xmldoc_release(leaving_doc);
699 xmldoc_add_orphan(old_child->node->doc, old_child->node);
703 IXMLDOMNode_AddRef(oldChild);
704 *outOldChild = oldChild;
710 static HRESULT WINAPI xmlnode_removeChild(
712 IXMLDOMNode* childNode,
713 IXMLDOMNode** oldChild)
715 xmlnode *This = impl_from_IXMLDOMNode( iface );
718 TRACE("(%p)->(%p %p)\n", This, childNode, oldChild);
720 if(!childNode) return E_INVALIDARG;
725 child_node = get_node_obj(childNode);
727 FIXME("childNode is not our node implementation\n");
731 if(child_node->node->parent != This->node)
733 WARN("childNode %p is not a child of %p\n", childNode, iface);
737 xmlUnlinkNode(child_node->node);
741 IXMLDOMNode_AddRef(childNode);
742 *oldChild = childNode;
748 static HRESULT WINAPI xmlnode_appendChild(
750 IXMLDOMNode* newChild,
751 IXMLDOMNode** outNewChild)
753 xmlnode *This = impl_from_IXMLDOMNode( iface );
758 TRACE("(%p)->(%p %p)\n", This, newChild, outNewChild);
760 hr = IXMLDOMNode_get_nodeType(newChild, &type);
761 if(FAILED(hr) || type == NODE_ATTRIBUTE) {
762 if(outNewChild) *outNewChild = NULL;
767 return IXMLDOMNode_insertBefore(iface, newChild, var, outNewChild);
770 static HRESULT WINAPI xmlnode_hasChildNodes(
772 VARIANT_BOOL* hasChild)
774 xmlnode *This = impl_from_IXMLDOMNode( iface );
776 TRACE("(%p)->(%p)\n", This, hasChild);
780 if (!This->node->children)
782 *hasChild = VARIANT_FALSE;
786 *hasChild = VARIANT_TRUE;
790 static HRESULT WINAPI xmlnode_get_ownerDocument(
792 IXMLDOMDocument** DOMDocument)
794 xmlnode *This = impl_from_IXMLDOMNode( iface );
796 TRACE("(%p)->(%p)\n", This, DOMDocument);
798 return DOMDocument_create_from_xmldoc(This->node->doc, (IXMLDOMDocument3**)DOMDocument);
801 static HRESULT WINAPI xmlnode_cloneNode(
804 IXMLDOMNode** cloneRoot)
806 xmlnode *This = impl_from_IXMLDOMNode( iface );
807 xmlNodePtr pClone = NULL;
808 IXMLDOMNode *pNode = NULL;
810 TRACE("(%p)->(%d %p)\n", This, deep, cloneRoot);
815 pClone = xmlCopyNode(This->node, deep ? 1 : 2);
818 pClone->doc = This->node->doc;
819 xmldoc_add_orphan(pClone->doc, pClone);
821 pNode = create_node(pClone);
824 ERR("Copy failed\n");
832 ERR("Copy failed\n");
839 static HRESULT WINAPI xmlnode_get_nodeTypeString(
843 xmlnode *This = impl_from_IXMLDOMNode( iface );
846 TRACE("(%p)->(%p)\n", This, xmlnodeType );
854 switch( This->node->type )
856 case XML_ATTRIBUTE_NODE:
857 str = (const xmlChar*) "attribute";
859 case XML_CDATA_SECTION_NODE:
860 str = (const xmlChar*) "cdatasection";
862 case XML_COMMENT_NODE:
863 str = (const xmlChar*) "comment";
865 case XML_DOCUMENT_NODE:
866 str = (const xmlChar*) "document";
868 case XML_DOCUMENT_FRAG_NODE:
869 str = (const xmlChar*) "documentfragment";
871 case XML_ELEMENT_NODE:
872 str = (const xmlChar*) "element";
874 case XML_ENTITY_NODE:
875 str = (const xmlChar*) "entity";
877 case XML_ENTITY_REF_NODE:
878 str = (const xmlChar*) "entityreference";
880 case XML_NOTATION_NODE:
881 str = (const xmlChar*) "notation";
884 str = (const xmlChar*) "processinginstruction";
887 str = (const xmlChar*) "text";
890 FIXME("Unknown node type (%d)\n", This->node->type);
891 str = This->node->name;
895 *xmlnodeType = bstr_from_xmlChar( str );
902 static HRESULT WINAPI xmlnode_get_text(
906 xmlnode *This = impl_from_IXMLDOMNode( iface );
910 TRACE("(%p, type %d)->(%p)\n", This, This->node->type, text);
915 pContent = xmlNodeGetContent((xmlNodePtr)This->node);
918 str = bstr_from_xmlChar(pContent);
922 /* Always return a string. */
923 if (!str) str = SysAllocStringLen( NULL, 0 );
925 TRACE("%p %s\n", This, debugstr_w(str) );
931 static HRESULT WINAPI xmlnode_put_text(
935 xmlnode *This = impl_from_IXMLDOMNode( iface );
938 TRACE("(%p)->(%s)\n", This, debugstr_w(text));
940 switch(This->node->type)
942 case XML_DOCUMENT_NODE:
948 str = xmlChar_from_wchar(text);
950 /* Escape the string. */
951 str2 = xmlEncodeEntitiesReentrant(This->node->doc, str);
954 xmlNodeSetContent(This->node, str2);
960 static HRESULT WINAPI xmlnode_get_specified(
962 VARIANT_BOOL* isSpecified)
964 xmlnode *This = impl_from_IXMLDOMNode( iface );
965 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
966 *isSpecified = VARIANT_TRUE;
970 static HRESULT WINAPI xmlnode_get_definition(
972 IXMLDOMNode** definitionNode)
974 xmlnode *This = impl_from_IXMLDOMNode( iface );
975 FIXME("(%p)->(%p)\n", This, definitionNode);
979 static inline BYTE hex_to_byte(xmlChar c)
981 if(c <= '9') return c-'0';
982 if(c <= 'F') return c-'A'+10;
986 static inline BYTE base64_to_byte(xmlChar c)
988 if(c == '+') return 62;
989 if(c == '/') return 63;
990 if(c <= '9') return c-'0'+52;
991 if(c <= 'Z') return c-'A';
995 static inline HRESULT VARIANT_from_xmlChar(xmlChar *str, VARIANT *v, BSTR type)
997 if(!type || !lstrcmpiW(type, szString) ||
998 !lstrcmpiW(type, szNumber) || !lstrcmpiW(type, szUUID))
1001 V_BSTR(v) = bstr_from_xmlChar(str);
1004 return E_OUTOFMEMORY;
1006 else if(!lstrcmpiW(type, szDateTime) || !lstrcmpiW(type, szDateTimeTZ) ||
1007 !lstrcmpiW(type, szDate) || !lstrcmpiW(type, szTime) ||
1008 !lstrcmpiW(type, szTimeTZ))
1018 st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
1020 V_VT(&src) = VT_BSTR;
1021 V_BSTR(&src) = bstr_from_xmlChar(str);
1024 return E_OUTOFMEMORY;
1027 e = p + SysStringLen(V_BSTR(&src));
1029 if(p+4<e && *(p+4)=='-') /* parse date (yyyy-mm-dd) */
1031 st.wYear = atoiW(p);
1032 st.wMonth = atoiW(p+5);
1033 st.wDay = atoiW(p+8);
1039 if(p+2<e && *(p+2)==':') /* parse time (hh:mm:ss.?) */
1041 st.wHour = atoiW(p);
1042 st.wMinute = atoiW(p+3);
1043 st.wSecond = atoiW(p+6);
1049 while(isdigitW(*p)) p++;
1053 SystemTimeToVariantTime(&st, &date);
1057 if(*p == '+') /* parse timezone offset (+hh:mm) */
1058 V_DATE(v) += (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
1059 else if(*p == '-') /* parse timezone offset (-hh:mm) */
1060 V_DATE(v) -= (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
1064 else if(!lstrcmpiW(type, szBinHex))
1069 len = xmlStrlen(str)/2;
1071 sab.cElements = len;
1073 V_VT(v) = (VT_ARRAY|VT_UI1);
1074 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
1077 return E_OUTOFMEMORY;
1079 for(i=0; i<len; i++)
1080 ((BYTE*)V_ARRAY(v)->pvData)[i] = (hex_to_byte(str[2*i])<<4)
1081 + hex_to_byte(str[2*i+1]);
1083 else if(!lstrcmpiW(type, szBinBase64))
1088 len = xmlStrlen(str);
1089 if(str[len-2] == '=') i = 2;
1090 else if(str[len-1] == '=') i = 1;
1094 sab.cElements = len/4*3-i;
1096 V_VT(v) = (VT_ARRAY|VT_UI1);
1097 V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);
1100 return E_OUTOFMEMORY;
1102 for(i=0; i<len/4; i++)
1104 ((BYTE*)V_ARRAY(v)->pvData)[3*i] = (base64_to_byte(str[4*i])<<2)
1105 + (base64_to_byte(str[4*i+1])>>4);
1106 if(3*i+1 < sab.cElements)
1107 ((BYTE*)V_ARRAY(v)->pvData)[3*i+1] = (base64_to_byte(str[4*i+1])<<4)
1108 + (base64_to_byte(str[4*i+2])>>2);
1109 if(3*i+2 < sab.cElements)
1110 ((BYTE*)V_ARRAY(v)->pvData)[3*i+2] = (base64_to_byte(str[4*i+2])<<6)
1111 + base64_to_byte(str[4*i+3]);
1119 if(!lstrcmpiW(type, szInt) || !lstrcmpiW(type, szI4))
1121 else if(!lstrcmpiW(type, szFixed))
1123 else if(!lstrcmpiW(type, szBoolean))
1125 else if(!lstrcmpiW(type, szI1))
1127 else if(!lstrcmpiW(type, szI2))
1129 else if(!lstrcmpiW(type, szIU1))
1131 else if(!lstrcmpiW(type, szIU2))
1133 else if(!lstrcmpiW(type, szIU4))
1135 else if(!lstrcmpiW(type, szR4))
1137 else if(!lstrcmpiW(type, szR8) || !lstrcmpiW(type, szFloat))
1141 FIXME("Type handling not yet implemented\n");
1145 V_VT(&src) = VT_BSTR;
1146 V_BSTR(&src) = bstr_from_xmlChar(str);
1149 return E_OUTOFMEMORY;
1151 hres = VariantChangeTypeEx(v, &src, MAKELCID(MAKELANGID(
1152 LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v));
1160 static HRESULT WINAPI xmlnode_get_nodeTypedValue(
1162 VARIANT* typedValue)
1164 xmlnode *This = impl_from_IXMLDOMNode( iface );
1167 HRESULT hres = S_FALSE;
1169 TRACE("(%p)->(%p)\n", This, typedValue);
1172 return E_INVALIDARG;
1174 V_VT(typedValue) = VT_NULL;
1176 if(This->node->type == XML_ELEMENT_NODE ||
1177 This->node->type == XML_TEXT_NODE ||
1178 This->node->type == XML_ENTITY_REF_NODE)
1179 hres = IXMLDOMNode_get_dataType(iface, &type);
1181 if(hres != S_OK && This->node->type != XML_ELEMENT_NODE)
1182 return IXMLDOMNode_get_nodeValue(iface, typedValue);
1184 content = xmlNodeGetContent(This->node);
1185 hres = VARIANT_from_xmlChar(content, typedValue,
1186 hres==S_OK ? V_BSTR(&type) : NULL);
1188 VariantClear(&type);
1193 static HRESULT WINAPI xmlnode_put_nodeTypedValue(
1197 xmlnode *This = impl_from_IXMLDOMNode( iface );
1198 FIXME("%p\n", This);
1202 static HRESULT WINAPI xmlnode_get_dataType(
1204 VARIANT* dataTypeName)
1206 xmlnode *This = impl_from_IXMLDOMNode( iface );
1209 TRACE("(%p)->(%p)\n", This, dataTypeName);
1212 return E_INVALIDARG;
1214 /* Attribute, CDATA Section, Comment, Document, Document Fragment,
1215 Entity, Notation, PI, and Text Node are non-typed. */
1216 V_BSTR(dataTypeName) = NULL;
1217 V_VT(dataTypeName) = VT_NULL;
1219 switch ( This->node->type )
1221 case XML_ELEMENT_NODE:
1222 pVal = xmlGetNsProp(This->node, (const xmlChar*)"dt",
1223 (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
1226 V_VT(dataTypeName) = VT_BSTR;
1227 V_BSTR(dataTypeName) = bstr_from_xmlChar( pVal );
1231 case XML_ENTITY_REF_NODE:
1232 FIXME("XML_ENTITY_REF_NODE should return a valid value.\n");
1235 TRACE("Type %d returning NULL\n", This->node->type);
1238 /* non-typed nodes return S_FALSE */
1239 if(V_VT(dataTypeName) == VT_NULL)
1247 static HRESULT WINAPI xmlnode_put_dataType(
1251 xmlnode *This = impl_from_IXMLDOMNode( iface );
1252 HRESULT hr = E_FAIL;
1254 TRACE("(%p)->(%s)\n", This, debugstr_w(dataTypeName));
1256 if(dataTypeName == NULL)
1257 return E_INVALIDARG;
1259 /* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
1260 This applies to changing types (string->bool) or setting a new one
1262 FIXME("Need to Validate the data before allowing a type to be set.\n");
1264 /* Check all supported types. */
1265 if(lstrcmpiW(dataTypeName,szString) == 0 ||
1266 lstrcmpiW(dataTypeName,szNumber) == 0 ||
1267 lstrcmpiW(dataTypeName,szUUID) == 0 ||
1268 lstrcmpiW(dataTypeName,szInt) == 0 ||
1269 lstrcmpiW(dataTypeName,szI4) == 0 ||
1270 lstrcmpiW(dataTypeName,szFixed) == 0 ||
1271 lstrcmpiW(dataTypeName,szBoolean) == 0 ||
1272 lstrcmpiW(dataTypeName,szDateTime) == 0 ||
1273 lstrcmpiW(dataTypeName,szDateTimeTZ) == 0 ||
1274 lstrcmpiW(dataTypeName,szDate) == 0 ||
1275 lstrcmpiW(dataTypeName,szTime) == 0 ||
1276 lstrcmpiW(dataTypeName,szTimeTZ) == 0 ||
1277 lstrcmpiW(dataTypeName,szI1) == 0 ||
1278 lstrcmpiW(dataTypeName,szI2) == 0 ||
1279 lstrcmpiW(dataTypeName,szIU1) == 0 ||
1280 lstrcmpiW(dataTypeName,szIU2) == 0 ||
1281 lstrcmpiW(dataTypeName,szIU4) == 0 ||
1282 lstrcmpiW(dataTypeName,szR4) == 0 ||
1283 lstrcmpiW(dataTypeName,szR8) == 0 ||
1284 lstrcmpiW(dataTypeName,szFloat) == 0 ||
1285 lstrcmpiW(dataTypeName,szBinHex) == 0 ||
1286 lstrcmpiW(dataTypeName,szBinBase64) == 0)
1288 xmlNsPtr pNS = NULL;
1289 xmlAttrPtr pAttr = NULL;
1290 xmlChar* str = xmlChar_from_wchar(dataTypeName);
1292 pAttr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
1293 (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
1296 pAttr = xmlSetNsProp(This->node, pAttr->ns, (const xmlChar*)"dt", str);
1302 pNS = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
1305 pAttr = xmlNewNsProp(This->node, pNS, (const xmlChar*)"dt", str);
1308 xmlAddChild(This->node, (xmlNodePtr)pAttr);
1313 ERR("Failed to create Attribute\n");
1316 ERR("Failed to Create Namepsace\n");
1324 static BSTR EnsureCorrectEOL(BSTR sInput)
1331 nLen = lstrlenW(sInput);
1332 /* Count line endings */
1333 for(i=0; i < nLen; i++)
1335 if(sInput[i] == '\n')
1339 TRACE("len=%d, num=%d\n", nLen, nNum);
1341 /* Add linefeed as needed */
1345 sNew = SysAllocStringLen(NULL, nLen + nNum+1);
1346 for(i=0; i < nLen; i++)
1348 if(sInput[i] == '\n')
1350 sNew[i+nPlace] = '\r';
1353 sNew[i+nPlace] = sInput[i];
1356 SysFreeString(sInput);
1363 TRACE("len %d\n", lstrlenW(sNew));
1368 /* Removes encoding information and last character (nullbyte) */
1369 static BSTR EnsureNoEncoding(BSTR sInput)
1371 static const WCHAR wszEncoding[] = {'e','n','c','o','d','i','n','g','='};
1376 while(*pBeg != '\n' && memcmp(pBeg, wszEncoding, sizeof(wszEncoding)))
1381 SysReAllocStringLen(&sInput, sInput, SysStringLen(sInput)-1);
1386 pEnd = pBeg + sizeof(wszEncoding)/sizeof(WCHAR) + 2;
1387 while(*pEnd != '\"') pEnd++;
1390 sNew = SysAllocStringLen(NULL,
1391 pBeg-sInput + SysStringLen(sInput)-(pEnd-sInput)-1);
1392 memcpy(sNew, sInput, (pBeg-sInput)*sizeof(WCHAR));
1393 memcpy(&sNew[pBeg-sInput], pEnd, (SysStringLen(sInput)-(pEnd-sInput)-1)*sizeof(WCHAR));
1395 SysFreeString(sInput);
1400 * We are trying to replicate the same behaviour as msxml by converting
1401 * line endings to \r\n and using indents as \t. The problem is that msxml
1402 * only formats nodes that have a line ending. Using libxml we cannot
1403 * reproduce behaviour exactly.
1406 static HRESULT WINAPI xmlnode_get_xml(
1410 xmlnode *This = impl_from_IXMLDOMNode( iface );
1411 xmlBufferPtr pXmlBuf;
1415 TRACE("(%p %d)->(%p)\n", This, This->node->type, xmlString);
1418 return E_INVALIDARG;
1422 xmldecl = xmldoc_unlink_xmldecl( This->node->doc );
1424 pXmlBuf = xmlBufferCreate();
1427 nSize = xmlNodeDump(pXmlBuf, This->node->doc, This->node, 0, 1);
1430 const xmlChar *pContent;
1433 /* Attribute Nodes return a space in front of their name */
1434 pContent = xmlBufferContent(pXmlBuf);
1435 if( ((const char*)pContent)[0] == ' ')
1436 bstrContent = bstr_from_xmlChar(pContent+1);
1438 bstrContent = bstr_from_xmlChar(pContent);
1440 switch(This->node->type)
1442 case XML_ELEMENT_NODE:
1443 *xmlString = EnsureCorrectEOL(bstrContent);
1445 case XML_DOCUMENT_NODE:
1446 *xmlString = EnsureCorrectEOL(bstrContent);
1447 *xmlString = EnsureNoEncoding(*xmlString);
1450 *xmlString = bstrContent;
1454 xmlBufferFree(pXmlBuf);
1457 xmldoc_link_xmldecl( This->node->doc, xmldecl );
1459 /* Always returns a string. */
1460 if(*xmlString == NULL) *xmlString = SysAllocStringLen( NULL, 0 );
1465 static HRESULT WINAPI xmlnode_transformNode(
1467 IXMLDOMNode* styleSheet,
1470 #ifdef SONAME_LIBXSLT
1471 xmlnode *This = impl_from_IXMLDOMNode( iface );
1472 xmlnode *pStyleSheet = NULL;
1473 xsltStylesheetPtr xsltSS = NULL;
1474 xmlDocPtr result = NULL;
1476 TRACE("(%p)->(%p %p)\n", This, styleSheet, xmlString);
1478 if (!libxslt_handle)
1480 if(!styleSheet || !xmlString)
1481 return E_INVALIDARG;
1485 pStyleSheet = get_node_obj(styleSheet);
1487 FIXME("styleSheet is not our xmlnode implementation\n");
1491 xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc);
1494 result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL);
1497 const xmlChar *pContent;
1499 if(result->type == XML_HTML_DOCUMENT_NODE)
1501 xmlOutputBufferPtr pOutput = xmlAllocOutputBuffer(NULL);
1504 htmlDocContentDumpOutput(pOutput, result->doc, NULL);
1505 pContent = xmlBufferContent(pOutput->buffer);
1506 *xmlString = bstr_from_xmlChar(pContent);
1507 xmlOutputBufferClose(pOutput);
1512 xmlBufferPtr pXmlBuf;
1515 pXmlBuf = xmlBufferCreate();
1518 nSize = xmlNodeDump(pXmlBuf, NULL, (xmlNodePtr)result, 0, 0);
1521 pContent = xmlBufferContent(pXmlBuf);
1522 *xmlString = bstr_from_xmlChar(pContent);
1524 xmlBufferFree(pXmlBuf);
1529 /* libxslt "helpfully" frees the XML document the stylesheet was
1530 generated from, too */
1532 pxsltFreeStylesheet(xsltSS);
1535 if(*xmlString == NULL)
1536 *xmlString = SysAllocStringLen(NULL, 0);
1540 FIXME("libxslt headers were not found at compile time\n");
1545 static HRESULT WINAPI xmlnode_selectNodes(
1548 IXMLDOMNodeList** resultList)
1550 xmlnode *This = impl_from_IXMLDOMNode( iface );
1552 TRACE("(%p)->(%s %p)\n", This, debugstr_w(queryString), resultList );
1554 return queryresult_create( This->node, queryString, resultList );
1557 static HRESULT WINAPI xmlnode_selectSingleNode(
1560 IXMLDOMNode** resultNode)
1562 xmlnode *This = impl_from_IXMLDOMNode( iface );
1563 IXMLDOMNodeList *list;
1566 TRACE("(%p)->(%s %p)\n", This, debugstr_w(queryString), resultNode );
1569 r = IXMLDOMNode_selectNodes(iface, queryString, &list);
1572 r = IXMLDOMNodeList_nextNode(list, resultNode);
1573 IXMLDOMNodeList_Release(list);
1578 static HRESULT WINAPI xmlnode_get_parsed(
1580 VARIANT_BOOL* isParsed)
1582 xmlnode *This = impl_from_IXMLDOMNode( iface );
1583 FIXME("(%p)->(%p) stub!\n", This, isParsed);
1584 *isParsed = VARIANT_TRUE;
1588 static HRESULT WINAPI xmlnode_get_namespaceURI(
1592 xmlnode *This = impl_from_IXMLDOMNode( iface );
1593 HRESULT hr = S_FALSE;
1596 TRACE("(%p)->(%p)\n", This, namespaceURI );
1599 return E_INVALIDARG;
1601 *namespaceURI = NULL;
1603 pNSList = xmlGetNsList(This->node->doc, This->node);
1606 *namespaceURI = bstr_from_xmlChar( pNSList[0]->href );
1615 static HRESULT WINAPI xmlnode_get_prefix(
1619 xmlnode *This = impl_from_IXMLDOMNode( iface );
1620 HRESULT hr = S_FALSE;
1623 TRACE("(%p)->(%p)\n", This, prefixString );
1626 return E_INVALIDARG;
1628 *prefixString = NULL;
1630 pNSList = xmlGetNsList(This->node->doc, This->node);
1633 *prefixString = bstr_from_xmlChar( pNSList[0]->prefix );
1642 static HRESULT WINAPI xmlnode_get_baseName(
1646 xmlnode *This = impl_from_IXMLDOMNode( iface );
1648 HRESULT r = S_FALSE;
1650 TRACE("(%p)->(%p)\n", This, nameString );
1653 return E_INVALIDARG;
1655 switch ( This->node->type )
1657 case XML_ELEMENT_NODE:
1658 case XML_ATTRIBUTE_NODE:
1660 str = bstr_from_xmlChar( This->node->name );
1664 case XML_COMMENT_NODE:
1665 case XML_DOCUMENT_NODE:
1668 ERR("Unhandled type %d\n", This->node->type );
1672 TRACE("returning %08x str = %s\n", r, debugstr_w( str ) );
1678 static HRESULT WINAPI xmlnode_transformNodeToObject(
1680 IXMLDOMNode* stylesheet,
1681 VARIANT outputObject)
1683 xmlnode *This = impl_from_IXMLDOMNode( iface );
1684 FIXME("(%p)->(%p)\n", This, stylesheet);
1688 static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
1690 xmlnode_QueryInterface,
1693 xmlnode_GetTypeInfoCount,
1694 xmlnode_GetTypeInfo,
1695 xmlnode_GetIDsOfNames,
1697 xmlnode_get_nodeName,
1698 xmlnode_get_nodeValue,
1699 xmlnode_put_nodeValue,
1700 xmlnode_get_nodeType,
1701 xmlnode_get_parentNode,
1702 xmlnode_get_childNodes,
1703 xmlnode_get_firstChild,
1704 xmlnode_get_lastChild,
1705 xmlnode_get_previousSibling,
1706 xmlnode_get_nextSibling,
1707 xmlnode_get_attributes,
1708 xmlnode_insertBefore,
1709 xmlnode_replaceChild,
1710 xmlnode_removeChild,
1711 xmlnode_appendChild,
1712 xmlnode_hasChildNodes,
1713 xmlnode_get_ownerDocument,
1715 xmlnode_get_nodeTypeString,
1718 xmlnode_get_specified,
1719 xmlnode_get_definition,
1720 xmlnode_get_nodeTypedValue,
1721 xmlnode_put_nodeTypedValue,
1722 xmlnode_get_dataType,
1723 xmlnode_put_dataType,
1725 xmlnode_transformNode,
1726 xmlnode_selectNodes,
1727 xmlnode_selectSingleNode,
1729 xmlnode_get_namespaceURI,
1731 xmlnode_get_baseName,
1732 xmlnode_transformNodeToObject,
1735 void destroy_xmlnode(xmlnode *This)
1738 xmldoc_release(This->node->doc);
1741 void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data)
1744 xmldoc_add_ref( node->doc );
1746 This->lpVtbl = &xmlnode_vtbl;
1748 This->iface = node_iface;
1751 init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data);
1753 This->dispex.outer = NULL;
1758 const IXMLDOMNodeVtbl *lpVtbl;
1762 static inline unknode *impl_from_unkIXMLDOMNode(IXMLDOMNode *iface)
1764 return (unknode *)((char*)iface - FIELD_OFFSET(unknode, lpVtbl));
1767 static HRESULT WINAPI unknode_QueryInterface(
1772 unknode *This = impl_from_unkIXMLDOMNode( iface );
1774 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
1776 if (IsEqualGUID(riid, &IID_IUnknown)) {
1778 }else if (IsEqualGUID( riid, &IID_IDispatch) ||
1779 IsEqualGUID( riid, &IID_IXMLDOMNode)) {
1780 *ppvObject = &This->lpVtbl;
1781 }else if(node_query_interface(&This->node, riid, ppvObject)) {
1782 return *ppvObject ? S_OK : E_NOINTERFACE;
1784 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1786 return E_NOINTERFACE;
1789 IUnknown_AddRef((IUnknown*)*ppvObject);
1793 static ULONG WINAPI unknode_AddRef(
1794 IXMLDOMNode *iface )
1796 unknode *This = impl_from_unkIXMLDOMNode( iface );
1798 return InterlockedIncrement(&This->ref);
1801 static ULONG WINAPI unknode_Release(
1802 IXMLDOMNode *iface )
1804 unknode *This = impl_from_unkIXMLDOMNode( iface );
1807 ref = InterlockedDecrement( &This->ref );
1809 destroy_xmlnode(&This->node);
1816 static HRESULT WINAPI unknode_GetTypeInfoCount(
1820 unknode *This = impl_from_unkIXMLDOMNode( iface );
1822 TRACE("(%p)->(%p)\n", This, pctinfo);
1829 static HRESULT WINAPI unknode_GetTypeInfo(
1833 ITypeInfo** ppTInfo )
1835 unknode *This = impl_from_unkIXMLDOMNode( iface );
1838 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1840 hr = get_typeinfo(IXMLDOMNode_tid, ppTInfo);
1845 static HRESULT WINAPI unknode_GetIDsOfNames(
1848 LPOLESTR* rgszNames,
1853 unknode *This = impl_from_unkIXMLDOMNode( iface );
1855 ITypeInfo *typeinfo;
1858 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1861 if(!rgszNames || cNames == 0 || !rgDispId)
1862 return E_INVALIDARG;
1864 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
1867 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1868 ITypeInfo_Release(typeinfo);
1874 static HRESULT WINAPI unknode_Invoke(
1876 DISPID dispIdMember,
1880 DISPPARAMS* pDispParams,
1881 VARIANT* pVarResult,
1882 EXCEPINFO* pExcepInfo,
1885 unknode *This = impl_from_unkIXMLDOMNode( iface );
1886 ITypeInfo *typeinfo;
1889 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1890 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1892 hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo);
1895 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
1896 pVarResult, pExcepInfo, puArgErr);
1897 ITypeInfo_Release(typeinfo);
1903 static HRESULT WINAPI unknode_get_nodeName(
1907 unknode *This = impl_from_unkIXMLDOMNode( iface );
1908 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), p );
1911 static HRESULT WINAPI unknode_get_nodeValue(
1915 unknode *This = impl_from_unkIXMLDOMNode( iface );
1916 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
1919 static HRESULT WINAPI unknode_put_nodeValue(
1923 unknode *This = impl_from_unkIXMLDOMNode( iface );
1924 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
1927 static HRESULT WINAPI unknode_get_nodeType(
1929 DOMNodeType* domNodeType )
1931 unknode *This = impl_from_unkIXMLDOMNode( iface );
1932 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), domNodeType );
1935 static HRESULT WINAPI unknode_get_parentNode(
1937 IXMLDOMNode** parent )
1939 unknode *This = impl_from_unkIXMLDOMNode( iface );
1940 TRACE("(%p)->(%p)\n", This, parent);
1941 if (!parent) return E_INVALIDARG;
1946 static HRESULT WINAPI unknode_get_childNodes(
1948 IXMLDOMNodeList** outList)
1950 unknode *This = impl_from_unkIXMLDOMNode( iface );
1951 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), outList );
1954 static HRESULT WINAPI unknode_get_firstChild(
1956 IXMLDOMNode** domNode)
1958 unknode *This = impl_from_unkIXMLDOMNode( iface );
1959 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), domNode );
1962 static HRESULT WINAPI unknode_get_lastChild(
1964 IXMLDOMNode** domNode)
1966 unknode *This = impl_from_unkIXMLDOMNode( iface );
1967 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), domNode );
1970 static HRESULT WINAPI unknode_get_previousSibling(
1972 IXMLDOMNode** domNode)
1974 unknode *This = impl_from_unkIXMLDOMNode( iface );
1975 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), domNode );
1978 static HRESULT WINAPI unknode_get_nextSibling(
1980 IXMLDOMNode** domNode)
1982 unknode *This = impl_from_unkIXMLDOMNode( iface );
1983 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), domNode );
1986 static HRESULT WINAPI unknode_get_attributes(
1988 IXMLDOMNamedNodeMap** attributeMap)
1990 unknode *This = impl_from_unkIXMLDOMNode( iface );
1991 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
1994 static HRESULT WINAPI unknode_insertBefore(
1996 IXMLDOMNode* newNode, VARIANT var1,
1997 IXMLDOMNode** outOldNode)
1999 unknode *This = impl_from_unkIXMLDOMNode( iface );
2000 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newNode, var1, outOldNode );
2003 static HRESULT WINAPI unknode_replaceChild(
2005 IXMLDOMNode* newNode,
2006 IXMLDOMNode* oldNode,
2007 IXMLDOMNode** outOldNode)
2009 unknode *This = impl_from_unkIXMLDOMNode( iface );
2010 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newNode, oldNode, outOldNode );
2013 static HRESULT WINAPI unknode_removeChild(
2015 IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
2017 unknode *This = impl_from_unkIXMLDOMNode( iface );
2018 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), domNode, oldNode );
2021 static HRESULT WINAPI unknode_appendChild(
2023 IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
2025 unknode *This = impl_from_unkIXMLDOMNode( iface );
2026 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newNode, outNewNode );
2029 static HRESULT WINAPI unknode_hasChildNodes(
2031 VARIANT_BOOL* pbool)
2033 unknode *This = impl_from_unkIXMLDOMNode( iface );
2034 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), pbool );
2037 static HRESULT WINAPI unknode_get_ownerDocument(
2039 IXMLDOMDocument** domDocument)
2041 unknode *This = impl_from_unkIXMLDOMNode( iface );
2042 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), domDocument );
2045 static HRESULT WINAPI unknode_cloneNode(
2047 VARIANT_BOOL pbool, IXMLDOMNode** outNode)
2049 unknode *This = impl_from_unkIXMLDOMNode( iface );
2050 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), pbool, outNode );
2053 static HRESULT WINAPI unknode_get_nodeTypeString(
2057 unknode *This = impl_from_unkIXMLDOMNode( iface );
2058 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), p );
2061 static HRESULT WINAPI unknode_get_text(
2065 unknode *This = impl_from_unkIXMLDOMNode( iface );
2066 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), p );
2069 static HRESULT WINAPI unknode_put_text(
2073 unknode *This = impl_from_unkIXMLDOMNode( iface );
2074 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), p );
2077 static HRESULT WINAPI unknode_get_specified(
2079 VARIANT_BOOL* pbool)
2081 unknode *This = impl_from_unkIXMLDOMNode( iface );
2082 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), pbool );
2085 static HRESULT WINAPI unknode_get_definition(
2087 IXMLDOMNode** domNode)
2089 unknode *This = impl_from_unkIXMLDOMNode( iface );
2090 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), domNode );
2093 static HRESULT WINAPI unknode_get_nodeTypedValue(
2097 unknode *This = impl_from_unkIXMLDOMNode( iface );
2098 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
2101 static HRESULT WINAPI unknode_put_nodeTypedValue(
2105 unknode *This = impl_from_unkIXMLDOMNode( iface );
2106 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
2109 static HRESULT WINAPI unknode_get_dataType(
2113 unknode *This = impl_from_unkIXMLDOMNode( iface );
2114 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), var1 );
2117 static HRESULT WINAPI unknode_put_dataType(
2121 unknode *This = impl_from_unkIXMLDOMNode( iface );
2122 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
2125 static HRESULT WINAPI unknode_get_xml(
2129 unknode *This = impl_from_unkIXMLDOMNode( iface );
2130 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), p );
2133 static HRESULT WINAPI unknode_transformNode(
2135 IXMLDOMNode* domNode, BSTR* p)
2137 unknode *This = impl_from_unkIXMLDOMNode( iface );
2138 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), domNode, p );
2141 static HRESULT WINAPI unknode_selectNodes(
2143 BSTR p, IXMLDOMNodeList** outList)
2145 unknode *This = impl_from_unkIXMLDOMNode( iface );
2146 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), p, outList );
2149 static HRESULT WINAPI unknode_selectSingleNode(
2151 BSTR p, IXMLDOMNode** outNode)
2153 unknode *This = impl_from_unkIXMLDOMNode( iface );
2154 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), p, outNode );
2157 static HRESULT WINAPI unknode_get_parsed(
2159 VARIANT_BOOL* pbool)
2161 unknode *This = impl_from_unkIXMLDOMNode( iface );
2162 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), pbool );
2165 static HRESULT WINAPI unknode_get_namespaceURI(
2169 unknode *This = impl_from_unkIXMLDOMNode( iface );
2170 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), p );
2173 static HRESULT WINAPI unknode_get_prefix(
2177 unknode *This = impl_from_unkIXMLDOMNode( iface );
2178 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), p );
2181 static HRESULT WINAPI unknode_get_baseName(
2185 unknode *This = impl_from_unkIXMLDOMNode( iface );
2186 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), p );
2189 static HRESULT WINAPI unknode_transformNodeToObject(
2191 IXMLDOMNode* domNode, VARIANT var1)
2193 unknode *This = impl_from_unkIXMLDOMNode( iface );
2194 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), domNode, var1 );
2197 static const struct IXMLDOMNodeVtbl unknode_vtbl =
2199 unknode_QueryInterface,
2202 unknode_GetTypeInfoCount,
2203 unknode_GetTypeInfo,
2204 unknode_GetIDsOfNames,
2206 unknode_get_nodeName,
2207 unknode_get_nodeValue,
2208 unknode_put_nodeValue,
2209 unknode_get_nodeType,
2210 unknode_get_parentNode,
2211 unknode_get_childNodes,
2212 unknode_get_firstChild,
2213 unknode_get_lastChild,
2214 unknode_get_previousSibling,
2215 unknode_get_nextSibling,
2216 unknode_get_attributes,
2217 unknode_insertBefore,
2218 unknode_replaceChild,
2219 unknode_removeChild,
2220 unknode_appendChild,
2221 unknode_hasChildNodes,
2222 unknode_get_ownerDocument,
2224 unknode_get_nodeTypeString,
2227 unknode_get_specified,
2228 unknode_get_definition,
2229 unknode_get_nodeTypedValue,
2230 unknode_put_nodeTypedValue,
2231 unknode_get_dataType,
2232 unknode_put_dataType,
2234 unknode_transformNode,
2235 unknode_selectNodes,
2236 unknode_selectSingleNode,
2238 unknode_get_namespaceURI,
2240 unknode_get_baseName,
2241 unknode_transformNodeToObject
2244 IXMLDOMNode *create_node( xmlNodePtr node )
2253 TRACE("type %d\n", node->type);
2256 case XML_ELEMENT_NODE:
2257 pUnk = create_element( node );
2259 case XML_ATTRIBUTE_NODE:
2260 pUnk = create_attribute( node );
2263 pUnk = create_text( node );
2265 case XML_CDATA_SECTION_NODE:
2266 pUnk = create_cdata( node );
2268 case XML_ENTITY_REF_NODE:
2269 pUnk = create_doc_entity_ref( node );
2272 pUnk = create_pi( node );
2274 case XML_COMMENT_NODE:
2275 pUnk = create_comment( node );
2277 case XML_DOCUMENT_NODE:
2278 pUnk = create_domdoc( node );
2280 case XML_DOCUMENT_FRAG_NODE:
2281 pUnk = create_doc_fragment( node );
2286 FIXME("only creating basic node for type %d\n", node->type);
2288 new_node = heap_alloc(sizeof(unknode));
2292 new_node->lpVtbl = &unknode_vtbl;
2294 init_xmlnode(&new_node->node, node, (IXMLDOMNode*)&new_node->lpVtbl, NULL);
2295 pUnk = (IUnknown*)&new_node->lpVtbl;
2299 hr = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMNode, (LPVOID*)&ret);
2300 IUnknown_Release(pUnk);
2301 if(FAILED(hr)) return NULL;