msxml3: Move document loading from stream to a separate function.
[wine] / dlls / msxml3 / pi.c
1 /*
2  *    DOM processing instruction node implementation
3  *
4  * Copyright 2006 Huw Davies
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "ole2.h"
35 #include "msxml6.h"
36
37 #include "msxml_private.h"
38
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42
43 #ifdef HAVE_LIBXML2
44
45 typedef struct _dom_pi
46 {
47     xmlnode node;
48     IXMLDOMProcessingInstruction IXMLDOMProcessingInstruction_iface;
49     LONG ref;
50 } dom_pi;
51
52 static const struct nodemap_funcs dom_pi_attr_map;
53
54 static const tid_t dompi_se_tids[] = {
55     IXMLDOMNode_tid,
56     IXMLDOMProcessingInstruction_tid,
57     0
58 };
59
60 static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingInstruction *iface )
61 {
62     return CONTAINING_RECORD(iface, dom_pi, IXMLDOMProcessingInstruction_iface);
63 }
64
65 static HRESULT WINAPI dom_pi_QueryInterface(
66     IXMLDOMProcessingInstruction *iface,
67     REFIID riid,
68     void** ppvObject )
69 {
70     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
71     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
72
73     if ( IsEqualGUID( riid, &IID_IXMLDOMProcessingInstruction ) ||
74          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
75          IsEqualGUID( riid, &IID_IDispatch ) ||
76          IsEqualGUID( riid, &IID_IUnknown ) )
77     {
78         *ppvObject = iface;
79     }
80     else if(node_query_interface(&This->node, riid, ppvObject))
81     {
82         return *ppvObject ? S_OK : E_NOINTERFACE;
83     }
84     else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
85     {
86         return node_create_supporterrorinfo(dompi_se_tids, ppvObject);
87     }
88     else
89     {
90         TRACE("Unsupported interface %s\n", debugstr_guid(riid));
91         *ppvObject = NULL;
92         return E_NOINTERFACE;
93     }
94
95     IUnknown_AddRef((IUnknown*)*ppvObject);
96     return S_OK;
97 }
98
99 static ULONG WINAPI dom_pi_AddRef(
100     IXMLDOMProcessingInstruction *iface )
101 {
102     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
103     ULONG ref = InterlockedIncrement( &This->ref );
104     TRACE("(%p)->(%d)\n", This, ref);
105     return ref;
106 }
107
108 static ULONG WINAPI dom_pi_Release(
109     IXMLDOMProcessingInstruction *iface )
110 {
111     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
112     ULONG ref = InterlockedDecrement( &This->ref );
113
114     TRACE("(%p)->(%d)\n", This, ref);
115     if ( ref == 0 )
116     {
117         destroy_xmlnode(&This->node);
118         heap_free( This );
119     }
120
121     return ref;
122 }
123
124 static HRESULT WINAPI dom_pi_GetTypeInfoCount(
125     IXMLDOMProcessingInstruction *iface,
126     UINT* pctinfo )
127 {
128     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
129     return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
130 }
131
132 static HRESULT WINAPI dom_pi_GetTypeInfo(
133     IXMLDOMProcessingInstruction *iface,
134     UINT iTInfo, LCID lcid,
135     ITypeInfo** ppTInfo )
136 {
137     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
138     return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface,
139         iTInfo, lcid, ppTInfo);
140 }
141
142 static HRESULT WINAPI dom_pi_GetIDsOfNames(
143     IXMLDOMProcessingInstruction *iface,
144     REFIID riid, LPOLESTR* rgszNames,
145     UINT cNames, LCID lcid, DISPID* rgDispId )
146 {
147     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
148     return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface,
149         riid, rgszNames, cNames, lcid, rgDispId);
150 }
151
152 static HRESULT WINAPI dom_pi_Invoke(
153     IXMLDOMProcessingInstruction *iface,
154     DISPID dispIdMember, REFIID riid, LCID lcid,
155     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
156     EXCEPINFO* pExcepInfo, UINT* puArgErr )
157 {
158     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
159     return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface,
160         dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
161 }
162
163 static HRESULT WINAPI dom_pi_get_nodeName(
164     IXMLDOMProcessingInstruction *iface,
165     BSTR* p )
166 {
167     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
168
169     TRACE("(%p)->(%p)\n", This, p);
170
171     return node_get_nodeName(&This->node, p);
172 }
173
174 static HRESULT WINAPI dom_pi_get_nodeValue(
175     IXMLDOMProcessingInstruction *iface,
176     VARIANT* value)
177 {
178     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
179
180     TRACE("(%p)->(%p)\n", This, value);
181
182     return node_get_content(&This->node, value);
183 }
184
185 static HRESULT WINAPI dom_pi_put_nodeValue(
186     IXMLDOMProcessingInstruction *iface,
187     VARIANT value)
188 {
189     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
190     BSTR target;
191     HRESULT hr;
192
193     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
194
195     /* Cannot set data to a PI node whose target is 'xml' */
196     hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
197     if(hr == S_OK)
198     {
199         static const WCHAR xmlW[] = {'x','m','l',0};
200         if(!strcmpW(target, xmlW))
201         {
202             SysFreeString(target);
203             return E_FAIL;
204         }
205
206         SysFreeString(target);
207     }
208
209     return node_put_value(&This->node, &value);
210 }
211
212 static HRESULT WINAPI dom_pi_get_nodeType(
213     IXMLDOMProcessingInstruction *iface,
214     DOMNodeType* domNodeType )
215 {
216     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
217
218     TRACE("(%p)->(%p)\n", This, domNodeType);
219
220     *domNodeType = NODE_PROCESSING_INSTRUCTION;
221     return S_OK;
222 }
223
224 static HRESULT WINAPI dom_pi_get_parentNode(
225     IXMLDOMProcessingInstruction *iface,
226     IXMLDOMNode** parent )
227 {
228     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
229
230     TRACE("(%p)->(%p)\n", This, parent);
231
232     return node_get_parent(&This->node, parent);
233 }
234
235 static HRESULT WINAPI dom_pi_get_childNodes(
236     IXMLDOMProcessingInstruction *iface,
237     IXMLDOMNodeList** outList)
238 {
239     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
240
241     TRACE("(%p)->(%p)\n", This, outList);
242
243     return node_get_child_nodes(&This->node, outList);
244 }
245
246 static HRESULT WINAPI dom_pi_get_firstChild(
247     IXMLDOMProcessingInstruction *iface,
248     IXMLDOMNode** domNode)
249 {
250     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
251
252     TRACE("(%p)->(%p)\n", This, domNode);
253
254     return return_null_node(domNode);
255 }
256
257 static HRESULT WINAPI dom_pi_get_lastChild(
258     IXMLDOMProcessingInstruction *iface,
259     IXMLDOMNode** domNode)
260 {
261     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
262
263     TRACE("(%p)->(%p)\n", This, domNode);
264
265     return return_null_node(domNode);
266 }
267
268 static HRESULT WINAPI dom_pi_get_previousSibling(
269     IXMLDOMProcessingInstruction *iface,
270     IXMLDOMNode** domNode)
271 {
272     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
273
274     TRACE("(%p)->(%p)\n", This, domNode);
275
276     return node_get_previous_sibling(&This->node, domNode);
277 }
278
279 static HRESULT WINAPI dom_pi_get_nextSibling(
280     IXMLDOMProcessingInstruction *iface,
281     IXMLDOMNode** domNode)
282 {
283     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
284
285     TRACE("(%p)->(%p)\n", This, domNode);
286
287     return node_get_next_sibling(&This->node, domNode);
288 }
289
290 static HRESULT WINAPI dom_pi_get_attributes(
291     IXMLDOMProcessingInstruction *iface,
292     IXMLDOMNamedNodeMap** map)
293 {
294     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
295     static const WCHAR xmlW[] = {'x','m','l',0};
296     HRESULT hr;
297     BSTR name;
298
299     TRACE("(%p)->(%p)\n", This, map);
300
301     if (!map) return E_INVALIDARG;
302
303     *map = NULL;
304
305     hr = node_get_nodeName(&This->node, &name);
306     if (hr != S_OK) return hr;
307
308     if (!strcmpW(name, xmlW))
309     {
310         FIXME("created dummy map for <?xml ?>\n");
311         *map = create_nodemap(This->node.node, &dom_pi_attr_map);
312         SysFreeString(name);
313         return S_OK;
314     }
315
316     SysFreeString(name);
317
318     return S_FALSE;
319 }
320
321 static HRESULT WINAPI dom_pi_insertBefore(
322     IXMLDOMProcessingInstruction *iface,
323     IXMLDOMNode* newNode, VARIANT refChild,
324     IXMLDOMNode** outOldNode)
325 {
326     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
327
328     FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
329
330     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
331 }
332
333 static HRESULT WINAPI dom_pi_replaceChild(
334     IXMLDOMProcessingInstruction *iface,
335     IXMLDOMNode* newNode,
336     IXMLDOMNode* oldNode,
337     IXMLDOMNode** outOldNode)
338 {
339     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
340
341     FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode);
342
343     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
344 }
345
346 static HRESULT WINAPI dom_pi_removeChild(
347     IXMLDOMProcessingInstruction *iface,
348     IXMLDOMNode *child, IXMLDOMNode **oldChild)
349 {
350     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
351     TRACE("(%p)->(%p %p)\n", This, child, oldChild);
352     return node_remove_child(&This->node, child, oldChild);
353 }
354
355 static HRESULT WINAPI dom_pi_appendChild(
356     IXMLDOMProcessingInstruction *iface,
357     IXMLDOMNode *child, IXMLDOMNode **outChild)
358 {
359     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
360     TRACE("(%p)->(%p %p)\n", This, child, outChild);
361     return node_append_child(&This->node, child, outChild);
362 }
363
364 static HRESULT WINAPI dom_pi_hasChildNodes(
365     IXMLDOMProcessingInstruction *iface,
366     VARIANT_BOOL *ret)
367 {
368     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
369     TRACE("(%p)->(%p)\n", This, ret);
370     return node_has_childnodes(&This->node, ret);
371 }
372
373 static HRESULT WINAPI dom_pi_get_ownerDocument(
374     IXMLDOMProcessingInstruction *iface,
375     IXMLDOMDocument **doc)
376 {
377     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
378     TRACE("(%p)->(%p)\n", This, doc);
379     return node_get_owner_doc(&This->node, doc);
380 }
381
382 static HRESULT WINAPI dom_pi_cloneNode(
383     IXMLDOMProcessingInstruction *iface,
384     VARIANT_BOOL deep, IXMLDOMNode** outNode)
385 {
386     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
387     TRACE("(%p)->(%d %p)\n", This, deep, outNode);
388     return node_clone( &This->node, deep, outNode );
389 }
390
391 static HRESULT WINAPI dom_pi_get_nodeTypeString(
392     IXMLDOMProcessingInstruction *iface,
393     BSTR* p)
394 {
395     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
396     static const WCHAR processinginstructionW[] =
397         {'p','r','o','c','e','s','s','i','n','g','i','n','s','t','r','u','c','t','i','o','n',0};
398
399     TRACE("(%p)->(%p)\n", This, p);
400
401     return return_bstr(processinginstructionW, p);
402 }
403
404 static HRESULT WINAPI dom_pi_get_text(
405     IXMLDOMProcessingInstruction *iface,
406     BSTR* p)
407 {
408     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
409     TRACE("(%p)->(%p)\n", This, p);
410     return node_get_text(&This->node, p);
411 }
412
413 static HRESULT WINAPI dom_pi_put_text(
414     IXMLDOMProcessingInstruction *iface,
415     BSTR p)
416 {
417     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
418     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
419     return node_put_text( &This->node, p );
420 }
421
422 static HRESULT WINAPI dom_pi_get_specified(
423     IXMLDOMProcessingInstruction *iface,
424     VARIANT_BOOL* isSpecified)
425 {
426     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
427     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
428     *isSpecified = VARIANT_TRUE;
429     return S_OK;
430 }
431
432 static HRESULT WINAPI dom_pi_get_definition(
433     IXMLDOMProcessingInstruction *iface,
434     IXMLDOMNode** definitionNode)
435 {
436     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
437     FIXME("(%p)->(%p)\n", This, definitionNode);
438     return E_NOTIMPL;
439 }
440
441 static HRESULT WINAPI dom_pi_get_nodeTypedValue(
442     IXMLDOMProcessingInstruction *iface,
443     VARIANT* v)
444 {
445     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
446     TRACE("(%p)->(%p)\n", This, v);
447     return node_get_content(&This->node, v);
448 }
449
450 static HRESULT WINAPI dom_pi_put_nodeTypedValue(
451     IXMLDOMProcessingInstruction *iface,
452     VARIANT typedValue)
453 {
454     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
455     FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
456     return E_NOTIMPL;
457 }
458
459 static HRESULT WINAPI dom_pi_get_dataType(
460     IXMLDOMProcessingInstruction *iface,
461     VARIANT* typename)
462 {
463     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
464     TRACE("(%p)->(%p)\n", This, typename);
465     return return_null_var( typename );
466 }
467
468 static HRESULT WINAPI dom_pi_put_dataType(
469     IXMLDOMProcessingInstruction *iface,
470     BSTR p)
471 {
472     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
473
474     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
475
476     if(!p)
477         return E_INVALIDARG;
478
479     return E_FAIL;
480 }
481
482 static HRESULT WINAPI dom_pi_get_xml(
483     IXMLDOMProcessingInstruction *iface,
484     BSTR* p)
485 {
486     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
487
488     TRACE("(%p)->(%p)\n", This, p);
489
490     return node_get_xml(&This->node, FALSE, p);
491 }
492
493 static HRESULT WINAPI dom_pi_transformNode(
494     IXMLDOMProcessingInstruction *iface,
495     IXMLDOMNode *node, BSTR *p)
496 {
497     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
498     TRACE("(%p)->(%p %p)\n", This, node, p);
499     return node_transform_node(&This->node, node, p);
500 }
501
502 static HRESULT WINAPI dom_pi_selectNodes(
503     IXMLDOMProcessingInstruction *iface,
504     BSTR p, IXMLDOMNodeList** outList)
505 {
506     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
507     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
508     return node_select_nodes(&This->node, p, outList);
509 }
510
511 static HRESULT WINAPI dom_pi_selectSingleNode(
512     IXMLDOMProcessingInstruction *iface,
513     BSTR p, IXMLDOMNode** outNode)
514 {
515     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
516     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
517     return node_select_singlenode(&This->node, p, outNode);
518 }
519
520 static HRESULT WINAPI dom_pi_get_parsed(
521     IXMLDOMProcessingInstruction *iface,
522     VARIANT_BOOL* isParsed)
523 {
524     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
525     FIXME("(%p)->(%p) stub!\n", This, isParsed);
526     *isParsed = VARIANT_TRUE;
527     return S_OK;
528 }
529
530 static HRESULT WINAPI dom_pi_get_namespaceURI(
531     IXMLDOMProcessingInstruction *iface,
532     BSTR* p)
533 {
534     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
535     TRACE("(%p)->(%p)\n", This, p);
536     return node_get_namespaceURI(&This->node, p);
537 }
538
539 static HRESULT WINAPI dom_pi_get_prefix(
540     IXMLDOMProcessingInstruction *iface,
541     BSTR* prefix)
542 {
543     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
544     TRACE("(%p)->(%p)\n", This, prefix);
545     return return_null_bstr( prefix );
546 }
547
548 static HRESULT WINAPI dom_pi_get_baseName(
549     IXMLDOMProcessingInstruction *iface,
550     BSTR* name)
551 {
552     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
553     TRACE("(%p)->(%p)\n", This, name);
554     return node_get_base_name( &This->node, name );
555 }
556
557 static HRESULT WINAPI dom_pi_transformNodeToObject(
558     IXMLDOMProcessingInstruction *iface,
559     IXMLDOMNode* domNode, VARIANT var1)
560 {
561     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
562     FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
563     return E_NOTIMPL;
564 }
565
566 static HRESULT WINAPI dom_pi_get_target(
567     IXMLDOMProcessingInstruction *iface,
568     BSTR *p)
569 {
570     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
571
572     TRACE("(%p)->(%p)\n", This, p);
573
574     /* target returns the same value as nodeName property */
575     return node_get_nodeName(&This->node, p);
576 }
577
578 static HRESULT WINAPI dom_pi_get_data(
579     IXMLDOMProcessingInstruction *iface,
580     BSTR *p)
581 {
582     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
583     HRESULT hr;
584     VARIANT ret;
585
586     TRACE("(%p)->(%p)\n", This, p);
587
588     if(!p)
589         return E_INVALIDARG;
590
591     hr = IXMLDOMProcessingInstruction_get_nodeValue( iface, &ret );
592     if(hr == S_OK)
593     {
594         *p = V_BSTR(&ret);
595     }
596
597     return hr;
598 }
599
600 static HRESULT WINAPI dom_pi_put_data(
601     IXMLDOMProcessingInstruction *iface,
602     BSTR data)
603 {
604     dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
605     BSTR target;
606     HRESULT hr;
607
608     TRACE("(%p)->(%s)\n", This, debugstr_w(data) );
609
610     /* cannot set data to a PI node whose target is 'xml' */
611     hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
612     if(hr == S_OK)
613     {
614         static const WCHAR xmlW[] = {'x','m','l',0};
615         if(!strcmpW(target, xmlW))
616         {
617             SysFreeString(target);
618             return E_FAIL;
619         }
620
621         SysFreeString(target);
622     }
623
624     return node_set_content(&This->node, data);
625 }
626
627 static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl =
628 {
629     dom_pi_QueryInterface,
630     dom_pi_AddRef,
631     dom_pi_Release,
632     dom_pi_GetTypeInfoCount,
633     dom_pi_GetTypeInfo,
634     dom_pi_GetIDsOfNames,
635     dom_pi_Invoke,
636     dom_pi_get_nodeName,
637     dom_pi_get_nodeValue,
638     dom_pi_put_nodeValue,
639     dom_pi_get_nodeType,
640     dom_pi_get_parentNode,
641     dom_pi_get_childNodes,
642     dom_pi_get_firstChild,
643     dom_pi_get_lastChild,
644     dom_pi_get_previousSibling,
645     dom_pi_get_nextSibling,
646     dom_pi_get_attributes,
647     dom_pi_insertBefore,
648     dom_pi_replaceChild,
649     dom_pi_removeChild,
650     dom_pi_appendChild,
651     dom_pi_hasChildNodes,
652     dom_pi_get_ownerDocument,
653     dom_pi_cloneNode,
654     dom_pi_get_nodeTypeString,
655     dom_pi_get_text,
656     dom_pi_put_text,
657     dom_pi_get_specified,
658     dom_pi_get_definition,
659     dom_pi_get_nodeTypedValue,
660     dom_pi_put_nodeTypedValue,
661     dom_pi_get_dataType,
662     dom_pi_put_dataType,
663     dom_pi_get_xml,
664     dom_pi_transformNode,
665     dom_pi_selectNodes,
666     dom_pi_selectSingleNode,
667     dom_pi_get_parsed,
668     dom_pi_get_namespaceURI,
669     dom_pi_get_prefix,
670     dom_pi_get_baseName,
671     dom_pi_transformNodeToObject,
672
673     dom_pi_get_target,
674     dom_pi_get_data,
675     dom_pi_put_data
676 };
677
678 static HRESULT dom_pi_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
679     IXMLDOMNode **item)
680 {
681     FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
682     return E_NOTIMPL;
683 }
684
685 static HRESULT dom_pi_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
686 {
687     FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item );
688     return E_NOTIMPL;
689 }
690
691 static HRESULT dom_pi_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
692 {
693     FIXME("(%p)->(%p %p): stub\n", node, newItem, namedItem );
694     return E_NOTIMPL;
695 }
696
697 static HRESULT dom_pi_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
698 {
699     FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
700     return E_NOTIMPL;
701 }
702
703 static HRESULT dom_pi_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
704 {
705     FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item);
706     return E_NOTIMPL;
707 }
708
709 static HRESULT dom_pi_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
710 {
711     FIXME("(%p)->(%d %p): stub\n", node, index, item);
712     return E_NOTIMPL;
713 }
714
715 static HRESULT dom_pi_get_length(const xmlNodePtr node, LONG *length)
716 {
717     FIXME("(%p)->(%p): stub\n", node, length);
718
719     *length = 0;
720     return S_OK;
721 }
722
723 static HRESULT dom_pi_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
724 {
725     FIXME("(%p)->(%d %p): stub\n", node, *iter, nextNode);
726     return E_NOTIMPL;
727 }
728
729 static const struct nodemap_funcs dom_pi_attr_map = {
730     dom_pi_get_named_item,
731     dom_pi_set_named_item,
732     dom_pi_remove_named_item,
733     dom_pi_get_item,
734     dom_pi_get_length,
735     dom_pi_get_qualified_item,
736     dom_pi_remove_qualified_item,
737     dom_pi_next_node
738 };
739
740 static const tid_t dompi_iface_tids[] = {
741     IXMLDOMProcessingInstruction_tid,
742     0
743 };
744
745 static dispex_static_data_t dompi_dispex = {
746     NULL,
747     IXMLDOMProcessingInstruction_tid,
748     NULL,
749     dompi_iface_tids
750 };
751
752 IUnknown* create_pi( xmlNodePtr pi )
753 {
754     dom_pi *This;
755
756     This = heap_alloc( sizeof *This );
757     if ( !This )
758         return NULL;
759
760     This->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl;
761     This->ref = 1;
762
763     init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, &dompi_dispex);
764
765     return (IUnknown*)&This->IXMLDOMProcessingInstruction_iface;
766 }
767
768 #endif