2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
50 #include <libxml/xmlsave.h>
52 /* not defined in older versions */
53 #define XML_SAVE_FORMAT 1
54 #define XML_SAVE_NO_DECL 2
55 #define XML_SAVE_NO_EMPTY 4
56 #define XML_SAVE_NO_XHTML 8
57 #define XML_SAVE_XHTML 16
58 #define XML_SAVE_AS_XML 32
59 #define XML_SAVE_AS_HTML 64
61 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
62 static const WCHAR SZ_PROPERTY_PROHIBIT_DTD
[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
63 static const WCHAR SZ_VALUE_XPATH
[] = {'X','P','a','t','h',0};
64 static const WCHAR SZ_VALUE_XSLPATTERN
[] = {'X','S','L','P','a','t','t','e','r','n',0};
66 typedef struct _domdoc
69 const struct IXMLDOMDocument2Vtbl
*lpVtbl
;
70 const struct IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
71 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
72 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
73 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
76 VARIANT_BOOL validating
;
77 VARIANT_BOOL resolving
;
78 VARIANT_BOOL preserving
;
80 IXMLDOMSchemaCollection
*schema
;
95 In native windows, the whole lifetime management of XMLDOMNodes is
96 managed automatically using reference counts. Wine emulates that by
97 maintaining a reference count to the document that is increased for
98 each IXMLDOMNode pointer passed out for this document. If all these
99 pointers are gone, the document is unreachable and gets freed, that
100 is, all nodes in the tree of the document get freed.
102 You are able to create nodes that are associated to a document (in
103 fact, in msxml's XMLDOM model, all nodes are associated to a document),
104 but not in the tree of that document, for example using the createFoo
105 functions from IXMLDOMDocument. These nodes do not get cleaned up
106 by libxml, so we have to do it ourselves.
108 To catch these nodes, a list of "orphan nodes" is introduced.
109 It contains pointers to all roots of node trees that are
110 associated with the document without being part of the document
111 tree. All nodes with parent==NULL (except for the document root nodes)
112 should be in the orphan node list of their document. All orphan nodes
113 get freed together with the document itself.
116 typedef struct _xmldoc_priv
{
121 typedef struct _orphan_entry
{
126 static inline xmldoc_priv
* priv_from_xmlDocPtr(xmlDocPtr doc
)
128 return doc
->_private
;
131 static xmldoc_priv
* create_priv(void)
134 priv
= heap_alloc( sizeof (*priv
) );
139 list_init( &priv
->orphans
);
145 /* links a "<?xml" node as a first child */
146 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
149 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
152 /* unlinks a first "<?xml" child if it was created */
153 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
159 if (doc
->standalone
!= -1)
161 node
= doc
->children
;
162 xmlUnlinkNode( node
);
170 static xmlDocPtr
doparse( char *ptr
, int len
, const char *encoding
)
174 #ifdef HAVE_XMLREADMEMORY
176 * use xmlReadMemory if possible so we can suppress
177 * writing errors to stderr
179 doc
= xmlReadMemory( ptr
, len
, NULL
, encoding
,
180 XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NOBLANKS
);
182 doc
= xmlParseMemory( ptr
, len
);
185 /* create first child as a <?xml...?> */
186 if (doc
&& doc
->standalone
!= -1)
190 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
192 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
194 /* version attribute can't be omitted */
195 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
196 xmlNodeAddContent( node
, xmlbuff
);
200 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
201 xmlNodeAddContent( node
, xmlbuff
);
204 if (doc
->standalone
!= -2)
206 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
207 xmlNodeAddContent( node
, xmlbuff
);
210 xmldoc_link_xmldecl( doc
, node
);
216 LONG
xmldoc_add_ref(xmlDocPtr doc
)
218 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
219 TRACE("(%p)->(%d)\n", doc
, ref
);
223 LONG
xmldoc_release(xmlDocPtr doc
)
225 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
226 LONG ref
= InterlockedDecrement(&priv
->refs
);
227 TRACE("(%p)->(%d)\n", doc
, ref
);
230 orphan_entry
*orphan
, *orphan2
;
231 TRACE("freeing docptr %p\n", doc
);
233 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
235 xmlFreeNode( orphan
->node
);
238 heap_free(doc
->_private
);
246 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
248 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
251 entry
= heap_alloc( sizeof (*entry
) );
253 return E_OUTOFMEMORY
;
256 list_add_head( &priv
->orphans
, &entry
->entry
);
260 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
262 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
263 orphan_entry
*entry
, *entry2
;
265 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
267 if( entry
->node
== node
)
269 list_remove( &entry
->entry
);
278 static HRESULT
attach_xmldoc( xmlnode
*node
, xmlDocPtr xml
)
281 xmldoc_release(node
->node
->doc
);
283 node
->node
= (xmlNodePtr
) xml
;
285 xmldoc_add_ref(node
->node
->doc
);
290 static inline domdoc
*impl_from_IXMLDOMDocument2( IXMLDOMDocument2
*iface
)
292 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
295 static inline xmlDocPtr
get_doc( domdoc
*This
)
297 return (xmlDocPtr
)This
->node
.node
;
300 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
302 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStreamInit
));
305 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
307 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
310 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
312 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
315 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
317 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
320 /************************************************************************
321 * domdoc implementation of IPersistStream.
323 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
324 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
326 domdoc
*this = impl_from_IPersistStreamInit(iface
);
327 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2
*)this, riid
, ppvObj
);
330 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
331 IPersistStreamInit
*iface
)
333 domdoc
*this = impl_from_IPersistStreamInit(iface
);
334 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2
*)this);
337 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
338 IPersistStreamInit
*iface
)
340 domdoc
*this = impl_from_IPersistStreamInit(iface
);
341 return IXMLDOMDocument2_Release((IXMLDOMDocument2
*)this);
344 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
345 IPersistStreamInit
*iface
, CLSID
*classid
)
347 TRACE("(%p,%p): stub!\n", iface
, classid
);
352 *classid
= CLSID_DOMDocument2
;
357 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
358 IPersistStreamInit
*iface
)
360 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
361 FIXME("(%p): stub!\n", This
);
365 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
366 IPersistStreamInit
*iface
, LPSTREAM pStm
)
368 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
371 DWORD read
, written
, len
;
374 xmlDocPtr xmldoc
= NULL
;
376 TRACE("(%p)->(%p)\n", This
, pStm
);
381 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
387 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
388 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
389 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
393 ERR("Failed to copy stream\n");
397 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
401 len
= GlobalSize(hglobal
);
402 ptr
= GlobalLock(hglobal
);
404 xmldoc
= doparse(ptr
, len
, NULL
);
405 GlobalUnlock(hglobal
);
409 ERR("Failed to parse xml\n");
413 xmldoc
->_private
= create_priv();
415 return attach_xmldoc( &This
->node
, xmldoc
);
418 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
419 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
421 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
425 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
427 hr
= IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This
->node
), &xmlString
);
430 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
432 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
433 SysFreeString(xmlString
);
436 TRACE("ret 0x%08x\n", hr
);
441 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
442 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
444 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
445 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
449 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
450 IPersistStreamInit
*iface
)
452 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
453 TRACE("(%p)\n", This
);
457 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
459 domdoc_IPersistStreamInit_QueryInterface
,
460 domdoc_IPersistStreamInit_AddRef
,
461 domdoc_IPersistStreamInit_Release
,
462 domdoc_IPersistStreamInit_GetClassID
,
463 domdoc_IPersistStreamInit_IsDirty
,
464 domdoc_IPersistStreamInit_Load
,
465 domdoc_IPersistStreamInit_Save
,
466 domdoc_IPersistStreamInit_GetSizeMax
,
467 domdoc_IPersistStreamInit_InitNew
470 /* ISupportErrorInfo interface */
471 static HRESULT WINAPI
support_error_QueryInterface(
472 ISupportErrorInfo
*iface
,
473 REFIID riid
, void** ppvObj
)
475 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
476 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2
*)This
, riid
, ppvObj
);
479 static ULONG WINAPI
support_error_AddRef(
480 ISupportErrorInfo
*iface
)
482 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
483 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2
*)This
);
486 static ULONG WINAPI
support_error_Release(
487 ISupportErrorInfo
*iface
)
489 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
490 return IXMLDOMDocument2_Release((IXMLDOMDocument2
*)This
);
493 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
494 ISupportErrorInfo
*iface
,
497 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
501 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
503 support_error_QueryInterface
,
504 support_error_AddRef
,
505 support_error_Release
,
506 support_error_InterfaceSupportsErrorInfo
509 /* IXMLDOMDocument2 interface */
510 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument2
*iface
, REFIID riid
, void** ppvObject
)
512 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
514 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
518 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
519 IsEqualGUID( riid
, &IID_IDispatch
) ||
520 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
521 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
) )
525 else if ( IsEqualGUID( riid
, &IID_IXMLDOMNode
) )
527 *ppvObject
= IXMLDOMNode_from_impl(&This
->node
);
529 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
530 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
532 *ppvObject
= &(This
->lpvtblIPersistStreamInit
);
534 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
536 *ppvObject
= &(This
->lpvtblIObjectWithSite
);
538 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
540 *ppvObject
= &(This
->lpvtblIObjectSafety
);
542 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
544 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
546 else if(dispex_query_interface(&This
->node
.dispex
, riid
, ppvObject
))
548 return *ppvObject
? S_OK
: E_NOINTERFACE
;
550 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
552 TRACE("IID_IRunnableObject not supported returning NULL\n");
553 return E_NOINTERFACE
;
557 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
558 return E_NOINTERFACE
;
561 IUnknown_AddRef((IUnknown
*)*ppvObject
);
567 static ULONG WINAPI
domdoc_AddRef(
568 IXMLDOMDocument2
*iface
)
570 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
571 TRACE("%p\n", This
);
572 return InterlockedIncrement( &This
->ref
);
576 static ULONG WINAPI
domdoc_Release(
577 IXMLDOMDocument2
*iface
)
579 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
582 TRACE("%p\n", This
);
584 ref
= InterlockedDecrement( &This
->ref
);
588 detach_bsc(This
->bsc
);
591 IUnknown_Release( This
->site
);
592 destroy_xmlnode(&This
->node
);
593 if(This
->schema
) IXMLDOMSchemaCollection_Release( This
->schema
);
594 if (This
->stream
) IStream_Release(This
->stream
);
595 HeapFree( GetProcessHeap(), 0, This
);
601 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument2
*iface
, UINT
* pctinfo
)
603 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
605 TRACE("(%p)->(%p)\n", This
, pctinfo
);
612 static HRESULT WINAPI
domdoc_GetTypeInfo(
613 IXMLDOMDocument2
*iface
,
614 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
616 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
619 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
621 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
626 static HRESULT WINAPI
domdoc_GetIDsOfNames(
627 IXMLDOMDocument2
*iface
,
634 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
638 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
641 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
644 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
647 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
648 ITypeInfo_Release(typeinfo
);
655 static HRESULT WINAPI
domdoc_Invoke(
656 IXMLDOMDocument2
*iface
,
661 DISPPARAMS
* pDispParams
,
663 EXCEPINFO
* pExcepInfo
,
666 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
670 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
671 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
673 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
676 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
677 pVarResult
, pExcepInfo
, puArgErr
);
678 ITypeInfo_Release(typeinfo
);
685 static HRESULT WINAPI
domdoc_get_nodeName(
686 IXMLDOMDocument2
*iface
,
689 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
690 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This
->node
), name
);
694 static HRESULT WINAPI
domdoc_get_nodeValue(
695 IXMLDOMDocument2
*iface
,
698 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
699 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This
->node
), value
);
703 static HRESULT WINAPI
domdoc_put_nodeValue(
704 IXMLDOMDocument2
*iface
,
707 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
708 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This
->node
), value
);
712 static HRESULT WINAPI
domdoc_get_nodeType(
713 IXMLDOMDocument2
*iface
,
716 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
717 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This
->node
), type
);
721 static HRESULT WINAPI
domdoc_get_parentNode(
722 IXMLDOMDocument2
*iface
,
723 IXMLDOMNode
** parent
)
725 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
726 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This
->node
), parent
);
730 static HRESULT WINAPI
domdoc_get_childNodes(
731 IXMLDOMDocument2
*iface
,
732 IXMLDOMNodeList
** childList
)
734 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
735 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This
->node
), childList
);
739 static HRESULT WINAPI
domdoc_get_firstChild(
740 IXMLDOMDocument2
*iface
,
741 IXMLDOMNode
** firstChild
)
743 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
744 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This
->node
), firstChild
);
748 static HRESULT WINAPI
domdoc_get_lastChild(
749 IXMLDOMDocument2
*iface
,
750 IXMLDOMNode
** lastChild
)
752 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
753 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This
->node
), lastChild
);
757 static HRESULT WINAPI
domdoc_get_previousSibling(
758 IXMLDOMDocument2
*iface
,
759 IXMLDOMNode
** previousSibling
)
761 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
762 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This
->node
), previousSibling
);
766 static HRESULT WINAPI
domdoc_get_nextSibling(
767 IXMLDOMDocument2
*iface
,
768 IXMLDOMNode
** nextSibling
)
770 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
771 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This
->node
), nextSibling
);
775 static HRESULT WINAPI
domdoc_get_attributes(
776 IXMLDOMDocument2
*iface
,
777 IXMLDOMNamedNodeMap
** attributeMap
)
779 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
780 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This
->node
), attributeMap
);
784 static HRESULT WINAPI
domdoc_insertBefore(
785 IXMLDOMDocument2
*iface
,
786 IXMLDOMNode
* newChild
,
788 IXMLDOMNode
** outNewChild
)
790 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
791 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This
->node
), newChild
, refChild
, outNewChild
);
795 static HRESULT WINAPI
domdoc_replaceChild(
796 IXMLDOMDocument2
*iface
,
797 IXMLDOMNode
* newChild
,
798 IXMLDOMNode
* oldChild
,
799 IXMLDOMNode
** outOldChild
)
801 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
802 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, oldChild
, outOldChild
);
806 static HRESULT WINAPI
domdoc_removeChild(
807 IXMLDOMDocument2
*iface
,
808 IXMLDOMNode
* childNode
,
809 IXMLDOMNode
** oldChild
)
811 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
812 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This
->node
), childNode
, oldChild
);
816 static HRESULT WINAPI
domdoc_appendChild(
817 IXMLDOMDocument2
*iface
,
818 IXMLDOMNode
* newChild
,
819 IXMLDOMNode
** outNewChild
)
821 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
822 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, outNewChild
);
826 static HRESULT WINAPI
domdoc_hasChildNodes(
827 IXMLDOMDocument2
*iface
,
828 VARIANT_BOOL
* hasChild
)
830 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
831 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This
->node
), hasChild
);
835 static HRESULT WINAPI
domdoc_get_ownerDocument(
836 IXMLDOMDocument2
*iface
,
837 IXMLDOMDocument
** DOMDocument
)
839 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
840 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This
->node
), DOMDocument
);
844 static HRESULT WINAPI
domdoc_cloneNode(
845 IXMLDOMDocument2
*iface
,
847 IXMLDOMNode
** cloneRoot
)
849 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
850 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This
->node
), deep
, cloneRoot
);
854 static HRESULT WINAPI
domdoc_get_nodeTypeString(
855 IXMLDOMDocument2
*iface
,
858 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
859 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This
->node
), nodeType
);
863 static HRESULT WINAPI
domdoc_get_text(
864 IXMLDOMDocument2
*iface
,
867 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
868 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This
->node
), text
);
872 static HRESULT WINAPI
domdoc_put_text(
873 IXMLDOMDocument2
*iface
,
876 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
877 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This
->node
), text
);
881 static HRESULT WINAPI
domdoc_get_specified(
882 IXMLDOMDocument2
*iface
,
883 VARIANT_BOOL
* isSpecified
)
885 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
886 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This
->node
), isSpecified
);
890 static HRESULT WINAPI
domdoc_get_definition(
891 IXMLDOMDocument2
*iface
,
892 IXMLDOMNode
** definitionNode
)
894 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
895 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This
->node
), definitionNode
);
899 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
900 IXMLDOMDocument2
*iface
,
901 VARIANT
* typedValue
)
903 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
904 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
907 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
908 IXMLDOMDocument2
*iface
,
911 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
912 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
916 static HRESULT WINAPI
domdoc_get_dataType(
917 IXMLDOMDocument2
*iface
,
918 VARIANT
* dataTypeName
)
920 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
921 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
925 static HRESULT WINAPI
domdoc_put_dataType(
926 IXMLDOMDocument2
*iface
,
929 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
930 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
934 static HRESULT WINAPI
domdoc_get_xml(
935 IXMLDOMDocument2
*iface
,
938 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
939 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This
->node
), xmlString
);
943 static HRESULT WINAPI
domdoc_transformNode(
944 IXMLDOMDocument2
*iface
,
945 IXMLDOMNode
* styleSheet
,
948 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
949 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This
->node
), styleSheet
, xmlString
);
953 static HRESULT WINAPI
domdoc_selectNodes(
954 IXMLDOMDocument2
*iface
,
956 IXMLDOMNodeList
** resultList
)
958 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
959 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultList
);
963 static HRESULT WINAPI
domdoc_selectSingleNode(
964 IXMLDOMDocument2
*iface
,
966 IXMLDOMNode
** resultNode
)
968 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
969 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultNode
);
973 static HRESULT WINAPI
domdoc_get_parsed(
974 IXMLDOMDocument2
*iface
,
975 VARIANT_BOOL
* isParsed
)
977 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
978 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This
->node
), isParsed
);
982 static HRESULT WINAPI
domdoc_get_namespaceURI(
983 IXMLDOMDocument2
*iface
,
986 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
987 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This
->node
), namespaceURI
);
991 static HRESULT WINAPI
domdoc_get_prefix(
992 IXMLDOMDocument2
*iface
,
995 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
996 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This
->node
), prefixString
);
1000 static HRESULT WINAPI
domdoc_get_baseName(
1001 IXMLDOMDocument2
*iface
,
1004 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1005 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This
->node
), nameString
);
1009 static HRESULT WINAPI
domdoc_transformNodeToObject(
1010 IXMLDOMDocument2
*iface
,
1011 IXMLDOMNode
* stylesheet
,
1012 VARIANT outputObject
)
1014 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1015 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This
->node
), stylesheet
, outputObject
);
1019 static HRESULT WINAPI
domdoc_get_doctype(
1020 IXMLDOMDocument2
*iface
,
1021 IXMLDOMDocumentType
** documentType
)
1023 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1024 FIXME("(%p)\n", This
);
1029 static HRESULT WINAPI
domdoc_get_implementation(
1030 IXMLDOMDocument2
*iface
,
1031 IXMLDOMImplementation
** impl
)
1033 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1035 TRACE("(%p)->(%p)\n", This
, impl
);
1038 return E_INVALIDARG
;
1040 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1045 static HRESULT WINAPI
domdoc_get_documentElement(
1046 IXMLDOMDocument2
*iface
,
1047 IXMLDOMElement
** DOMElement
)
1049 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1050 xmlDocPtr xmldoc
= NULL
;
1051 xmlNodePtr root
= NULL
;
1052 IXMLDOMNode
*element_node
;
1055 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1058 return E_INVALIDARG
;
1062 xmldoc
= get_doc( This
);
1064 root
= xmlDocGetRootElement( xmldoc
);
1068 element_node
= create_node( root
);
1069 if(!element_node
) return S_FALSE
;
1071 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (LPVOID
*)DOMElement
);
1072 IXMLDOMNode_Release(element_node
);
1078 static HRESULT WINAPI
domdoc_put_documentElement(
1079 IXMLDOMDocument2
*iface
,
1080 IXMLDOMElement
* DOMElement
)
1082 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1083 IXMLDOMNode
*elementNode
;
1088 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1090 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1094 xmlNode
= impl_from_IXMLDOMNode( elementNode
);
1096 if(!xmlNode
->node
->parent
)
1097 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1098 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1100 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1101 IXMLDOMNode_Release( elementNode
);
1104 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1110 static HRESULT WINAPI
domdoc_createElement(
1111 IXMLDOMDocument2
*iface
,
1113 IXMLDOMElement
** element
)
1115 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1120 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1122 if (!element
|| !tagname
) return E_INVALIDARG
;
1124 V_VT(&type
) = VT_I1
;
1125 V_I1(&type
) = NODE_ELEMENT
;
1127 hr
= IXMLDOMDocument2_createNode(iface
, type
, tagname
, NULL
, &node
);
1130 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1131 IXMLDOMNode_Release(node
);
1138 static HRESULT WINAPI
domdoc_createDocumentFragment(
1139 IXMLDOMDocument2
*iface
,
1140 IXMLDOMDocumentFragment
** frag
)
1142 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1147 TRACE("(%p)->(%p)\n", This
, frag
);
1149 if (!frag
) return E_INVALIDARG
;
1153 V_VT(&type
) = VT_I1
;
1154 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1156 hr
= IXMLDOMDocument2_createNode(iface
, type
, NULL
, NULL
, &node
);
1159 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1160 IXMLDOMNode_Release(node
);
1167 static HRESULT WINAPI
domdoc_createTextNode(
1168 IXMLDOMDocument2
*iface
,
1170 IXMLDOMText
** text
)
1172 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1177 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1179 if (!text
) return E_INVALIDARG
;
1183 V_VT(&type
) = VT_I1
;
1184 V_I1(&type
) = NODE_TEXT
;
1186 hr
= IXMLDOMDocument2_createNode(iface
, type
, NULL
, NULL
, &node
);
1189 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1190 IXMLDOMNode_Release(node
);
1191 hr
= IXMLDOMText_put_data(*text
, data
);
1198 static HRESULT WINAPI
domdoc_createComment(
1199 IXMLDOMDocument2
*iface
,
1201 IXMLDOMComment
** comment
)
1203 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1208 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1210 if (!comment
) return E_INVALIDARG
;
1214 V_VT(&type
) = VT_I1
;
1215 V_I1(&type
) = NODE_COMMENT
;
1217 hr
= IXMLDOMDocument2_createNode(iface
, type
, NULL
, NULL
, &node
);
1220 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1221 IXMLDOMNode_Release(node
);
1222 hr
= IXMLDOMComment_put_data(*comment
, data
);
1229 static HRESULT WINAPI
domdoc_createCDATASection(
1230 IXMLDOMDocument2
*iface
,
1232 IXMLDOMCDATASection
** cdata
)
1234 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1239 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1241 if (!cdata
) return E_INVALIDARG
;
1245 V_VT(&type
) = VT_I1
;
1246 V_I1(&type
) = NODE_CDATA_SECTION
;
1248 hr
= IXMLDOMDocument2_createNode(iface
, type
, NULL
, NULL
, &node
);
1251 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1252 IXMLDOMNode_Release(node
);
1253 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1260 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1261 IXMLDOMDocument2
*iface
,
1264 IXMLDOMProcessingInstruction
** pi
)
1266 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1271 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1273 if (!pi
) return E_INVALIDARG
;
1277 V_VT(&type
) = VT_I1
;
1278 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1280 hr
= IXMLDOMDocument2_createNode(iface
, type
, target
, NULL
, &node
);
1285 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1286 V_VT(&v_data
) = VT_BSTR
;
1287 V_BSTR(&v_data
) = data
;
1289 hr
= IXMLDOMNode_put_nodeValue( node
, v_data
);
1291 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1292 IXMLDOMNode_Release(node
);
1299 static HRESULT WINAPI
domdoc_createAttribute(
1300 IXMLDOMDocument2
*iface
,
1302 IXMLDOMAttribute
** attribute
)
1304 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1309 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1311 if (!attribute
|| !name
) return E_INVALIDARG
;
1313 V_VT(&type
) = VT_I1
;
1314 V_I1(&type
) = NODE_ATTRIBUTE
;
1316 hr
= IXMLDOMDocument2_createNode(iface
, type
, name
, NULL
, &node
);
1319 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1320 IXMLDOMNode_Release(node
);
1327 static HRESULT WINAPI
domdoc_createEntityReference(
1328 IXMLDOMDocument2
*iface
,
1330 IXMLDOMEntityReference
** entityref
)
1332 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1337 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1339 if (!entityref
) return E_INVALIDARG
;
1343 V_VT(&type
) = VT_I1
;
1344 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1346 hr
= IXMLDOMDocument2_createNode(iface
, type
, name
, NULL
, &node
);
1349 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1350 IXMLDOMNode_Release(node
);
1357 static HRESULT WINAPI
domdoc_getElementsByTagName(
1358 IXMLDOMDocument2
*iface
,
1360 IXMLDOMNodeList
** resultList
)
1362 static const WCHAR xpathformat
[] =
1363 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1364 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1367 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagName
), resultList
);
1369 if (tagName
[0] == '*' && tagName
[1] == 0)
1371 szPattern
= heap_alloc(sizeof(WCHAR
)*4);
1372 szPattern
[0] = szPattern
[1] = '/';
1378 szPattern
= heap_alloc(sizeof(WCHAR
)*(20+lstrlenW(tagName
)+1));
1379 wsprintfW(szPattern
, xpathformat
, tagName
);
1382 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), szPattern
, resultList
);
1383 heap_free(szPattern
);
1388 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1394 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1396 return E_INVALIDARG
;
1403 static HRESULT WINAPI
domdoc_createNode(
1404 IXMLDOMDocument2
*iface
,
1408 IXMLDOMNode
** node
)
1410 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1411 DOMNodeType node_type
;
1416 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1418 if(!node
) return E_INVALIDARG
;
1420 if(namespaceURI
&& namespaceURI
[0])
1421 FIXME("nodes with namespaces currently not supported.\n");
1423 hr
= get_node_type(Type
, &node_type
);
1424 if(FAILED(hr
)) return hr
;
1426 TRACE("node_type %d\n", node_type
);
1428 /* exit earlier for types that need name */
1432 case NODE_ATTRIBUTE
:
1433 case NODE_ENTITY_REFERENCE
:
1434 case NODE_PROCESSING_INSTRUCTION
:
1435 if (!name
|| *name
== 0) return E_FAIL
;
1440 xml_name
= xmlChar_from_wchar(name
);
1445 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, xml_name
, NULL
);
1447 case NODE_ATTRIBUTE
:
1448 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1451 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1453 case NODE_CDATA_SECTION
:
1454 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1456 case NODE_ENTITY_REFERENCE
:
1457 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1459 case NODE_PROCESSING_INSTRUCTION
:
1460 #ifdef HAVE_XMLNEWDOCPI
1461 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1463 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1468 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1470 case NODE_DOCUMENT_FRAGMENT
:
1471 xmlnode
= xmlNewDocFragment(get_doc(This
));
1473 /* unsupported types */
1475 case NODE_DOCUMENT_TYPE
:
1478 heap_free(xml_name
);
1479 return E_INVALIDARG
;
1481 FIXME("unhandled node type %d\n", node_type
);
1486 *node
= create_node(xmlnode
);
1487 heap_free(xml_name
);
1491 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1492 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1499 static HRESULT WINAPI
domdoc_nodeFromID(
1500 IXMLDOMDocument2
*iface
,
1502 IXMLDOMNode
** node
)
1504 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1505 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1509 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1514 xmldoc
= doparse( ptr
, len
, NULL
);
1516 xmldoc
->_private
= create_priv();
1517 return attach_xmldoc(&This
->node
, xmldoc
);
1523 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
1528 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
1533 detach_bsc(This
->bsc
);
1539 static HRESULT WINAPI
domdoc_load(
1540 IXMLDOMDocument2
*iface
,
1542 VARIANT_BOOL
* isSuccessful
)
1544 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1545 LPWSTR filename
= NULL
;
1546 HRESULT hr
= S_FALSE
;
1547 IXMLDOMDocument2
*pNewDoc
= NULL
;
1548 IStream
*pStream
= NULL
;
1551 TRACE("(%p)->type %d\n", This
, V_VT(&xmlSource
) );
1553 *isSuccessful
= VARIANT_FALSE
;
1555 assert( &This
->node
);
1557 switch( V_VT(&xmlSource
) )
1560 filename
= V_BSTR(&xmlSource
);
1563 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument2
, (void**)&pNewDoc
);
1568 domdoc
*newDoc
= impl_from_IXMLDOMDocument2( pNewDoc
);
1569 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
1570 hr
= attach_xmldoc(&This
->node
, xmldoc
);
1573 *isSuccessful
= VARIANT_TRUE
;
1578 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
1581 IPersistStream
*pDocStream
;
1582 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
1585 hr
= IPersistStream_Load(pDocStream
, pStream
);
1586 IStream_Release(pStream
);
1589 *isSuccessful
= VARIANT_TRUE
;
1591 TRACE("Using IStream to load Document\n");
1596 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
1601 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
1606 /* ISequentialStream */
1607 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
1611 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
1614 TRACE("filename (%s)\n", debugstr_w(filename
));
1618 hr
= doread( This
, filename
);
1621 This
->error
= E_FAIL
;
1624 hr
= This
->error
= S_OK
;
1625 *isSuccessful
= VARIANT_TRUE
;
1629 if(!filename
|| FAILED(hr
)) {
1630 xmldoc
= xmlNewDoc(NULL
);
1631 xmldoc
->_private
= create_priv();
1632 hr
= attach_xmldoc(&This
->node
, xmldoc
);
1637 TRACE("ret (%d)\n", hr
);
1643 static HRESULT WINAPI
domdoc_get_readyState(
1644 IXMLDOMDocument2
*iface
,
1647 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1648 FIXME("(%p)->(%p)\n", This
, value
);
1653 static HRESULT WINAPI
domdoc_get_parseError(
1654 IXMLDOMDocument2
*iface
,
1655 IXMLDOMParseError
** errorObj
)
1657 BSTR error_string
= NULL
;
1658 static const WCHAR err
[] = {'e','r','r','o','r',0};
1659 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1661 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
1664 error_string
= SysAllocString(err
);
1666 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
1667 if(!*errorObj
) return E_OUTOFMEMORY
;
1672 static HRESULT WINAPI
domdoc_get_url(
1673 IXMLDOMDocument2
*iface
,
1676 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1677 FIXME("(%p)->(%p)\n", This
, urlString
);
1682 static HRESULT WINAPI
domdoc_get_async(
1683 IXMLDOMDocument2
*iface
,
1684 VARIANT_BOOL
* isAsync
)
1686 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1688 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
1689 *isAsync
= This
->async
;
1694 static HRESULT WINAPI
domdoc_put_async(
1695 IXMLDOMDocument2
*iface
,
1696 VARIANT_BOOL isAsync
)
1698 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1700 TRACE("(%p)->(%d)\n", This
, isAsync
);
1701 This
->async
= isAsync
;
1706 static HRESULT WINAPI
domdoc_abort(
1707 IXMLDOMDocument2
*iface
)
1709 domdoc
*This
= impl_from_IXMLDOMDocument2(iface
);
1710 FIXME("%p\n", This
);
1715 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
1720 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, NULL
, 0, NULL
, NULL
);
1721 str
= heap_alloc( len
);
1724 WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, str
, len
, NULL
, NULL
);
1730 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1731 static HRESULT WINAPI
domdoc_loadXML(
1732 IXMLDOMDocument2
*iface
,
1734 VARIANT_BOOL
* isSuccessful
)
1736 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1737 xmlDocPtr xmldoc
= NULL
;
1740 HRESULT hr
= S_FALSE
, hr2
;
1742 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
1744 assert ( &This
->node
);
1748 *isSuccessful
= VARIANT_FALSE
;
1750 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
1752 xmldoc
= doparse( str
, len
, "UTF-8" );
1755 This
->error
= E_FAIL
;
1758 hr
= This
->error
= S_OK
;
1759 *isSuccessful
= VARIANT_TRUE
;
1764 xmldoc
= xmlNewDoc(NULL
);
1766 xmldoc
->_private
= create_priv();
1767 hr2
= attach_xmldoc( &This
->node
, xmldoc
);
1774 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
,
1779 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
1781 WARN("write error\n");
1788 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
1790 return CloseHandle(ctx
) ? 0 : -1;
1793 static HRESULT WINAPI
domdoc_save(
1794 IXMLDOMDocument2
*iface
,
1795 VARIANT destination
)
1797 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1803 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
1804 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
1806 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
1808 FIXME("Unhandled vt %d\n", V_VT(&destination
));
1812 if(V_VT(&destination
) == VT_UNKNOWN
)
1814 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
1815 IXMLDOMDocument2
*pDocument
;
1817 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument2
, (void**)&pDocument
);
1821 VARIANT_BOOL bSuccessful
;
1823 ret
= IXMLDOMDocument2_get_xml(iface
, &bXML
);
1826 ret
= IXMLDOMDocument2_loadXML(pDocument
, bXML
, &bSuccessful
);
1828 SysFreeString(bXML
);
1831 IXMLDOMDocument2_Release(pDocument
);
1834 TRACE("ret %d\n", ret
);
1839 handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
1840 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1841 if( handle
== INVALID_HANDLE_VALUE
)
1843 WARN("failed to create file\n");
1847 /* disable top XML declaration */
1848 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
1849 handle
, NULL
, XML_SAVE_NO_DECL
);
1852 CloseHandle(handle
);
1856 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
1857 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
1858 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
1860 /* will close file through close callback */
1866 static HRESULT WINAPI
domdoc_get_validateOnParse(
1867 IXMLDOMDocument2
*iface
,
1868 VARIANT_BOOL
* isValidating
)
1870 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1872 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
1873 *isValidating
= This
->validating
;
1878 static HRESULT WINAPI
domdoc_put_validateOnParse(
1879 IXMLDOMDocument2
*iface
,
1880 VARIANT_BOOL isValidating
)
1882 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1884 TRACE("(%p)->(%d)\n", This
, isValidating
);
1885 This
->validating
= isValidating
;
1890 static HRESULT WINAPI
domdoc_get_resolveExternals(
1891 IXMLDOMDocument2
*iface
,
1892 VARIANT_BOOL
* isResolving
)
1894 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1896 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
1897 *isResolving
= This
->resolving
;
1902 static HRESULT WINAPI
domdoc_put_resolveExternals(
1903 IXMLDOMDocument2
*iface
,
1904 VARIANT_BOOL isResolving
)
1906 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1908 TRACE("(%p)->(%d)\n", This
, isResolving
);
1909 This
->resolving
= isResolving
;
1914 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
1915 IXMLDOMDocument2
*iface
,
1916 VARIANT_BOOL
* isPreserving
)
1918 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1920 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->preserving
);
1921 *isPreserving
= This
->preserving
;
1926 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
1927 IXMLDOMDocument2
*iface
,
1928 VARIANT_BOOL isPreserving
)
1930 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1932 TRACE("(%p)->(%d)\n", This
, isPreserving
);
1933 This
->preserving
= isPreserving
;
1938 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
1939 IXMLDOMDocument2
*iface
,
1940 VARIANT readyStateChangeSink
)
1942 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1943 FIXME("%p\n", This
);
1948 static HRESULT WINAPI
domdoc_put_onDataAvailable(
1949 IXMLDOMDocument2
*iface
,
1950 VARIANT onDataAvailableSink
)
1952 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1953 FIXME("%p\n", This
);
1957 static HRESULT WINAPI
domdoc_put_onTransformNode(
1958 IXMLDOMDocument2
*iface
,
1959 VARIANT onTransformNodeSink
)
1961 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1962 FIXME("%p\n", This
);
1966 static HRESULT WINAPI
domdoc_get_namespaces(
1967 IXMLDOMDocument2
* iface
,
1968 IXMLDOMSchemaCollection
** schemaCollection
)
1970 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1971 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
1975 static HRESULT WINAPI
domdoc_get_schemas(
1976 IXMLDOMDocument2
* iface
,
1979 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1980 HRESULT hr
= S_FALSE
;
1981 IXMLDOMSchemaCollection
*cur_schema
= This
->schema
;
1983 TRACE("(%p)->(%p)\n", This
, var1
);
1985 VariantInit(var1
); /* Test shows we don't call VariantClear here */
1986 V_VT(var1
) = VT_NULL
;
1990 hr
= IXMLDOMSchemaCollection_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
1992 V_VT(var1
) = VT_DISPATCH
;
1997 static HRESULT WINAPI
domdoc_putref_schemas(
1998 IXMLDOMDocument2
* iface
,
2001 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
2002 HRESULT hr
= E_FAIL
;
2003 IXMLDOMSchemaCollection
*new_schema
= NULL
;
2005 FIXME("(%p): semi-stub\n", This
);
2009 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2013 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2022 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2027 IXMLDOMSchemaCollection
*old_schema
= InterlockedExchangePointer((void**)&This
->schema
, new_schema
);
2028 if(old_schema
) IXMLDOMSchemaCollection_Release(old_schema
);
2034 static HRESULT WINAPI
domdoc_validate(
2035 IXMLDOMDocument2
* iface
,
2036 IXMLDOMParseError
** err
)
2038 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
2039 FIXME("(%p)->(%p)\n", This
, err
);
2043 static HRESULT WINAPI
domdoc_setProperty(
2044 IXMLDOMDocument2
* iface
,
2048 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
2050 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2052 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
2058 V_VT(&varStr
) = VT_EMPTY
;
2059 if (V_VT(&var
) != VT_BSTR
)
2061 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2063 bstr
= V_BSTR(&varStr
);
2066 bstr
= V_BSTR(&var
);
2069 if (lstrcmpiW(bstr
, SZ_VALUE_XPATH
) == 0)
2070 This
->bUseXPath
= TRUE
;
2071 else if (lstrcmpiW(bstr
, SZ_VALUE_XSLPATTERN
) == 0)
2072 This
->bUseXPath
= FALSE
;
2076 VariantClear(&varStr
);
2079 else if (lstrcmpiW(p
, SZ_PROPERTY_PROHIBIT_DTD
) == 0)
2082 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var
));
2086 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2090 static HRESULT WINAPI
domdoc_getProperty(
2091 IXMLDOMDocument2
* iface
,
2095 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
2097 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2100 return E_INVALIDARG
;
2101 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
2103 V_VT(var
) = VT_BSTR
;
2104 if (This
->bUseXPath
)
2105 V_BSTR(var
) = SysAllocString(SZ_VALUE_XPATH
);
2107 V_BSTR(var
) = SysAllocString(SZ_VALUE_XSLPATTERN
);
2111 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2115 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl
=
2117 domdoc_QueryInterface
,
2120 domdoc_GetTypeInfoCount
,
2122 domdoc_GetIDsOfNames
,
2124 domdoc_get_nodeName
,
2125 domdoc_get_nodeValue
,
2126 domdoc_put_nodeValue
,
2127 domdoc_get_nodeType
,
2128 domdoc_get_parentNode
,
2129 domdoc_get_childNodes
,
2130 domdoc_get_firstChild
,
2131 domdoc_get_lastChild
,
2132 domdoc_get_previousSibling
,
2133 domdoc_get_nextSibling
,
2134 domdoc_get_attributes
,
2135 domdoc_insertBefore
,
2136 domdoc_replaceChild
,
2139 domdoc_hasChildNodes
,
2140 domdoc_get_ownerDocument
,
2142 domdoc_get_nodeTypeString
,
2145 domdoc_get_specified
,
2146 domdoc_get_definition
,
2147 domdoc_get_nodeTypedValue
,
2148 domdoc_put_nodeTypedValue
,
2149 domdoc_get_dataType
,
2150 domdoc_put_dataType
,
2152 domdoc_transformNode
,
2154 domdoc_selectSingleNode
,
2156 domdoc_get_namespaceURI
,
2158 domdoc_get_baseName
,
2159 domdoc_transformNodeToObject
,
2161 domdoc_get_implementation
,
2162 domdoc_get_documentElement
,
2163 domdoc_put_documentElement
,
2164 domdoc_createElement
,
2165 domdoc_createDocumentFragment
,
2166 domdoc_createTextNode
,
2167 domdoc_createComment
,
2168 domdoc_createCDATASection
,
2169 domdoc_createProcessingInstruction
,
2170 domdoc_createAttribute
,
2171 domdoc_createEntityReference
,
2172 domdoc_getElementsByTagName
,
2176 domdoc_get_readyState
,
2177 domdoc_get_parseError
,
2184 domdoc_get_validateOnParse
,
2185 domdoc_put_validateOnParse
,
2186 domdoc_get_resolveExternals
,
2187 domdoc_put_resolveExternals
,
2188 domdoc_get_preserveWhiteSpace
,
2189 domdoc_put_preserveWhiteSpace
,
2190 domdoc_put_onReadyStateChange
,
2191 domdoc_put_onDataAvailable
,
2192 domdoc_put_onTransformNode
,
2193 domdoc_get_namespaces
,
2195 domdoc_putref_schemas
,
2201 /* xmldoc implementation of IObjectWithSite */
2202 static HRESULT WINAPI
2203 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
2205 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2206 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppvObject
);
2210 xmldoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
2212 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2213 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2217 xmldoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
2219 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2220 return IXMLDocument_Release((IXMLDocument
*)This
);
2223 static HRESULT WINAPI
2224 xmldoc_GetSite( IObjectWithSite
*iface
, REFIID iid
, void ** ppvSite
)
2226 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2228 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
2233 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
2236 static HRESULT WINAPI
2237 xmldoc_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
2239 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2241 TRACE("(%p)->(%p)\n", iface
, punk
);
2247 IUnknown_Release( This
->site
);
2254 IUnknown_AddRef( punk
);
2257 IUnknown_Release( This
->site
);
2264 static const IObjectWithSiteVtbl domdocObjectSite
=
2266 xmldoc_ObjectWithSite_QueryInterface
,
2267 xmldoc_ObjectWithSite_AddRef
,
2268 xmldoc_ObjectWithSite_Release
,
2273 static HRESULT WINAPI
xmldoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
2275 domdoc
*This
= impl_from_IObjectSafety(iface
);
2276 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppv
);
2279 static ULONG WINAPI
xmldoc_Safety_AddRef(IObjectSafety
*iface
)
2281 domdoc
*This
= impl_from_IObjectSafety(iface
);
2282 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2285 static ULONG WINAPI
xmldoc_Safety_Release(IObjectSafety
*iface
)
2287 domdoc
*This
= impl_from_IObjectSafety(iface
);
2288 return IXMLDocument_Release((IXMLDocument
*)This
);
2291 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2293 static HRESULT WINAPI
xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2294 DWORD
*pdwSupportedOptions
, DWORD
*pdwEnabledOptions
)
2296 domdoc
*This
= impl_from_IObjectSafety(iface
);
2298 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), pdwSupportedOptions
, pdwEnabledOptions
);
2300 if(!pdwSupportedOptions
|| !pdwEnabledOptions
)
2303 *pdwSupportedOptions
= SAFETY_SUPPORTED_OPTIONS
;
2304 *pdwEnabledOptions
= This
->safeopt
;
2309 static HRESULT WINAPI
xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2310 DWORD dwOptionSetMask
, DWORD dwEnabledOptions
)
2312 domdoc
*This
= impl_from_IObjectSafety(iface
);
2313 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), dwOptionSetMask
, dwEnabledOptions
);
2315 if ((dwOptionSetMask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
2318 This
->safeopt
= dwEnabledOptions
& dwOptionSetMask
& SAFETY_SUPPORTED_OPTIONS
;
2322 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
2323 xmldoc_Safety_QueryInterface
,
2324 xmldoc_Safety_AddRef
,
2325 xmldoc_Safety_Release
,
2326 xmldoc_Safety_GetInterfaceSafetyOptions
,
2327 xmldoc_Safety_SetInterfaceSafetyOptions
2331 static const tid_t domdoc_iface_tids
[] = {
2333 IXMLDOMDocument_tid
,
2334 IXMLDOMDocument2_tid
,
2337 static dispex_static_data_t domdoc_dispex
= {
2339 IXMLDOMDocument2_tid
,
2344 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument2
**document
)
2348 doc
= heap_alloc( sizeof (*doc
) );
2350 return E_OUTOFMEMORY
;
2352 doc
->lpVtbl
= &domdoc_vtbl
;
2353 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
2354 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
2355 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
2356 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
2358 doc
->async
= VARIANT_TRUE
;
2359 doc
->validating
= 0;
2361 doc
->preserving
= 0;
2362 doc
->bUseXPath
= FALSE
;
2370 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IUnknown
*)&doc
->lpVtbl
, &domdoc_dispex
);
2372 *document
= (IXMLDOMDocument2
*)&doc
->lpVtbl
;
2374 TRACE("returning iface %p\n", *document
);
2378 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2383 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
2385 xmldoc
= xmlNewDoc(NULL
);
2387 return E_OUTOFMEMORY
;
2389 xmldoc
->_private
= create_priv();
2391 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument2
**)ppObj
);
2398 IUnknown
* create_domdoc( xmlNodePtr document
)
2403 TRACE("(%p)\n", document
);
2405 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument2
**)&pObj
);
2414 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2416 MESSAGE("This program tried to use a DOMDocument object, but\n"
2417 "libxml2 support was not present at compile time.\n");