added more methods of XmlTextReader. this increased the methods in the

* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: added
  more methods of XmlTextReader.
* python/libxml2class.txt python/tests/reader.py: this increased the
  methods in the bndings, augmented the test to check those new
  functions.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 4d1f1b2..68e583d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Dec 16 00:34:25 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: added
+	  more methods of XmlTextReader.
+	* python/libxml2class.txt python/tests/reader.py: this increased the
+	  methods in the bndings, augmented the test to check those new
+	  functions.
+
 Sat Dec 14 23:57:39 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* xmlreader.c doc/libxml2-api.xml: added the close and getattribute
diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml
index 7909b8e..14b8103 100644
--- a/doc/libxml2-api.xml
+++ b/doc/libxml2-api.xml
@@ -1098,11 +1098,19 @@
      <exports symbol='xmlTextReaderGetAttribute'/>
      <exports symbol='xmlTextReaderGetAttributeNo'/>
      <exports symbol='xmlTextReaderGetAttributeNs'/>
+     <exports symbol='xmlTextReaderGetRemainder'/>
      <exports symbol='xmlTextReaderHasAttributes'/>
      <exports symbol='xmlTextReaderHasValue'/>
      <exports symbol='xmlTextReaderIsDefault'/>
      <exports symbol='xmlTextReaderIsEmptyElement'/>
      <exports symbol='xmlTextReaderLocalName'/>
+     <exports symbol='xmlTextReaderLookupNamespace'/>
+     <exports symbol='xmlTextReaderMoveToAttribute'/>
+     <exports symbol='xmlTextReaderMoveToAttributeNo'/>
+     <exports symbol='xmlTextReaderMoveToAttributeNs'/>
+     <exports symbol='xmlTextReaderMoveToElement'/>
+     <exports symbol='xmlTextReaderMoveToFirstAttribute'/>
+     <exports symbol='xmlTextReaderMoveToNextAttribute'/>
      <exports symbol='xmlTextReaderName'/>
      <exports symbol='xmlTextReaderNamespaceUri'/>
      <exports symbol='xmlTextReaderNodeType'/>
@@ -7909,6 +7917,11 @@
       <arg name='localName' type='const xmlChar *' info='the local name of the attribute.'/>
       <arg name='namespaceURI' type='const xmlChar *' info='the namespace URI of the attribute.'/>
     </function>
+    <function name='xmlTextReaderGetRemainder' file='xmlreader'>
+      <info>Method to get the remainder of the buffered XML. this method stops the parser, set its state to End Of File and return the input stream with what is left that the parser did not use.</info>
+      <return type='xmlParserInputBufferPtr' info='the xmlParserInputBufferPtr attached to the XML or NULL in case of error.'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+    </function>
     <function name='xmlTextReaderHasAttributes' file='xmlreader'>
       <info>Whether the node has attributes.</info>
       <return type='int' info='1 if true, 0 if false, and -1 in case or error'/>
@@ -7934,6 +7947,46 @@
       <return type='xmlChar *' info='the local name or NULL if not available'/>
       <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
     </function>
+    <function name='xmlTextReaderLookupNamespace' file='xmlreader'>
+      <info>Resolves a namespace prefix in the scope of the current element.</info>
+      <return type='xmlChar *' info='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.'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+      <arg name='prefix' type='const xmlChar *' info='the prefix whose namespace URI is to be resolved. To return the default namespace, specify NULL'/>
+    </function>
+    <function name='xmlTextReaderMoveToAttribute' file='xmlreader'>
+      <info>Moves the position of the current instance to the attribute with the specified qualified name.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not found'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+      <arg name='name' type='const xmlChar *' info='the qualified name of the attribute.'/>
+    </function>
+    <function name='xmlTextReaderMoveToAttributeNo' file='xmlreader'>
+      <info>Moves the position of the current instance to the attribute with the specified index relative to the containing element.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not found'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+      <arg name='no' type='int' info='the zero-based index of the attribute relative to the containing element.'/>
+    </function>
+    <function name='xmlTextReaderMoveToAttributeNs' file='xmlreader'>
+      <info>Moves the position of the current instance to the attribute with the specified local name and namespace URI.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not found'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+      <arg name='localName' type='const xmlChar *' info='the local name of the attribute.'/>
+      <arg name='namespaceURI' type='const xmlChar *' info='the namespace URI of the attribute.'/>
+    </function>
+    <function name='xmlTextReaderMoveToElement' file='xmlreader'>
+      <info>Moves the position of the current instance to the node that contains the current Attribute  node.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not moved'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+    </function>
+    <function name='xmlTextReaderMoveToFirstAttribute' file='xmlreader'>
+      <info>Moves the position of the current instance to the first attribute associated with the current node.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not found'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+    </function>
+    <function name='xmlTextReaderMoveToNextAttribute' file='xmlreader'>
+      <info>Moves the position of the current instance to the next attribute associated with the current node.</info>
+      <return type='int' info='1 in case of success, -1 in case of error, 0 if not found'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='the xmlTextReaderPtr used'/>
+    </function>
     <function name='xmlTextReaderName' file='xmlreader'>
       <info>The qualified name of the node, equal to Prefix :LocalName.</info>
       <return type='xmlChar *' info='the local name or NULL if not available'/>
