2 * XPath query result node list implementation (TODO: XSLPattern support)
4 * Copyright 2005 Mike McCormack
5 * Copyright 2007 Mikolaj Zalewski
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "msxml_private.h"
35 #include "wine/debug.h"
37 /* This file implements the object returned by a XPath query. Note that this is
38 * not the IXMLDOMNodeList returned by childNodes - it's implemented in nodelist.c.
39 * They are different because the list returned by XPath queries:
40 * - is static - gives the results for the XML tree as it existed during the
41 * execution of the query
42 * - supports IXMLDOMSelection (TODO)
44 * TODO: XSLPattern support
47 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
51 #include <libxml/xpath.h>
53 static const struct IXMLDOMNodeListVtbl queryresult_vtbl
;
55 typedef struct _queryresult
57 const struct IXMLDOMNodeListVtbl
*lpVtbl
;
60 xmlXPathObjectPtr result
;
64 static inline queryresult
*impl_from_IXMLDOMNodeList( IXMLDOMNodeList
*iface
)
66 return (queryresult
*)((char*)iface
- FIELD_OFFSET(queryresult
, lpVtbl
));
69 HRESULT
queryresult_create(xmlNodePtr node
, LPWSTR szQuery
, IXMLDOMNodeList
**out
)
71 queryresult
*This
= CoTaskMemAlloc(sizeof(queryresult
));
72 xmlXPathContextPtr ctxt
= xmlXPathNewContext(node
->doc
);
73 xmlChar
*str
= xmlChar_from_wchar(szQuery
);
77 TRACE("(%p, %s, %p)\n", node
, wine_dbgstr_w(szQuery
), out
);
80 if (This
== NULL
|| ctxt
== NULL
|| str
== NULL
)
86 This
->lpVtbl
= &queryresult_vtbl
;
90 xmldoc_add_ref(This
->node
->doc
);
93 This
->result
= xmlXPathEval(str
, ctxt
);
94 if (!This
->result
|| This
->result
->type
!= XPATH_NODESET
)
100 *out
= (IXMLDOMNodeList
*)This
;
102 TRACE("found %d matches\n", This
->result
->nodesetval
->nodeNr
);
105 if (This
!= NULL
&& FAILED(hr
))
106 IXMLDOMNodeList_Release( (IXMLDOMNodeList
*) &This
->lpVtbl
);
108 xmlXPathFreeContext(ctxt
);
109 HeapFree(GetProcessHeap(), 0, str
);
114 static HRESULT WINAPI
queryresult_QueryInterface(
115 IXMLDOMNodeList
*iface
,
119 TRACE("%p %s %p\n", iface
, debugstr_guid(riid
), ppvObject
);
121 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
122 IsEqualGUID( riid
, &IID_IDispatch
) ||
123 IsEqualGUID( riid
, &IID_IXMLDOMNodeList
) )
129 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
131 return E_NOINTERFACE
;
134 IXMLDOMNodeList_AddRef( iface
);
139 static ULONG WINAPI
queryresult_AddRef(
140 IXMLDOMNodeList
*iface
)
142 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
143 return InterlockedIncrement( &This
->ref
);
146 static ULONG WINAPI
queryresult_Release(
147 IXMLDOMNodeList
*iface
)
149 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
152 ref
= InterlockedDecrement(&This
->ref
);
155 xmlXPathFreeObject(This
->result
);
156 xmldoc_release(This
->node
->doc
);
163 static HRESULT WINAPI
queryresult_GetTypeInfoCount(
164 IXMLDOMNodeList
*iface
,
167 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
169 TRACE("(%p)->(%p)\n", This
, pctinfo
);
176 static HRESULT WINAPI
queryresult_GetTypeInfo(
177 IXMLDOMNodeList
*iface
,
180 ITypeInfo
** ppTInfo
)
182 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
185 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
187 hr
= get_typeinfo(IXMLDOMNodeList_tid
, ppTInfo
);
192 static HRESULT WINAPI
queryresult_GetIDsOfNames(
193 IXMLDOMNodeList
*iface
,
200 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
204 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
207 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
210 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
213 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
214 ITypeInfo_Release(typeinfo
);
220 static HRESULT WINAPI
queryresult_Invoke(
221 IXMLDOMNodeList
*iface
,
226 DISPPARAMS
* pDispParams
,
228 EXCEPINFO
* pExcepInfo
,
231 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
235 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
236 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
238 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
241 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
242 pVarResult
, pExcepInfo
, puArgErr
);
243 ITypeInfo_Release(typeinfo
);
249 static HRESULT WINAPI
queryresult_get_item(
250 IXMLDOMNodeList
* iface
,
252 IXMLDOMNode
** listItem
)
254 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
256 TRACE("%p %ld\n", This
, index
);
260 if (index
< 0 || index
>= This
->result
->nodesetval
->nodeNr
)
263 *listItem
= create_node(This
->result
->nodesetval
->nodeTab
[index
]);
264 This
->resultPos
= index
+ 1;
269 static HRESULT WINAPI
queryresult_get_length(
270 IXMLDOMNodeList
* iface
,
273 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
277 *listLength
= This
->result
->nodesetval
->nodeNr
;
281 static HRESULT WINAPI
queryresult_nextNode(
282 IXMLDOMNodeList
* iface
,
283 IXMLDOMNode
** nextItem
)
285 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
287 TRACE("%p %p\n", This
, nextItem
);
291 if (This
->resultPos
>= This
->result
->nodesetval
->nodeNr
)
294 *nextItem
= create_node(This
->result
->nodesetval
->nodeTab
[This
->resultPos
]);
299 static HRESULT WINAPI
queryresult_reset(
300 IXMLDOMNodeList
* iface
)
302 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
309 static HRESULT WINAPI
queryresult__newEnum(
310 IXMLDOMNodeList
* iface
,
318 static const struct IXMLDOMNodeListVtbl queryresult_vtbl
=
320 queryresult_QueryInterface
,
323 queryresult_GetTypeInfoCount
,
324 queryresult_GetTypeInfo
,
325 queryresult_GetIDsOfNames
,
327 queryresult_get_item
,
328 queryresult_get_length
,
329 queryresult_nextNode
,
331 queryresult__newEnum
,