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/ChangeLog b/ChangeLog
index ae2fa9d..81404ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jan 3 13:50:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+ * xmlreader.c python/tests/reader2py: okay the DTD validation
+ code on top of the XMLTextParser API should be solid now.
+
Fri Jan 3 02:17:18 CET 2003 Daniel Veillard <daniel@veillard.com>
* xmlreader.c python/tests/reader2py: Fixing some more mess
diff --git a/python/tests/reader2.py b/python/tests/reader2.py
index 2488820..2d0835e 100755
--- a/python/tests/reader2.py
+++ b/python/tests/reader2.py
@@ -198,6 +198,45 @@
sys.exit(1)
#
+# The same test but without entity substitution this time
+#
+
+s = """<!DOCTYPE test [
+<!ELEMENT test (x, x)>
+<!ELEMENT x (y)>
+<!ELEMENT y (#PCDATA)>
+<!ENTITY x "<x>&y;</x>">
+<!ENTITY y "<y>yyy</y>">
+]>
+<test>
+ &x;
+ &x;
+</test>"""
+expect="""1 test 0
+3 #text 1
+5 x 1
+3 #text 1
+5 x 1
+3 #text 1
+15 test 0
+"""
+res=""
+err=""
+
+input = libxml2.inputBuffer(StringIO.StringIO(s))
+reader = input.newTextReader("test4")
+reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
+while reader.Read() == 1:
+ res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth())
+
+if res != expect:
+ print "test5 failed: unexpected output"
+ print res
+if err != "":
+ print "test5 failed: validation error found"
+ print err
+
+#
# cleanup
#
del input
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) &&