diff --git a/include/libxml/xmlreader.h b/include/libxml/xmlreader.h
index 15937a1..ac3737c 100644
--- a/include/libxml/xmlreader.h
+++ b/include/libxml/xmlreader.h
@@ -61,6 +61,20 @@
 xmlChar *	xmlTextReaderGetAttributeNs	(xmlTextReaderPtr reader,
 						 const xmlChar *localName,
 						 const xmlChar *namespaceURI);
+xmlParserInputBufferPtr xmlTextReaderGetRemainder(xmlTextReaderPtr reader);
+xmlChar *	xmlTextReaderLookupNamespace	(xmlTextReaderPtr reader,
+						 const xmlChar *prefix);
+int		xmlTextReaderMoveToAttributeNo	(xmlTextReaderPtr reader,
+						 int no);
+int		xmlTextReaderMoveToAttribute	(xmlTextReaderPtr reader,
+						 const xmlChar *name);
+int		xmlTextReaderMoveToAttributeNs	(xmlTextReaderPtr reader,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+int		xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader);
+int		xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader);
+int		xmlTextReaderMoveToElement	(xmlTextReaderPtr reader);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index 6127f7b..b303384 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -570,11 +570,19 @@
     getAttribute()
     getAttributeNo()
     getAttributeNs()
+    getRemainder()
     hasAttributes()
     hasValue()
     isDefault()
     isEmptyElement()
     localName()
+    lookupNamespace()
+    moveToAttribute()
+    moveToAttributeNo()
+    moveToAttributeNs()
+    moveToElement()
+    moveToFirstAttribute()
+    moveToNextAttribute()
     name()
     namespaceUri()
     nodeType()
diff --git a/python/tests/reader.py b/python/tests/reader.py
index 1817fe9..b6efa48 100755
--- a/python/tests/reader.py
+++ b/python/tests/reader.py
@@ -81,6 +81,157 @@
     print "error reading test attributes"
     sys.exit(1)
 
