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
,
171 static HRESULT WINAPI
queryresult_GetTypeInfo(
172 IXMLDOMNodeList
*iface
,
175 ITypeInfo
** ppTInfo
)
181 static HRESULT WINAPI
queryresult_GetIDsOfNames(
182 IXMLDOMNodeList
*iface
,
193 static HRESULT WINAPI
queryresult_Invoke(
194 IXMLDOMNodeList
*iface
,
199 DISPPARAMS
* pDispParams
,
201 EXCEPINFO
* pExcepInfo
,
208 static HRESULT WINAPI
queryresult_get_item(
209 IXMLDOMNodeList
* iface
,
211 IXMLDOMNode
** listItem
)
213 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
215 TRACE("%p %ld\n", This
, index
);
219 if (index
< 0 || index
>= This
->result
->nodesetval
->nodeNr
)
222 *listItem
= create_node(This
->result
->nodesetval
->nodeTab
[index
]);
223 This
->resultPos
= index
+ 1;
228 static HRESULT WINAPI
queryresult_get_length(
229 IXMLDOMNodeList
* iface
,
232 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
236 *listLength
= This
->result
->nodesetval
->nodeNr
;
240 static HRESULT WINAPI
queryresult_nextNode(
241 IXMLDOMNodeList
* iface
,
242 IXMLDOMNode
** nextItem
)
244 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
246 TRACE("%p %p\n", This
, nextItem
);
250 if (This
->resultPos
>= This
->result
->nodesetval
->nodeNr
)
253 *nextItem
= create_node(This
->result
->nodesetval
->nodeTab
[This
->resultPos
]);
258 static HRESULT WINAPI
queryresult_reset(
259 IXMLDOMNodeList
* iface
)
261 queryresult
*This
= impl_from_IXMLDOMNodeList( iface
);
268 static HRESULT WINAPI
queryresult__newEnum(
269 IXMLDOMNodeList
* iface
,
277 static const struct IXMLDOMNodeListVtbl queryresult_vtbl
=
279 queryresult_QueryInterface
,
282 queryresult_GetTypeInfoCount
,
283 queryresult_GetTypeInfo
,
284 queryresult_GetIDsOfNames
,
286 queryresult_get_item
,
287 queryresult_get_length
,
288 queryresult_nextNode
,
290 queryresult__newEnum
,