version 1.61, 2000/04/03 18:45:48
|
version 1.62, 2000/06/26 07:32:33
|
Line 154 void xmlValidDebug(xmlNodePtr cur, xmlEl
|
Line 154 void xmlValidDebug(xmlNodePtr cur, xmlEl
|
xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name); |
xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name); |
xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem); |
xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem); |
|
|
|
/************************************************************************ |
|
* * |
|
* QName handling helper * |
|
* * |
|
************************************************************************/ |
|
|
|
/** |
|
* xmlSplitQName2: |
|
* @name: an XML parser context |
|
* @prefix: a xmlChar ** |
|
* |
|
* parse an XML qualified name string |
|
* |
|
* [NS 5] QName ::= (Prefix ':')? LocalPart |
|
* |
|
* [NS 6] Prefix ::= NCName |
|
* |
|
* [NS 7] LocalPart ::= NCName |
|
* |
|
* Returns NULL if not a QName, otherwise the local part, and prefix |
|
* is updated to get the Prefix if any. |
|
*/ |
|
|
|
xmlChar * |
|
xmlSplitQName2(const xmlChar *name, xmlChar **prefix) { |
|
int len = 0; |
|
xmlChar *ret = NULL; |
|
|
|
*prefix = NULL; |
|
|
|
/* xml: prefix is not really a namespace */ |
|
if ((name[0] == 'x') && (name[1] == 'm') && |
|
(name[2] == 'l') && (name[3] == ':')) |
|
return(NULL); |
|
|
|
/* nasty but valid */ |
|
if (name[0] == ':') |
|
return(NULL); |
|
|
|
/* |
|
* we are not trying to validate but just to cut, and yes it will |
|
* work even if this is as set of UTF-8 encoded chars |
|
*/ |
|
while ((name[len] != 0) && (name[len] != ':')) |
|
len++; |
|
|
|
if (name[len] == 0) |
|
return(NULL); |
|
|
|
*prefix = xmlStrndup(name, len); |
|
ret = xmlStrdup(&name[len + 1]); |
|
|
|
return(ret); |
|
} |
|
|
/**************************************************************** |
/**************************************************************** |
* * |
* * |
* Util functions for data allocation/deallocation * |
* Util functions for data allocation/deallocation * |
Line 428 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
Line 483 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
xmlElementContentPtr content) { |
xmlElementContentPtr content) { |
xmlElementPtr ret, cur; |
xmlElementPtr ret, cur; |
xmlElementTablePtr table; |
xmlElementTablePtr table; |
|
xmlChar *ns, *uqname; |
int i; |
int i; |
|
|
if (dtd == NULL) { |
if (dtd == NULL) { |
Line 473 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
Line 529 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
} |
} |
|
|
/* |
/* |
|
* check if name is a QName |
|
*/ |
|
uqname = xmlSplitQName2(name, &ns); |
|
if (uqname != NULL) |
|
name = uqname; |
|
|
|
/* |
* Create the Element table if needed. |
* Create the Element table if needed. |
*/ |
*/ |
table = dtd->elements; |
table = dtd->elements; |
Line 489 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
Line 552 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
*/ |
*/ |
for (i = 0;i < table->nb_elements;i++) { |
for (i = 0;i < table->nb_elements;i++) { |
cur = table->table[i]; |
cur = table->table[i]; |
if (!xmlStrcmp(cur->name, name)) { |
if ((ns != NULL) && (cur->prefix == NULL)) continue; |
|
if ((ns == NULL) && (cur->prefix != NULL)) continue; |
|
if ((!xmlStrcmp(cur->name, name)) && |
|
((ns == NULL) || (!xmlStrcmp(cur->prefix, ns)))) { |
/* |
/* |
* The element is already defined in this Dtd. |
* The element is already defined in this Dtd. |
*/ |
*/ |
Line 527 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
Line 593 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
*/ |
*/ |
ret->etype = type; |
ret->etype = type; |
ret->name = xmlStrdup(name); |
ret->name = xmlStrdup(name); |
|
ret->prefix = ns; |
ret->content = xmlCopyElementContent(content); |
ret->content = xmlCopyElementContent(content); |
ret->attributes = xmlScanAttributeDecl(dtd, name); |
ret->attributes = xmlScanAttributeDecl(dtd, name); |
table->nb_elements++; |
table->nb_elements++; |
Line 543 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
Line 610 xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
ret->prev = dtd->last; |
ret->prev = dtd->last; |
dtd->last = (xmlNodePtr) ret; |
dtd->last = (xmlNodePtr) ret; |
} |
} |
|
if (uqname != NULL) |
|
xmlFree(uqname); |
return(ret); |
return(ret); |
} |
} |
|
|
Line 559 xmlFreeElement(xmlElementPtr elem) {
|
Line 628 xmlFreeElement(xmlElementPtr elem) {
|
xmlFreeElementContent(elem->content); |
xmlFreeElementContent(elem->content); |
if (elem->name != NULL) |
if (elem->name != NULL) |
xmlFree((xmlChar *) elem->name); |
xmlFree((xmlChar *) elem->name); |
|
if (elem->prefix != NULL) |
|
xmlFree((xmlChar *) elem->prefix); |
memset(elem, -1, sizeof(xmlElement)); |
memset(elem, -1, sizeof(xmlElement)); |
xmlFree(elem); |
xmlFree(elem); |
} |
} |
Line 896 xmlScanIDAttributeDecl(xmlValidCtxtPtr c
|
Line 967 xmlScanIDAttributeDecl(xmlValidCtxtPtr c
|
* |
* |
* Register a new attribute declaration |
* Register a new attribute declaration |
* |
* |
* Returns NULL if not, othervise the entity |
* Returns NULL if not new, othervise the attribute decl |
*/ |
*/ |
xmlAttributePtr |
xmlAttributePtr |
xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem, |
xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem, |
Line 981 xmlAddAttributeDecl(xmlValidCtxtPtr ctxt
|
Line 1052 xmlAddAttributeDecl(xmlValidCtxtPtr ctxt
|
*/ |
*/ |
VWARNING(ctxt->userData, "Attribute %s on %s: already defined\n", |
VWARNING(ctxt->userData, "Attribute %s on %s: already defined\n", |
elem, name); |
elem, name); |
|
return(NULL); |
} |
} |
} |
} |
|
|
Line 1157 xmlDumpAttributeDecl(xmlBufferPtr buf, x
|
Line 1229 xmlDumpAttributeDecl(xmlBufferPtr buf, x
|
xmlBufferWriteChar(buf, "<!ATTLIST "); |
xmlBufferWriteChar(buf, "<!ATTLIST "); |
xmlBufferWriteCHAR(buf, attr->elem); |
xmlBufferWriteCHAR(buf, attr->elem); |
xmlBufferWriteChar(buf, " "); |
xmlBufferWriteChar(buf, " "); |
|
if (attr->prefix != NULL) { |
|
xmlBufferWriteCHAR(buf, attr->prefix); |
|
xmlBufferWriteChar(buf, ":"); |
|
} |
xmlBufferWriteCHAR(buf, attr->name); |
xmlBufferWriteCHAR(buf, attr->name); |
switch (attr->atype) { |
switch (attr->atype) { |
case XML_ATTRIBUTE_CDATA: |
case XML_ATTRIBUTE_CDATA: |
Line 2066 xmlElementPtr
|
Line 2142 xmlElementPtr
|
xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) { |
xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) { |
xmlElementTablePtr table; |
xmlElementTablePtr table; |
xmlElementPtr cur; |
xmlElementPtr cur; |
|
xmlChar *uqname = NULL, *prefix = NULL; |
int i; |
int i; |
|
|
if (dtd == NULL) return(NULL); |
if (dtd == NULL) return(NULL); |
Line 2077 xmlGetDtdElementDesc(xmlDtdPtr dtd, cons
|
Line 2154 xmlGetDtdElementDesc(xmlDtdPtr dtd, cons
|
if (!xmlStrcmp(cur->name, name)) |
if (!xmlStrcmp(cur->name, name)) |
return(cur); |
return(cur); |
} |
} |
|
|
|
/* |
|
* Specific case if name is a QName. |
|
*/ |
|
uqname = xmlSplitQName2(name, &prefix); |
|
if (uqname == NULL) return(NULL); |
|
|
|
for (i = 0;i < table->nb_elements;i++) { |
|
cur = table->table[i]; |
|
if ((!xmlStrcmp(cur->name, uqname)) && |
|
((prefix == cur->prefix) || |
|
((prefix != NULL) && (cur->prefix != NULL) && |
|
(!xmlStrcmp(cur->prefix, prefix))))) { |
|
if (prefix != NULL) xmlFree(prefix); |
|
if (uqname != NULL) xmlFree(uqname); |
|
return(cur); |
|
} |
|
} |
|
if (prefix != NULL) xmlFree(prefix); |
|
if (uqname != NULL) xmlFree(uqname); |
|
return(NULL); |
|
} |
|
|
|
/** |
|
* xmlGetDtdQElementDesc: |
|
* @dtd: a pointer to the DtD to search |
|
* @name: the element name |
|
* @prefix: the element namespace prefix |
|
* |
|
* Search the Dtd for the description of this element |
|
* |
|
* returns the xmlElementPtr if found or NULL |
|
*/ |
|
|
|
xmlElementPtr |
|
xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name, |
|
const xmlChar *prefix) { |
|
xmlElementTablePtr table; |
|
xmlElementPtr cur; |
|
int i; |
|
|
|
if (dtd == NULL) return(NULL); |
|
if (dtd->elements == NULL) return(NULL); |
|
table = dtd->elements; |
|
|
|
for (i = 0;i < table->nb_elements;i++) { |
|
cur = table->table[i]; |
|
if (!xmlStrcmp(cur->name, name) && |
|
((prefix == cur->prefix) || |
|
((prefix != NULL) && (cur->prefix != NULL) && |
|
(!xmlStrcmp(cur->prefix, prefix))))) |
|
return(cur); |
|
} |
return(NULL); |
return(NULL); |
} |
} |
|
|
Line 2096 xmlAttributePtr
|
Line 2226 xmlAttributePtr
|
xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) { |
xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) { |
xmlAttributeTablePtr table; |
xmlAttributeTablePtr table; |
xmlAttributePtr cur; |
xmlAttributePtr cur; |
|
xmlChar *uqname = NULL, *prefix = NULL; |
int i; |
int i; |
|
|
if (dtd == NULL) return(NULL); |
if (dtd == NULL) return(NULL); |
Line 2108 xmlGetDtdAttrDesc(xmlDtdPtr dtd, const x
|
Line 2239 xmlGetDtdAttrDesc(xmlDtdPtr dtd, const x
|
(!xmlStrcmp(cur->elem, elem))) |
(!xmlStrcmp(cur->elem, elem))) |
return(cur); |
return(cur); |
} |
} |
|
|
|
/* |
|
* Specific case if name is a QName. |
|
*/ |
|
uqname = xmlSplitQName2(name, &prefix); |
|
if (uqname == NULL) return(NULL); |
|
|
|
for (i = 0;i < table->nb_attributes;i++) { |
|
cur = table->table[i]; |
|
if ((!xmlStrcmp(cur->name, uqname)) && |
|
(!xmlStrcmp(cur->elem, elem)) && |
|
((prefix == cur->prefix) || |
|
((prefix != NULL) && (cur->prefix != NULL) && |
|
(!xmlStrcmp(cur->prefix, prefix))))) { |
|
if (prefix != NULL) xmlFree(prefix); |
|
if (uqname != NULL) xmlFree(uqname); |
|
return(cur); |
|
} |
|
} |
|
if (prefix != NULL) xmlFree(prefix); |
|
if (uqname != NULL) xmlFree(uqname); |
|
return(NULL); |
|
} |
|
|
|
/** |
|
* xmlGetDtdQAttrDesc: |
|
* @dtd: a pointer to the DtD to search |
|
* @elem: the element name |
|
* @name: the attribute name |
|
* @prefix: the attribute namespace prefix |
|
* |
|
* Search the Dtd for the description of this qualified attribute on |
|
* this element. |
|
* |
|
* returns the xmlAttributePtr if found or NULL |
|
*/ |
|
|
|
xmlAttributePtr |
|
xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name, |
|
const xmlChar *prefix) { |
|
xmlAttributeTablePtr table; |
|
xmlAttributePtr cur; |
|
int i; |
|
|
|
if (dtd == NULL) return(NULL); |
|
if (dtd->attributes == NULL) return(NULL); |
|
table = dtd->attributes; |
|
|
|
for (i = 0;i < table->nb_attributes;i++) { |
|
cur = table->table[i]; |
|
if ((!xmlStrcmp(cur->name, name)) && |
|
(!xmlStrcmp(cur->elem, elem)) && |
|
((prefix == cur->prefix) || |
|
((prefix != NULL) && (cur->prefix != NULL) && |
|
(!xmlStrcmp(cur->prefix, prefix))))) |
|
return(cur); |
|
} |
return(NULL); |
return(NULL); |
} |
} |
|
|
Line 2586 xmlValidNormalizeAttributeValue(xmlDocPt
|
Line 2774 xmlValidNormalizeAttributeValue(xmlDocPt
|
const xmlChar *name, const xmlChar *value) { |
const xmlChar *name, const xmlChar *value) { |
xmlChar *ret, *dst; |
xmlChar *ret, *dst; |
const xmlChar *src; |
const xmlChar *src; |
xmlAttributePtr attrDecl; |
xmlAttributePtr attrDecl = NULL; |
|
|
if (doc == NULL) return(NULL); |
if (doc == NULL) return(NULL); |
if (elem == NULL) return(NULL); |
if (elem == NULL) return(NULL); |
if (name == NULL) return(NULL); |
if (name == NULL) return(NULL); |
if (value == NULL) return(NULL); |
if (value == NULL) return(NULL); |
|
|
|
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { |
|
xmlChar qname[500]; |
|
#ifdef HAVE_SNPRINTF |
|
snprintf((char *) qname, sizeof(qname), "%s:%s", |
|
elem->ns->prefix, elem->name); |
|
#else |
|
sprintf(qname, "%s:%s", elem->name, elem->ns->prefix); |
|
#endif |
|
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name); |
|
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
|
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name); |
|
} |
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); |
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); |
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name); |
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name); |
Line 2850 int
|
Line 3050 int
|
xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) { |
xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) { |
/* xmlElementPtr elemDecl; */ |
/* xmlElementPtr elemDecl; */ |
xmlAttributePtr attrDecl; |
xmlAttributePtr attrDecl = NULL; |
int val; |
int val; |
int ret = 1; |
int ret = 1; |
|
|
Line 2858 xmlValidateOneAttribute(xmlValidCtxtPtr
|
Line 3058 xmlValidateOneAttribute(xmlValidCtxtPtr
|
if ((elem == NULL) || (elem->name == NULL)) return(0); |
if ((elem == NULL) || (elem->name == NULL)) return(0); |
if ((attr == NULL) || (attr->name == NULL)) return(0); |
if ((attr == NULL) || (attr->name == NULL)) return(0); |
|
|
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name); |
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { |
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
xmlChar qname[500]; |
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, attr->name); |
#ifdef HAVE_SNPRINTF |
|
snprintf((char *) qname, sizeof(qname), "%s:%s", |
|
elem->ns->prefix, elem->name); |
|
#else |
|
sprintf(qname, "%s:%s", elem->name, elem->ns->prefix); |
|
#endif |
|
if (attr->ns != NULL) { |
|
attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname, |
|
attr->name, attr->ns->prefix); |
|
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
|
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname, |
|
attr->name, attr->ns->prefix); |
|
} else { |
|
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name); |
|
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
|
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, |
|
qname, attr->name); |
|
} |
|
} |
|
if (attrDecl == NULL) { |
|
if (attr->ns != NULL) { |
|
attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name, |
|
attr->name, attr->ns->prefix); |
|
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
|
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name, |
|
attr->name, attr->ns->prefix); |
|
} else { |
|
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, |
|
elem->name, attr->name); |
|
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
|
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, |
|
elem->name, attr->name); |
|
} |
|
} |
|
|
|
|
/* Validity Constraint: Attribute Value Type */ |
/* Validity Constraint: Attribute Value Type */ |
Line 3274 xmlSprintfElementChilds(char *buf, xmlNo
|
Line 3507 xmlSprintfElementChilds(char *buf, xmlNo
|
int |
int |
xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
xmlNodePtr elem) { |
xmlNodePtr elem) { |
xmlElementPtr elemDecl; |
xmlElementPtr elemDecl = NULL; |
xmlElementContentPtr cont; |
xmlElementContentPtr cont; |
xmlAttributePtr attr; |
xmlAttributePtr attr; |
xmlNodePtr child; |
xmlNodePtr child; |
Line 3347 xmlValidateOneElement(xmlValidCtxtPtr ct
|
Line 3580 xmlValidateOneElement(xmlValidCtxtPtr ct
|
} |
} |
if (elem->name == NULL) return(0); |
if (elem->name == NULL) return(0); |
|
|
elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name); |
/* |
if ((elemDecl == NULL) && (doc->extSubset != NULL)) |
* Fetch the declaration for the qualified name |
elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name); |
*/ |
|
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { |
|
elemDecl = xmlGetDtdQElementDesc(doc->intSubset, |
|
elem->name, elem->ns->prefix); |
|
if ((elemDecl == NULL) && (doc->extSubset != NULL)) |
|
elemDecl = xmlGetDtdQElementDesc(doc->extSubset, |
|
elem->name, elem->ns->prefix); |
|
} |
|
|
|
/* |
|
* Fetch the declaration for the non qualified name |
|
*/ |
|
if (elemDecl == NULL) { |
|
elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name); |
|
if ((elemDecl == NULL) && (doc->extSubset != NULL)) |
|
elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name); |
|
} |
if (elemDecl == NULL) { |
if (elemDecl == NULL) { |
VERROR(ctxt->userData, "No declaration for element %s\n", |
VERROR(ctxt->userData, "No declaration for element %s\n", |
elem->name); |
elem->name); |
Line 3375 xmlValidateOneElement(xmlValidCtxtPtr ct
|
Line 3624 xmlValidateOneElement(xmlValidCtxtPtr ct
|
while (child != NULL) { |
while (child != NULL) { |
if (child->type == XML_ELEMENT_NODE) { |
if (child->type == XML_ELEMENT_NODE) { |
name = child->name; |
name = child->name; |
|
if ((child->ns != NULL) && (child->ns->prefix != NULL)) { |
|
xmlChar qname[500]; |
|
#ifdef HAVE_SNPRINTF |
|
snprintf((char *) qname, sizeof(qname), "%s:%s", |
|
child->ns->prefix, child->name); |
|
#else |
|
sprintf(qname, "%s:%s", child->name, child->ns->prefix); |
|
#endif |
|
cont = elemDecl->content; |
|
while (cont != NULL) { |
|
if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) { |
|
if (!xmlStrcmp(cont->name, qname)) break; |
|
} else if ((cont->type == XML_ELEMENT_CONTENT_OR) && |
|
(cont->c1 != NULL) && |
|
(cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){ |
|
if (!xmlStrcmp(cont->c1->name, qname)) break; |
|
} else if ((cont->type != XML_ELEMENT_CONTENT_OR) || |
|
(cont->c1 == NULL) || |
|
(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){ |
|
/* Internal error !!! */ |
|
fprintf(stderr, "Internal: MIXED struct bad\n"); |
|
break; |
|
} |
|
cont = cont->c2; |
|
} |
|
if (cont != NULL) |
|
goto child_ok; |
|
} |
cont = elemDecl->content; |
cont = elemDecl->content; |
while (cont != NULL) { |
while (cont != NULL) { |
if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) { |
if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) { |
Line 3399 xmlValidateOneElement(xmlValidCtxtPtr ct
|
Line 3676 xmlValidateOneElement(xmlValidCtxtPtr ct
|
ret = 0; |
ret = 0; |
} |
} |
} |
} |
|
child_ok: |
child = child->next; |
child = child->next; |
} |
} |
break; |
break; |
Line 3518 xmlValidateRoot(xmlValidCtxtPtr ctxt, xm
|
Line 3796 xmlValidateRoot(xmlValidCtxtPtr ctxt, xm
|
VERROR(ctxt->userData, "Not valid: no root element\n"); |
VERROR(ctxt->userData, "Not valid: no root element\n"); |
return(0); |
return(0); |
} |
} |
|
|
|
/* |
|
* Check first the document root against the NQName |
|
*/ |
if (xmlStrcmp(doc->intSubset->name, root->name)) { |
if (xmlStrcmp(doc->intSubset->name, root->name)) { |
if ((xmlStrcmp(doc->intSubset->name, BAD_CAST "HTML")) || |
if ((root->ns != NULL) && (root->ns->prefix != NULL)) { |
(xmlStrcmp(root->name, BAD_CAST "html"))) { |
xmlChar qname[500]; |
VERROR(ctxt->userData, |
#ifdef HAVE_SNPRINTF |
"Not valid: root and DtD name do not match '%s' and '%s'\n", |
snprintf((char *) qname, sizeof(qname), "%s:%s", |
root->name, doc->intSubset->name); |
root->ns->prefix, root->name); |
return(0); |
#else |
} |
sprintf(qname, "%s:%s", root->name, root->ns->prefix); |
|
#endif |
|
if (!xmlStrcmp(doc->intSubset->name, qname)) |
|
goto name_ok; |
|
} |
|
if ((!xmlStrcmp(doc->intSubset->name, BAD_CAST "HTML")) && |
|
(!xmlStrcmp(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); |
|
|
} |
} |
|
name_ok: |
return(1); |
return(1); |
} |
} |
|
|