+#
+# example from the XmlTextReader docs
+#
+f = StringIO.StringIO("""<root xmlns:a="urn:456">
+<item>
+<ref href="a:b"/>
+</item>
+</root>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+
+ret = reader.read()
+while ret == 1:
+    if reader.name() == "ref":
+        if reader.lookupNamespace("a") != "urn:456":
+	    print "error resolving namespace prefix"
+	    sys.exit(1)
+	break
+    ret = reader.read()
+if ret != 1:
+    print "Error finding the ref element"
+    sys.exit(1)
+
+#
+# Home made example for the various attribute access functions
+#
+f = StringIO.StringIO("""<testattr xmlns="urn:1" xmlns:a="urn:2" b="b" a:b="a:b"/>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+ret = reader.read()
+if ret != 1:
+    print "Error reading the testattr element"
+    sys.exit(1)
+#
+# Attribute exploration by index
+#
+if reader.moveToAttributeNo(0) != 1:
+    print "Failed moveToAttribute(0)"
+    sys.exit(1)
+if reader.value() != "urn:1":
+    print "Failed to read attribute(0)"
+    sys.exit(1)
+if reader.name() != "xmlns":
+    print "Failed to read attribute(0) name"
+    sys.exit(1)
+if reader.moveToAttributeNo(1) != 1:
+    print "Failed moveToAttribute(1)"
+    sys.exit(1)
+if reader.value() != "urn:2":
+    print "Failed to read attribute(1)"
+    sys.exit(1)
+if reader.name() != "xmlns:a":
+    print "Failed to read attribute(1) name"
+    sys.exit(1)
+if reader.moveToAttributeNo(2) != 1:
+    print "Failed moveToAttribute(2)"
+    sys.exit(1)
+if reader.value() != "b":
+    print "Failed to read attribute(2)"
+    sys.exit(1)
+if reader.name() != "b":
+    print "Failed to read attribute(2) name"
+    sys.exit(1)
+if reader.moveToAttributeNo(3) != 1:
+    print "Failed moveToAttribute(3)"
+    sys.exit(1)
+if reader.value() != "a:b":
+    print "Failed to read attribute(3)"
+    sys.exit(1)
+if reader.name() != "a:b":
+    print "Failed to read attribute(3) name"
+    sys.exit(1)
+#
+# Attribute exploration by name
+#
+if reader.moveToAttribute("xmlns") != 1:
+    print "Failed moveToAttribute('xmlns')"
+    sys.exit(1)
+if reader.value() != "urn:1":
+    print "Failed to read attribute('xmlns')"
+    sys.exit(1)
+if reader.moveToAttribute("xmlns:a") != 1:
+    print "Failed moveToAttribute('xmlns')"
+    sys.exit(1)
+if reader.value() != "urn:2":
+    print "Failed to read attribute('xmlns:a')"
+    sys.exit(1)
+if reader.moveToAttribute("b") != 1:
+    print "Failed moveToAttribute('b')"
+    sys.exit(1)
+if reader.value() != "b":
+    print "Failed to read attribute('b')"
+    sys.exit(1)
+if reader.moveToAttribute("a:b") != 1:
+    print "Failed moveToAttribute('a:b')"
+    sys.exit(1)
+if reader.value() != "a:b":
+    print "Failed to read attribute('a:b')"
+    sys.exit(1)
+if reader.moveToAttributeNs("b", "urn:2") != 1:
+    print "Failed moveToAttribute('b', 'urn:2')"
+    sys.exit(1)
+if reader.value() != "a:b":
+    print "Failed to read attribute('b', 'urn:2')"
+    sys.exit(1)
+#
+# Go back and read in sequence
+#
+if reader.moveToElement() != 1:
+    print "Failed to move back to element"
+    sys.exit(1)
+if reader.moveToFirstAttribute() != 1:
+    print "Failed to move to first attribute"
+    sys.exit(1)
+if reader.value() != "urn:1":
+    print "Failed to read attribute(0)"
+    sys.exit(1)
+if reader.name() != "xmlns":
+    print "Failed to read attribute(0) name"
+    sys.exit(1)
+if reader.moveToNextAttribute() != 1:
+    print "Failed to move to next attribute"
+    sys.exit(1)
+if reader.value() != "urn:2":
+    print "Failed to read attribute(1)"
+    sys.exit(1)
+if reader.name() != "xmlns:a":
+    print "Failed to read attribute(1) name"
+    sys.exit(1)
+if reader.moveToNextAttribute() != 1:
+    print "Failed to move to next attribute"
+    sys.exit(1)
+if reader.value() != "b":
+    print "Failed to read attribute(2)"
+    sys.exit(1)
+if reader.name() != "b":
+    print "Failed to read attribute(2) name"
+    sys.exit(1)
+if reader.moveToNextAttribute() != 1:
+    print "Failed to move to next attribute"
+    sys.exit(1)
+if reader.value() != "a:b":
+    print "Failed to read attribute(3)"
+    sys.exit(1)
+if reader.name() != "a:b":
+    print "Failed to read attribute(3) name"
+    sys.exit(1)
+if reader.moveToNextAttribute() != 0:
+    print "Failed to detect last attribute"
+    sys.exit(1)
+
 del f
 del input
 del reader
diff --git a/xmlreader.c b/xmlreader.c
index 0b6b13a..91c1102 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -78,6 +78,7 @@
     unsigned int 		base;	/* base of the segment in the input */
     unsigned int 		cur;	/* current position in the input */
     xmlNodePtr			node;	/* current node */
+    xmlNodePtr			curnode;/* current attribute node */
     int				depth;  /* depth of the current node */
 };
 
