Implemented IXMLDOMNode::selectNodes.

diff --git a/configure b/configure
index 841e47e..07b0dd7 100755
--- a/configure
+++ b/configure
@@ -311,7 +311,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os WIN16_FILES WIN16_INSTALL SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE PKG_CONFIG PRELINK LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS XML2LIBS XML2INCL CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS LCMSLIBS LDAPLIBS FREETYPELIBS FREETYPEINCL ft_devel ft_devel2 FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ESDCONFIG ESDLIBS ESDINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS BUILTINFLAG DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os WIN16_FILES WIN16_INSTALL SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE PKG_CONFIG PRELINK LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS XML2LIBS XML2INCL XSLTLIBS XSLTINCL CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS LCMSLIBS LDAPLIBS FREETYPELIBS FREETYPEINCL ft_devel ft_devel2 FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ESDCONFIG ESDLIBS ESDINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS BUILTINFLAG DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD LIBOBJS LTLIBOBJS'
 ac_subst_files='MAKE_RULES MAKE_DLL_RULES MAKE_IMPLIB_RULES MAKE_TEST_RULES MAKE_LIB_RULES MAKE_PROG_RULES'
 
 # Initialize some variables set by options.
@@ -8597,6 +8597,10 @@
 
 XML2INCL=""
 
+XSLTLIBS=""
+
+XSLTINCL=""
+
 if test "$PKG_CONFIG" != "false"
 then
     ac_save_CPPFLAGS="$CPPFLAGS"
@@ -8826,7 +8830,7 @@
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lxml2  $LIBS"
+LIBS="-lxml2 $ac_xml_libs $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -8897,6 +8901,236 @@
 done
 
     CPPFLAGS="$ac_save_CPPFLAGS"
+    ac_xslt_libs="`$PKG_CONFIG --libs libxslt`"
+    ac_xslt_cflags="`$PKG_CONFIG --cflags libxslt`"
+    CPPFLAGS="$CPPFLAGS $ac_xslt_cflags"
+
+
+
+for ac_header in libxslt/xslt.h \
+                     libxslt/pattern.h \
+                     libxslt/transform.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to wine-devel@winehq.org ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ echo "$as_me:$LINENO: checking for xsltCompilePattern in -lxslt" >&5
+echo $ECHO_N "checking for xsltCompilePattern in -lxslt... $ECHO_C" >&6
+if test "${ac_cv_lib_xslt_xsltCompilePattern+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxslt $ac_xslt_libs $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char xsltCompilePattern ();
+int
+main ()
+{
+xsltCompilePattern ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_xslt_xsltCompilePattern=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_xslt_xsltCompilePattern=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_xslt_xsltCompilePattern" >&5
+echo "${ECHO_T}$ac_cv_lib_xslt_xsltCompilePattern" >&6
+if test $ac_cv_lib_xslt_xsltCompilePattern = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBXSLT 1
+_ACEOF
+
+             XSLTLIBS="$ac_xslt_libs"
+             XSLTINCL="$ac_xslt_cflags"
+fi
+
+
+fi
+
+done
+
+    CPPFLAGS="$ac_save_CPPFLAGS"
 fi
 
 CURSESLIBS=""
@@ -19309,6 +19543,8 @@
 s,@NASLIBS@,$NASLIBS,;t t
 s,@XML2LIBS@,$XML2LIBS,;t t
 s,@XML2INCL@,$XML2INCL,;t t
+s,@XSLTLIBS@,$XSLTLIBS,;t t
+s,@XSLTINCL@,$XSLTINCL,;t t
 s,@CURSESLIBS@,$CURSESLIBS,;t t
 s,@sane_devel@,$sane_devel,;t t
 s,@SANELIBS@,$SANELIBS,;t t
diff --git a/configure.ac b/configure.ac
index c1148b2..76a1519 100644
--- a/configure.ac
+++ b/configure.ac
@@ -442,6 +442,8 @@
 
 AC_SUBST(XML2LIBS,"")
 AC_SUBST(XML2INCL,"")
+AC_SUBST(XSLTLIBS,"")
+AC_SUBST(XSLTINCL,"")
 if test "$PKG_CONFIG" != "false"
 then
     ac_save_CPPFLAGS="$CPPFLAGS"
@@ -454,7 +456,19 @@
              XML2LIBS="$ac_xml_libs"
              XML2INCL="$ac_xml_cflags"],,$ac_xml_libs)
          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"
 fi
diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in
index 80dd36d..7bd520d 100644
--- a/dlls/msxml3/Makefile.in
+++ b/dlls/msxml3/Makefile.in
@@ -5,8 +5,8 @@
 VPATH     = @srcdir@
 MODULE    = msxml3.dll
 IMPORTS   = oleaut32 advapi32 kernel32 ntdll
-EXTRALIBS = -luuid $(LIBUNICODE) @XML2LIBS@
-EXTRAINCL = @XML2INCL@
+EXTRALIBS = -luuid $(LIBUNICODE) @XML2LIBS@ @XSLTLIBS@
+EXTRAINCL = @XML2INCL@ @XSLTINCL@
 
 C_SRCS = \
 	domdoc.c \
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 7398c1e..51bd609 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -36,6 +36,7 @@
 extern IXMLDOMElement   *create_element( xmlNodePtr element );
 extern IXMLDOMNodeList  *create_nodelist( xmlNodePtr node );
 extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
+extern IXMLDOMNodeList  *create_filtered_nodelist( xmlNodePtr, const xmlChar * );
 
 /* data accessors */
 xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 3ffb947..3d8b190 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -524,8 +524,19 @@
     BSTR queryString,
     IXMLDOMNodeList** resultList)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    xmlnode *This = impl_from_IXMLDOMNode( iface );
+    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(
diff --git a/dlls/msxml3/nodelist.c b/dlls/msxml3/nodelist.c
index 17ae49b..c64eddb 100644
--- a/dlls/msxml3/nodelist.c
+++ b/dlls/msxml3/nodelist.c
@@ -37,9 +37,111 @@
 
 #include "wine/debug.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+
 #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
 {
@@ -47,6 +149,7 @@
     LONG ref;
     xmlNodePtr node;
     xmlNodePtr current;
+    struct xslt_info xinfo;
 } xmlnodelist;
 
 static inline xmlnodelist *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface )
@@ -91,6 +194,7 @@
     ref = InterlockedDecrement( &This->ref );
     if ( ref == 0 )
     {
+        free_xslt_info( &This->xinfo );
         HeapFree( GetProcessHeap(), 0, This );
     }
 
@@ -164,9 +268,14 @@
         IXMLDOMNode** nextItem)
 {
     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
+    HRESULT r;
 
     TRACE("%p %p\n", This, nextItem );
 
+    r = xslt_next_match( &This->xinfo, &This->current );
+    if (FAILED(r) )
+        return r;
+
     if (!This->current)
         return S_FALSE;
 
@@ -178,8 +287,11 @@
 static HRESULT WINAPI xmlnodelist_reset(
         IXMLDOMNodeList* iface)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
+
+    TRACE("%p\n", This);
+    This->current = This->node;
+    return S_OK;
 }
 
 static HRESULT WINAPI xmlnodelist__newEnum(
@@ -207,7 +319,7 @@
     xmlnodelist__newEnum,
 };
 
-IXMLDOMNodeList* create_nodelist( xmlNodePtr node )
+static xmlnodelist *new_nodelist( xmlNodePtr node )
 {
     xmlnodelist *nodelist;
 
@@ -219,8 +331,28 @@
     nodelist->ref = 1;
     nodelist->node = 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;
 }
 
+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
diff --git a/include/config.h.in b/include/config.h.in
index c075484..2da7275 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -284,6 +284,18 @@
 /* Define if you have the X Shape extension */
 #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 */
 #undef HAVE_LIBXXF86DGA2