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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include "msxml_private.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
45 typedef struct _xmlnode
47 const struct IXMLDOMNodeVtbl
*lpVtbl
;
52 static inline xmlnode
*impl_from_IXMLDOMNode( IXMLDOMNode
*iface
)
54 return (xmlnode
*)((char*)iface
- FIELD_OFFSET(xmlnode
, lpVtbl
));
57 xmlNodePtr
xmlNodePtr_from_domnode( IXMLDOMNode
*iface
, xmlElementType type
)
63 This
= impl_from_IXMLDOMNode( iface
);
66 if ( type
&& This
->node
->type
!= type
)
71 static HRESULT WINAPI
xmlnode_QueryInterface(
76 TRACE("%p %s %p\n", iface
, debugstr_guid(riid
), ppvObject
);
78 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
79 IsEqualGUID( riid
, &IID_IDispatch
) ||
80 IsEqualGUID( riid
, &IID_IXMLDOMNode
) )
87 IXMLDOMElement_AddRef( iface
);
92 static ULONG WINAPI
xmlnode_AddRef(
95 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
96 return InterlockedIncrement( &This
->ref
);
99 static ULONG WINAPI
xmlnode_Release(
102 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
105 ref
= InterlockedDecrement( &This
->ref
);
108 if( This
->node
->type
== XML_DOCUMENT_NODE
)
110 xmlFreeDoc( (xmlDocPtr
) This
->node
);
115 assert( This
->node
->doc
);
116 root
= This
->node
->doc
->_private
;
118 IXMLDOMNode_Release( root
);
119 This
->node
->_private
= NULL
;
121 HeapFree( GetProcessHeap(), 0, This
);
127 static HRESULT WINAPI
xmlnode_GetTypeInfoCount(
135 static HRESULT WINAPI
xmlnode_GetTypeInfo(
139 ITypeInfo
** ppTInfo
)
145 static HRESULT WINAPI
xmlnode_GetIDsOfNames(
157 static HRESULT WINAPI
xmlnode_Invoke(
163 DISPPARAMS
* pDispParams
,
165 EXCEPINFO
* pExcepInfo
,
172 static HRESULT WINAPI
xmlnode_get_nodeName(
176 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
179 TRACE("%p\n", This
);
187 switch( This
->node
->type
)
190 str
= (const xmlChar
*) "#text";
192 case XML_DOCUMENT_NODE
:
193 str
= (const xmlChar
*) "#document";
196 str
= This
->node
->name
;
200 *name
= bstr_from_xmlChar( str
);
207 BSTR
bstr_from_xmlChar( const xmlChar
*buf
)
216 len
= MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
) buf
, -1, NULL
, 0 );
217 str
= (LPWSTR
) HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
220 MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
) buf
, -1, str
, len
);
221 bstr
= SysAllocString( str
);
222 HeapFree( GetProcessHeap(), 0, str
);
226 static HRESULT WINAPI
xmlnode_get_nodeValue(
230 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
233 TRACE("%p %p\n", This
, value
);
235 V_BSTR(value
) = NULL
;
236 V_VT(value
) = VT_NULL
;
238 switch ( This
->node
->type
)
240 case XML_ATTRIBUTE_NODE
:
241 V_VT(value
) = VT_BSTR
;
242 V_BSTR(value
) = bstr_from_xmlChar( This
->node
->name
);
246 V_VT(value
) = VT_BSTR
;
247 V_BSTR(value
) = bstr_from_xmlChar( This
->node
->content
);
250 case XML_ELEMENT_NODE
:
251 case XML_DOCUMENT_NODE
:
252 /* these seem to return NULL */
256 FIXME("node %p type %d\n", This
, This
->node
->type
);
259 TRACE("%p returned %s\n", This
, debugstr_w( V_BSTR(value
) ) );
264 static HRESULT WINAPI
xmlnode_put_nodeValue(
272 static HRESULT WINAPI
xmlnode_get_nodeType(
276 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
278 TRACE("%p %p\n", This
, type
);
280 assert( NODE_ELEMENT
== XML_ELEMENT_NODE
);
281 assert( NODE_NOTATION
== XML_NOTATION_NODE
);
283 *type
= This
->node
->type
;
288 static HRESULT
get_node(
294 TRACE("%p->%s %p\n", This
, name
, node
);
298 *out
= create_node( node
);
304 static HRESULT WINAPI
xmlnode_get_parentNode(
306 IXMLDOMNode
** parent
)
308 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
309 return get_node( This
, "parent", This
->node
->parent
, parent
);
312 static HRESULT WINAPI
xmlnode_get_childNodes(
314 IXMLDOMNodeList
** childList
)
316 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
318 TRACE("%p %p\n", This
, childList
);
323 switch(This
->node
->type
)
325 case XML_ELEMENT_NODE
:
326 *childList
= create_filtered_nodelist( This
->node
->children
, (const xmlChar
*)"*" );
329 case XML_ATTRIBUTE_NODE
:
330 *childList
= create_filtered_nodelist( This
->node
->children
, (const xmlChar
*)"node()" );
334 FIXME("unhandled node type %d\n", This
->node
->type
);
343 static HRESULT WINAPI
xmlnode_get_firstChild(
345 IXMLDOMNode
** firstChild
)
347 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
348 return get_node( This
, "firstChild", This
->node
->children
, firstChild
);
351 static HRESULT WINAPI
xmlnode_get_lastChild(
353 IXMLDOMNode
** lastChild
)
355 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
356 return get_node( This
, "lastChild", This
->node
->last
, lastChild
);
359 static HRESULT WINAPI
xmlnode_get_previousSibling(
361 IXMLDOMNode
** previousSibling
)
363 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
364 return get_node( This
, "previous", This
->node
->prev
, previousSibling
);
367 static HRESULT WINAPI
xmlnode_get_nextSibling(
369 IXMLDOMNode
** nextSibling
)
371 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
372 return get_node( This
, "next", This
->node
->next
, nextSibling
);
375 static HRESULT WINAPI
xmlnode_get_attributes(
377 IXMLDOMNamedNodeMap
** attributeMap
)
379 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
381 *attributeMap
= create_nodemap( iface
);
385 static HRESULT WINAPI
xmlnode_insertBefore(
387 IXMLDOMNode
* newChild
,
389 IXMLDOMNode
** outNewChild
)
395 static HRESULT WINAPI
xmlnode_replaceChild(
397 IXMLDOMNode
* newChild
,
398 IXMLDOMNode
* oldChild
,
399 IXMLDOMNode
** outOldChild
)
405 static HRESULT WINAPI
xmlnode_removeChild(
407 IXMLDOMNode
* childNode
,
408 IXMLDOMNode
** oldChild
)
414 static HRESULT WINAPI
xmlnode_appendChild(
416 IXMLDOMNode
* newChild
,
417 IXMLDOMNode
** outNewChild
)
423 static HRESULT WINAPI
xmlnode_hasChildNodes(
425 VARIANT_BOOL
* hasChild
)
427 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
433 if (!This
->node
->children
)
435 *hasChild
= VARIANT_FALSE
;
439 *hasChild
= VARIANT_TRUE
;
443 static HRESULT WINAPI
xmlnode_get_ownerDocument(
445 IXMLDOMDocument
** DOMDocument
)
451 static HRESULT WINAPI
xmlnode_cloneNode(
454 IXMLDOMNode
** cloneRoot
)
460 static HRESULT WINAPI
xmlnode_get_nodeTypeString(
468 static HRESULT WINAPI
xmlnode_get_text(
472 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
481 child
= This
->node
->children
;
482 if ( child
&& child
->type
== XML_TEXT_NODE
)
483 str
= bstr_from_xmlChar( child
->content
);
485 TRACE("%p %s\n", This
, debugstr_w(str
) );
491 static HRESULT WINAPI
xmlnode_put_text(
499 static HRESULT WINAPI
xmlnode_get_specified(
501 VARIANT_BOOL
* isSpecified
)
507 static HRESULT WINAPI
xmlnode_get_definition(
509 IXMLDOMNode
** definitionNode
)
515 static HRESULT WINAPI
xmlnode_get_nodeTypedValue(
523 static HRESULT WINAPI
xmlnode_put_nodeTypedValue(
531 static HRESULT WINAPI
xmlnode_get_dataType(
533 VARIANT
* dataTypeName
)
539 static HRESULT WINAPI
xmlnode_put_dataType(
547 static HRESULT WINAPI
xmlnode_get_xml(
555 static HRESULT WINAPI
xmlnode_transformNode(
557 IXMLDOMNode
* styleSheet
,
564 static HRESULT WINAPI
xmlnode_selectNodes(
567 IXMLDOMNodeList
** resultList
)
569 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
573 TRACE("%p %s %p\n", This
, debugstr_w(queryString
), resultList
);
575 str
= xmlChar_from_wchar( queryString
);
579 *resultList
= create_filtered_nodelist( This
->node
->children
, str
);
580 HeapFree( GetProcessHeap(), 0, str
);
584 static HRESULT WINAPI
xmlnode_selectSingleNode(
587 IXMLDOMNode
** resultNode
)
589 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
590 IXMLDOMNodeList
*list
;
593 TRACE("%p %s %p\n", This
, debugstr_w(queryString
), resultNode
);
595 r
= IXMLDOMNode_selectNodes(iface
, queryString
, &list
);
598 r
= IXMLDOMNodeList_nextNode(list
, resultNode
);
599 IXMLDOMNodeList_Release(list
);
604 static HRESULT WINAPI
xmlnode_get_parsed(
606 VARIANT_BOOL
* isParsed
)
612 static HRESULT WINAPI
xmlnode_get_namespaceURI(
620 static HRESULT WINAPI
xmlnode_get_prefix(
628 static HRESULT WINAPI
xmlnode_get_baseName(
632 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
636 TRACE("%p %p\n", This
, nameString
);
641 switch ( This
->node
->type
)
643 case XML_ELEMENT_NODE
:
644 case XML_ATTRIBUTE_NODE
:
645 str
= bstr_from_xmlChar( This
->node
->name
);
651 ERR("Unhandled type %d\n", This
->node
->type
);
655 TRACE("returning %08lx str = %s\n", r
, debugstr_w( str
) );
661 static HRESULT WINAPI
xmlnode_transformNodeToObject(
663 IXMLDOMNode
* stylesheet
,
664 VARIANT outputObject
)
670 static const struct IXMLDOMNodeVtbl xmlnode_vtbl
=
672 xmlnode_QueryInterface
,
675 xmlnode_GetTypeInfoCount
,
677 xmlnode_GetIDsOfNames
,
679 xmlnode_get_nodeName
,
680 xmlnode_get_nodeValue
,
681 xmlnode_put_nodeValue
,
682 xmlnode_get_nodeType
,
683 xmlnode_get_parentNode
,
684 xmlnode_get_childNodes
,
685 xmlnode_get_firstChild
,
686 xmlnode_get_lastChild
,
687 xmlnode_get_previousSibling
,
688 xmlnode_get_nextSibling
,
689 xmlnode_get_attributes
,
690 xmlnode_insertBefore
,
691 xmlnode_replaceChild
,
694 xmlnode_hasChildNodes
,
695 xmlnode_get_ownerDocument
,
697 xmlnode_get_nodeTypeString
,
700 xmlnode_get_specified
,
701 xmlnode_get_definition
,
702 xmlnode_get_nodeTypedValue
,
703 xmlnode_put_nodeTypedValue
,
704 xmlnode_get_dataType
,
705 xmlnode_put_dataType
,
707 xmlnode_transformNode
,
709 xmlnode_selectSingleNode
,
711 xmlnode_get_namespaceURI
,
713 xmlnode_get_baseName
,
714 xmlnode_transformNodeToObject
,
717 IXMLDOMNode
*create_node( xmlNodePtr node
)
726 /* if an interface already exists for this node, return it */
727 if ( node
->_private
)
729 IXMLDOMNode
*n
= node
->_private
;
730 IXMLDOMNode_AddRef( n
);
735 * Try adding a reference to the IXMLDOMNode implementation
736 * containing the document's root element.
738 if ( node
->type
!= XML_DOCUMENT_NODE
)
740 IXMLDOMNode
*root
= NULL
;
742 root
= node
->doc
->_private
;
744 IXMLDOMNode_AddRef( root
);
747 assert( node
->doc
== (xmlDocPtr
) node
);
749 This
= HeapAlloc( GetProcessHeap(), 0, sizeof *This
);
753 This
->lpVtbl
= &xmlnode_vtbl
;
757 /* remember which interface we associated with this node */
758 node
->_private
= This
;
760 return (IXMLDOMNode
*) &This
->lpVtbl
;