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