okay the DTD validation code on top of the XMLTextParser API should be

* xmlreader.c python/tests/reader2py: okay the DTD validation
  code on top of the XMLTextParser API should be solid now.
Daniel
diff --git a/xmlreader.c b/xmlreader.c
index f7d5b43..5bf9355 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -243,21 +243,12 @@
     printf("xmlTextReaderEndElement(%s)\n", fullname);
 #endif
     if ((reader != NULL) && (reader->endElement != NULL)) {
-	xmlNodePtr node = ctxt->node;
 	/*
 	 * when processing an entity, the context may have been changed
 	 */
 	origctxt = reader->ctxt;
 
 	reader->endElement(ctx, fullname);
-
-#if 0
-	123
-	if (origctxt->validate) {
-	    ctxt->valid &= xmlValidatePopElement(&origctxt->vctxt,
-		                ctxt->myDoc, node, fullname);
-	}
-#endif
     }
     if (reader != NULL) {
 	if (reader->state == XML_TEXTREADER_ELEMENT)
@@ -472,6 +463,86 @@
 	    xmlFree(qname);
     }
 }
+/**
+ * xmlTextReaderValidateEntity:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Handle the validation when an entity reference is encountered and
+ * entity substitution is not activated. As a result the parser interface
+ * must walk through the entity and do the validation calls
+ */
+static void
+xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
+    xmlNodePtr oldnode = reader->node;
+    xmlNodePtr node = reader->node;
+    xmlParserCtxtPtr ctxt = reader->ctxt;
+
+    do {
+	if (node->type == XML_ENTITY_REF_NODE) {
+	    /*
+	     * Case where the underlying tree is not availble, lookup the entity
+	     * and walk it.
+	     */
+	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
+		(ctxt->sax->getEntity != NULL)) {
+		node->children = (xmlNodePtr) 
+		    ctxt->sax->getEntity(ctxt, node->name);
+	    }
+
+	    if ((node->children != NULL) &&
+		(node->children->type == XML_ENTITY_DECL) &&
+		(node->children->children != NULL)) {
+		xmlTextReaderEntPush(reader, node);
+		node = node->children->children;
+		continue;
+	    } else {
+		/*
+		 * The error has probably be raised already.
+		 */
+		if (node == oldnode)
+		    break;
+		node = node->next;
+	    }
+	} else if (node->type == XML_ELEMENT_NODE) {
+	    reader->node = node;
+	    xmlTextReaderValidatePush(reader);
+	} else if ((node->type == XML_TEXT_NODE) ||
+		   (node->type == XML_CDATA_SECTION_NODE)) {
+	    ctxt->valid &= xmlValidatePushCData(&ctxt->vctxt,
+			      node->content, xmlStrlen(node->content));
+	}
+
+	/*
+	 * go to next node
+	 */
+	if (node->children != NULL) {
+	    node = node->children;
+	    continue;
+	}
+	if (node->next != NULL) {
+	    node = node->next;
+	    continue;
+	}
+	do {
+	    node = node->parent;
+	    if (node->type == XML_ELEMENT_NODE) {
+		reader->node = node;
+		xmlTextReaderValidatePop(reader);
+	    }
+	    if ((node->type == XML_ENTITY_DECL) &&
+		(reader->ent != NULL) && (reader->ent->children == node)) {
+		node = xmlTextReaderEntPop(reader);
+	    }
+	    if (node == oldnode)
+		break;
+	    if (node->next != NULL) {
+		node = node->next;
+		break;
+	    }
+	} while ((node != NULL) && (node != oldnode));
+    } while ((node != NULL) && (node != oldnode));
+    reader->node = oldnode;
+}
 
 
 /**
@@ -633,7 +704,7 @@
     DUMP_READER
 
     /*
-     * Handle entities enter and exit
+     * Handle entities enter and exit when in entity replacement mode
      */
     if ((reader->node != NULL) &&
 	(reader->node->type == XML_ENTITY_REF_NODE) &&
@@ -654,6 +725,10 @@
 	    xmlTextReaderEntPush(reader, reader->node);
 	    reader->node = reader->node->children->children;
 	}
+    } else if ((reader->node != NULL) &&
+	       (reader->node->type == XML_ENTITY_REF_NODE) &&
+	       (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
+	xmlTextReaderValidateEntity(reader);
     }
     if ((reader->node != NULL) &&
 	(reader->node->type == XML_ENTITY_DECL) &&