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", xmlXPathNodeSetGetLength(This
->result
->nodesetval
));
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
);
124 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
125 IsEqualGUID( riid
, &IID_IDispatch
) ||
126 IsEqualGUID( riid
, &IID_IXMLDOMNodeList
) )
132 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
134 return E_NOINTERFACE
;
137 IXMLDOMNodeList_AddRef( iface
);
142 static ULONG WINAPI
queryresult_AddRef(
143 IXMLDOMNodeList
*iface
)
145 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
146 return InterlockedIncrement( &This
->ref
);
149 static ULONG WINAPI
queryresult_Release(
150 IXMLDOMNodeList
*iface
)
152 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
155 ref
= InterlockedDecrement(&This
->ref
);
158 xmlXPathFreeObject(This
->result
);
159 xmldoc_release(This
->node
->doc
);
166 static HRESULT WINAPI
queryresult_GetTypeInfoCount(
167 IXMLDOMNodeList
*iface
,
170 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
172 TRACE("(%p)->(%p)\n", This
, pctinfo
);
179 static HRESULT WINAPI
queryresult_GetTypeInfo(
180 IXMLDOMNodeList
*iface
,
183 ITypeInfo
** ppTInfo
)
185 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
188 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
190 hr
= get_typeinfo(IXMLDOMNodeList_tid
, ppTInfo
);
195 static HRESULT WINAPI
queryresult_GetIDsOfNames(
196 IXMLDOMNodeList
*iface
,
203 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
207 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
210 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
213 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
216 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
217 ITypeInfo_Release(typeinfo
);
223 static HRESULT WINAPI
queryresult_Invoke(
224 IXMLDOMNodeList
*iface
,
229 DISPPARAMS
* pDispParams
,
231 EXCEPINFO
* pExcepInfo
,
234 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
238 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
239 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
241 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
244 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
245 pVarResult
, pExcepInfo
, puArgErr
);
246 ITypeInfo_Release(typeinfo
);
252 static HRESULT WINAPI
queryresult_get_item(
253 IXMLDOMNodeList
* iface
,
255 IXMLDOMNode
** listItem
)
257 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
259 TRACE("%p %ld\n", This
, index
);
266 if (index
< 0 || index
>= xmlXPathNodeSetGetLength(This
->result
->nodesetval
))
269 *listItem
= create_node(This
->result
->nodesetval
->nodeTab
[index
]);
270 This
->resultPos
= index
+ 1;
275 static HRESULT WINAPI
queryresult_get_length(
276 IXMLDOMNodeList
* iface
,
279 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
286 *listLength
= xmlXPathNodeSetGetLength(This
->result
->nodesetval
);
290 static HRESULT WINAPI
queryresult_nextNode(
291 IXMLDOMNodeList
* iface
,
292 IXMLDOMNode
** nextItem
)
294 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
296 TRACE("%p %p\n", This
, nextItem
);
303 if (This
->resultPos
>= xmlXPathNodeSetGetLength(This
->result
->nodesetval
))
306 *nextItem
= create_node(This
->result
->nodesetval
->nodeTab
[This
->resultPos
]);
311 static HRESULT WINAPI
queryresult_reset(
312 IXMLDOMNodeList
* iface
)
314 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
321 static HRESULT WINAPI
queryresult__newEnum(
322 IXMLDOMNodeList
* iface
,
330 static const struct IXMLDOMNodeListVtbl queryresult_vtbl
=
332 queryresult_QueryInterface
,
335 queryresult_GetTypeInfoCount
,
336 queryresult_GetTypeInfo
,
337 queryresult_GetIDsOfNames
,
339 queryresult_get_item
,
340 queryresult_get_length
,
341 queryresult_nextNode
,
343 queryresult__newEnum
,