integrated the xmlDocWalker API given by Alfred Mickautsch, and providing

* Makefile.am configure.in xmldwalk.c include/libxml/Makefile.am
  include/libxml/xmldwalk.h include/libxml/xmlversion.h.in:
  integrated the xmlDocWalker API given by Alfred Mickautsch,
  and providing an xmlReader like API but working on a xmlDocPtr.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 8f72283..975ff82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Oct  4 01:58:27 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in xmldwalk.c include/libxml/Makefile.am
+	  include/libxml/xmldwalk.h include/libxml/xmlversion.h.in:
+	  integrated the xmlDocWalker API given by Alfred Mickautsch,
+	  and providing an xmlReader like API but working on a xmlDocPtr.
+
 Sat Oct  4 00:18:29 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* Makefile.am: more cleanup in make tests
diff --git a/Makefile.am b/Makefile.am
index 876269b..a32d483 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,7 @@
 		catalog.c globals.c threads.c c14n.c \
 		xmlregexp.c xmlschemas.c xmlschemastypes.c xmlunicode.c \
 		triostr.c trio.c xmlreader.c relaxng.c dict.c SAX2.c \
-		legacy.c
+		legacy.c walker.c
 else
 libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c  \
 		parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c  \
@@ -36,7 +36,7 @@
 		catalog.c globals.c threads.c c14n.c \
 		xmlregexp.c xmlschemas.c xmlschemastypes.c xmlunicode.c \
 		xmlreader.c relaxng.c dict.c SAX2.c \
-		legacy.c
+		legacy.c xmldwalk.c
 endif
 
 DEPS = $(top_builddir)/libxml2.la
diff --git a/configure.in b/configure.in
index 2746dcc..a8f274b 100644
--- a/configure.in
+++ b/configure.in
@@ -637,6 +637,23 @@
 AC_SUBST(WITH_SAX1)
 AC_SUBST(TEST_SAX)
 
+AC_ARG_WITH(walker,
+[  --with-walker             add the xmlDocWalker interface (on)])
+if test "$with_minimum" = "yes" -a "$with_walker" = ""
+then
+    with_walker=no
+fi
+if test "$with_walker" = "no" ; then
+    echo Disabling the xmlDocWalker interface
+    WITH_WALKER=0
+    TEST_WALKER=
+else    
+    WITH_WALKER=1
+    TEST_WALKER=WALKERtests
+fi
+AC_SUBST(WITH_WALKER)
+AC_SUBST(TEST_WALKER)
+
 AC_ARG_WITH(push,
 [  --with-push             add the PUSH parser interfaces (on)])
 if test "$with_minimum" = "yes" -a "$with_push" = ""
diff --git a/include/libxml/Makefile.am b/include/libxml/Makefile.am
index 0dd7e73..b9b7014 100644
--- a/include/libxml/Makefile.am
+++ b/include/libxml/Makefile.am
@@ -42,7 +42,8 @@
 		relaxng.h \
 		dict.h \
 		SAX2.h \
-		xmlexports.h
+		xmlexports.h \
+		xmldwalk.h
 
 install-exec-hook:
 	$(mkinstalldirs) $(DESTDIR)$(xmlincdir)
diff --git a/include/libxml/xmldwalk.h b/include/libxml/xmldwalk.h
new file mode 100644
index 0000000..f0bd536
--- /dev/null
+++ b/include/libxml/xmldwalk.h
@@ -0,0 +1,116 @@
+/*
+ * xmldwalk.h : Interfaces, constants and types of the document traversing API.for XML
+ *
+ * this is heavily based upon the xmlTextReader streaming node API
+ * of libxml2 by Daniel Veillard (daniel@veillard.com). In fact I
+ * just copied and modified xmlreader.h
+ *
+ * So for license and disclaimer see the license and disclaimer of
+ * libxml2.
+ *
+ * alfred@mickautsch.de
+ */
+
+#ifndef __XML_XMLDWALK_H__
+#define __XML_XMLDWALK_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    XML_DWALK_NONE = 0,
+    XML_DWALK_START,
+    XML_DWALK_BACKTRACK,
+    XML_DWALK_END
+} xmlDocWalkerState;
+
+typedef struct _xmlDocWalker xmlDocWalker;
+typedef xmlDocWalker *xmlDocWalkerPtr;
+
+/*
+ * Constructor & Destructor
+ */
+XMLPUBFUN xmlDocWalkerPtr XMLCALL
+		xmlNewDocWalker			(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL
+		xmlFreeDocWalker		(xmlDocWalkerPtr iter);
+
+/*
+ * Iterator Functions
+ */
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerRewind		(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerStep		(xmlDocWalkerPtr iter);
+
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerAttributeCount	(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerDepth		(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerHasAttributes	(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerHasValue		(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerIsEmptyElement	(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerLocalName		(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerName		(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerNodeType		(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerPrefix		(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerNamespaceUri	(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerBaseUri		(xmlDocWalkerPtr iter);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerValue		(xmlDocWalkerPtr iter);
+
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerGetAttributeNo	(xmlDocWalkerPtr iter,
+						 int no);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerGetAttribute	(xmlDocWalkerPtr iter,
+						 const xmlChar *name);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerGetAttributeNs	(xmlDocWalkerPtr iter,
+						 const xmlChar *localName,
+						 				 const xmlChar *namespaceURI);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDocWalkerLookupNamespace	(xmlDocWalkerPtr iter,
+						 const xmlChar *prefix);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToAttributeNo	(xmlDocWalkerPtr iter,
+						 int no);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToAttribute	(xmlDocWalkerPtr iter,
+						 const xmlChar *name);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToAttributeNs	(xmlDocWalkerPtr iter,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToFirstAttribute(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToNextAttribute	(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerMoveToElement	(xmlDocWalkerPtr iter);
+
+xmlNodePtr
+		xmlDocWalkerCurrentNode		(xmlDocWalkerPtr iter);
+xmlDocPtr
+		xmlDocWalkerCurrentDoc		(xmlDocWalkerPtr iter);
+XMLPUBFUN int XMLCALL
+		xmlDocWalkerNext		(xmlDocWalkerPtr iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XMLDWALK_H__ */
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
index e1cd434..7b87a43 100644
--- a/include/libxml/xmlversion.h.in
+++ b/include/libxml/xmlversion.h.in
@@ -129,6 +129,15 @@
 #endif
 
 /**
+ * LIBXML_WALKER_ENABLED:
+ *
+ * Whether the xmlDocWalker interface is configured in
+ */
+#if @WITH_WALKER@
+#define LIBXML_WALKER_ENABLED
+#endif
+
+/**
  * LIBXML_FTP_ENABLED:
  *
  * Whether the FTP support is configured in
diff --git a/xmldwalk.c b/xmldwalk.c
new file mode 100644
index 0000000..560c946
--- /dev/null
+++ b/xmldwalk.c
@@ -0,0 +1,1197 @@
+/*
+ * xmldwalk.c : the document traversing API.for XML 
+ *
+ * this is heavily based upon the xmlTextReader streaming node API
+ * of libxml2 by Daniel Veillard (daniel@veillard.com). In fact I
+ * just copied and modified xmlreader.c
+ *
+ * So for license and disclaimer see the license and disclaimer of
+ * libxml2.
+ *
+ * alfred@mickautsch.de
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_WALKER_ENABLED
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmldwalk.h>
+
+struct _xmlDocWalker {
+    xmlDocPtr doc;              /* current document */
+    xmlNodePtr node;            /* current node */
+    xmlNodePtr curnode;         /* current attribute node */
+    int depth;                  /* depth of the current node */
+    xmlDocWalkerState state;    /* state of the iterator */
+};
+
+/**
+ * xmlNewDocWalker:
+ * @doc:  the xmlDocPtr
+ *
+ * Creates a new instance of the xmlDocWalker
+ *
+ * Returns 0 in case of error, the new allocated xmlDocWalkerPtr otherwise
+ */
+xmlDocWalkerPtr
+xmlNewDocWalker(xmlDocPtr doc)
+{
+    xmlDocWalkerPtr ret;
+
+    if (doc == 0)
+        return(0);
+
+    ret = xmlMalloc(sizeof(xmlDocWalker));
+    if (ret == 0) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNewDocWalker : malloc failed\n");
+        return(0);
+    }
+
+    memset(ret, 0, sizeof(xmlDocWalker));
+
+    ret->doc = doc;
+    ret->node = 0;
+    ret->state = XML_DWALK_NONE;
+
+    return ret;
+}
+
+/**
+ * xmlFreeDocWalker:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Deallocate the xmlDocWalker
+ */
+void
+xmlFreeDocWalker(xmlDocWalkerPtr iter)
+{
+    if (iter != 0)
+        xmlFree(iter);
+}
+
+/**
+ * xmlDocWalkerRewind:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Initializes the xmlDocWalker
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlDocWalkerRewind(xmlDocWalkerPtr iter)
+{
+    if (iter == 0 || iter->doc == 0)
+        return(-1);
+
+    if (iter->doc->children == 0)
+        return(0);
+
+    iter->state = XML_DWALK_NONE;
+    iter->depth = 0;
+    iter->node = 0;
+
+    return(1);
+}
+
+/**
+ * xmlDocWalkerStep:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Steps through the xml tree
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlDocWalkerStep(xmlDocWalkerPtr iter)
+{
+    if (iter == 0)
+        return(-1);
+
+    if (iter->state == XML_DWALK_END)
+        return(0);
+
+    if (iter->node == 0) {
+        if (iter->doc->children == 0) {
+            iter->state = XML_DWALK_END;
+            return(0);
+        }
+
+        iter->node = iter->doc->children;
+        iter->state = XML_DWALK_START;
+        return(1);
+    }
+
+    if (iter->state != XML_DWALK_BACKTRACK) {
+        if (iter->node->children != 0) {
+            iter->node = iter->node->children;
+            iter->depth++;
+            iter->state = XML_DWALK_START;
+            return(1);
+        }
+
+        if ((iter->node->type == XML_ELEMENT_NODE) ||
+            (iter->node->type == XML_ATTRIBUTE_NODE)) {
+            iter->state = XML_DWALK_BACKTRACK;
+            return(1);
+        }
+    }
+
+    if (iter->node->next != 0) {
+        iter->node = iter->node->next;
+        iter->state = XML_DWALK_START;
+        return(1);
+    }
+
+    if (iter->node->parent != 0) {
+        if (iter->node->parent->type == XML_DOCUMENT_NODE) {
+            iter->state = XML_DWALK_END;
+            return(0);
+        }
+
+        iter->node = iter->node->parent;
+        iter->depth--;
+        iter->state = XML_DWALK_BACKTRACK;
+        return(1);
+    }
+
+    iter->state = XML_DWALK_END;
+
+    return(1);
+}
+
+/**
+ * xmlDocWalkerAttributeCount:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Provides the number of attributes of the current node
+ *
+ * Returns 0 if no attributes, -1 in case of error or the attribute count
+ */
+int
+xmlDocWalkerAttributeCount(xmlDocWalkerPtr iter)
+{
+    int ret;
+    xmlAttrPtr attr;
+    xmlNsPtr ns;
+    xmlNodePtr node;
+
+    if (iter == 0)
+        return(-1);
+
+    if (iter->node == 0)
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if (node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    ret = 0;
+    attr = node->properties;
+    while (attr != 0) {
+        ret++;
+        attr = attr->next;
+    }
+
+    ns = node->nsDef;
+    while (ns != 0) {
+        ret++;
+        ns = ns->next;
+    }
+
+    return ret;
+}
+
+/**
+ * xmlDocWalkerDepth:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * The depth of the node in the tree.
+ *
+ * Returns the depth or -1 in case of error
+ */
+int
+xmlDocWalkerDepth(xmlDocWalkerPtr iter)
+{
+    if (iter == 0)
+        return(-1);
+
+    if (iter->node == 0)
+        return(0);
+
+    if (iter->curnode != 0) {
+        if ((iter->curnode->type == XML_ATTRIBUTE_NODE) ||
+            (iter->curnode->type == XML_NAMESPACE_DECL))
+            return iter->depth + 1;
+
+        return iter->depth + 2;
+    }
+
+    return iter->depth;
+}
+
+/**
+ * xmlDocWalkerHasAttributes:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Whether the node has attributes.
+ *
+ * Returns 1 if true, 0 if false, and -1 in case or error
+ */
+int
+xmlDocWalkerHasAttributes(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if (iter == 0)
+        return(-1);
+
+    if (iter->node == 0)
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if ((node->type == XML_ELEMENT_NODE) && (node->properties != 0))
+        return(1);
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerHasValue:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Whether the node can have a text value.
+ *
+ * Returns 1 if true, 0 if false, and -1 in case or error
+ */
+int
+xmlDocWalkerHasValue(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if (iter == 0)
+        return(-1);
+
+    if (iter->node == 0)
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    switch (node->type) {
+        case XML_ATTRIBUTE_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_NAMESPACE_DECL:
+            return(1);
+        default:
+            break;
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerIsEmptyElement:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Check if the current node is empty
+ *
+ * Returns 1 if empty, 0 if not and -1 in case of error
+ */
+int
+xmlDocWalkerIsEmptyElement(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->node == 0))
+        return(-1);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    if (iter->curnode != 0)
+        return(0);
+
+    if (iter->node->children != 0)
+        return(0);
+
+    return(1);
+}
+
+/**
+ * xmlDocWalkerLocalName:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * The local name of the node.
+ *
+ * Returns the local name or NULL if not available
+ */
+xmlChar *
+xmlDocWalkerLocalName(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if (node->type == XML_NAMESPACE_DECL) {
+        xmlNsPtr ns = (xmlNsPtr) node;
+
+        if (ns->prefix == 0)
+            return xmlStrdup(BAD_CAST "xmlns");
+        else
+            return xmlStrdup(ns->prefix);
+    }
+
+    if ((node->type != XML_ELEMENT_NODE)
+        && (node->type != XML_ATTRIBUTE_NODE))
+        return (xmlDocWalkerName(iter));
+
+    return xmlStrdup(node->name);
+
+}
+
+/**
+ * xmlDocWalkerName:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * The qualified name of the node, equal to Prefix :LocalName.
+ *
+ * Returns the local name or NULL if not available
+ */
+xmlChar *
+xmlDocWalkerName(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+    xmlChar *ret;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+            if ((node->ns == 0) || (node->ns->prefix == NULL))
+                return xmlStrdup(node->name);
+
+            if ((ret = xmlStrdup(node->ns->prefix)) &&
+                (ret = xmlStrcat(ret, BAD_CAST ":")) &&
+                (ret = xmlStrcat(ret, node->name)))
+                return ret;
+            if (ret)
+                xmlFree(ret);
+            return(0);
+        case XML_TEXT_NODE:
+            return xmlStrdup(BAD_CAST "#text");
+        case XML_CDATA_SECTION_NODE:
+            return xmlStrdup(BAD_CAST "#cdata-section");
+        case XML_ENTITY_NODE:
+        case XML_ENTITY_REF_NODE:
+            return xmlStrdup(node->name);
+        case XML_PI_NODE:
+            return xmlStrdup(node->name);
+        case XML_COMMENT_NODE:
+            return xmlStrdup(BAD_CAST "#comment");
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+            return xmlStrdup(BAD_CAST "#document");
+        case XML_DOCUMENT_FRAG_NODE:
+            return xmlStrdup(BAD_CAST "#document-fragment");
+        case XML_NOTATION_NODE:
+            return xmlStrdup(node->name);
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DTD_NODE:
+            return xmlStrdup(node->name);
+        case XML_NAMESPACE_DECL:
+            {
+                xmlNsPtr ns = (xmlNsPtr) node;
+
+                ret = xmlStrdup(BAD_CAST "xmlns");
+                if (ns->prefix == 0)
+                    return ret;
+                if ((ret) &&
+                    (ret = xmlStrcat(ret, BAD_CAST ":")) &&
+                    (ret = xmlStrcat(ret, ns->prefix)))
+                    return ret;
+                if (ret)
+                    xmlFree(ret);
+                return(0);
+            }
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            return(0);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerNodeType:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Get the node type of the current node
+ * Reference:
+ * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
+ *
+ * Returns the xmlNodeType of the current node or -1 in case of error
+ */
+int
+xmlDocWalkerNodeType(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if (iter == 0)
+        return(-1);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if (node == 0)
+        return(0);
+
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+            if ((iter->state == XML_DWALK_END) ||
+                (iter->state == XML_DWALK_BACKTRACK))
+                return XML_READER_TYPE_END_ELEMENT;
+            return XML_READER_TYPE_ELEMENT;
+
+        case XML_NAMESPACE_DECL:
+        case XML_ATTRIBUTE_NODE:
+            return XML_READER_TYPE_ATTRIBUTE;
+
+        case XML_TEXT_NODE:
+            if (xmlIsBlankNode(iter->node)) {
+                if (xmlNodeGetSpacePreserve(iter->node))
+                    return XML_READER_TYPE_SIGNIFICANT_WHITESPACE;
+
+                return XML_READER_TYPE_WHITESPACE;
+            }
+            return XML_READER_TYPE_TEXT;
+
+        case XML_CDATA_SECTION_NODE:
+            return XML_READER_TYPE_CDATA;
+
+        case XML_ENTITY_REF_NODE:
+            return XML_READER_TYPE_ENTITY_REFERENCE;
+
+        case XML_ENTITY_NODE:
+            return XML_READER_TYPE_ENTITY;
+
+        case XML_PI_NODE:
+            return XML_READER_TYPE_PROCESSING_INSTRUCTION;
+
+        case XML_COMMENT_NODE:
+            return XML_READER_TYPE_COMMENT;
+
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+            return XML_READER_TYPE_DOCUMENT;
+
+        case XML_DOCUMENT_FRAG_NODE:
+            return XML_READER_TYPE_DOCUMENT_FRAGMENT;
+
+        case XML_NOTATION_NODE:
+            return XML_READER_TYPE_NOTATION;
+
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DTD_NODE:
+            return XML_READER_TYPE_DOCUMENT_TYPE;
+
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            return XML_READER_TYPE_NONE;
+    }
+
+    return(-1);
+}
+
+/**
+ * xmlDocWalkerPrefix:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * A shorthand reference to the namespace associated with the node.
+ *
+ * Returns the prefix or NULL if not available
+ */
+xmlChar *
+xmlDocWalkerPrefix(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if ((iter == 0) || (iter->node == 0) || (iter->node->ns == 0))
+        return(0);
+
+    if (iter->curnode != NULL)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if (node->type == XML_NAMESPACE_DECL) {
+        xmlNsPtr ns = (xmlNsPtr) node;
+
+        if (ns->prefix == 0)
+            return(0);
+
+        return xmlStrdup(BAD_CAST "xmlns");
+    }
+
+    if ((node->type != XML_ELEMENT_NODE) &&
+        (node->type != XML_ATTRIBUTE_NODE))
+        return NULL;
+
+    if ((node->ns != 0) && (node->ns->prefix != 0))
+        return xmlStrdup(node->ns->prefix);
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerNamespaceUri:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * The URI defining the namespace associated with the node.
+ *
+ * Returns the namespace URI or NULL if not available
+ */
+xmlChar *
+xmlDocWalkerNamespaceUri(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    if (node->type == XML_NAMESPACE_DECL)
+        return xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/");
+
+    if ((node->type != XML_ELEMENT_NODE)
+        && (node->type != XML_ATTRIBUTE_NODE))
+        return(0);
+
+    if (node->ns != 0)
+        return xmlStrdup(node->ns->href);
+
+    return(0);
+}
+
+/**
+ * xmlTextReaderBaseUri:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * The base URI of the node.
+ *
+ * Returns the base URI or NULL if not available
+ */
+xmlChar *
+xmlDocWalkerBaseUri(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    return xmlNodeGetBase(0, iter->node);
+}
+
+/**
+ * xmlDocWalkerValue:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Provides the text value of the node if present
+ *
+ * Returns the string or NULL if not available. The retsult must be deallocated
+ *     with xmlFree()
+ */
+xmlChar *
+xmlDocWalkerValue(xmlDocWalkerPtr iter)
+{
+    xmlNodePtr node;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    if (iter->curnode != 0)
+        node = iter->curnode;
+    else
+        node = iter->node;
+
+    switch (node->type) {
+        case XML_NAMESPACE_DECL:
+            return xmlStrdup(((xmlNsPtr) node)->href);
+        case XML_ATTRIBUTE_NODE:
+            {
+                xmlAttrPtr attr = (xmlAttrPtr) node;
+
+                if (attr->parent != 0)
+                    return xmlNodeListGetString(attr->parent->doc,
+                                                attr->children, 1);
+                else
+                    return xmlNodeListGetString(0, attr->children, 1);
+            }
+            break;
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+            if (node->content != 0)
+                return xmlStrdup(node->content);
+        default:
+            break;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlDocWalkerGetAttributeNo:
+ * @iter:  the xmlDocWalkerPtr
+ * @no: the zero-based index of the attribute relative to the containing element
+ *
+ * Provides the value of the attribute with the specified index relative
+ * to the containing element.
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlDocWalkerGetAttributeNo(xmlDocWalkerPtr iter, int no)
+{
+    xmlChar *ret;
+    int i;
+    xmlAttrPtr cur;
+    xmlNsPtr ns;
+
+    if ((iter == 0) || (iter->node == 0) || (iter->curnode != 0) ||
+        (iter->node->type != XML_ELEMENT_NODE))
+        return(0);
+
+    ns = iter->node->nsDef;
+    for (i = 0; i < no && ns != 0; i++)
+        ns = ns->next;
+
+    if (ns != 0)
+        return (xmlStrdup(ns->href));
+
+    cur = iter->node->properties;
+    if (cur == 0)
+        return(0);
+
+    for (; i < no; i++) {
+        cur = cur->next;
+        if (cur == 0)
+            return(0);
+    }
+
+    ret = xmlNodeListGetString(iter->node->doc, cur->children, 1);
+    if (ret == 0)
+        return (xmlStrdup((xmlChar *) ""));
+
+    return ret;
+}
+
+/**
+ * xmlDocWalkerGetAttribute:
+ * @iter:  the xmlDocWalkerPtr
+ * @name: the qualified name of the attribute.
+ *
+ * Provides the value of the attribute with the specified qualified name.
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlDocWalkerGetAttribute(xmlDocWalkerPtr iter, const xmlChar * name)
+{
+    xmlChar *prefix = 0;
+    xmlChar *localname;
+    xmlNsPtr ns;
+    xmlChar *ret = 0;
+
+    if ((iter == 0) || (iter->node == 0) || (iter->curnode != 0) ||
+        (iter->node->type != XML_ELEMENT_NODE))
+        return(0);
+
+    localname = xmlSplitQName2(name, &prefix);
+    if (localname == 0)
+        return xmlGetProp(iter->node, name);
+
+    ns = xmlSearchNs(iter->node->doc, iter->node, prefix);
+    if (ns != 0)
+        ret = xmlGetNsProp(iter->node, localname, ns->href);
+
+    if (localname != 0)
+        xmlFree(localname);
+    if (prefix != 0)
+        xmlFree(prefix);
+
+    return ret;
+}
+
+/**
+ * xmlDocWalkerGetAttributeNs:
+ * @iter:  the xmlDocWalkerPtr
+ * @localName: the local name of the attribute.
+ * @namespaceURI: the namespace URI of the attribute.
+ *
+ * Provides the value of the specified attribute
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlDocWalkerGetAttributeNs(xmlDocWalkerPtr iter,
+                           const xmlChar * localName,
+                           const xmlChar * namespaceURI)
+{
+    if ((iter == 0) || (iter->node == 0)
+        || (iter->node->type != XML_ELEMENT_NODE))
+        return(0);
+
+    return xmlGetNsProp(iter->node, localName, namespaceURI);
+}
+
+/**
+ * xmlDocWalkerLookupNamespace:
+ * @iter:  the xmlDocWalkerPtr
+ * @prefix: the prefix whose namespace URI is to be resolved. To return
+ *          the default namespace, specify NULL
+ *
+ * Resolves a namespace prefix in the scope of the current element.
+ *
+ * Returns a string containing the namespace URI to which the prefix maps
+ *    or NULL in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlDocWalkerLookupNamespace(xmlDocWalkerPtr iter, const xmlChar * prefix)
+{
+    xmlNsPtr ns;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(0);
+
+    ns = xmlSearchNs(iter->node->doc, iter->node, prefix);
+    if (ns == NULL)
+        return (NULL);
+    return (xmlStrdup(ns->href));
+}
+
+/**
+ * xmlDocWalkerMoveToAttributeNo:
+ * @iter:  the xmlDocWalkerPtr
+ * @no: the zero-based index of the attribute relative to the containing
+ *      element.
+ *
+ * Moves the position of the current instance to the attribute with
+ * the specified index relative to the containing element.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlDocWalkerMoveToAttributeNo(xmlDocWalkerPtr iter, int no)
+{
+    int i;
+    xmlAttrPtr cur;
+    xmlNsPtr ns;
+
+    if ((iter == 0) || (iter->node == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        return(0);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    iter->curnode = NULL;
+
+    ns = iter->node->nsDef;
+    for (i = 0; i < no && ns != NULL; i++)
+        ns = ns->next;
+
+    if (ns != 0) {
+        iter->curnode = (xmlNodePtr) ns;
+        return(1);
+    }
+
+    cur = iter->node->properties;
+    if (cur == 0)
+        return(0);
+
+    for (; i < no; i++) {
+        cur = cur->next;
+        if (cur == 0)
+            return(0);
+    }
+
+    iter->curnode = (xmlNodePtr) cur;
+    return(1);
+}
+
+/**
+ * xmlDocWalkerMoveToAttribute:
+ * @iter:  the xmlDocWalkerPtr
+ * @name: the qualified name of the attribute.
+ *
+ * Moves the position of the current instance to the attribute with
+ * the specified qualified name.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlDocWalkerMoveToAttribute(xmlDocWalkerPtr iter, const xmlChar * name)
+{
+    xmlChar *prefix = NULL;
+    xmlChar *localname = NULL;
+    xmlNsPtr ns;
+    xmlAttrPtr prop;
+    int ret = 0;
+
+    if ((iter == 0) || (iter->node == 0) || (name == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        goto not_found;
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        goto not_found;
+
+    localname = xmlSplitQName2(name, &prefix);
+    if (localname == 0) {
+        if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+            ns = iter->node->nsDef;
+            while (ns != 0) {
+                if (ns->prefix == 0) {
+                    iter->curnode = (xmlNodePtr) ns;
+                    goto found;
+                }
+                ns = ns->next;
+            }
+
+            goto not_found;
+        }
+
+        prop = iter->node->properties;
+        while (prop != 0) {
+            if (xmlStrEqual(prop->name, name) &&
+                ((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
+                iter->curnode = (xmlNodePtr) prop;
+                goto found;
+            }
+            prop = prop->next;
+        }
+
+        goto not_found;
+    }
+
+    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+        ns = iter->node->nsDef;
+        while (ns != 0) {
+            if (ns->prefix != NULL && xmlStrEqual(ns->prefix, localname)) {
+                iter->curnode = (xmlNodePtr) ns;
+                goto found;
+            }
+            ns = ns->next;
+        }
+        goto not_found;
+    }
+
+    prop = iter->node->properties;
+    while (prop != NULL) {
+        if (xmlStrEqual(prop->name, localname) &&
+            (prop->ns != NULL) && xmlStrEqual(prop->ns->prefix, prefix)) {
+            iter->curnode = (xmlNodePtr) prop;
+            goto found;
+        }
+        prop = prop->next;
+    }
+
+    if (0)
+  found:{
+        ret = 1;
+    }
+  not_found:
+
+    if (localname != 0)
+        xmlFree(localname);
+    if (prefix != 0)
+        xmlFree(prefix);
+    return ret;
+}
+
+/**
+ * xmlDocWalkerMoveToAttributeNs:
+ * @iter:  the xmlDocWalkerPtr
+ * @localName:  the local name of the attribute.
+ * @namespaceURI:  the namespace URI of the attribute.
+ *
+ * Moves the position of the current instance to the attribute with the
+ * specified local name and namespace URI.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlDocWalkerMoveToAttributeNs(xmlDocWalkerPtr iter,
+                              const xmlChar * localName,
+                              const xmlChar * namespaceURI)
+{
+    xmlAttrPtr prop;
+    xmlNodePtr node;
+
+    if ((iter == 0) || (iter->node == 0) || (localName == 0)
+        || (namespaceURI == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        return(0);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    node = iter->node;
+
+    prop = node->properties;
+    while (prop != NULL) {
+        if (xmlStrEqual(prop->name, localName) &&
+            ((prop->ns != NULL)
+             && (xmlStrEqual(prop->ns->href, namespaceURI)))) {
+            iter->curnode = (xmlNodePtr) prop;
+            return(1);
+        }
+
+        prop = prop->next;
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerMoveToFirstAttribute:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Moves the position of the current instance to the first attribute
+ * associated with the current node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlDocWalkerMoveToFirstAttribute(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->node == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        return(0);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    if (iter->node->nsDef != NULL) {
+        iter->curnode = (xmlNodePtr) iter->node->nsDef;
+        return(1);
+    }
+
+    if (iter->node->properties != NULL) {
+        iter->curnode = (xmlNodePtr) iter->node->properties;
+        return(1);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerMoveToNextAttribute:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Moves the position of the current instance to the next attribute
+ * associated with the current node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlDocWalkerMoveToNextAttribute(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->node == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        return(0);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+    if (iter->curnode == NULL)
+        return (xmlDocWalkerMoveToFirstAttribute(iter));
+
+    if (iter->curnode->type == XML_NAMESPACE_DECL) {
+        xmlNsPtr ns = (xmlNsPtr) iter->curnode;
+
+        if (ns->next != NULL) {
+            iter->curnode = (xmlNodePtr) ns->next;
+            return(1);
+        }
+        if (iter->node->properties != NULL) {
+            iter->curnode = (xmlNodePtr) iter->node->properties;
+            return(1);
+        }
+
+        return(0);
+    } else if ((iter->curnode->type == XML_ATTRIBUTE_NODE) &&
+               (iter->curnode->next != NULL)) {
+        iter->curnode = iter->curnode->next;
+        return(1);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerMoveToElement:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Moves the position of the current instance to the node that
+ * contains the current Attribute  node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not moved
+ */
+int
+xmlDocWalkerMoveToElement(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->node == 0))
+        return(-1);
+
+    if ((iter->state == XML_DWALK_NONE) ||
+        (iter->state == XML_DWALK_BACKTRACK) ||
+        (iter->state == XML_DWALK_END))
+        return(0);
+
+    if (iter->node->type != XML_ELEMENT_NODE)
+        return(0);
+
+    if (iter->curnode != NULL) {
+        iter->curnode = NULL;
+        return(1);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDocWalkerCurrentNode:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Hacking interface allowing to get the xmlNodePtr correponding to the
+ * current node being accessed by the xmlDocWalker.
+ *
+ * Returns the xmlNodePtr or NULL in case of error.
+ */
+xmlNodePtr
+xmlDocWalkerCurrentNode(xmlDocWalkerPtr iter)
+{
+    if (iter == 0)
+        return(0);
+
+    if (iter->curnode != NULL)
+        return iter->curnode;
+
+    return iter->node;
+}
+
+/**
+ * xmlDocWalkerCurrentDoc:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Hacking interface allowing to get the xmlDocPtr correponding to the
+ * current document being accessed by the xmlDocWalker.
+ *
+ * Returns the xmlDocPtr or NULL in case of error.
+ */
+xmlDocPtr
+xmlDocWalkerCurrentDoc(xmlDocWalkerPtr iter)
+{
+    if (iter == 0)
+        return(0);
+
+    return iter->doc;
+}
+
+/**
+ * xmlDocWalkerNext:
+ * @iter:  the xmlDocWalkerPtr
+ *
+ * Step to the next sibling of the current node in document order
+ *
+ * Returns 1 if ok, 0 if there are no more nodes, or -1 in case of error
+ */
+int
+xmlDocWalkerNext(xmlDocWalkerPtr iter)
+{
+    if ((iter == 0) || (iter->doc == 0))
+        return(-1);
+
+    if (iter->state == XML_DWALK_END)
+        return(0);
+
+    if (iter->node == 0)
+        return xmlDocWalkerStep(iter);
+
+    if (iter->node->next != 0) {
+        iter->node = iter->node->next;
+        iter->state = XML_DWALK_START;
+        return(1);
+    }
+
+    return(0);
+}
+#endif /* LIBXML_WALKER_ENABLED */