A posteriori validation should now work,
Added --postvalid to tester program
Added xmlDocGetRootElement() to the API,
Daniel
diff --git a/valid.c b/valid.c
index bc6d2ab..1efdbd0 100644
--- a/valid.c
+++ b/valid.c
@@ -2730,7 +2730,69 @@
CHECK_DTD;
- if ((elem == NULL) || (elem->name == NULL)) return(0);
+ if (elem == NULL) return(0);
+ if (elem->type == XML_TEXT_NODE) {
+ }
+ switch (elem->type) {
+ case XML_ATTRIBUTE_NODE:
+ VERROR(ctxt->userData,
+ "Attribute element not expected here\n");
+ return(0);
+ case XML_TEXT_NODE:
+ if (elem->childs != NULL) {
+ VERROR(ctxt->userData, "Text element has childs !\n");
+ return(0);
+ }
+ if (elem->properties != NULL) {
+ VERROR(ctxt->userData, "Text element has attributes !\n");
+ return(0);
+ }
+ if (elem->ns != NULL) {
+ VERROR(ctxt->userData, "Text element has namespace !\n");
+ return(0);
+ }
+ if (elem->ns != NULL) {
+ VERROR(ctxt->userData,
+ "Text element carries namespace definitions !\n");
+ return(0);
+ }
+ if (elem->content == NULL) {
+ VERROR(ctxt->userData,
+ "Text element has no content !\n");
+ return(0);
+ }
+ return(1);
+ case XML_CDATA_SECTION_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ return(1);
+ case XML_ENTITY_NODE:
+ VERROR(ctxt->userData,
+ "Entity element not expected here\n");
+ return(0);
+ case XML_NOTATION_NODE:
+ VERROR(ctxt->userData,
+ "Notation element not expected here\n");
+ return(0);
+ case XML_DOCUMENT_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ VERROR(ctxt->userData,
+ "Document element not expected here\n");
+ return(0);
+ case XML_HTML_DOCUMENT_NODE:
+ VERROR(ctxt->userData,
+ "\n");
+ return(0);
+ case XML_ELEMENT_NODE:
+ break;
+ default:
+ VERROR(ctxt->userData,
+ "unknown element type %d\n", elem->type);
+ return(0);
+ }
+ if (elem->name == NULL) return(0);
elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
if ((elemDecl == NULL) && (doc->extSubset != NULL))
@@ -2828,6 +2890,7 @@
int
xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
+ xmlNodePtr root;
if (doc == NULL) return(0);
if ((doc->intSubset == NULL) ||
@@ -2835,14 +2898,15 @@
VERROR(ctxt->userData, "Not valid: no DtD found\n");
return(0);
}
- if ((doc->root == NULL) || (doc->root->name == NULL)) {
+ root = xmlDocGetRootElement(doc);
+ if ((root == NULL) || (root->name == NULL)) {
VERROR(ctxt->userData, "Not valid: no root element\n");
return(0);
}
- if (xmlStrcmp(doc->intSubset->name, doc->root->name)) {
+ if (xmlStrcmp(doc->intSubset->name, root->name)) {
VERROR(ctxt->userData,
- "Not valid: root and DtD name do not match %s and %s\n",
- doc->root->name, doc->intSubset->name);
+ "Not valid: root and DtD name do not match '%s' and '%s'\n",
+ root->name, doc->intSubset->name);
return(0);
}
return(1);
@@ -2876,7 +2940,7 @@
value = xmlNodeListGetString(doc, attr->val, 0);
ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
if (value != NULL)
- free(value);
+ xmlFree(value);
attr= attr->next;
}
child = elem->childs;
@@ -2937,7 +3001,7 @@
* @doc: a document instance
* @dtd: a dtd instance
*
- * Try to validate the dtd instance
+ * Try to validate the document against the dtd instance
*
* basically it does check all the definitions in the DtD.
*
@@ -2946,8 +3010,24 @@
int
xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
- /* TODO xmlValidateDtd */
- return(1);
+ int ret;
+ xmlDtdPtr oldExt;
+ xmlNodePtr root;
+
+ if (dtd == NULL) return(0);
+ if (doc == NULL) return(0);
+ oldExt = doc->extSubset;
+ doc->extSubset = dtd;
+ ret = xmlValidateRoot(ctxt, doc);
+ if (ret == 0) {
+ doc->extSubset = oldExt;
+ return(ret);
+ }
+ root = xmlDocGetRootElement(doc);
+ ret = xmlValidateElement(ctxt, doc, root);
+ ret &= xmlValidateDocumentFinal(ctxt, doc);
+ doc->extSubset = oldExt;
+ return(ret);
}
/**
@@ -2967,10 +3047,32 @@
int
xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
int ret;
+ xmlNodePtr root;
+
+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
+ return(0);
+ if ((doc->intSubset != NULL) && ((doc->intSubset->SystemID != NULL) ||
+ (doc->intSubset->ExternalID != NULL)) && (doc->extSubset == NULL)) {
+ doc->extSubset = xmlParseDTD(doc->intSubset->ExternalID,
+ doc->intSubset->SystemID);
+ if (doc->extSubset == NULL) {
+ if (doc->intSubset->SystemID != NULL) {
+ VERROR(ctxt->userData,
+ "Could not load the external subset '%s'\n",
+ doc->intSubset->SystemID);
+ } else {
+ VERROR(ctxt->userData,
+ "Could not load the external subset '%s'\n",
+ doc->intSubset->ExternalID);
+ }
+ return(0);
+ }
+ }
if (!xmlValidateRoot(ctxt, doc)) return(0);
- ret = xmlValidateElement(ctxt, doc, doc->root);
+ root = xmlDocGetRootElement(doc);
+ ret = xmlValidateElement(ctxt, doc, root);
ret &= xmlValidateDocumentFinal(ctxt, doc);
return(ret);
}