diff --git a/ChangeLog b/ChangeLog index ae2fa9da..81404ed2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Jan 3 13:50:55 CET 2003 Daniel Veillard + + * 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 * xmlreader.c python/tests/reader2py: Fixing some more mess diff --git a/python/tests/reader2.py b/python/tests/reader2.py index 2488820e..2d0835e0 100755 --- a/python/tests/reader2.py +++ b/python/tests/reader2.py @@ -197,6 +197,45 @@ if err != "": print err sys.exit(1) +# +# The same test but without entity substitution this time +# + +s = """ + + +&y;"> +yyy"> +]> + + &x; + &x; +""" +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 # diff --git a/xmlreader.c b/xmlreader.c index f7d5b433..5bf93553 100644 --- a/xmlreader.c +++ b/xmlreader.c @@ -243,21 +243,12 @@ xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) { 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 @@ xmlTextReaderValidatePop(xmlTextReaderPtr reader) { 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 @@ node_found: 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 @@ node_found: 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) &&