Commit f3719a88 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Implemented IXMLDOMNode::selectNodes.

parent e4a20a4b
...@@ -442,6 +442,8 @@ dnl **** Check for libxml2 **** ...@@ -442,6 +442,8 @@ dnl **** Check for libxml2 ****
AC_SUBST(XML2LIBS,"") AC_SUBST(XML2LIBS,"")
AC_SUBST(XML2INCL,"") AC_SUBST(XML2INCL,"")
AC_SUBST(XSLTLIBS,"")
AC_SUBST(XSLTINCL,"")
if test "$PKG_CONFIG" != "false" if test "$PKG_CONFIG" != "false"
then then
ac_save_CPPFLAGS="$CPPFLAGS" ac_save_CPPFLAGS="$CPPFLAGS"
...@@ -454,7 +456,19 @@ then ...@@ -454,7 +456,19 @@ then
XML2LIBS="$ac_xml_libs" XML2LIBS="$ac_xml_libs"
XML2INCL="$ac_xml_cflags"],,$ac_xml_libs) XML2INCL="$ac_xml_cflags"],,$ac_xml_libs)
AC_CHECK_LIB(xml2, xmlReadMemory, AC_CHECK_LIB(xml2, xmlReadMemory,
[AC_DEFINE(HAVE_XMLREADMEMORY,1,[Define if libxml2 has the xmlReadMemory function])]) [AC_DEFINE(HAVE_XMLREADMEMORY,1,[Define if libxml2 has the xmlReadMemory function])],,$ac_xml_libs)
])
CPPFLAGS="$ac_save_CPPFLAGS"
ac_xslt_libs="`$PKG_CONFIG --libs libxslt`"
ac_xslt_cflags="`$PKG_CONFIG --cflags libxslt`"
CPPFLAGS="$CPPFLAGS $ac_xslt_cflags"
AC_CHECK_HEADERS(libxslt/xslt.h \
libxslt/pattern.h \
libxslt/transform.h,
[AC_CHECK_LIB(xslt, xsltCompilePattern,
[AC_DEFINE(HAVE_LIBXSLT, 1, [Define if you have the libxslt library])
XSLTLIBS="$ac_xslt_libs"
XSLTINCL="$ac_xslt_cflags"],,$ac_xslt_libs)
]) ])
CPPFLAGS="$ac_save_CPPFLAGS" CPPFLAGS="$ac_save_CPPFLAGS"
fi fi
......
...@@ -5,8 +5,8 @@ SRCDIR = @srcdir@ ...@@ -5,8 +5,8 @@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = msxml3.dll MODULE = msxml3.dll
IMPORTS = oleaut32 advapi32 kernel32 ntdll IMPORTS = oleaut32 advapi32 kernel32 ntdll
EXTRALIBS = -luuid $(LIBUNICODE) @XML2LIBS@ EXTRALIBS = -luuid $(LIBUNICODE) @XML2LIBS@ @XSLTLIBS@
EXTRAINCL = @XML2INCL@ EXTRAINCL = @XML2INCL@ @XSLTINCL@
C_SRCS = \ C_SRCS = \
domdoc.c \ domdoc.c \
......
...@@ -36,6 +36,7 @@ extern IXMLDOMNode *create_node( xmlNodePtr node ); ...@@ -36,6 +36,7 @@ extern IXMLDOMNode *create_node( xmlNodePtr node );
extern IXMLDOMElement *create_element( xmlNodePtr element ); extern IXMLDOMElement *create_element( xmlNodePtr element );
extern IXMLDOMNodeList *create_nodelist( xmlNodePtr node ); extern IXMLDOMNodeList *create_nodelist( xmlNodePtr node );
extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node ); extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
extern IXMLDOMNodeList *create_filtered_nodelist( xmlNodePtr, const xmlChar * );
/* data accessors */ /* data accessors */
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ); xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
......
...@@ -524,8 +524,19 @@ static HRESULT WINAPI xmlnode_selectNodes( ...@@ -524,8 +524,19 @@ static HRESULT WINAPI xmlnode_selectNodes(
BSTR queryString, BSTR queryString,
IXMLDOMNodeList** resultList) IXMLDOMNodeList** resultList)
{ {
FIXME("\n"); xmlnode *This = impl_from_IXMLDOMNode( iface );
return E_NOTIMPL; xmlChar *str = NULL;
HRESULT r = E_FAIL;
TRACE("%p %s %p\n", This, debugstr_w(queryString), resultList );
str = xmlChar_from_wchar( queryString );
if (!str)
return r;
*resultList = create_filtered_nodelist( This->node->children, str );
HeapFree( GetProcessHeap(), 0, str );
return S_OK;
} }
static HRESULT WINAPI xmlnode_selectSingleNode( static HRESULT WINAPI xmlnode_selectSingleNode(
......
...@@ -37,9 +37,111 @@ ...@@ -37,9 +37,111 @@
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2 #ifdef HAVE_LIBXML2
WINE_DEFAULT_DEBUG_CHANNEL(msxml); #ifdef HAVE_LIBXSLT
#ifdef HAVE_LIBXSLT_PATTERN_H
#include <libxslt/pattern.h>
#endif
#ifdef HAVE_LIBXSLT_TRANSFORM_H
#include <libxslt/transform.h>
#endif
struct xslt_info {
xsltTransformContextPtr ctxt;
xsltCompMatchPtr pattern;
xsltStylesheetPtr sheet;
};
static void xlst_info_init( struct xslt_info *info )
{
info->ctxt = NULL;
info->pattern = NULL;
info->sheet = NULL;
}
static int create_xslt_parser( struct xslt_info *info, xmlNodePtr node, const xmlChar *str )
{
info->sheet = xsltNewStylesheet();
if (!info->sheet)
return 0;
info->ctxt = xsltNewTransformContext( info->sheet, node->doc );
if (!info->ctxt)
return 0;
info->pattern = xsltCompilePattern( str, node->doc,
node, info->sheet, info->ctxt );
if (!info->pattern)
return 0;
return 1;
}
void free_xslt_info( struct xslt_info *info )
{
if (info->pattern)
xsltFreeCompMatchList( info->pattern );
if (info->sheet)
xsltFreeStylesheet( info->sheet );
if (info->ctxt)
xsltFreeTransformContext( info->ctxt );
}
static HRESULT xslt_next_match( struct xslt_info *info, xmlNodePtr *node )
{
if (!info->ctxt)
return S_FALSE;
/* make sure that the current element matches the pattern */
while ( *node )
{
int r;
r = xsltTestCompMatchList( info->ctxt, *node, info->pattern );
if ( 1 == r )
{
TRACE("Matched %p (%s)\n", *node, (*node)->name );
return S_OK;
}
if (r != 0)
{
ERR("Pattern match failed\n");
return E_FAIL;
}
*node = (*node)->next;
}
return S_OK;
}
#else
struct xslt_info {
/* empty */
};
static void xlst_info_init( struct xslt_info *info )
{
}
void free_xslt_info( struct xslt_info *info )
{
}
static int create_xslt_parser( struct xslt_info *info, xmlNodePtr node, const xmlChar *str )
{
MESSAGE("libxslt was missing at compile time\n");
return 0;
}
static HRESULT xslt_next_match( struct xslt_info *info, xmlNodePtr *node )
{
return S_FALSE;
}
#endif
typedef struct _xmlnodelist typedef struct _xmlnodelist
{ {
...@@ -47,6 +149,7 @@ typedef struct _xmlnodelist ...@@ -47,6 +149,7 @@ typedef struct _xmlnodelist
LONG ref; LONG ref;
xmlNodePtr node; xmlNodePtr node;
xmlNodePtr current; xmlNodePtr current;
struct xslt_info xinfo;
} xmlnodelist; } xmlnodelist;
static inline xmlnodelist *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface ) static inline xmlnodelist *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface )
...@@ -91,6 +194,7 @@ static ULONG WINAPI xmlnodelist_Release( ...@@ -91,6 +194,7 @@ static ULONG WINAPI xmlnodelist_Release(
ref = InterlockedDecrement( &This->ref ); ref = InterlockedDecrement( &This->ref );
if ( ref == 0 ) if ( ref == 0 )
{ {
free_xslt_info( &This->xinfo );
HeapFree( GetProcessHeap(), 0, This ); HeapFree( GetProcessHeap(), 0, This );
} }
...@@ -164,9 +268,14 @@ static HRESULT WINAPI xmlnodelist_nextNode( ...@@ -164,9 +268,14 @@ static HRESULT WINAPI xmlnodelist_nextNode(
IXMLDOMNode** nextItem) IXMLDOMNode** nextItem)
{ {
xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
HRESULT r;
TRACE("%p %p\n", This, nextItem ); TRACE("%p %p\n", This, nextItem );
r = xslt_next_match( &This->xinfo, &This->current );
if (FAILED(r) )
return r;
if (!This->current) if (!This->current)
return S_FALSE; return S_FALSE;
...@@ -178,8 +287,11 @@ static HRESULT WINAPI xmlnodelist_nextNode( ...@@ -178,8 +287,11 @@ static HRESULT WINAPI xmlnodelist_nextNode(
static HRESULT WINAPI xmlnodelist_reset( static HRESULT WINAPI xmlnodelist_reset(
IXMLDOMNodeList* iface) IXMLDOMNodeList* iface)
{ {
FIXME("\n"); xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
return E_NOTIMPL;
TRACE("%p\n", This);
This->current = This->node;
return S_OK;
} }
static HRESULT WINAPI xmlnodelist__newEnum( static HRESULT WINAPI xmlnodelist__newEnum(
...@@ -207,7 +319,7 @@ static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl = ...@@ -207,7 +319,7 @@ static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl =
xmlnodelist__newEnum, xmlnodelist__newEnum,
}; };
IXMLDOMNodeList* create_nodelist( xmlNodePtr node ) static xmlnodelist *new_nodelist( xmlNodePtr node )
{ {
xmlnodelist *nodelist; xmlnodelist *nodelist;
...@@ -219,8 +331,28 @@ IXMLDOMNodeList* create_nodelist( xmlNodePtr node ) ...@@ -219,8 +331,28 @@ IXMLDOMNodeList* create_nodelist( xmlNodePtr node )
nodelist->ref = 1; nodelist->ref = 1;
nodelist->node = node; nodelist->node = node;
nodelist->current = node; nodelist->current = node;
xlst_info_init( &nodelist->xinfo );
return nodelist;
}
IXMLDOMNodeList* create_nodelist( xmlNodePtr node )
{
xmlnodelist *nodelist = new_nodelist( node );
if (!node)
return NULL;
return (IXMLDOMNodeList*) &nodelist->lpVtbl; return (IXMLDOMNodeList*) &nodelist->lpVtbl;
} }
IXMLDOMNodeList* create_filtered_nodelist( xmlNodePtr node, const xmlChar *str )
{
xmlnodelist *This = new_nodelist( node );
if (create_xslt_parser( &This->xinfo, node, str ))
return (IXMLDOMNodeList*) &This->lpVtbl;
IXMLDOMNodeList_Release( (IXMLDOMNodeList*) &This->lpVtbl );
return NULL;
}
#endif #endif
...@@ -284,6 +284,18 @@ ...@@ -284,6 +284,18 @@
/* Define if you have the X Shape extension */ /* Define if you have the X Shape extension */
#undef HAVE_LIBXSHAPE #undef HAVE_LIBXSHAPE
/* Define if you have the libxslt library */
#undef HAVE_LIBXSLT
/* Define to 1 if you have the <libxslt/pattern.h> header file. */
#undef HAVE_LIBXSLT_PATTERN_H
/* Define to 1 if you have the <libxslt/transform.h> header file. */
#undef HAVE_LIBXSLT_TRANSFORM_H
/* Define to 1 if you have the <libxslt/xslt.h> header file. */
#undef HAVE_LIBXSLT_XSLT_H
/* Define if you have the Xxf86dga library version 2 */ /* Define if you have the Xxf86dga library version 2 */
#undef HAVE_LIBXXF86DGA2 #undef HAVE_LIBXXF86DGA2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment