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 */