- tree.c valid.c xmllint.c: Fixed a few postvalidation bugs
  and added a --dtdvalid option to xmllint used to test it
Daniel
diff --git a/ChangeLog b/ChangeLog
index 48506cd..2448a50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Oct 11 17:53:57 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* 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 <Daniel.Veillard@w3.org>
 
 	* xml-config.1 Makefile.am libxml.spec.in: adding a man page for
diff --git a/tree.c b/tree.c
index 850f554..ee3584b 100644
--- a/tree.c
+++ b/tree.c
@@ -3795,7 +3795,7 @@
     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 f5b40e2..28d6c9d 100644
--- a/valid.c
+++ b/valid.c
@@ -149,7 +149,8 @@
 
 #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 @@
 		*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 @@
 		*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 @@
 		*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 @@
 		     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 @@
     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 @@
     }
 
     /*
-     * 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 190632f..118a691 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -67,6 +67,7 @@
 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 @@
     /*
      * 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 @@
 	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 @@
 	    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 @@
 	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");