@@ -407,6 +408,7 @@
 
     ret->mode = XML_TEXTREADER_MODE_NORMAL;
     ret->node = NULL;
+    ret->curnode = NULL;
     val = xmlParserInputBufferRead(input, 4);
     if (val >= 4) {
 	ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
@@ -493,6 +495,7 @@
     if (reader == NULL)
 	return(-1);
     reader->node = NULL;
+    reader->curnode = NULL;
     reader->mode = XML_TEXTREADER_MODE_CLOSED;
     if (reader->ctxt != NULL) {
 	if (reader->ctxt->myDoc != NULL) {
@@ -537,6 +540,8 @@
 	return(NULL);
     if (reader->node == NULL)
 	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
     /* TODO: handle the xmlDecl */
     if (reader->node->type != XML_ELEMENT_NODE) 
 	return(NULL);
@@ -584,6 +589,8 @@
 	return(NULL);
     if (reader->node == NULL)
 	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
 
     /* TODO: handle the xmlDecl */
     if (reader->node->type != XML_ELEMENT_NODE)
@@ -623,6 +630,8 @@
 	return(NULL);
     if (reader->node == NULL)
 	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
 
     /* TODO: handle the xmlDecl */
     if (reader->node->type != XML_ELEMENT_NODE)
@@ -631,6 +640,377 @@
     return(xmlGetNsProp(reader->node, localName, namespaceURI));
 }
 
+/**
+ * xmlTextReaderGetRemainder:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Method to get the remainder of the buffered XML. this method stops the
+ * parser, set its state to End Of File and return the input stream with
+ * what is left that the parser did not use.
+ *
+ * Returns the xmlParserInputBufferPtr attached to the XML or NULL
+ *    in case of error.
+ */
+xmlParserInputBufferPtr
+xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
+    xmlParserInputBufferPtr ret = NULL;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+
+    reader->node = NULL;
+    reader->curnode = NULL;
+    reader->mode = XML_TEXTREADER_MODE_EOF;
+    if (reader->ctxt != NULL) {
+	if (reader->ctxt->myDoc != NULL) {
+	    xmlFreeDoc(reader->ctxt->myDoc);
+	    reader->ctxt->myDoc = NULL;
+	}
+	if (reader->allocs & XML_TEXTREADER_CTXT) {
+	    xmlFreeParserCtxt(reader->ctxt);
+	    reader->allocs -= XML_TEXTREADER_CTXT;
+	}
+    }
+    if (reader->sax != NULL) {
+        xmlFree(reader->sax);
+	reader->sax = NULL;
+    }
+    if (reader->allocs & XML_TEXTREADER_INPUT) {
+	ret = reader->input;
+	reader->allocs -= XML_TEXTREADER_INPUT;
+    } else {
+	/*
+	 * Hum, one may need to duplicate the data structure because
+	 * without reference counting the input may be freed twice:
+	 *   - by the layer which allocated it.
+	 *   - by the layer to which would have been returned to.
+	 */
+	TODO
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlTextReaderLookupNamespace:
+ * @reader:  the xmlTextReaderPtr used
+ * @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 *
+xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
+    xmlNsPtr ns;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+
+    ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
+    if (ns == NULL)
+	return(NULL);
+    return(xmlStrdup(ns->href));
+}
+
+/**
+ * xmlTextReaderMoveToAttributeNo:
+ * @reader:  the xmlTextReaderPtr used
+ * @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
+xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
+    int i;
+    xmlAttrPtr cur;
+    xmlNsPtr ns;
+
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE) 
+	return(-1);
+
+    reader->curnode = NULL;
+
+    ns = reader->node->nsDef;
+    for (i = 0;(i < no) && (ns != NULL);i++) {
+	ns = ns->next;
+    }
+    if (ns != NULL) {
+	reader->curnode = (xmlNodePtr) ns;
+	return(1);
+    }
+
+    cur = reader->node->properties;
+    if (cur == NULL)
+	return(0);
+    for (;i < no;i++) {
+	cur = cur->next;
+	if (cur == NULL)
+	    return(0);
+    }
+    /* TODO walk the DTD if present */
+
+    reader->curnode = (xmlNodePtr) cur;
+    return(1);
+}
+
+/**
+ * xmlTextReaderMoveToAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ * @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
+xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
+    xmlChar *prefix = NULL;
+    xmlChar *localname;
+    xmlNsPtr ns;
+    xmlAttrPtr prop;
+
+    if ((reader == NULL) || (name == NULL))
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+
+    localname = xmlSplitQName2(name, &prefix);
+    if (localname == NULL) {
+	/*
+	 * Namespace default decl
+	 */
+	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+	    ns = reader->node->nsDef;
+	    while (ns != NULL) {
+		if (ns->prefix == NULL) {
+		    reader->curnode = (xmlNodePtr) ns;
+		    return(1);
+		}
+		ns = ns->next;
+	    }
+	    return(0);
+	}
+
+	prop = reader->node->properties;
+	while (prop != NULL) {
+	    /*
+	     * One need to have
+	     *   - same attribute names
+	     *   - and the attribute carrying that namespace
+	     */
+	    if ((xmlStrEqual(prop->name, name)) &&
+		((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
+		reader->curnode = (xmlNodePtr) prop;
+		return(1);
+	    }
+	    prop = prop->next;
+	}
+	return(0);
+    }
+    
+    /*
+     * Namespace default decl
+     */
+    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+	ns = reader->node->nsDef;
+	while (ns != NULL) {
+	    if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
+		reader->curnode = (xmlNodePtr) ns;
+		goto found;
+	    }
+	    ns = ns->next;
+	}
+	goto not_found;
+    }
+    prop = reader->node->properties;
+    while (prop != NULL) {
+	/*
+	 * One need to have
+	 *   - same attribute names
+	 *   - and the attribute carrying that namespace
+	 */
+	if ((xmlStrEqual(prop->name, localname)) &&
+	    (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
+	    reader->curnode = (xmlNodePtr) prop;
+	    goto found;
+	}
+	prop = prop->next;
+    }
+not_found:
+    if (localname != NULL)
+        xmlFree(localname);
+    if (prefix != NULL)
+        xmlFree(prefix);
+    return(0);
+
+found:
+    if (localname != NULL)
+        xmlFree(localname);
+    if (prefix != NULL)
+        xmlFree(prefix);
+    return(1);
+}
+
+/**
+ * xmlTextReaderMoveToAttributeNs:
+ * @reader:  the xmlTextReaderPtr used
+ * @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
+xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
+	const xmlChar *localName, const xmlChar *namespaceURI) {
+    xmlAttrPtr prop;
+    xmlNodePtr node;
+
+    if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    node = reader->node;
+
+    /*
+     * A priori reading http://www.w3.org/TR/REC-xml-names/ there is no
+     * namespace name associated to "xmlns"
+     */
+    prop = node->properties;
+    while (prop != NULL) {
+	/*
+	 * One need to have
+	 *   - same attribute names
+	 *   - and the attribute carrying that namespace
+	 */
+        if (xmlStrEqual(prop->name, localName) &&
+	    ((prop->ns != NULL) &&
+	     (xmlStrEqual(prop->ns->href, namespaceURI)))) {
+	    reader->curnode = (xmlNodePtr) prop;
+	    return(1);
+        }
+	prop = prop->next;
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToFirstAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * 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
+xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+
+    if (reader->node->nsDef != NULL) {
+	reader->curnode = (xmlNodePtr) reader->node->nsDef;
+	return(1);
+    }
+    if (reader->node->properties != NULL) {
+	reader->curnode = (xmlNodePtr) reader->node->properties;
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToNextAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * 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
+xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (reader->curnode == NULL)
+	return(xmlTextReaderMoveToFirstAttribute(reader));
+
+    if (reader->curnode->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) reader->curnode;
+	if (ns->next != NULL) {
+	    reader->curnode = (xmlNodePtr) ns->next;
+	    return(1);
+	}
+	if (reader->node->properties != NULL) {
+	    reader->curnode = (xmlNodePtr) reader->node->properties;
+	    return(1);
+	}
+	return(0);
+    } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
+	       (reader->curnode->next != NULL)) {
+	reader->curnode = reader->curnode->next;
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToElement:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * 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
+xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (reader->curnode != NULL) {
+	reader->curnode = NULL;
+	return(1);
+    }
+    return(0);
+}
+
 /************************************************************************
  *									*
  *			Acces API to the current node			*
@@ -648,18 +1028,25 @@
 xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
     int ret;
     xmlAttrPtr attr;
+    xmlNodePtr node;
 
     if (reader == NULL)
 	return(-1);
     if (reader->node == NULL)
 	return(0);
-    if (reader->node->type != XML_ELEMENT_NODE)
+    
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    if (node->type != XML_ELEMENT_NODE)
 	return(0);
     if ((reader->state == XML_TEXTREADER_END) ||
 	(reader->state == XML_TEXTREADER_BACKTRACK))
 	return(0);
     ret = 0;
-    attr = reader->node->properties;
+    attr = node->properties;
     while (attr != NULL) {
 	ret++;
 	attr = attr->next;
@@ -679,11 +1066,16 @@
  */
 int
 xmlTextReaderNodeType(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if (reader == NULL)
 	return(-1);
     if (reader->node == NULL)
 	return(0);
-    switch (reader->node->type) {
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    switch (node->type) {
         case XML_ELEMENT_NODE:
 	    if ((reader->state == XML_TEXTREADER_END) ||
 		(reader->state == XML_TEXTREADER_BACKTRACK))
@@ -758,12 +1150,24 @@
  */
 xmlChar *
 xmlTextReaderLocalName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if ((reader == NULL) || (reader->node == NULL))
 	return(NULL);
-    if ((reader->node->type != XML_ELEMENT_NODE) &&
-	(reader->node->type != XML_ATTRIBUTE_NODE))
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(xmlStrdup(BAD_CAST "xmlns"));
+	else
+	    return(xmlStrdup(ns->prefix));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
 	return(xmlTextReaderName(reader));
-    return(xmlStrdup(reader->node->name));
+    return(xmlStrdup(node->name));
 }
 
 /**
@@ -776,20 +1180,25 @@
  */
 xmlChar *
 xmlTextReaderName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     xmlChar *ret;
 
     if ((reader == NULL) || (reader->node == NULL))
 	return(NULL);
-    switch (reader->node->type) {
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    switch (node->type) {
         case XML_ELEMENT_NODE:
         case XML_ATTRIBUTE_NODE:
-	    if ((reader->node->ns == NULL) ||
-		(reader->node->ns->prefix == NULL))
-		return(xmlStrdup(reader->node->name));
+	    if ((node->ns == NULL) ||
+		(node->ns->prefix == NULL))
+		return(xmlStrdup(node->name));
 	    
-	    ret = xmlStrdup(reader->node->ns->prefix);
+	    ret = xmlStrdup(node->ns->prefix);
 	    ret = xmlStrcat(ret, BAD_CAST ":");
-	    ret = xmlStrcat(ret, reader->node->name);
+	    ret = xmlStrcat(ret, node->name);
 	    return(ret);
         case XML_TEXT_NODE:
 	    return(xmlStrdup(BAD_CAST "#text"));
@@ -797,9 +1206,9 @@
 	    return(xmlStrdup(BAD_CAST "#cdata-section"));
         case XML_ENTITY_NODE:
         case XML_ENTITY_REF_NODE:
-	    return(xmlStrdup(reader->node->name));
+	    return(xmlStrdup(node->name));
         case XML_PI_NODE:
-	    return(xmlStrdup(reader->node->name));
+	    return(xmlStrdup(node->name));
         case XML_COMMENT_NODE:
 	    return(xmlStrdup(BAD_CAST "#comment"));
         case XML_DOCUMENT_NODE:
@@ -811,15 +1220,24 @@
         case XML_DOCUMENT_FRAG_NODE:
 	    return(xmlStrdup(BAD_CAST "#document-fragment"));
         case XML_NOTATION_NODE:
-	    return(xmlStrdup(reader->node->name));
+	    return(xmlStrdup(node->name));
         case XML_DOCUMENT_TYPE_NODE:
         case XML_DTD_NODE:
-	    return(xmlStrdup(reader->node->name));
+	    return(xmlStrdup(node->name));
+        case XML_NAMESPACE_DECL: {
+	    xmlNsPtr ns = (xmlNsPtr) node;
+
+	    ret = xmlStrdup(BAD_CAST "xmlns");
+	    if (ns->prefix == NULL)
+		return(ret);
+	    ret = xmlStrcat(ret, BAD_CAST ":");
+	    ret = xmlStrcat(ret, ns->prefix);
+	    return(ret);
+	}
 
         case XML_ELEMENT_DECL:
         case XML_ATTRIBUTE_DECL:
         case XML_ENTITY_DECL:
-        case XML_NAMESPACE_DECL:
         case XML_XINCLUDE_START:
         case XML_XINCLUDE_END:
 	    return(NULL);
@@ -837,13 +1255,24 @@
  */
 xmlChar *
 xmlTextReaderPrefix(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if ((reader == NULL) || (reader->node == NULL))
 	return(NULL);
-    if ((reader->node->type != XML_ELEMENT_NODE) &&
-	(reader->node->type != XML_ATTRIBUTE_NODE))
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(NULL);
+	return(xmlStrdup(BAD_CAST "xmlns"));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
 	return(NULL);
-    if ((reader->node->ns != NULL) || (reader->node->ns->prefix != NULL))
-	return(xmlStrdup(reader->node->ns->prefix));
+    if ((node->ns != NULL) || (node->ns->prefix != NULL))
+	return(xmlStrdup(node->ns->prefix));
     return(NULL);
 }
 
@@ -857,13 +1286,22 @@
  */
 xmlChar *
 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if ((reader == NULL) || (reader->node == NULL))
 	return(NULL);
-    if ((reader->node->type != XML_ELEMENT_NODE) &&
-	(reader->node->type != XML_ATTRIBUTE_NODE))
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	return(xmlStrdup(ns->href));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
 	return(NULL);
-    if (reader->node->ns != NULL)
-	return(xmlStrdup(reader->node->ns->href));
+    if (node->ns != NULL)
+	return(xmlStrdup(node->ns->href));
     return(NULL);
 }
 
@@ -910,13 +1348,18 @@
  */
 int
 xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if (reader == NULL)
 	return(-1);
     if (reader->node == NULL)
 	return(0);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
 
-    if ((reader->node->type == XML_ELEMENT_NODE) &&
-	(reader->node->properties != NULL))
+    if ((node->type == XML_ELEMENT_NODE) &&
+	(node->properties != NULL))
 	return(1);
     /* TODO: handle the xmlDecl */
     return(0);
@@ -932,12 +1375,17 @@
  */
 int
 xmlTextReaderHasValue(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if (reader == NULL)
 	return(-1);
     if (reader->node == NULL)
 	return(0);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
 
-    switch (reader->node->type) {
+    switch (node->type) {
         case XML_ATTRIBUTE_NODE:
         case XML_TEXT_NODE:
         case XML_CDATA_SECTION_NODE:
@@ -961,14 +1409,21 @@
  */
 xmlChar *
 xmlTextReaderValue(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
     if (reader == NULL)
 	return(NULL);
     if (reader->node == NULL)
 	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
 
-    switch (reader->node->type) {
+    switch (node->type) {
+        case XML_NAMESPACE_DECL:
+	    return(xmlStrdup(((xmlNsPtr) node)->href));
         case XML_ATTRIBUTE_NODE:{
-	    xmlAttrPtr attr = (xmlAttrPtr) reader->node;
+	    xmlAttrPtr attr = (xmlAttrPtr) node;
 
 	    if (attr->parent != NULL)
 		return (xmlNodeListGetString
@@ -981,8 +1436,8 @@
         case XML_CDATA_SECTION_NODE:
         case XML_PI_NODE:
         case XML_COMMENT_NODE:
-            if (reader->node->content != NULL)
-                return (xmlStrdup(reader->node->content));
+            if (node->content != NULL)
+                return (xmlStrdup(node->content));
 	default:
 	    return(NULL);
     }