diff --git a/ChangeLog b/ChangeLog index 48506cd1..2448a50c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Oct 11 17:53:57 CEST 2000 Daniel Veillard + + * tree.c valid.c xmllint.c: Fixed a few postvalidation bugs + and added a --dtdvalid option to xmllint used to test it + Wed Oct 11 15:01:29 CEST 2000 Daniel Veillard * xml-config.1 Makefile.am libxml.spec.in: adding a man page for diff --git a/tree.c b/tree.c index 850f554f..ee3584b6 100644 --- a/tree.c +++ b/tree.c @@ -3795,7 +3795,7 @@ xmlIsBlankNode(xmlNodePtr node) { if (node == NULL) return(0); if (node->type != XML_TEXT_NODE) return(0); - if (node->content == NULL) return(0); + if (node->content == NULL) return(1); cur = node->content; while (*cur != 0) { if (!IS_BLANK(*cur)) return(0); diff --git a/valid.c b/valid.c index f5b40e23..28d6c9d9 100644 --- a/valid.c +++ b/valid.c @@ -149,7 +149,8 @@ void xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) { #define CHECK_DTD \ if (doc == NULL) return(0); \ - else if (doc->intSubset == NULL) return(0) + else if ((doc->intSubset == NULL) && \ + (doc->extSubset == NULL)) return(0) xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name); xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem); @@ -3329,6 +3330,14 @@ xmlValidateElementTypeExpr(xmlValidCtxtPtr ctxt, xmlNodePtr *child, *child = (*child)->next; continue; } + if (((*child)->type == XML_TEXT_NODE) && + (xmlIsBlankNode(*child)) && + ((cont->type == XML_ELEMENT_CONTENT_ELEMENT) || + (cont->type == XML_ELEMENT_CONTENT_SEQ) || + (cont->type == XML_ELEMENT_CONTENT_OR))) { + *child = (*child)->next; + continue; + } if ((*child)->type == XML_PI_NODE) { *child = (*child)->next; continue; @@ -3434,6 +3443,14 @@ xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child, *child = (*child)->next; continue; } + if (((*child)->type == XML_TEXT_NODE) && + (xmlIsBlankNode(*child)) && + ((cont->type == XML_ELEMENT_CONTENT_ELEMENT) || + (cont->type == XML_ELEMENT_CONTENT_SEQ) || + (cont->type == XML_ELEMENT_CONTENT_OR))) { + *child = (*child)->next; + continue; + } if ((*child)->type == XML_PI_NODE) { *child = (*child)->next; continue; @@ -3511,6 +3528,14 @@ xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child, *child = (*child)->next; continue; } + if (((*child)->type == XML_TEXT_NODE) && + (xmlIsBlankNode(*child)) && + ((cont->type == XML_ELEMENT_CONTENT_ELEMENT) || + (cont->type == XML_ELEMENT_CONTENT_SEQ) || + (cont->type == XML_ELEMENT_CONTENT_OR))) { + *child = (*child)->next; + continue; + } if ((*child)->type == XML_PI_NODE) { *child = (*child)->next; continue; @@ -3551,6 +3576,8 @@ xmlSprintfElementChilds(char *buf, xmlNodePtr node, int glob) { strcat(buf, " "); break; case XML_TEXT_NODE: + if (xmlIsBlankNode(cur)) + break; case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: strcat(buf, "CDATA"); @@ -3887,11 +3914,6 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { xmlNodePtr root; if (doc == NULL) return(0); - if ((doc->intSubset == NULL) || - (doc->intSubset->name == NULL)) { - VERROR(ctxt->userData, "Not valid: no DtD found\n"); - return(0); - } root = xmlDocGetRootElement(doc); if ((root == NULL) || (root->name == NULL)) { VERROR(ctxt->userData, "Not valid: no root element\n"); @@ -3899,29 +3921,36 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { } /* - * Check first the document root against the NQName + * When doing post validation against a separate DTD, those may + * no internal subset has been generated */ - if (!xmlStrEqual(doc->intSubset->name, root->name)) { - if ((root->ns != NULL) && (root->ns->prefix != NULL)) { - xmlChar qname[500]; + if ((doc->intSubset != NULL) && + (doc->intSubset->name != NULL)) { + /* + * Check first the document root against the NQName + */ + if (!xmlStrEqual(doc->intSubset->name, root->name)) { + if ((root->ns != NULL) && (root->ns->prefix != NULL)) { + xmlChar qname[500]; #ifdef HAVE_SNPRINTF - snprintf((char *) qname, sizeof(qname), "%s:%s", - root->ns->prefix, root->name); + snprintf((char *) qname, sizeof(qname), "%s:%s", + root->ns->prefix, root->name); #else - sprintf((char *) qname, "%s:%s", root->ns->prefix, root->name); + sprintf((char *) qname, "%s:%s", root->ns->prefix, root->name); #endif - qname[sizeof(qname) - 1] = 0; - if (xmlStrEqual(doc->intSubset->name, qname)) + qname[sizeof(qname) - 1] = 0; + if (xmlStrEqual(doc->intSubset->name, qname)) + goto name_ok; + } + if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) && + (xmlStrEqual(root->name, BAD_CAST "html"))) goto name_ok; - } - if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) && - (xmlStrEqual(root->name, BAD_CAST "html"))) - goto name_ok; - VERROR(ctxt->userData, - "Not valid: root and DtD name do not match '%s' and '%s'\n", - root->name, doc->intSubset->name); - return(0); - + VERROR(ctxt->userData, + "Not valid: root and DtD name do not match '%s' and '%s'\n", + root->name, doc->intSubset->name); + return(0); + + } } name_ok: return(1); diff --git a/xmllint.c b/xmllint.c index 190632f7..118a6919 100644 --- a/xmllint.c +++ b/xmllint.c @@ -67,6 +67,7 @@ static int noout = 0; static int nowrap = 0; static int valid = 0; static int postvalid = 0; +static char * dtdvalid = NULL; static int repeat = 0; static int insert = 0; static int compress = 0; @@ -562,10 +563,27 @@ void parseAndPrintFile(char *filename) { /* * A posteriori validation test */ - if (postvalid) { + if (dtdvalid != NULL) { + xmlDtdPtr dtd; + + dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); + if (dtd == NULL) { + fprintf(stderr, "Could not parse DTD %s\n", dtdvalid); + } else { + xmlValidCtxt cvp; + cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf; + if (!xmlValidateDtd(&cvp, doc, dtd)) { + fprintf(stderr, "Document %s does not validate against %s\n", + filename, dtdvalid); + } + xmlFreeDtd(dtd); + } + } else if (postvalid) { xmlValidCtxt cvp; cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf; - xmlValidateDocument(&cvp, doc); + if (!xmlValidateDocument(&cvp, doc)) { + fprintf(stderr, "Document %s does not validate\n", filename); + } } #ifdef LIBXML_DEBUG_ENABLED @@ -623,6 +641,11 @@ int main(int argc, char **argv) { else if ((!strcmp(argv[i], "-postvalid")) || (!strcmp(argv[i], "--postvalid"))) postvalid++; + else if ((!strcmp(argv[i], "-dtdvalid")) || + (!strcmp(argv[i], "--dtdvalid"))) { + i++; + dtdvalid = argv[i]; + } else if ((!strcmp(argv[i], "-insert")) || (!strcmp(argv[i], "--insert"))) insert++; @@ -696,6 +719,11 @@ int main(int argc, char **argv) { i++; continue; } + if ((!strcmp(argv[i], "-dtdvalid")) || + (!strcmp(argv[i], "--dtdvalid"))) { + i++; + continue; + } if (argv[i][0] != '-') { if (repeat) { for (count = 0;count < 100 * repeat;count++) @@ -725,6 +753,7 @@ int main(int argc, char **argv) { printf("\t--nowarp : do not put HTML doc wrapper\n"); printf("\t--valid : validate the document in addition to std well-formed check\n"); printf("\t--postvalid : do a posteriori validation, i.e after parsing\n"); + printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n"); printf("\t--repeat : repeat 100 times, for timing or profiling\n"); printf("\t--insert : ad-hoc test for valid insertions\n"); printf("\t--compress : turn on gzip compression of output\n");