applied Schemas patches from Kasimier Buchcik lot of new tests for things
* configure.in xmlregexp.c xmlschemas.c xmlschemastypes.c
include/libxml/schemasInternals.h include/libxml/xmlerror.h
include/libxml/xmlschemastypes.h: applied Schemas patches
from Kasimier Buchcik
* test/ result/ bug141333* annot-err* any[1-4]* bug145246*
element-err* element-minmax-err* include1* restrict-CT-attr-ref*:
lot of new tests for things fixed by the patch
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index 59cfee0..c95caf0 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -47,6 +47,9 @@
/* #define DEBUG_ATTR_VALIDATION 1 */
+/* #define DEBUG_UNION_VALIDATION 1 */
+
+
#define UNBOUNDED (1 << 30)
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
@@ -55,6 +58,8 @@
#define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"
+#define XML_SCHEMAS_NO_NS (const xmlChar *) "##"
+
/*
* The XML Schemas namespaces
*/
@@ -64,11 +69,34 @@
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
"http://www.w3.org/2001/XMLSchema-instance";
+static const xmlChar *xmlSchemaElemDesElemDecl = (const xmlChar *)
+ "Element decl.";
+static const xmlChar *xmlSchemaElemDesElemRef = (const xmlChar *)
+ "Element ref.";
+static const xmlChar *xmlSchemaElemDesAttrDecl = (const xmlChar *)
+ "Attribute decl.";
+static const xmlChar *xmlSchemaElemDesAttrRef = (const xmlChar *)
+ "Attribute ref.";
+static const xmlChar *xmlSchemaElemDesST = (const xmlChar *)
+ "ST";
+static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
+ "CT";
+
#define IS_SCHEMA(node, type) \
((node != NULL) && (node->ns != NULL) && \
(xmlStrEqual(node->name, (const xmlChar *) type)) && \
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
+#define FREE_AND_NULL(str) \
+ if (str != NULL) { \
+ xmlFree(str); \
+ str = NULL; \
+ }
+
+#define XML_SCHEMAS_VAL_WTSP_PRESERVE 0
+#define XML_SCHEMAS_VAL_WTSP_REPLACE 1
+#define XML_SCHEMAS_VAL_WTSP_COLLAPSE 2
+
#define XML_SCHEMAS_PARSE_ERROR 1
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
@@ -160,6 +188,8 @@
/* xmlSchemaAttrStatePtr attrBase; */
/* int attrMax; */
xmlSchemaAttrStatePtr attr;
+ xmlNodePtr scope;
+ int valueWS;
};
/*
@@ -189,22 +219,10 @@
* Some predeclarations *
* *
************************************************************************/
-#if 0 /* Not currently used. */
-static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type,
- const xmlChar * value);
-#endif
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema,
xmlNodePtr node);
-#if 0
-static int
-xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type,
- const xmlChar * value,
- int fireErrors);
-#endif /* Not currently used. */
static void
xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
@@ -214,7 +232,8 @@
xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
const xmlChar *value,
int fireErrors,
- int applyFacets);
+ int applyFacets,
+ int normalize);
/************************************************************************
* *
@@ -392,6 +411,44 @@
(const char *) str3, 0, 0,
msg, str1, str2, str3);
}
+
+/**
+ * xmlSchemaVErrExt:
+ * @ctxt: the validation context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the message
+ * @str1: extra parameter for the message display
+ * @str2: extra parameter for the message display
+ * @str3: extra parameter for the message display
+ * @str4: extra parameter for the message display
+ * @str5: extra parameter for the message display
+ *
+ * Handle a validation error
+ */
+static void
+xmlSchemaVErrExt(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
+ const char *msg, const xmlChar * str1,
+ const xmlChar * str2, const xmlChar * str3,
+ const xmlChar * str4, const xmlChar * str5)
+{
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+
+ if (ctxt != NULL) {
+ ctxt->nberrors++;
+ ctxt->err = error;
+ channel = ctxt->error;
+ schannel = ctxt->serror;
+ data = ctxt->userData;
+ }
+ /* reajust to global error numbers */
+ error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
+ __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
+ error, XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,
+ msg, str1, str2, str3, str4, str5);
+}
/**
* xmlSchemaVErr:
* @ctxt: the validation context
@@ -426,6 +483,1013 @@
msg, str1, str2);
}
+/**
+ * xmlSchemaGetOnymousTypeName:
+ * @attr: the attribute declaration/use
+ *
+ * Returns the name of the attribute; if the attribute
+ * is a reference, the name of the referenced global type will be returned.
+ */
+static const xmlChar *
+xmlSchemaGetAttrName(xmlSchemaAttributePtr attr)
+{
+ if (attr->ref != NULL)
+ return(attr->ref);
+ else
+ return(attr->name);
+}
+
+/**
+ * xmlSchemaGetOnymousTargetNsURI:
+ * @type: the type (element or attribute)
+ *
+ * Returns the target namespace URI of the type; if the type is a reference,
+ * the target namespace of the referenced type will be returned.
+ */
+static const xmlChar *
+xmlSchemaGetAttrTargetNsURI(xmlSchemaAttributePtr attr)
+{
+ if (attr->ref != NULL)
+ return (attr->refNs);
+ else
+ return(attr->targetNamespace);
+}
+
+/**
+ * xmlSchemaFormatNsUriLocal:
+ * @buf: the string buffer
+ * @uri: the namespace URI
+ * @local: the local name
+ *
+ * Returns a representation of the given URI used
+ * for error reports.
+ *
+ * Returns an empty string, if @ns is NULL, a formatted
+ * string otherwise.
+ */
+static const xmlChar*
+xmlSchemaFormatNsUriLocal(xmlChar **buf,
+ const xmlChar *uri, const xmlChar *local)
+{
+ if (*buf != NULL)
+ xmlFree(*buf);
+ if (uri == NULL) {
+ *buf = xmlStrdup(BAD_CAST "{'");
+ *buf = xmlStrcat(*buf, local);
+ } else {
+ *buf = xmlStrdup(BAD_CAST "{'");
+ *buf = xmlStrcat(*buf, uri);
+ *buf = xmlStrcat(*buf, BAD_CAST "', '");
+ *buf = xmlStrcat(*buf, local);
+ }
+ *buf = xmlStrcat(*buf, BAD_CAST "'}");
+ return ((const xmlChar *) *buf);
+}
+
+/**
+ * xmlSchemaFormatNsPrefixLocal:
+ * @buf: the string buffer
+ * @ns: the namespace
+ * @local: the local name
+ *
+ * Returns a representation of the given URI used
+ * for error reports.
+ *
+ * Returns an empty string, if @ns is NULL, a formatted
+ * string otherwise.
+ */
+static const xmlChar*
+xmlSchemaFormatNsPrefixLocal(xmlChar **buf,
+ xmlNsPtr ns, const xmlChar *local)
+{
+ if (*buf != NULL) {
+ xmlFree(*buf);
+ *buf = NULL;
+ }
+ if ((ns == NULL) || (ns->prefix == NULL))
+ return(local);
+ else {
+ *buf = xmlStrdup(ns->prefix);
+ *buf = xmlStrcat(*buf, BAD_CAST ":");
+ *buf = xmlStrcat(*buf, local);
+ }
+ return ((const xmlChar *) *buf);
+}
+
+/**
+ * xmlSchemaFormatItemForReport:
+ * @buf: the string buffer
+ * @itemDes: the designation of the item
+ * @itemName: the name of the item
+ * @item: the item as an object
+ * @itemNode: the node of the item
+ * @local: the local name
+ * @parsing: if the function is used during the parse
+ *
+ * Returns a representation of the given item used
+ * for error reports.
+ *
+ * The following order is used to build the resulting
+ * designation if the arguments are not NULL:
+ * 1a. If itemDes not NULL -> itemDes
+ * 1b. If (itemDes not NULL) and (itemName not NULL)
+ * -> itemDes + itemName
+ * 2. If the preceding was NULL and (item not NULL) -> item
+ * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
+ *
+ * If the itemNode is an attribute node, the name of the attribute
+ * will be appended to the result.
+ *
+ * Returns the formatted string and sets @buf to the resulting value.
+ */
+static xmlChar*
+xmlSchemaFormatItemForReport(xmlChar **buf,
+ const xmlChar *itemDes,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemNode,
+ int parsing)
+{
+ xmlChar *str = NULL;
+
+ if (*buf != NULL) {
+ xmlFree(*buf);
+ *buf = NULL;
+ }
+
+ if (itemDes != NULL)
+ *buf = xmlStrdup(itemDes);
+ else if (item != NULL) {
+ if (item->type == XML_SCHEMA_TYPE_BASIC) {
+ if (item->builtInType == XML_SCHEMAS_ANYTYPE)
+ *buf = xmlStrdup(BAD_CAST "'anyType'");
+ else if (item->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)
+ *buf = xmlStrdup(BAD_CAST "'anySimpleType'");
+ else {
+ /* *buf = xmlStrdup(BAD_CAST "bi "); */
+ /* *buf = xmlStrcat(*buf, xmlSchemaElemDesST); */
+ *buf = xmlStrdup(BAD_CAST "'");
+ *buf = xmlStrcat(*buf, item->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ } else if (item->type == XML_SCHEMA_TYPE_SIMPLE) {
+ if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+ *buf = xmlStrdup(xmlSchemaElemDesST);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, item->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrdup(xmlSchemaElemDesST);
+ *buf = xmlStrcat(*buf, BAD_CAST " local");
+ }
+ } else if (item->type == XML_SCHEMA_TYPE_COMPLEX) {
+ if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+ *buf = xmlStrdup(xmlSchemaElemDesCT);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, item->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrdup(xmlSchemaElemDesCT);
+ *buf = xmlStrcat(*buf, BAD_CAST " local");
+ }
+ } else if (item->type == XML_SCHEMA_TYPE_ATTRIBUTE) {
+ xmlSchemaAttributePtr attr;
+
+ attr = (xmlSchemaAttributePtr) item;
+ if ((attr->flags & XML_SCHEMAS_TYPE_GLOBAL) ||
+ (attr->ref == NULL)) {
+ *buf = xmlStrdup(xmlSchemaElemDesAttrDecl);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, attr->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrdup(xmlSchemaElemDesAttrRef);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, attr->refPrefix);
+ *buf = xmlStrcat(*buf, BAD_CAST ":");
+ *buf = xmlStrcat(*buf, attr->ref);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ } else if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
+ xmlSchemaElementPtr elem;
+
+ elem = (xmlSchemaElementPtr) item;
+ if ((elem->flags & XML_SCHEMAS_TYPE_GLOBAL) ||
+ (elem->ref == NULL)) {
+ *buf = xmlStrdup(xmlSchemaElemDesElemDecl);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, elem->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrdup(xmlSchemaElemDesElemRef);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, elem->refPrefix);
+ *buf = xmlStrcat(*buf, BAD_CAST ":");
+ *buf = xmlStrcat(*buf, elem->ref);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ }
+ } else if (itemNode != NULL) {
+ xmlNodePtr elem;
+
+ if (itemNode->type == XML_ATTRIBUTE_NODE)
+ elem = itemNode->parent;
+ else
+ elem = itemNode;
+ *buf = xmlStrdup(BAD_CAST "Element '");
+ if (parsing)
+ *buf = xmlStrcat(*buf, elem->name);
+ else
+ *buf = xmlStrcat(*buf,
+ xmlSchemaFormatNsPrefixLocal(&str, elem->ns, elem->name));
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
+ *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
+ *buf = xmlStrcat(*buf, xmlSchemaFormatNsPrefixLocal(&str,
+ itemNode->ns, itemNode->name));
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ FREE_AND_NULL(str);
+
+ return (*buf);
+}
+
+/**
+ * xmlSchemaPFormatItemDes:
+ * @buf: the string buffer
+ * @item: the item as a schema object
+ * @itemNode: the item as a node
+ *
+ * If the pointer to @buf is not NULL and @but holds no value,
+ * the value is set to a item designation using
+ * xmlSchemaFormatItemForReport. This one avoids adding
+ * an attribute designation postfix.
+ *
+ * Returns a string of all enumeration elements.
+ */
+static void
+xmlSchemaPRequestItemDes(xmlChar **buf,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemNode)
+{
+ if ((buf == 0) || (*buf != NULL))
+ return;
+ if (itemNode->type == XML_ATTRIBUTE_NODE)
+ itemNode = itemNode->parent;
+ xmlSchemaFormatItemForReport(buf, NULL, item, itemNode, 1);
+}
+
+/**
+ * xmlSchemaFormatFacetEnumSet:
+ * @buf: the string buffer
+ * @type: the type holding the enumeration facets
+ *
+ * Builds a string consisting of all enumeration elements.
+ *
+ * Returns a string of all enumeration elements.
+ */
+static const xmlChar *
+xmlSchemaFormatFacetEnumSet(xmlChar **buf, xmlSchemaTypePtr type)
+{
+ xmlSchemaFacetLinkPtr link;
+
+ if (*buf != NULL)
+ xmlFree(*buf);
+ *buf = NULL;
+ for (link = type->facetSet; link != NULL; link = link->next) {
+ if (link->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
+ if (*buf == NULL) {
+ *buf = xmlStrdup(BAD_CAST "'");
+ *buf = xmlStrcat(*buf, link->facet->value);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrcat(*buf, BAD_CAST ", '");
+ *buf = xmlStrcat(*buf, link->facet->value);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
+ }
+ }
+ return ((const xmlChar *) *buf);
+}
+
+/**
+ * xmlSchemaVFacetErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @node: the node to be validated
+ * @value: the value of the node
+ * @type: the type holding the facet
+ * @facet: the facet
+ * @message: the error message of NULL
+ * @str1: extra data
+ * @str2: extra data
+ * @str3: extra data
+ *
+ * Reports a facet validation error.
+ * TODO: Should this report the value of an element as well?
+ */
+static void
+xmlSchemaVFacetErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlNodePtr node,
+ const xmlChar *value,
+ unsigned long length,
+ xmlSchemaTypePtr type,
+ xmlSchemaFacetPtr facet,
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2,
+ const xmlChar *str3)
+{
+ xmlChar *str = NULL, *msg = NULL;
+ xmlSchemaTypeType facetType;
+
+ xmlSchemaFormatItemForReport(&msg, NULL, NULL, node, 0);
+ msg = xmlStrcat(msg, BAD_CAST " [");
+ msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0));
+ msg = xmlStrcat(msg, BAD_CAST ", facet '");
+ if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
+ facetType = XML_SCHEMA_FACET_ENUMERATION;
+ /*
+ * If enumerations are validated, one must not expect the
+ * facet to be given.
+ */
+ } else
+ facetType = facet->type;
+ msg = xmlStrcat(msg, BAD_CAST xmlSchemaFacetTypeToString(facetType));
+ msg = xmlStrcat(msg, BAD_CAST "']: ");
+ if (message == NULL) {
+ /*
+ * Use a default message.
+ */
+ if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
+ (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
+ (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
+
+ char len[25], actLen[25];
+
+ /* FIXME, TODO: What is the max expected string length of the
+ * this value?
+ */
+ if (node->type == XML_ATTRIBUTE_NODE)
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
+ else
+ msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
+
+ snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
+ snprintf(actLen, 24, "%lu", length);
+
+ if (facetType == XML_SCHEMA_FACET_LENGTH)
+ msg = xmlStrcat(msg,
+ BAD_CAST "this differs from the allowed length of '%s'.\n");
+ else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
+ msg = xmlStrcat(msg,
+ BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
+ else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
+ msg = xmlStrcat(msg,
+ BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
+
+ if (node->type == XML_ATTRIBUTE_NODE)
+ xmlSchemaVErrExt(ctxt, node, error,
+ (const char *) msg,
+ value, (const xmlChar *) actLen, (const xmlChar *) len,
+ NULL, NULL);
+ else
+ xmlSchemaVErr(ctxt, node, error,
+ (const char *) msg,
+ (const xmlChar *) actLen, (const xmlChar *) len);
+
+ } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
+ "of the set {%s}.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ xmlSchemaFormatFacetEnumSet(&str, type));
+ } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
+ "by the pattern '%s'.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ facet->value);
+ } else if (node->type == XML_ATTRIBUTE_NODE) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, NULL);
+ } else {
+ msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, NULL, NULL);
+ }
+ } else {
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ xmlSchemaVErr3(ctxt, node, error, (const char *) msg, str1, str2, str3);
+ }
+ FREE_AND_NULL(str)
+ xmlFree(msg);
+}
+
+/**
+ * xmlSchemaVSimpleTypeErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @type: the type used for validation
+ * @node: the node containing the validated value
+ * @value: the validated value
+ *
+ * Reports a simple type validation error.
+ * TODO: Should this report the value of an element as well?
+ */
+static void
+xmlSchemaVSimpleTypeErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlNodePtr node,
+ const xmlChar *value,
+ xmlSchemaTypePtr type)
+{
+ xmlChar *str = NULL, *msg = NULL;
+
+ xmlSchemaFormatItemForReport(&msg, NULL, NULL, node, 0);
+ msg = xmlStrcat(msg, BAD_CAST " [");
+ msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0));
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ msg = xmlStrcat(msg, BAD_CAST "]: The value '%s' is not valid.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, NULL);
+ } else {
+ msg = xmlStrcat(msg, BAD_CAST "]: The character content is not valid.\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, NULL, NULL);
+ }
+ FREE_AND_NULL(str)
+ xmlFree(msg);
+}
+
+/**
+ * xmlSchemaPMissingAttrErr:
+ * @ctxt: the schema validation context
+ * @ownerDes: the designation of the owner
+ * @ownerName: the name of the owner
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the owner as an element node
+ * @node: the parent element node of the missing attribute node
+ * @type: the corresponding type of the attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ const char *name,
+ const char *message)
+{
+ xmlChar *des = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ if (message != NULL)
+ xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
+ else
+ xmlSchemaPErr(ctxt, ownerElem, error,
+ "%s: The attribute '%s' is required but missing.\n",
+ BAD_CAST des, BAD_CAST name);
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des);
+}
+
+static const char *
+xmlSchemaCompTypeToString(xmlSchemaTypeType type)
+{
+ switch (type) {
+ case XML_SCHEMA_TYPE_SIMPLE:
+ return("simple type definition");
+ case XML_SCHEMA_TYPE_COMPLEX:
+ return("complex type definition");
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return("element declaration");
+ case XML_SCHEMA_TYPE_ATTRIBUTE:
+ return("attribute declaration");
+ case XML_SCHEMA_TYPE_GROUP:
+ return("model group definition");
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+ return("attribute group definition");
+ case XML_SCHEMA_TYPE_NOTATION:
+ return("notation declaration");
+ default:
+ return("Not a schema component");
+ }
+}
+/**
+ * xmlSchemaPResCompAttrErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @ownerDes: the designation of the owner
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the owner as an element node
+ * @name: the name of the attribute holding the QName
+ * @refName: the referenced local name
+ * @refURI: the referenced namespace URI
+ * @message: optional message
+ *
+ * Used to report QName attribute values that failed to resolve
+ * to schema components.
+ */
+static void
+xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ const char *name,
+ const xmlChar *refName,
+ const xmlChar *refURI,
+ xmlSchemaTypeType refType,
+ const char *refTypeStr)
+{
+ xmlChar *des = NULL, *strA = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ /*
+ if (message != NULL)
+ xmlSchemaPErrExt(ctxt, ownerElem, error, NULL, NULL, NULL,
+ "%s, attribute '%s': %s.\n",
+ BAD_CAST des, name, message, NULL, NULL);
+ else
+ */
+ if (refTypeStr == NULL)
+ refTypeStr = xmlSchemaCompTypeToString(refType);
+ xmlSchemaPErrExt(ctxt, ownerElem, error,
+ NULL, NULL, NULL,
+ "%s, attribute '%s': The QName value %s does not resolve to a(n) "
+ "%s.\n", BAD_CAST des, BAD_CAST name,
+ xmlSchemaFormatNsUriLocal(&strA, refURI, refName),
+ BAD_CAST refTypeStr, NULL);
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des)
+ FREE_AND_NULL(strA)
+}
+
+static void
+xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ const char *msg)
+{
+ xmlChar *des = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
+ "%s, attribute '%s': %s.\n",
+ BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des);
+}
+
+/**
+ * xmlSchemaPIllegalAttrErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @ownerDes: the designation of the owner
+ * @ownerItem: the owner as a schema object
+ * @attr: the illegal attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr)
+{
+ xmlChar *des = NULL, *strA = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ xmlSchemaPErr(ctxt, (xmlNodePtr) attr, error,
+ "%s: The attribute '%s' is not allowed.\n", BAD_CAST des,
+ xmlSchemaFormatNsPrefixLocal(&strA, attr->ns, attr->name));
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(strA);
+}
+
+static void
+xmlSchemaPAquireDes(xmlChar **des,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemElem)
+{
+ if (itemDes == NULL)
+ xmlSchemaFormatItemForReport(des, NULL, item, itemElem, 1);
+ else if (*itemDes == NULL) {
+ xmlSchemaFormatItemForReport(itemDes, NULL, item, itemElem, 1);
+ *des = *itemDes;
+ } else
+ *des = *itemDes;
+}
+
+static void
+xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemElem,
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2,
+ const xmlChar *str3)
+{
+ xmlChar *des = NULL, *msg = NULL;
+
+ xmlSchemaPAquireDes(&des, itemDes, item, itemElem);
+ msg = xmlStrdup(BAD_CAST "%s: ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ if ((itemElem == NULL) && (item != NULL))
+ itemElem = item->node;
+ xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
+ (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
+ if (itemDes == NULL)
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(msg);
+}
+
+static void
+xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemElem,
+ const char *message,
+ const xmlChar *str1)
+{
+ xmlSchemaPCustomErrExt(ctxt, error, itemDes, item, itemElem, message,
+ str1, NULL, NULL);
+}
+
+static void
+xmlSchemaPAttrUseErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlNodePtr itemElem,
+ const xmlSchemaAttributePtr attr,
+ const char *message,
+ const xmlChar *str1)
+{
+ xmlChar *des = NULL, *strA = NULL, *msg = NULL;
+
+ xmlSchemaPAquireDes(&des, itemDes, item, itemElem);
+ xmlSchemaFormatNsUriLocal(&strA, xmlSchemaGetAttrTargetNsURI(attr),
+ xmlSchemaGetAttrName(attr));
+ msg = xmlStrdup(BAD_CAST "%s, attr. use %s: ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ if ((itemElem == NULL) && (item != NULL))
+ itemElem = item->node;
+ xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
+ (const char *) msg, BAD_CAST des, BAD_CAST strA, str1, NULL, NULL);
+ if (itemDes == NULL)
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(strA);
+ xmlFree(msg);
+}
+
+
+
+static void
+xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlSchemaTypePtr baseItem,
+ xmlSchemaFacetPtr facet)
+{
+ xmlChar *des = NULL, *strT = NULL;
+
+ xmlSchemaPAquireDes(&des, itemDes, item, item->node);
+ xmlSchemaPErrExt(ctxt, item->node, error, NULL, NULL, NULL,
+ "%s: The facet '%s' is not allowed on types derived from the "
+ "type %s.\n",
+ BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type),
+ xmlSchemaFormatItemForReport(&strT, NULL, baseItem, NULL, 1),
+ NULL, NULL);
+ if (itemDes == NULL)
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(strT);
+}
+
+static void
+xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **itemDes,
+ xmlSchemaTypePtr item,
+ xmlSchemaFacetPtr facet)
+{
+ xmlChar *des = NULL, *strT = NULL;
+
+ xmlSchemaPAquireDes(&des, itemDes, item, item->node);
+ xmlSchemaPErr(ctxt, item->node, error,
+ "%s: The facet '%s' is not allowed.\n",
+ BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type));
+ if (itemDes == NULL)
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(strT);
+}
+
+/**
+ * xmlSchemaPMutualExclAttrErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @elemDes: the designation of the parent element node
+ * @attr: the bad attribute node
+ * @type: the corresponding type of the attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ const char *name1,
+ const char *name2)
+{
+ xmlChar *des = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
+ "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
+ BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des)
+}
+
+/**
+ * xmlSchemaPSimpleTypeErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @biType: the built in type specifier
+ * @ownerDes: the designation of the owner
+ * @ownerItem: the schema object if existent
+ * @node: the validated node
+ * @value: the validated value
+ *
+ * Reports a simple type validation error.
+ * TODO: Should this report the value of an element as well?
+ */
+static void
+xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr node,
+ xmlSchemaValType biType,
+ const char *typeDes,
+ const xmlChar *value,
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2)
+{
+ xmlChar *des = NULL, *strA = NULL, *strT = NULL;
+ xmlSchemaTypePtr type = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaPRequestItemDes(&des, ownerItem, node);
+ else if (*ownerDes == NULL) {
+ xmlSchemaPRequestItemDes(ownerDes, ownerItem, node);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ if (biType != XML_SCHEMAS_UNKNOWN) {
+ type = xmlSchemaGetBuiltInType(biType);
+ if (type == NULL) {
+ xmlSchemaPErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaPSimpleTypeErr, could not "
+ "aquire the built-in type.\n",
+ BAD_CAST des, BAD_CAST typeDes);
+ return;
+ }
+ typeDes = (const char *) xmlSchemaFormatItemForReport(&strT, NULL, type, NULL, 1);
+ }
+ if (message == NULL) {
+ /*
+ * Use default messages.
+ */
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
+ "%s, attribute '%s' [%s]: The value '%s' is not "
+ "valid.\n",
+ BAD_CAST des, xmlSchemaFormatNsPrefixLocal(&strA, node->ns,
+ node->name), BAD_CAST typeDes, value, NULL);
+ } else {
+ xmlSchemaPErr(ctxt, node, error,
+ "%s [%s]: The character content is not valid.\n",
+ BAD_CAST des, BAD_CAST typeDes);
+ }
+ } else {
+ xmlChar *msg;
+
+ msg = xmlStrdup(BAD_CAST "%s");
+ if (node->type == XML_ATTRIBUTE_NODE)
+ msg = xmlStrcat(msg, BAD_CAST ", attribute '%s'");
+ msg = xmlStrcat(msg, BAD_CAST " [%s]: ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
+ (const char *) msg,
+ BAD_CAST des, xmlSchemaFormatNsPrefixLocal(&strA,
+ node->ns, node->name), BAD_CAST typeDes, str1, str2);
+ } else {
+ xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
+ (const char *) msg,
+ BAD_CAST des, BAD_CAST typeDes, str1, str2, NULL);
+ }
+ xmlFree(msg);
+ }
+ /* Cleanup. */
+ FREE_AND_NULL(strA)
+ FREE_AND_NULL(strT)
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des)
+}
+
+static void
+xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ xmlNodePtr child,
+ const char *message,
+ const char *content)
+{
+ xmlChar *des = NULL;
+
+ if (ownerDes == NULL)
+ xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1);
+ else if (*ownerDes == NULL) {
+ xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1);
+ des = *ownerDes;
+ } else
+ des = *ownerDes;
+ if (message != NULL)
+ xmlSchemaPErr2(ctxt, ownerElem, child, error,
+ "%s: %s.\n",
+ BAD_CAST des, BAD_CAST message);
+ else {
+ if (content != NULL) {
+ xmlSchemaPErr2(ctxt, ownerElem, child, error,
+ "%s: The content is not valid. Expected is %s.\n",
+ BAD_CAST des, BAD_CAST content);
+ } else {
+ xmlSchemaPErr2(ctxt, ownerElem, child, error,
+ "%s: The content is not valid.\n",
+ BAD_CAST des, NULL);
+ }
+ }
+ if (ownerDes == NULL)
+ FREE_AND_NULL(des)
+}
+
+/**
+ * xmlSchemaVIllegalAttrErr:
+ * @ctxt: the schema validation context
+ * @attr: the illegal attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaVIllegalAttrErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlAttrPtr attr)
+{
+ xmlChar *strE = NULL, *strA = NULL;
+
+ xmlSchemaVErr(ctxt, (xmlNodePtr) attr,
+ XML_SCHEMAS_ERR_ATTRUNKNOWN,
+ "%s: The attribute '%s' is not allowed.\n",
+ xmlSchemaFormatItemForReport(&strE, NULL, NULL, attr->parent, 0),
+ xmlSchemaFormatNsPrefixLocal(&strA, attr->ns, attr->name));
+ FREE_AND_NULL(strE)
+ FREE_AND_NULL(strA)
+}
+
+static void
+xmlSchemaVCustomErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlNodePtr node,
+ const char *message,
+ const xmlChar *str1)
+{
+ xmlChar *des = NULL, *msg = NULL;
+
+ xmlSchemaFormatItemForReport(&des, NULL, NULL, node, 0);
+ msg = xmlStrdup(BAD_CAST "%s: ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ xmlSchemaVErrExt(ctxt, node, error, (const char *) msg,
+ BAD_CAST des, str1, NULL, NULL, NULL);
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(msg);
+}
+
+static const char *
+xmlSchemaWildcardPCToString(int pc)
+{
+ switch (pc) {
+ case XML_SCHEMAS_ANY_SKIP:
+ return ("skip");
+ case XML_SCHEMAS_ANY_LAX:
+ return ("lax");
+ case XML_SCHEMAS_ANY_STRICT:
+ return ("strict");
+ default:
+ return ("invalid process contents");
+ }
+}
+
+static void
+xmlSchemaVWildcardErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlParserErrors error,
+ xmlNodePtr node,
+ xmlSchemaWildcardPtr wild,
+ const char *message)
+{
+ xmlChar *des = NULL, *msg = NULL;
+
+ xmlSchemaFormatItemForReport(&des, NULL, NULL, node, 0);
+ msg = xmlStrdup(BAD_CAST "%s, [");
+ msg = xmlStrcat(msg, BAD_CAST xmlSchemaWildcardPCToString(wild->processContents));
+ msg = xmlStrcat(msg, BAD_CAST " WC]: ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, BAD_CAST des, NULL);
+ FREE_AND_NULL(des);
+ FREE_AND_NULL(msg);
+}
+
+/**
+ * xmlSchemaVMissingAttrErr:
+ * @ctxt: the schema validation context
+ * @node: the parent element node of the missing attribute node
+ * @type: the corresponding type of the attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaVMissingAttrErr(xmlSchemaValidCtxtPtr ctxt,
+ xmlNodePtr elem,
+ xmlSchemaAttributePtr type)
+{
+ const xmlChar *name, *uri;
+ xmlChar *strE = NULL, *strA = NULL;
+
+ if (type->ref != NULL) {
+ name = type->ref;
+ uri = type->refNs;
+ } else {
+ name = type->name;
+ uri = type->targetNamespace;
+ }
+ xmlSchemaVErr(ctxt, elem,
+ XML_SCHEMAS_ERR_MISSING,
+ "%s: The attribute %s is required but missing.\n",
+ xmlSchemaFormatItemForReport(&strE, NULL, NULL, elem, 0),
+ xmlSchemaFormatNsUriLocal(&strA, uri, name));
+ FREE_AND_NULL(strE)
+ FREE_AND_NULL(strA)
+}
+
/************************************************************************
* *
* Allocation functions *
@@ -591,6 +1655,8 @@
{
if (attr == NULL)
return;
+ if (attr->annot != NULL)
+ xmlSchemaFreeAnnot(attr->annot);
xmlFree(attr);
}
@@ -604,7 +1670,7 @@
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
{
xmlSchemaWildcardNsPtr next;
-
+
while (set != NULL) {
next = set->next;
xmlFree(set);
@@ -1081,16 +2147,55 @@
* *
************************************************************************/
+/**
+ * xmlSchemaGetPropNode:
+ * @node: the element node
+ * @name: the name of the attribute
+ *
+ * Seeks an attribute with a name of @name in
+ * no namespace.
+ *
+ * Returns the attribute or NULL if not present.
+ */
static xmlAttrPtr
-xmlSchemaGetPropNode(xmlNodePtr node, const xmlChar *name)
+xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
{
xmlAttrPtr prop;
- if ((node == NULL) || (name == NULL)) return(NULL);
+ if ((node == NULL) || (name == NULL))
+ return(NULL);
prop = node->properties;
while (prop != NULL) {
- if ((xmlStrEqual(prop->name, name)) &&
- (prop->ns == NULL))
+ if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
+ return(prop);
+ prop = prop->next;
+ }
+ return (NULL);
+}
+
+/**
+ * xmlSchemaGetPropNodeNs:
+ * @node: the element node
+ * @uri: the uri
+ * @name: the name of the attribute
+ *
+ * Seeks an attribute with a local name of @name and
+ * a namespace URI of @uri.
+ *
+ * Returns the attribute or NULL if not present.
+ */
+static xmlAttrPtr
+xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
+{
+ xmlAttrPtr prop;
+
+ if ((node == NULL) || (name == NULL))
+ return(NULL);
+ prop = node->properties;
+ while (prop != NULL) {
+ if ((prop->ns != NULL) &&
+ xmlStrEqual(prop->name, BAD_CAST name) &&
+ xmlStrEqual(prop->ns->href, BAD_CAST uri))
return(prop);
prop = prop->next;
}
@@ -1206,7 +2311,7 @@
ns = xmlSearchNs(node->doc, node, prefix);
if (ns == NULL) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
- "%s: the QName prefix %s is undefined\n",
+ "%s: The QName prefix %s is undefined\n",
node->name, prefix);
return(name);
}
@@ -1523,7 +2628,7 @@
* @schema: the schema being built
* @name: the item name
*
- * Add an XML schema Attrribute declaration
+ * Add an XML schema annotation declaration
* *WARNING* this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
@@ -1553,9 +2658,13 @@
val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
ret);
if (val != 0) {
+ /*
+ * TODO: This should never happen, since a unique name will be computed.
+ * If it fails, then an other internal error must have occured.
+ */
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
XML_SCHEMAP_REDEFINED_NOTATION,
- "Notation %s already defined\n",
+ "Annotation declaration '%s' is already declared.\n",
name, NULL);
xmlFree(ret);
return (NULL);
@@ -1608,10 +2717,14 @@
val = xmlHashAddEntry3(schema->attrDecl, name,
schema->targetNamespace, ctxt->container, ret);
if (val != 0) {
+ /*
+ * TODO: Change this somehow, since this can be either an attribute
+ * declaration or a particle referencing an attribute declaration.
+ */
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
- XML_SCHEMAP_REDEFINED_ATTR,
- "Attribute %s already defined\n",
- name, NULL);
+ XML_SCHEMAP_REDEFINED_ATTR,
+ "Attribute declaration '%s' is already declared.\n",
+ name, NULL);
xmlFree(ret);
return (NULL);
}
@@ -1657,7 +2770,7 @@
if (val != 0) {
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
XML_SCHEMAP_REDEFINED_ATTRGROUP,
- "Attribute group %s already defined\n",
+ "Attribute group '%s' is already defined.\n",
name, NULL);
xmlFree(ret);
return (NULL);
@@ -1709,19 +2822,21 @@
val = xmlHashAddEntry3(schema->elemDecl, name,
namespace, ctxt->container, ret);
if (val != 0) {
+ /*
char buf[100];
snprintf(buf, 99, "privatieelem %d", ctxt->counter++ + 1);
val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
namespace, ret);
if (val != 0) {
- xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
- XML_SCHEMAP_REDEFINED_ELEMENT,
- "Element %s already defined\n",
- name, NULL);
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_REDEFINED_ELEMENT,
+ (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, NULL,
+ "A global declaration for '%s' is already existent", name);
xmlFree(ret);
return (NULL);
- }
+
}
return (ret);
}
@@ -1772,7 +2887,7 @@
if (ctxt->includes == 0) {
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
XML_SCHEMAP_REDEFINED_TYPE,
- "Type %s already defined\n",
+ "Type '%s' is already defined.\n",
name, NULL);
xmlFree(ret);
return (NULL);
@@ -1782,9 +2897,10 @@
prev = xmlHashLookup2(schema->typeDecl, name, namespace);
if (prev == NULL) {
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
- XML_ERR_INTERNAL_ERROR,
- "Internal error on type %s definition\n",
- name, NULL);
+ XML_ERR_INTERNAL_ERROR,
+ "Internal error: xmlSchemaAddType, on type "
+ "'%s'.\n",
+ name, NULL);
xmlFree(ret);
return (NULL);
}
@@ -1838,7 +2954,7 @@
if (val != 0) {
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
XML_SCHEMAP_REDEFINED_GROUP,
- "Group %s already defined\n",
+ "Group '%s' is already defined.\n",
name, NULL);
xmlFree(ret);
return (NULL);
@@ -1876,10 +2992,9 @@
/**
* xmlSchemaAddWildcard:
* @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the group name
- *
- * Add an XML schema Group definition
+ * Adds a wildcard. It corresponds to a
+ * xsd:anyAttribute and is used as storage for namespace
+ * constraints on a xsd:any.
*
* Returns the new struture or NULL in case of error
*/
@@ -1952,8 +3067,9 @@
ns = xmlSearchNs(node->doc, node, prefix);
if (ns == NULL) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
- "Attribute \"%s\": the QName prefix \"%s\" is undefined\n",
- (const xmlChar *) name, prefix);
+ "Attribute '%s': The prefix '%s' of the QName "
+ "'%s' has no corresponding namespace declaration is scope.\n",
+ (const xmlChar *) name, prefix);
} else {
*namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
}
@@ -1961,6 +3077,164 @@
}
/**
+ * xmlSchemaPValAttrNodeQNameValue:
+ * @ctxt: a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the parent as a schema object
+ * @value: the QName value
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri: the resulting namespace URI if found
+ *
+ * Extracts the local name and the URI of a QName value and validates it.
+ * This one is intended to be used on attribute values that
+ * should resolve to schema components.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ const xmlChar *value,
+ const xmlChar **uri,
+ const xmlChar **prefix,
+ const xmlChar **local)
+{
+ const xmlChar *pref;
+ xmlNsPtr ns;
+ int len, ret;
+
+ *uri = NULL;
+ *local = NULL;
+ if (prefix != 0)
+ *prefix = NULL;
+ ret = xmlValidateQName(value, 1);
+ if (ret > 0) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ XML_SCHEMAS_QNAME, "QName", value,
+ NULL, NULL, NULL);
+ *local = value;
+ return (ctxt->err);
+ } else if (ret < 0)
+ return (-1);
+
+ if (!strchr((char *) value, ':')) {
+ ns = xmlSearchNs(attr->doc, attr->parent, 0);
+ if (ns)
+ *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
+ else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
+ /*
+ * This one takes care of included schemas with no
+ * target namespace.
+ */
+ *uri = schema->targetNamespace;
+ }
+ *local = value;
+ return (0);
+ }
+ /*
+ * At this point xmlSplitQName3 has to return a local name.
+ */
+ *local = xmlSplitQName3(value, &len);
+ *local = xmlDictLookup(ctxt->dict, *local, -1);
+ pref = xmlDictLookup(ctxt->dict, value, len);
+ if (prefix != 0)
+ *prefix = pref;
+ ns = xmlSearchNs(attr->doc, attr->parent, pref);
+ if (ns == NULL) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ XML_SCHEMAS_QNAME, "QName", value,
+ "The prefix '%s' of the value '%s' is not declared.\n",
+ pref, value);
+ return (ctxt->err);
+ } else {
+ *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
+ }
+ return (0);
+}
+
+/**
+ * xmlSchemaPValAttrNodeQName:
+ * @ctxt: a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the owner element
+ * @ownerItem: the owner as a schema object
+ * @attr: the attribute node
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri: the resulting namespace URI if found
+ *
+ * Extracts and validates the QName of an attribute value.
+ * This one is intended to be used on attribute values that
+ * should resolve to schema components.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ const xmlChar **uri,
+ const xmlChar **prefix,
+ const xmlChar **local)
+{
+ const xmlChar *value;
+
+ value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
+ ownerDes, ownerItem, attr, value, uri, prefix, local));
+}
+
+/**
+ * xmlSchemaPValAttrQName:
+ * @ctxt: a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the parent node of the attribute
+ * @name: the name of the attribute
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri: the resulting namespace URI if found
+ *
+ * Extracts and validates the QName of an attribute value.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ const char *name,
+ const xmlChar **uri,
+ const xmlChar **prefix,
+ const xmlChar **local)
+{
+ xmlAttrPtr attr;
+
+ attr = xmlSchemaGetPropNode(ownerElem, name);
+ if (attr == NULL) {
+ *local = NULL;
+ *uri = NULL;
+ return (0);
+ }
+ return (xmlSchemaPValAttrNodeQName(ctxt, schema,
+ ownerDes, ownerItem, attr, uri, prefix, local));
+}
+
+/**
* xmlGetMaxOccurs:
* @ctxt: a schema validation context
* @node: a subtree containing XML Schema informations
@@ -1994,7 +3268,8 @@
cur++;
if (*cur != 0) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
- "invalid value for maxOccurs: %s\n", val, NULL);
+ "The value '%s' of the attribute 'maxOccurs' is invalid.\n",
+ val, NULL);
return (1);
}
return (ret);
@@ -2043,13 +3318,16 @@
* @name: the attribute name
* @def: the default value
*
- * Get is a bolean property is set
+ * Evaluate if a boolean property is set
*
* Returns the default if not found, 0 if found to be false,
- * 1 if found to be true
+ * 1 if found to be true
*/
static int
-xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr node,
const char *name, int def)
{
const xmlChar *val;
@@ -2057,15 +3335,25 @@
val = xmlSchemaGetProp(ctxt, node, name);
if (val == NULL)
return (def);
-
+ /*
+ * 3.2.2.1 Lexical representation
+ * An instance of a datatype that is defined as ·boolean·
+ * can have the following legal literals {true, false, 1, 0}.
+ */
if (xmlStrEqual(val, BAD_CAST "true"))
def = 1;
else if (xmlStrEqual(val, BAD_CAST "false"))
def = 0;
+ else if (xmlStrEqual(val, BAD_CAST "1"))
+ def = 1;
+ else if (xmlStrEqual(val, BAD_CAST "0"))
+ def = 0;
else {
- xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_BOOLEAN,
- "Attribute %s: the value %s is not boolean\n",
- (const xmlChar *) name, val);
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_INVALID_BOOLEAN,
+ ownerDes, ownerItem, node,
+ XML_SCHEMAS_BOOLEAN, "(1 | 0 | true | false)", val,
+ NULL, NULL, NULL);
}
return (def);
}
@@ -2114,12 +3402,14 @@
xmlSchemaPtr schema, xmlNodePtr node);
/**
- * xmlSchemaParseSchemaAttrValue:
+ * xmlSchemaPValAttrNode:
*
* @ctxt: a schema parser context
- * @attr: the schema attribute being validated
- * @type: the built-in type to be validated against
- * @value: the value to be validated
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @attr: the schema attribute node being validated
+ * @value: the value
+ * @type: the built-in type to be validated against
*
* Validates a value against the given built-in type.
* This one is intended to be used internally for validation
@@ -2129,85 +3419,202 @@
* number otherwise and -1 in case of an internal or API error.
*/
static int
-xmlSchemaParseSchemaAttrValue(xmlSchemaParserCtxtPtr ctxt,
- xmlAttrPtr attr,
- xmlSchemaTypePtr type)
+xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr ctxt,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ const xmlChar *value,
+ xmlSchemaTypePtr type)
{
- const xmlChar *value;
- int ret;
+ int ret = 0;
+
+ /*
+ * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
+ * one is really meant to be used internally, so better not.
+ */
if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
+ return (-1);
+ if (type->type != XML_SCHEMA_TYPE_BASIC) {
+ xmlSchemaPErr(ctxt, (xmlNodePtr) attr,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaPvalueAttrNode, the given "
+ "type '%s' is not a built-in type.\n",
+ type->name, NULL);
return (-1);
- value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ }
switch (type->builtInType) {
case XML_SCHEMAS_NCNAME:
ret = xmlValidateNCName(value, 1);
break;
case XML_SCHEMAS_QNAME:
- ret = xmlValidateQName(value, 1);
- if ((ret == 0) && (attr != NULL)) {
- xmlChar *local = NULL;
- xmlChar *prefix;
-
- local = xmlSplitQName2(value, &prefix);
- if (prefix != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(attr->doc, (xmlNodePtr) attr, prefix);
- if (ns == NULL) {
- xmlSchemaPErr(ctxt, (xmlNodePtr) attr,
- XML_SCHEMAP_PREFIX_UNDEFINED,
- "Attribute \"%s\": the QName prefix "
- "\"%s\" is undefined.\n",
- attr->name, prefix);
- ret = 1;
- }
- }
- if (local != NULL)
- xmlFree(local);
- if (prefix != NULL)
- xmlFree(prefix);
+ xmlSchemaPErr(ctxt, (xmlNodePtr) attr,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaPvalueAttrNode, use "
+ "the function xmlSchemaExtractSchemaQNamePropvalueidated "
+ "for extracting QName valueues instead.\n",
+ NULL, NULL);
+ return (-1);
+ case XML_SCHEMAS_ANYURI:
+ if (value != NULL) {
+ xmlURIPtr uri = xmlParseURI((const char *) value);
+ if (uri == NULL)
+ ret = 1;
+ else
+ xmlFreeURI(uri);
}
break;
+ case XML_SCHEMAS_TOKEN: {
+ const xmlChar *cur = value;
+
+ if (IS_BLANK_CH(*cur)) {
+ ret = 1;
+ } else while (*cur != 0) {
+ if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
+ ret = 1;
+ break;
+ } else if (*cur == ' ') {
+ cur++;
+ if ((*cur == 0) || (*cur == ' ')) {
+ ret = 1;
+ break;
+ }
+ } else {
+ cur++;
+ }
+ }
+ }
+ break;
+ case XML_SCHEMAS_LANGUAGE:
+ if (xmlCheckLanguageID(value) != 1)
+ ret = 1;
+ break;
default: {
xmlSchemaPErr(ctxt, (xmlNodePtr) attr,
XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaParseSchemaAttrValue, validation "
- "using this type in not implemented yet\"%s\".\n",
+ "Internal error: xmlSchemaPvalueAttrNode, "
+ "valueidation using the type '%s' is not implemented "
+ "yet.\n",
type->name, NULL);
return (-1);
}
- }
- if (ret > 0) {
- if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
- xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2,
- NULL, NULL, NULL,
- "The schema attribute \"%s\" with the value \"%s\" is not "
- "of built-in list simple type \"%s\".\n",
- attr->name, value, type->name, NULL, NULL);
- } else {
- if (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE) {
- xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- NULL, NULL, NULL,
- "The schema attribute \"%s\" with the value \"%s\" is not "
- "of built-in primitive type \"%s\".\n",
- attr->name, value, type->name, NULL, NULL);
- } else {
- xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- NULL, NULL, NULL,
- "The schema attribute \"%s\" with the value \"%s\" is not "
- "of built-in atomic simple type \"%s\".\n",
- attr->name, value, type->name, NULL, NULL);
- }
- }
+ }
+ /*
+ * TODO: Should we use the S4S error codes instead?
+ */
+ if (ret > 0) {
+ if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ type->builtInType, NULL, value,
+ NULL, NULL, NULL);
+ return(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2);
+ } else {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ type->builtInType, NULL, value,
+ NULL, NULL, NULL);
+ return(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
+ }
}
return (ret);
}
/**
+ * xmlSchemaPValAttrNode:
+ *
+ * @ctxt: a schema parser context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @attr: the schema attribute node being validated
+ * @type: the built-in type to be validated against
+ * @value: the resulting value if any
+ *
+ * Extracts and validates a value against the given built-in type.
+ * This one is intended to be used internally for validation
+ * of schema attribute values during parsing of the schema.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlAttrPtr attr,
+ xmlSchemaTypePtr type,
+ const xmlChar **value)
+{
+ const xmlChar *val;
+
+ if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
+ return (-1);
+
+ val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (value != NULL)
+ *value = val;
+
+ return (xmlSchemaPValAttrNodeValue(ctxt, ownerDes, ownerItem, attr,
+ val, type));
+}
+
+/**
+ * xmlSchemaPValAttr:
+ *
+ * @ctxt: a schema parser context
+ * @node: the element node of the attribute
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @ownerElem: the owner element node
+ * @name: the name of the schema attribute node
+ * @type: the built-in type to be validated against
+ * @value: the resulting value if any
+ *
+ * Extracts and validates a value against the given built-in type.
+ * This one is intended to be used internally for validation
+ * of schema attribute values during parsing of the schema.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ const char *name,
+ xmlSchemaTypePtr type,
+ const xmlChar **value)
+{
+ xmlAttrPtr attr;
+
+ if ((ctxt == NULL) || (type == NULL)) {
+ if (value != NULL)
+ *value = NULL;
+ return (-1);
+ }
+ if (type->type != XML_SCHEMA_TYPE_BASIC) {
+ if (value != NULL)
+ *value = NULL;
+ xmlSchemaPErr(ctxt, ownerElem,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaPValAttr, the given "
+ "type '%s' is not a built-in type.\n",
+ type->name, NULL);
+ return (-1);
+ }
+ attr = xmlSchemaGetPropNode(ownerElem, name);
+ if (attr == NULL) {
+ if (value != NULL)
+ *value = NULL;
+ return (0);
+ }
+ return (xmlSchemaPValAttrNode(ctxt, ownerDes, ownerItem, attr,
+ type, value));
+}
+/**
* xmlSchemaParseAttrDecls:
* @ctxt: a schema validation context
* @schema: the schema being built
@@ -2280,11 +3687,109 @@
xmlNodePtr node)
{
xmlSchemaAnnotPtr ret;
+ xmlNodePtr child = NULL;
+ xmlAttrPtr attr;
+ int barked = 0;
+ /*
+ * INFO: S4S completed.
+ */
+ /*
+ * id = ID
+ * {any attributes with non-schema namespace . . .}>
+ * Content: (appinfo | documentation)*
+ */
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
ret = xmlSchemaNewAnnot(ctxt, node);
+ attr = node->properties;
+ while (attr != NULL) {
+ if (((attr->ns == NULL) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
+ ((attr->ns != NULL) &&
+ xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
+
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
+ /* TODO: Check id. */
+
+ /*
+ * And now for the children...
+ */
+ child = node->children;
+ while (child != NULL) {
+ if (IS_SCHEMA(child, "appinfo")) {
+ /* TODO: make available the content of "appinfo". */
+ /*
+ * source = anyURI
+ * {any attributes with non-schema namespace . . .}>
+ * Content: ({any})*
+ */
+ attr = child->properties;
+ while (attr != NULL) {
+ if (((attr->ns == NULL) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
+ ((attr->ns != NULL) &&
+ xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
+ xmlSchemaPValAttr(ctxt, NULL, NULL, child, "source",
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "documentation")) {
+ /* TODO: make available the content of "documentation". */
+ /*
+ * source = anyURI
+ * {any attributes with non-schema namespace . . .}>
+ * Content: ({any})*
+ */
+ attr = child->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else {
+ if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
+ (xmlStrEqual(attr->name, BAD_CAST "lang") &&
+ (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
+
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ }
+ attr = attr->next;
+ }
+ /*
+ * Attribute "xml:lang".
+ */
+ attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
+ if (attr != NULL)
+ xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
+ child = child->next;
+ } else {
+ if (!barked)
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL, "(appinfo | documentation)*");
+ barked = 1;
+ child = child->next;
+ }
+ }
+
return (ret);
}
@@ -2381,6 +3886,128 @@
}
/**
+ * xmlSchemaParseWildcardNs:
+ * @ctxt: a schema parser context
+ * @wildc: the wildcard, already created
+ * @node: a subtree containing XML Schema informations
+ *
+ * Parses the attribute "processContents" and "namespace"
+ * of a xsd:anyAttribute and xsd:any.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns 0 if everything goes fine, a positive error code
+ * if something is not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlSchemaWildcardPtr wildc,
+ xmlNodePtr node)
+{
+ const xmlChar *pc, *ns, *dictnsItem;
+ int ret = 0;
+ xmlChar *nsItem;
+ xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
+ xmlAttrPtr attr;
+
+ pc = xmlSchemaGetProp(ctxt, node, "processContents");
+ if ((pc == NULL)
+ || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
+ wildc->processContents = XML_SCHEMAS_ANY_STRICT;
+ } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
+ wildc->processContents = XML_SCHEMAS_ANY_SKIP;
+ } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
+ wildc->processContents = XML_SCHEMAS_ANY_LAX;
+ } else {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD,
+ NULL, NULL, node,
+ XML_SCHEMAS_UNKNOWN, "(strict | skip | lax)", pc,
+ NULL, NULL, NULL);
+ wildc->processContents = XML_SCHEMAS_ANY_STRICT;
+ ret = XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD;
+ }
+ /*
+ * Build the namespace constraints.
+ */
+ attr = xmlSchemaGetPropNode(node, "namespace");
+ ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if ((ns == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
+ wildc->any = 1;
+ else if (xmlStrEqual(ns, BAD_CAST "##other")) {
+ wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+ if (wildc->negNsSet == NULL) {
+ return (-1);
+ }
+ wildc->negNsSet->value = schema->targetNamespace;
+ } else {
+ const xmlChar *end, *cur;
+
+ cur = ns;
+ do {
+ while (IS_BLANK_CH(*cur))
+ cur++;
+ end = cur;
+ while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+ end++;
+ if (end == cur)
+ break;
+ nsItem = xmlStrndup(cur, end - cur);
+ if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
+ (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
+ NULL, NULL, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN,
+ "((##any | ##other) | List of (anyURI | "
+ "(##targetNamespace | ##local)))",
+ nsItem, NULL, NULL, NULL);
+ ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
+ } else {
+ if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
+ dictnsItem = schema->targetNamespace;
+ } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
+ dictnsItem = NULL;
+ } else {
+ /*
+ * Validate the item (anyURI).
+ */
+ xmlSchemaPValAttrNodeValue(ctxt, NULL, NULL, attr,
+ nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
+ dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
+ }
+ /*
+ * Avoid dublicate namespaces.
+ */
+ tmp = wildc->nsSet;
+ while (tmp != NULL) {
+ if (dictnsItem == tmp->value)
+ break;
+ tmp = tmp->next;
+ }
+ if (tmp == NULL) {
+ tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
+ if (tmp == NULL) {
+ xmlFree(nsItem);
+ return (-1);
+ }
+ tmp->value = dictnsItem;
+ tmp->next = NULL;
+ if (wildc->nsSet == NULL)
+ wildc->nsSet = tmp;
+ else
+ lastNs->next = tmp;
+ lastNs = tmp;
+ }
+
+ }
+ xmlFree(nsItem);
+ cur = end;
+ } while (*cur != 0);
+ }
+ return (ret);
+}
+/**
* xmlSchemaParseAny:
* @ctxt: a schema validation context
* @schema: the schema being built
@@ -2398,6 +4025,7 @@
xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
xmlChar name[30];
+ xmlSchemaWildcardPtr wildc;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -2407,10 +4035,16 @@
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_ANY;
- child = node->children;
type->minOccurs = xmlGetMinOccurs(ctxt, node);
type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
+ wildc = xmlSchemaAddWildcard(ctxt);
+ /*
+ * This is not nice, since it is won't be used as a attribute wildcard,
+ * but better than adding a field to the structure.
+ */
+ type->attributeWildcard = wildc;
+ xmlSchemaParseWildcardNs(ctxt, schema, wildc, node);
+ child = node->children;
if (IS_SCHEMA(child, "annotation")) {
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
@@ -2484,10 +4118,7 @@
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node)
{
- const xmlChar *processContents, *nsConstraint, *end, *cur, *dictMember;
- xmlChar *member;
xmlSchemaWildcardPtr ret;
- xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
xmlNodePtr child = NULL;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
@@ -2499,103 +4130,21 @@
}
ret->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE;
ret->id = xmlSchemaGetProp(ctxt, node, "id");
- processContents = xmlSchemaGetProp(ctxt, node, "processContents");
- if ((processContents == NULL)
- || (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
- ret->processContents = XML_SCHEMAS_ANY_STRICT;
- } else if (xmlStrEqual(processContents, (const xmlChar *) "skip")) {
- ret->processContents = XML_SCHEMAS_ANY_SKIP;
- } else if (xmlStrEqual(processContents, (const xmlChar *) "lax")) {
- ret->processContents = XML_SCHEMAS_ANY_LAX;
- } else {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD,
- "anyAttribute has unexpected content "
- "for processContents: %s\n",
- processContents, NULL);
- ret->processContents = XML_SCHEMAS_ANY_STRICT;
- }
- /*
- * Build the namespace constraints.
- */
- nsConstraint = xmlSchemaGetProp(ctxt, node, "namespace");
- if ((nsConstraint == NULL) || (xmlStrEqual(nsConstraint, BAD_CAST "##any")))
- ret->any = 1;
- else if (xmlStrEqual(nsConstraint, BAD_CAST "##other")) {
- ret->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
- if (ret->negNsSet == NULL) {
- xmlSchemaFreeWildcard(ret);
- return (NULL);
- }
- ret->negNsSet->value = schema->targetNamespace;
- } else {
- cur = nsConstraint;
- do {
- while (IS_BLANK_CH(*cur))
- cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK_CH(*end))))
- end++;
- if (end == cur)
- break;
- member = xmlStrndup(cur, end - cur);
- if ((xmlStrEqual(member, BAD_CAST "##other")) ||
- (xmlStrEqual(member, BAD_CAST "##any"))) {
- xmlSchemaPErr(ctxt, ret->node, XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
- "The namespace constraint of an anyAttribute "
- "is a set and must not contain \"%s\"\n",
- member, NULL);
- } else {
- /*
- * TODO: Validate the value (anyURI).
- */
- if (xmlStrEqual(member, BAD_CAST "##targetNamespace")) {
- dictMember = schema->targetNamespace;
- } else if (xmlStrEqual(member, BAD_CAST "##local")) {
- dictMember = NULL;
- } else
- dictMember = xmlDictLookup(ctxt->dict, member, -1);
- /*
- * Avoid dublicate namespaces.
- */
- tmp = ret->nsSet;
- while (tmp != NULL) {
- if (dictMember == tmp->value)
- break;
- tmp = tmp->next;
- }
- if (tmp == NULL) {
- tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
- if (tmp == NULL) {
- xmlFree(member);
- xmlSchemaFreeWildcard(ret);
- return (NULL);
- }
- tmp->value = dictMember;
- tmp->next = NULL;
- if (ret->nsSet == NULL)
- ret->nsSet = tmp;
- else
- lastNs->next = tmp;
- lastNs = tmp;
- }
-
- }
- xmlFree(member);
- cur = end;
- } while (*cur != 0);
- }
-
+ if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) {
+ xmlSchemaFreeWildcard(ret);
+ return (NULL);
+ }
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD,
- "anyAttribute has unexpected content\n",
- NULL, NULL);
+ /* TODO: Change the error code. */
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD,
+ NULL, NULL, node, child,
+ NULL, "(annotation?)");
}
return (ret);
@@ -2617,198 +4166,318 @@
xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- const xmlChar *name, *refNs = NULL, *ref = NULL, *attrVal;
+ const xmlChar *name, *attrValue;
+ xmlChar *repName = NULL; /* The reported designation. */
xmlSchemaAttributePtr ret;
- xmlNodePtr child = NULL;
- char buf[100];
- int hasRefType = 0;
+ xmlNodePtr child = NULL;
+ xmlAttrPtr attr, nameAttr;
+ int isRef = 0;
/*
* Note that the w3c spec assumes the schema to be validated with schema
* for schemas beforehand.
*
* 3.2.3 Constraints on XML Representations of Attribute Declarations
- *
- * TODO: Complete implementation of:
- * 3.2.6 Schema Component Constraint: Attribute Declaration Properties
- * Correct
*/
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
-
- name = xmlSchemaGetProp(ctxt, node, "name");
- if (name == NULL) {
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- /* 3.2.3 : 3.1
- * One of ref or name must be present, but not both
- */
- if (ref == NULL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_ATTR_NONAME_NOREF,
- "Attribute declaration has no \"name\" or \"ref\"\n",
- NULL, NULL);
+ attr = xmlSchemaGetPropNode(node, "ref");
+ nameAttr = xmlSchemaGetPropNode(node, "name");
+
+ if ((attr == NULL) && (nameAttr == NULL)) {
+ /*
+ * 3.2.3 : 3.1
+ * One of ref or name must be present, but not both
+ */
+ xmlSchemaPMissingAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_1,
+ (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node, NULL,
+ "One of the attributes 'ref' or 'name' must be present");
+ return (NULL);
+ }
+ if ((topLevel) || (attr == NULL)) {
+ if (nameAttr == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
+ (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node,
+ "name", NULL);
return (NULL);
- }
- hasRefType = 1;
- snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
- name = (const xmlChar *) buf;
+ }
+ } else
+ isRef = 1;
+
+ if (isRef) {
+ char buf[100];
+ const xmlChar *refNs = NULL, *ref = NULL, *refPrefix = NULL;
+
+ /*
+ * Parse as attribute reference.
+ */
+ if (xmlSchemaPValAttrNodeQName(ctxt, schema,
+ (xmlChar **) &xmlSchemaElemDesAttrRef, NULL, attr, &refNs,
+ &refPrefix, &ref) != 0) {
+ return (NULL);
+ }
+ snprintf(buf, 99, "#aRef %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
- if (!topLevel) {
- /* 3.2.3 : 3.2
- * If ref is present, then all of <simpleType>,
- * form and type must be absent.
- */
- if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration %s has \"ref\", thus "
- "\"form\" must be absent\n", name, NULL);
- }
- if (xmlSchemaGetProp(ctxt, node, "type") != NULL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration %s has \"ref\", thus "
- "\"type\" must be absent\n", name, NULL);
- }
+ if (ret == NULL) {
+ if (repName != NULL)
+ xmlFree(repName);
+ return (NULL);
}
+ ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
+ ret->node = node;
+ ret->refNs = refNs;
+ ret->refPrefix = refPrefix;
+ ret->ref = ref;
+ /*
+ xmlSchemaFormatTypeRep(&repName, (xmlSchemaTypePtr) ret, NULL, NULL);
+ */
+ if (nameAttr != NULL)
+ xmlSchemaPMutualExclAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_1,
+ &repName, (xmlSchemaTypePtr) ret, nameAttr,
+ "ref", "name");
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if (xmlStrEqual(attr->name, BAD_CAST "type") ||
+ xmlStrEqual(attr->name, BAD_CAST "form")) {
+ /*
+ * 3.2.3 : 3.2
+ * If ref is present, then all of <simpleType>,
+ * form and type must be absent.
+ */
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_SRC_ATTRIBUTE_3_2, &repName,
+ (xmlSchemaTypePtr) ret, attr);
+ } else if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "use")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "default"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ attr = attr->next;
+ }
} else {
const xmlChar *ns = NULL;
- /* 3.2.3 : 3.1
- * One of ref or name must be present, but not both
- */
- if ((!topLevel) && (xmlSchemaGetProp(ctxt, node, "ref") != NULL)) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration \"%s\" has both, \"name\" and "
- "\"ref\"\n", name, NULL);
+
+ /*
+ * Parse as attribute declaration.
+ */
+ if (xmlSchemaPValAttrNode(ctxt,
+ (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, nameAttr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+ return (NULL);
}
-
- /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
- /* Evaluate the target namespace */
+ /*
+ xmlSchemaFormatTypeRep(&repName, NULL, xmlSchemaElemDesAttrDecl, name);
+ */
+ /*
+ * 3.2.6 Schema Component Constraint: xmlns Not Allowed
+ */
+ if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_NO_XMLNS,
+ &repName, NULL, (xmlNodePtr) nameAttr,
+ XML_SCHEMAS_NCNAME, "NCName", NULL,
+ "The value must not match 'xmlns'",
+ NULL, NULL);
+ if (repName != NULL)
+ xmlFree(repName);
+ return (NULL);
+ }
+ /*
+ * Evaluate the target namespace
+ */
if (schema->targetNamespace != NULL) {
if (topLevel) {
ns = schema->targetNamespace;
- } else if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
- if (xmlStrEqual( xmlSchemaGetProp(ctxt, node, "form"),
- BAD_CAST "qualified")) {
- ns = schema->targetNamespace;
- }
- } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) {
- ns = schema->targetNamespace;
- }
- }
+ } else {
+ attr = xmlSchemaGetPropNode(node, "form");
+ if (attr != NULL) {
+ attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
+ ns = schema->targetNamespace;
+ } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ &repName, NULL, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(qualified | unqualified)",
+ attrValue, NULL, NULL, NULL);
+ }
+ } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
+ ns = schema->targetNamespace;
+ }
+ }
ret = xmlSchemaAddAttribute(ctxt, schema, name, ns);
- if (ret == NULL)
+ if (ret == NULL) {
+ if (repName != NULL)
+ xmlFree(repName);
return (NULL);
- /* 3.2.6 Schema Component Constraint: xmlns Not Allowed */
- if (xmlStrEqual(name, BAD_CAST "xmlns")) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_NAME,
- "The name of an attribute declaration must not match "
- "\"xmlns\".\n", NULL, NULL);
- }
-
- /* 3.2.6 Schema Component Constraint: xsi: Not Allowed */
- if (xmlStrEqual(ret->targetNamespace, xmlSchemaInstanceNs)) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_NAME,
- "The target namespace of an attribute declaration, "
- "must not match \"http://www.w3.org/2001/"
- "XMLSchema-instance\"", NULL, NULL);
- }
- }
- if (ret == NULL) {
- return (NULL);
- }
- ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
- if (topLevel)
- ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
-
- /* Handle the "use" attribute. */
- attrVal = xmlSchemaGetProp(ctxt, node, "use");
- if (attrVal != NULL) {
- if (xmlStrEqual(attrVal, BAD_CAST "optional"))
- ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
- else if (xmlStrEqual(attrVal, BAD_CAST "prohibited"))
- ret->occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
- else if (xmlStrEqual(attrVal, BAD_CAST "required"))
- ret->occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
- else
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_USE,
- "Attribute declaration %s has an invalid "
- "value for \"use\"\n", name, NULL);
- } else
- ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
-
-
- if (xmlSchemaGetProp(ctxt, node, "default") != NULL) {
- /* 3.2.3 : 1
- * default and fixed must not both be present.
- */
- if (xmlSchemaGetProp(ctxt, node, "fixed") != NULL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration has both, \"default\" "
- "and \"fixed\"\n", NULL, NULL);
}
- /* 3.2.3 : 2
- * If default and use are both present, use must have
- * the actual value optional.
- */
- if (ret->occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration has \"default\" but "
- "\"use\" is not \"optional\"\n", NULL, NULL);
- }
+ ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
+ ret->node = node;
+ if (topLevel)
+ ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
+ /*
+ * 3.2.6 Schema Component Constraint: xsi: Not Allowed
+ */
+ if (xmlStrEqual(ret->targetNamespace, xmlSchemaInstanceNs)) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_NO_XSI,
+ &repName, (xmlSchemaTypePtr) ret, node,
+ "The target namespace must not match '%s'",
+ xmlSchemaInstanceNs);
+ }
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "type"))) {
+ if ((topLevel) ||
+ ((!xmlStrEqual(attr->name, BAD_CAST "form")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "use")))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt, XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ attr = attr->next;
+ }
+ xmlSchemaPValAttrQName(ctxt, schema, &repName, (xmlSchemaTypePtr) ret,
+ node, "type", &ret->typeNs, NULL, &ret->typeName);
}
-
- ret->ref = ref;
- ret->refNs = refNs;
- /*
- * The setting of XML_SCHEMAS_ATTR_NSDEFAULT is not needed anymore,
- * since the target namespace was already evaluated and took
- * attributeFormDefault into account.
- */
+ /* TODO: Check ID. */
+ ret->id = xmlSchemaGetProp(ctxt, node, "id");
/*
- if ((ret->targetNamespace != NULL) &&
- ((schema->flags & XML_SCHEMAS_QUALIF_ATTR) == 0) &&
- (xmlStrEqual(ret->targetNamespace, schema->targetNamespace)))
- ret->flags |= XML_SCHEMAS_ATTR_NSDEFAULT;
+ * Attribute "fixed".
*/
- ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
- if (ret->typeName != NULL)
- hasRefType = 1;
- ret->node = node;
+ ret->defValue = xmlSchemaGetProp(ctxt, node, "fixed");
+ if (ret->defValue != NULL)
+ ret->flags |= XML_SCHEMAS_ATTR_FIXED;
+ /*
+ * Attribute "default".
+ */
+ attr = xmlSchemaGetPropNode(node, "default");
+ if (attr != NULL) {
+ /*
+ * 3.2.3 : 1
+ * default and fixed must not both be present.
+ */
+ if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
+ xmlSchemaPMutualExclAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
+ &repName, (xmlSchemaTypePtr) ret, attr, "default", "fixed");
+ } else
+ ret->defValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ }
+ if (topLevel == 0) {
+ /*
+ * Attribute "use".
+ */
+ attr = xmlSchemaGetPropNode(node, "use");
+ if (attr != NULL) {
+ attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (xmlStrEqual(attrValue, BAD_CAST "optional"))
+ ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
+ else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
+ ret->occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
+ else if (xmlStrEqual(attrValue, BAD_CAST "required"))
+ ret->occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
+ else
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_INVALID_ATTR_USE,
+ &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(optional | prohibited | required)",
+ attrValue, NULL, NULL, NULL);
+ } else
+ ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
+ /*
+ * 3.2.3 : 2
+ * If default and use are both present, use must have
+ * the actual value optional.
+ */
+ if ((ret->occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
+ (ret->defValue != NULL) &&
+ ((ret->flags & XML_SCHEMAS_ATTR_FIXED) == 0)) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_SRC_ATTRIBUTE_2,
+ &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(optional | prohibited | required)", NULL,
+ "The value must be 'optional' if the attribute "
+ "'default' is present as well", NULL, NULL);
+ }
+ }
+ /*
+ * And now for the children...
+ */
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
+ }
+ if (isRef) {
+ if (child != NULL) {
+ if (IS_SCHEMA(child, "simpleType"))
+ /*
+ * 3.2.3 : 3.2
+ * If ref is present, then all of <simpleType>,
+ * form and type must be absent.
+ */
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
+ &repName, (xmlSchemaTypePtr) ret, node, child, NULL,
+ "(annotation?)");
+ else
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, node, child, NULL,
+ "(annotation?)");
+ }
+ } else {
+ if (IS_SCHEMA(child, "simpleType")) {
+ if (ret->typeName != NULL) {
+ /*
+ * 3.2.3 : 4
+ * type and <simpleType> must not both be present.
+ */
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
+ &repName, (xmlSchemaTypePtr) ret, node, child,
+ "The attribute 'type' and the <simpleType> child "
+ "are mutually exclusive", NULL);
+ } else
+ ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ child = child->next;
+ }
+ if (child != NULL)
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, node, child, NULL,
+ "(annotation?, simpleType?)");
}
- if (IS_SCHEMA(child, "simpleType")) {
- if (hasRefType) {
- /* 3.2.3 : 4
- * type and <simpleType> must not both be present.
- *
- * TODO: XML_SCHEMAP_INVALID_ATTR_COMBINATION seems not to be
- * a proper error type here.
- */
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Attribute declaration %s has both (\"ref\" or "
- "\"type\") and <simpleType>\n", name, NULL);
- } else
- ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ATTR_CHILD,
- "attribute %s has unexpected content\n", name,
- NULL);
- }
-
+ /*
+ * Cleanup.
+ */
+ if (repName != NULL)
+ xmlFree(repName);
return (ret);
}
@@ -2842,9 +4511,10 @@
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_ATTRGRP_NONAME_NOREF,
- "AttributeGroup has no name nor ref\n", NULL,
- NULL);
+ XML_SCHEMAP_ATTRGRP_NONAME_NOREF,
+ "Attribute group or particle: One of the attributes 'name' "
+ "or 'ref' must be present.\n", NULL,
+ NULL);
return (NULL);
}
snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
@@ -2870,38 +4540,11 @@
ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- child = xmlSchemaParseAttrDecls(ctxt, schema, child, (xmlSchemaTypePtr) ret);
- /* Seems that this can be removed. */
- /*
- while ((IS_SCHEMA(child, "attribute")) ||
- (IS_SCHEMA(child, "attributeGroup"))) {
- attr = NULL;
- if (IS_SCHEMA(child, "attribute")) {
- attr = xmlSchemaParseAttribute(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "attributeGroup")) {
- attr = (xmlSchemaAttributePtr)
- xmlSchemaParseAttributeGroup(ctxt, schema, child, 0);
- }
- if (attr != NULL) {
- if (last == NULL) {
- ret->attributes = attr;
- last = attr;
- } else {
- last->next = attr;
- last = attr;
- }
- }
- child = child->next;
- }
- if (IS_SCHEMA(child, "anyAttribute")) {
- TODO
- child = child->next;
- }
- */
+ child = xmlSchemaParseAttrDecls(ctxt, schema, child, (xmlSchemaTypePtr) ret);
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD,
- "attribute group %s has unexpected content\n", name,
+ "Attribute group '%s' has unexpected content.\n", name,
NULL);
}
ctxt->container = oldcontainer;
@@ -2909,6 +4552,107 @@
}
/**
+ * xmlSchemaPValAttrBlockFinal:
+ * @value: the value
+ * @flags: the flags to be modified
+ * @flagAll: the specific flag for "#all"
+ * @flagExtension: the specific flag for "extension"
+ * @flagRestriction: the specific flag for "restriction"
+ * @flagSubstitution: the specific flag for "substitution"
+ * @flagList: the specific flag for "list"
+ * @flagUnion: the specific flag for "union"
+ *
+ * Validates the value of the attribute "final" and "block". The value
+ * is converted into the specified flag values and returned in @flags.
+ *
+ * Returns 0 if the value is valid, 1 otherwise.
+ */
+
+static int
+xmlSchemaPValAttrBlockFinal(const xmlChar *value,
+ int *flags,
+ int flagAll,
+ int flagExtension,
+ int flagRestriction,
+ int flagSubstitution,
+ int flagList,
+ int flagUnion)
+{
+ int ret = 0;
+
+ /*
+ * TODO: This does not check for dublicate entries.
+ */
+ if (xmlStrEqual(value, BAD_CAST "#all")) {
+ if (flagAll != -1)
+ *flags |= flagAll;
+ else {
+ if (flagExtension != -1)
+ *flags |= flagExtension;
+ if (flagRestriction != -1)
+ *flags |= flagRestriction;
+ if (flagSubstitution != -1)
+ *flags |= flagSubstitution;
+ if (flagList != -1)
+ *flags |= flagList;
+ if (flagUnion != -1)
+ *flags |= flagUnion;
+ }
+ } else {
+ const xmlChar *end, *cur = value;
+ xmlChar *item;
+
+ do {
+ while (IS_BLANK_CH(*cur))
+ cur++;
+ end = cur;
+ while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+ end++;
+ if (end == cur)
+ break;
+ item = xmlStrndup(cur, end - cur);
+ if (xmlStrEqual(item, BAD_CAST "extension")) {
+ if (flagExtension != -1) {
+ if ((*flags & flagExtension) == 0)
+ *flags |= flagExtension;
+ } else
+ ret = 1;
+ } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
+ if (flagRestriction != -1) {
+ if ((*flags & flagRestriction) == 0)
+ *flags |= flagRestriction;
+ } else
+ ret = 1;
+ } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
+ if (flagSubstitution != -1) {
+ if ((*flags & flagSubstitution) == 0)
+ *flags |= flagSubstitution;
+ } else
+ ret = 1;
+ } else if (xmlStrEqual(item, BAD_CAST "list")) {
+ if (flagList != -1) {
+ if ((*flags & flagList) == 0)
+ *flags |= flagList;
+ } else
+ ret = 1;
+ } else if (xmlStrEqual(item, BAD_CAST "union")) {
+ if (flagUnion != -1) {
+ if ((*flags & flagUnion) == 0)
+ *flags |= flagUnion;
+ } else
+ ret = 1;
+ } else
+ ret = 1;
+ if (item != NULL)
+ xmlFree(item);
+ cur = end;
+ } while ((ret == 0) && (*cur != 0));
+ }
+
+ return (ret);
+}
+
+/**
* xmlSchemaParseElement:
* @ctxt: a schema validation context
* @schema: the schema being built
@@ -2923,206 +4667,399 @@
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- const xmlChar *name, *fixed;
- const xmlChar *refNs = NULL, *ref = NULL;
+ const xmlChar *name = NULL;
+ const xmlChar *attrValue;
+ xmlChar *repName = NULL;
xmlSchemaElementPtr ret;
xmlNodePtr child = NULL;
- const xmlChar *oldcontainer;
- char buf[100];
- xmlAttrPtr attr;
+ const xmlChar *oldcontainer;
+ xmlAttrPtr attr, nameAttr;
+ int minOccurs, maxOccurs;
+ int isRef = 0;
/* 3.3.3 Constraints on XML Representations of Element Declarations */
/* TODO: Complete implementation of 3.3.6 */
-
+
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- oldcontainer = ctxt->container;
- name = xmlSchemaGetProp(ctxt, node, "name");
- if (name == NULL) {
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- /* 3.3.3 : 2.1
- * One of ref or name must be present, but not both
- */
- if (ref == NULL) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_ELEM_NONAME_NOREF,
- "Element declaration has no name nor ref\n", NULL, NULL);
- return (NULL);
- }
-
- snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
- name = (const xmlChar *) buf;
- ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
- } else {
- const xmlChar *ns = NULL;
- /* Evaluate the target namespace */
+ oldcontainer = ctxt->container;
+
+ nameAttr = xmlSchemaGetPropNode(node, "name");
+ attr = xmlSchemaGetPropNode(node, "ref");
+ if ((topLevel) || (attr == NULL)) {
+ if (nameAttr == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, node,
+ "name", NULL);
+ return (NULL);
+ }
+ name = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) nameAttr);
+ } else {
+ isRef = 1;
+
+ }
+ /*
+ * ... unless minOccurs=maxOccurs=0, in which case the item corresponds
+ * to no component at all
+ * TODO: It might be better to validate the element, even if it won't be
+ * used.
+ */
+ minOccurs = xmlGetMinOccurs(ctxt, node);
+ maxOccurs = xmlGetMaxOccurs(ctxt, node);
+ if ((minOccurs == 0) && (maxOccurs == 0))
+ return (NULL);
+ /*
+ * If we get a "ref" attribute on a local <element> we will assume it's
+ * a reference - even if there's a "name" attribute; this seems to be more
+ * robust.
+ */
+ if (isRef) {
+ char buf[100];
+ const xmlChar *refNs = NULL, *ref = NULL, *refPrefix;
+
+ /*
+ * Parse as a particle.
+ */
+ xmlSchemaPValAttrNodeQName(ctxt, schema,
+ (xmlChar **) &xmlSchemaElemDesAttrRef,
+ NULL, attr, &refNs, &refPrefix, &ref);
+
+ snprintf(buf, 99, "#eRef %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
+ ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
+ if (ret == NULL) {
+ if (repName != NULL)
+ xmlFree(repName);
+ return (NULL);
+ }
+ ret->type = XML_SCHEMA_TYPE_ELEMENT;
+ ret->node = node;
+ ret->ref = ref;
+ ret->refNs = refNs;
+ ret->refPrefix = refPrefix;
+ ret->flags |= XML_SCHEMAS_ELEM_REF;
+ /*
+ * Check for illegal attributes.
+ */
+ /*
+ * 3.3.3 : 2.1
+ * One of ref or name must be present, but not both
+ */
+ if (nameAttr != NULL) {
+ xmlSchemaPMutualExclAttrErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_2_1,
+ &repName, (xmlSchemaTypePtr) ret, nameAttr,
+ "ref", "name");
+ }
+ /* 3.3.3 : 2.2 */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "name"))) {
+ xmlSchemaPCustomAttrErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_2_2,
+ &repName, (xmlSchemaTypePtr) ret, attr,
+ "Only the attributes 'minOccurs', 'maxOccurs' and "
+ "'id' are allowed in addition to 'ref'");
+ break;
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ attr = attr->next;
+ }
+ } else {
+ const xmlChar *ns = NULL, *fixed;
+
+ /*
+ * Parse as an element declaration.
+ */
+ if (xmlSchemaPValAttrNode(ctxt,
+ (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, nameAttr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
+ return (NULL);
+ /*
+ * Evaluate the target namespace.
+ */
if (schema->targetNamespace != NULL) {
if (topLevel) {
ns = schema->targetNamespace;
- } else if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
- if (xmlStrEqual( xmlSchemaGetProp(ctxt, node, "form"),
- BAD_CAST "qualified")) {
+ } else {
+ attr = xmlSchemaGetPropNode(node, "form");
+ if (attr != NULL) {
+ attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
+ ns = schema->targetNamespace;
+ } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ (xmlChar **) &xmlSchemaElemDesElemDecl, NULL,
+ (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(qualified | unqualified)",
+ attrValue, NULL, NULL, NULL);
+ }
+ } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
ns = schema->targetNamespace;
- }
- } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) {
- ns = schema->targetNamespace;
}
- }
- /*local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
+ }
ret = xmlSchemaAddElement(ctxt, schema, name, ns);
- /* 3.3.3 : 2.1
- * One of ref or name must be present, but not both
- */
- if ((!topLevel) && (xmlSchemaGetProp(ctxt, node, "ref") != NULL)) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Element declaration has both, \"name\" and "
- "\"ref\"\n", NULL, NULL);
+ if (ret == NULL) {
+ if (repName != NULL)
+ xmlFree(repName);
+ return (NULL);
}
- }
- if (ret != NULL)
- ret->node = node;
- if (ret == NULL) {
- return (NULL);
- }
- ret->type = XML_SCHEMA_TYPE_ELEMENT;
- ret->ref = ref;
- ret->refNs = refNs;
- if (ref != NULL)
- ret->flags |= XML_SCHEMAS_ELEM_REF;
-
- /* 3.3.3 : 2.2 */
- if ((!topLevel) && (ref != NULL)) {
+ ret->type = XML_SCHEMA_TYPE_ELEMENT;
+ ret->node = node;
+ /*
+ * Check for illegal attributes.
+ */
attr = node->properties;
while (attr != NULL) {
- if ((attr->ns == NULL) &&
- (!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) {
+ if (topLevel == 0) {
+ if (xmlStrEqual(attr->name, BAD_CAST "substitutionGroup")) {
+ /*
+ * 3.3.6 : 3 If there is a non-·absent· {substitution
+ * group affiliation}, then {scope} must be global.
+ * TODO: This one is redundant, since the S4S does
+ * prohibit this attribute on local declarations already;
+ * so why an explicit error code? Weird spec.
+ */
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_E_PROPS_CORRECT_3,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ } else if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "form"))) {
- xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Element declaration %s: only minOccurs, maxOccurs "
- "and id are allowed in addition to ref\n",
- ret->name, NULL);
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
+
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
+ }
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, attr);
}
attr = attr->next;
- }
- }
-
- if (topLevel) {
- ret->flags |= XML_SCHEMAS_ELEM_GLOBAL;
- ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
- }
- if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
- ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
- if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
- ret->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
- ctxt->container = name;
-
- ret->id = xmlSchemaGetProp(ctxt, node, "id");
- ret->namedType =
- xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
- ret->substGroup =
- xmlGetQNameProp(ctxt, node, "substitutionGroup",
- &(ret->substGroupNs));
- if ((ret->substGroup != NULL) && (!topLevel)) {
- /* 3.3.6 : 3 */
+ }
/*
- * TODO: This seems to be redundant, since the schema for schemas
- * already prohibits the use of the "substitutionGroup" attribute
- * in local element declarations.
- */
- xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_ATTR_COMBINATION,
- "Element declaration %s: substitutionGroup is allowed "
- "on top-level declarations only\n", ret->name, NULL);
-
- }
- fixed = xmlSchemaGetProp(ctxt, node, "fixed");
- ret->minOccurs = xmlGetMinOccurs(ctxt, node);
- ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);
+ * Extract/validate attributes.
+ */
+ if (topLevel) {
+ /*
+ * Process top attributes of global element declarations here.
+ */
+ ret->flags |= XML_SCHEMAS_ELEM_GLOBAL;
+ ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
+ xmlSchemaPValAttrQName(ctxt, schema, &repName,
+ (xmlSchemaTypePtr) ret, node, "substitutionGroup",
+ &(ret->substGroupNs), NULL, &(ret->substGroup));
+ if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret,
+ node, "abstract", 0))
+ ret->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
+ /*
+ * Attribute "final".
+ */
+ attr = xmlSchemaGetPropNode(node, "final");
+ if (attr == NULL) {
+ ret->flags |= XML_SCHEMAS_ELEM_FINAL_ABSENT;
+ } else {
+ attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags),
+ -1,
+ XML_SCHEMAS_ELEM_FINAL_EXTENSION,
+ XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(#all | List of (extension | restriction))",
+ attrValue, NULL, NULL, NULL);
+ }
+ }
+ }
+ /*
+ * Attribute "block".
+ */
+ attr = xmlSchemaGetPropNode(node, "block");
+ if (attr == NULL) {
+ ret->flags |= XML_SCHEMAS_ELEM_BLOCK_ABSENT;
+ } else {
+ attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags),
+ -1,
+ XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
+ XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
+ XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(#all | List of (extension | "
+ "restriction | substitution))", attrValue,
+ NULL, NULL, NULL);
+ }
+ }
+ if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret,
+ node, "nillable", 0))
+ ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
- ret->value = xmlSchemaGetProp(ctxt, node, "default");
- if ((ret->value != NULL) && (fixed != NULL)) {
- /* 3.3.3 : 1
- * default and fixed must not both be present.
- */
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_ELEM_DEFAULT_FIXED,
- "Element %s has both default and fixed\n",
- ret->name, NULL);
- } else if (fixed != NULL) {
- ret->flags |= XML_SCHEMAS_ELEM_FIXED;
- ret->value = fixed;
- }
+ xmlSchemaPValAttrQName(ctxt, schema,
+ &repName, (xmlSchemaTypePtr) ret, node,
+ "type", &(ret->namedTypeNs), NULL, &(ret->namedType));
+ ret->value = xmlSchemaGetProp(ctxt, node, "default");
+ attr = xmlSchemaGetPropNode(node, "fixed");
+ if (attr != NULL) {
+ fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ if (ret->value != NULL) {
+ /*
+ * 3.3.3 : 1
+ * default and fixed must not both be present.
+ */
+ xmlSchemaPMutualExclAttrErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_1,
+ &repName, (xmlSchemaTypePtr) ret, attr,
+ "default", "fixed");
+ } else {
+ ret->flags |= XML_SCHEMAS_ELEM_FIXED;
+ ret->value = fixed;
+ }
+ }
+ }
+ /*
+ * Extract/validate common attributes.
+ */
+ /* TODO: Check ID: */
+ ret->id = xmlSchemaGetProp(ctxt, node, "id");
+ ret->minOccurs = minOccurs;
+ ret->maxOccurs = maxOccurs;
+ if ((topLevel != 1) && (ret->maxOccurs != UNBOUNDED)) {
+ /*
+ * TODO: Maby we should better not create the element/particle,
+ * if min/max is invalid, since it could confuse the build of the
+ * content model.
+ */
+ /*
+ * 3.9.6 Schema Component Constraint: Particle Correct
+ *
+ */
+ if (maxOccurs < 1) {
+ /*
+ * 2.2 {max occurs} must be greater than or equal to 1.
+ */
+ xmlSchemaPCustomAttrErr(ctxt,
+ XML_SCHEMAP_P_PROPS_CORRECT_2_2,
+ &repName, (xmlSchemaTypePtr) ret,
+ xmlSchemaGetPropNode(node, "maxOccurs"),
+ "The value must be greater than or equal to 1");
+ } else if (minOccurs > maxOccurs) {
+ /*
+ * 2.1 {min occurs} must not be greater than {max occurs}.
+ */
+ xmlSchemaPCustomAttrErr(ctxt,
+ XML_SCHEMAP_P_PROPS_CORRECT_2_1,
+ &repName, (xmlSchemaTypePtr) ret,
+ xmlSchemaGetPropNode(node, "minOccurs"),
+ "The value must not be greater than the value of 'maxOccurs'");
+ }
+ }
+
+ /*
+ * And now for the children...
+ */
+ ctxt->container = name;
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
+ ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ child = child->next;
}
-
- if (ref != NULL) {
- /* 3.3.3 (2.2) */
- while (child != NULL) {
- if ((IS_SCHEMA(child, "complexType")) ||
- (IS_SCHEMA(child, "simpleType")) ||
- (IS_SCHEMA(child, "unique")) ||
- (IS_SCHEMA(child, "key")) ||
- (IS_SCHEMA(child, "keyref"))) {
-
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_REF_AND_CONTENT,
- "Element declaration %s: only annotation is "
- "allowed as content in addition to ref\n",
- ret->name, NULL);
- } else {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ELEM_CHILD,
- "element %s has unexpected content\n", name, NULL);
- }
- child = child->next;
+ if (isRef) {
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_2_2,
+ &repName, (xmlSchemaTypePtr) ret, node, child,
+ NULL, "(annotation?)");
}
- } else {
+ } else {
if (IS_SCHEMA(child, "complexType")) {
- /* 3.3.3 : 3
- * type and either <simpleType> or <complexType> are mutually
- * exclusive
- */
+ /*
+ * 3.3.3 : 3
+ * "type" and either <simpleType> or <complexType> are mutually
+ * exclusive
+ */
if (ret->namedType != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION,
- "Element declaration %s has both \"type\" "
- "and a local complex type\n",
- ret->name, NULL);
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_3,
+ &repName, (xmlSchemaTypePtr) ret, node, child,
+ "The attribute 'type' and the <complexType> child are "
+ "mutually exclusive", NULL);
} else
ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0);
child = child->next;
} else if (IS_SCHEMA(child, "simpleType")) {
- /* 3.3.3 : 3
- * type and either <simpleType> or <complexType> are
- * mutually exclusive
- */
+ /*
+ * 3.3.3 : 3
+ * "type" and either <simpleType> or <complexType> are
+ * mutually exclusive
+ */
if (ret->namedType != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION,
- "Element declaration %s has both \"type\" "
- "and a local simple type\n",
- ret->name, NULL);
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_SRC_ELEMENT_3,
+ &repName, (xmlSchemaTypePtr) ret, node, child,
+ "The attribute 'type' and the <simpleType> child are "
+ "mutually exclusive", NULL);
} else
ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
child = child->next;
- }
-
+ }
while ((IS_SCHEMA(child, "unique")) ||
- (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
+ (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
TODO child = child->next;
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ELEM_CHILD,
- "element %s has unexpected content\n", name, NULL);
- }
- }
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ &repName, (xmlSchemaTypePtr) ret, node, child,
+ NULL, "(annotation?, ((simpleType | complexType)?, "
+ "(unique | key | keyref)*))");
+ }
+ }
ctxt->container = oldcontainer;
+ /*
+ * Cleanup.
+ */
+ if (repName != NULL)
+ xmlFree(repName);
+ /*
+ * NOTE: Element Declaration Representation OK 4. will be checked at a
+ * different layer.
+ */
return (ret);
}
@@ -3181,7 +5118,7 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_UNION_CHILD,
- "Union %s has unexpected content\n", type->name,
+ "<union> has unexpected content.\n", type->name,
NULL);
}
return (type);
@@ -3206,7 +5143,6 @@
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
xmlChar name[30];
- xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -3224,16 +5160,8 @@
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- /*
- * Check type of "itemType".
- */
- attr = xmlSchemaGetPropNode(node, BAD_CAST "itemType");
- if (attr != NULL) {
- type->base = xmlGetQNameProp(ctxt, node, "itemType", &(type->baseNs));
- xmlSchemaParseSchemaAttrValue(ctxt, attr,
- xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME));
-
- }
+ xmlSchemaPValAttrQName(ctxt, schema, NULL, NULL,
+ node, "itemType", &(type->baseNs), NULL, &(type->base));
subtype = NULL;
if (IS_SCHEMA(child, "simpleType")) {
subtype = (xmlSchemaTypePtr)
@@ -3248,7 +5176,7 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_LIST_CHILD,
- "List %s has unexpected content\n", type->name,
+ "<list> has unexpected content.\n", type->name,
NULL);
}
return (type);
@@ -3264,7 +5192,7 @@
* *WARNING* this interface is highly subject to change
*
* Returns -1 in case of error, 0 if the declaration is improper and
- * 1 in case of success.
+ * 1 in case of success.
*/
static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
@@ -3272,95 +5200,124 @@
{
xmlSchemaTypePtr type, subtype, ctxtType;
xmlNodePtr child = NULL;
- const xmlChar *propVal;
+ const xmlChar *attrValue = NULL;
+ xmlChar *repName = NULL;
+ xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- ctxtType = ctxt->ctxtType;
- propVal = xmlSchemaGetProp(ctxt, node, "name");
- if (propVal == NULL) {
- char buf[100];
+ attr = xmlSchemaGetPropNode(node, "name");
- snprintf(buf, 99, "simpleType %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
- } else {
- if (!topLevel) {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- "The attribute \"name\" is not allowed on a local "
- "simpleType definition\n",
- propVal, NULL);
+ if (topLevel) {
+ if (attr == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node,
+ "name", NULL);
+ return (NULL);
+ } else if (xmlSchemaPValAttrNode(ctxt,
+ (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
return (NULL);
}
+ }
+
+ if (topLevel == 0) {
+ char buf[100];
+
/*
- * "name" has to be of type NCName.
- * TODO: Actually this should be validated by the schema for schemas.
+ * Parse as local simple type definition.
*/
- if (xmlSchemaParseSchemaAttrValue(ctxt,
- xmlSchemaGetPropNode(node, BAD_CAST "name"),
- xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME)) != 0)
- return (NULL);
- type = xmlSchemaAddType(ctxt, schema, propVal, schema->targetNamespace);
- }
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_SIMPLE;
- if (topLevel)
- type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
- propVal = xmlSchemaGetProp(ctxt, node, "final");
- if (propVal == NULL) {
- type->flags |= XML_SCHEMAS_TYPE_FINAL_DEFAULT;
- } else {
- if (xmlStrEqual(propVal, BAD_CAST "#all")) {
- type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
- type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
- type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
- } else {
- const xmlChar *end, *cur = propVal;
- xmlChar *item;
-
- do {
- while (IS_BLANK_CH(*cur))
- cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK_CH(*end))))
- end++;
- if (end == cur)
- break;
- item = xmlStrndup(cur, end - cur);
- if (xmlStrEqual(item, BAD_CAST "restriction")) {
- if ((type->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) == 0)
- type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
- } else if (xmlStrEqual(item, BAD_CAST "list")) {
- if ((type->flags & XML_SCHEMAS_TYPE_FINAL_LIST) == 0)
- type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
- } else if (xmlStrEqual(item, BAD_CAST "union")) {
- if ((type->flags & XML_SCHEMAS_TYPE_FINAL_UNION) == 0)
- type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
- } else {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAS_ERR_INTERNAL,
- "The attribute \"final\" of type \"%s\" "
- "has an invalid value\n",
- type->name, NULL);
+ snprintf(buf, 99, "#st %d", ctxt->counter++ + 1);
+ type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
+ if (type == NULL)
+ return (NULL);
+ type->node = node;
+ type->type = XML_SCHEMA_TYPE_SIMPLE;
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, type, attr);
}
- if (item != NULL)
- xmlFree(item);
- cur = end;
- } while (*cur != 0);
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, type, attr);
+ }
+ attr = attr->next;
}
- }
+ } else {
+ /*
+ * Parse as global simple type definition.
+ */
+ type = xmlSchemaAddType(ctxt, schema, attrValue, schema->targetNamespace);
+ if (type == NULL)
+ return (NULL);
+ type->node = node;
+ type->type = XML_SCHEMA_TYPE_SIMPLE;
+ type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "final"))){
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, type, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ &repName, type, attr);
+ }
+ attr = attr->next;
+ }
+ /*
+ * Attribute "final".
+ */
+ attr = xmlSchemaGetPropNode(node, "final");
+ if (attr == NULL) {
+ type->flags |= XML_SCHEMAS_TYPE_FINAL_DEFAULT;
+ } else {
+ attrValue = xmlSchemaGetProp(ctxt, node, "final");
+ if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
+ -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
+ XML_SCHEMAS_TYPE_FINAL_LIST,
+ XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
+
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ &repName, type, (xmlNodePtr) attr,
+ XML_SCHEMAS_UNKNOWN, "(#all | List of (list | union | restriction)",
+ attrValue, NULL, NULL, NULL);
+ }
+ }
+ }
+ /* TODO: Check id. */
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
+ /*
+ * And now for the children...
+ */
+ ctxtType = ctxt->ctxtType;
+ ctxt->ctxtType = type;
+ ctxt->parentItem = type;
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- subtype = NULL;
- ctxt->ctxtType = type;
- ctxt->parentItem = type;
+ subtype = NULL;
if (IS_SCHEMA(child, "restriction")) {
subtype = (xmlSchemaTypePtr)
xmlSchemaParseRestriction(ctxt, schema, child);
@@ -3374,23 +5331,15 @@
xmlSchemaParseUnion(ctxt, schema, child);
child = child->next;
}
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- "SimpleType \"%s\" has unexpected content\n",
- type->name, NULL);
- } else {
- if (subtype == NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_S4S_ELEM_MISSING,
- "SimpleType \"%s\" must have one of <restriction> or "
- "<list> or <union> as a child\n",
- type->name, NULL);
- }
+ type->subtypes = subtype;
+ if ((child != NULL) || (subtype == NULL)) {
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ &repName, type, node, child, NULL,
+ "(annotation?, (restriction | list | union))");
}
-
ctxt->ctxtType = ctxtType;
+ if (repName != NULL)
+ xmlFree(repName);
return (type);
}
@@ -3427,8 +5376,9 @@
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_GROUP_NONAME_NOREF,
- "Group has no name nor ref\n", NULL, NULL);
+ XML_SCHEMAP_GROUP_NONAME_NOREF,
+ "Group definition or particle: One of the attributes \"name\" "
+ "or \"ref\" must be present.\n", NULL, NULL);
return (NULL);
}
if (refNs == NULL)
@@ -3471,7 +5421,7 @@
type->subtypes = subtype;
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_GROUP_CHILD,
- "Group %s has unexpected content\n", type->name,
+ "Group definition \"%s\" has unexpected content.\n", type->name,
NULL);
}
@@ -3512,11 +5462,13 @@
type->minOccurs = xmlGetMinOccurs(ctxt, node);
if (type->minOccurs > 1)
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
- "invalid value for minOccurs (must be 0 or 1)\n", NULL, NULL);
+ "<all>: The value of the attribute \"minOccurs\" is invalid. "
+ "Either \"0\" or \"1\" is expected.\n", NULL, NULL);
type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
if (type->maxOccurs > 1)
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
- "invalid value for maxOccurs (must be 0 or 1)\n", NULL, NULL);
+ "<all>: The value of the attribute \"maxOccurs\" is invalid. "
+ "Either \"0\" or \"1\" is expected.\n", NULL, NULL);
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -3529,11 +5481,11 @@
if (subtype != NULL) {
if (subtype->minOccurs > 1)
xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MINOCCURS,
- "invalid value for minOccurs (must be 0 or 1)\n",
+ "invalid value for minOccurs (must be 0 or 1).\n",
NULL, NULL);
if (subtype->maxOccurs > 1)
xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MAXOCCURS,
- "invalid value for maxOccurs (must be 0 or 1)\n",
+ "invalid value for maxOccurs (must be 0 or 1).\n",
NULL, NULL);
if (last == NULL) {
type->subtypes = subtype;
@@ -3548,7 +5500,7 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ALL_CHILD,
- "All %s has unexpected content\n", type->name,
+ "<all> has unexpected content.\n", type->name,
NULL);
}
@@ -3604,12 +5556,14 @@
if (import->schema == NULL) {
/* FIXME use another error enum here ? */
xmlSchemaPErr(ctxt, NULL, XML_SCHEMAS_ERR_INTERNAL,
- "failed to import schema at location %s\n",
+ "Failed to import schema from location \"%s\".\n",
schemaLocation, NULL);
xmlSchemaFreeParserCtxt(newctxt);
+ /* The schemaLocation is held by the dictionary.
if (import->schemaLocation != NULL)
xmlFree((xmlChar *)import->schemaLocation);
+ */
xmlFree(import);
return NULL;
}
@@ -3651,9 +5605,10 @@
check = xmlParseURI((const char *) namespace);
if (check == NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
- "Import namespace attribute is not an URI: %s\n",
- namespace, NULL);
+ XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
+ "Element <import>: The value \"%s\" of the attribute \"namespace\" is "
+ "not a valid URI.\n",
+ namespace, NULL);
return (-1);
} else {
xmlFreeURI(check);
@@ -3666,9 +5621,10 @@
check = xmlParseURI((const char *) schemaLocation);
if (check == NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
- "Import schemaLocation attribute is not an URI: %s\n",
- schemaLocation, NULL);
+ XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
+ "Element <import>: The value \"%s\" of the attribute \"schemaLocation\" is "
+ "not a valid URI.\n",
+ schemaLocation, NULL);
return (-1);
} else {
xmlFreeURI(check);
@@ -3690,7 +5646,7 @@
if (schema->schemasImports == NULL) {
xmlSchemaPErr2(ctxt, node, child,
XML_SCHEMAP_FAILED_BUILD_IMPORT,
- "Internal: failed to build import table\n",
+ "Internal error: failed to build import table.\n",
NULL, NULL);
return (-1);
}
@@ -3707,10 +5663,10 @@
if (previous != NULL) {
if (!xmlStrEqual(schemaLocation, previous)) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
- "Redefining import for default namespace "
- "with a different URI: %s\n",
- schemaLocation, NULL);
+ XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
+ "<import>: Redefining import for default namespace "
+ "with a different URI: \"%s\".\n",
+ schemaLocation, NULL);
}
} else {
import = xmlSchemaImportSchema(ctxt, schemaLocation);
@@ -3733,10 +5689,10 @@
if (previous != NULL) {
if (!xmlStrEqual(schemaLocation, previous)) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
- "Redefining import for namespace %s with "
- "a different URI: %s\n",
- namespace, schemaLocation);
+ XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
+ "<import>: Redefining import for namespace \"%s\" with "
+ "a different URI: \"%s\".\n",
+ namespace, schemaLocation);
}
} else {
import = xmlSchemaImportSchema(ctxt, schemaLocation);
@@ -3745,27 +5701,27 @@
}
if (!xmlStrEqual(import->schema->targetNamespace, namespace)) {
if (namespace == NULL) {
+
if (import->schema->targetNamespace != NULL) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_SRC_IMPORT_3_2,
- "There is no namespace attribute on the <import> "
- "element information item, so the imported document "
- "must have no targetNamespace attribute.\n",
- NULL, NULL);
+ "<import>: No \"namespace\" attribute was "
+ "specified, thus the imported schema document "
+ "must have no target namespace.\n",
+ NULL, NULL);
}
} else {
if (import->schema->targetNamespace != NULL) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_SRC_IMPORT_3_1,
- "The namespace attribute \"%s\" of an <import> "
- "element information item must be identical to the "
- "targetNamespace attribute \"%s\" of the "
- "imported document.\n",
+ "<import>: The value \"%s\" of the attribute "
+ "\"namespace\" is not identical to the "
+ "target namespace \"%s\" of the "
+ "imported schema document.\n",
namespace, import->schema->targetNamespace);
} else {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_SRC_IMPORT_3_1,
- "The namespace attribute on the <import> "
- "element information item, requires the imported "
- "document to have a targetNamespace attribute "
- "with the value \"%s\".\n",
+ "<import>: The attribute \"namespace\", requires "
+ "the imported schema document to have a target "
+ "namespace of \"%s\".\n",
namespace, NULL);
}
}
@@ -3789,7 +5745,7 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_IMPORT_CHILD,
- "Import has unexpected content\n", NULL, NULL);
+ "<import> has unexpected content.\n", NULL, NULL);
return (-1);
}
return (1);
@@ -3936,7 +5892,7 @@
} else {
xmlSchemaPErr2(ctxt, NULL, child,
XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD,
- "Schemas: unexpected element %s here \n",
+ "Unexpected element \"%s\" as child of <schema>.\n",
child->name, NULL);
child = child->next;
}
@@ -3969,11 +5925,12 @@
xmlNodePtr node)
{
xmlNodePtr child = NULL;
- const xmlChar *schemaLocation;
+ const xmlChar *schemaLocation, *targetNamespace;
xmlURIPtr check;
xmlDocPtr doc;
xmlNodePtr root;
xmlSchemaIncludePtr include;
+ int wasConvertingNs = 0;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
@@ -3990,9 +5947,10 @@
check = xmlParseURI((const char *) schemaLocation);
if (check == NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI,
- "Include schemaLocation attribute is not an URI: %s\n",
- schemaLocation, NULL);
+ XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI,
+ "<include>: The value \"%s\" of the attribute "
+ "\"schemaLocation\" is not a valid URI.\n",
+ schemaLocation, NULL);
return (-1);
} else {
xmlFreeURI(check);
@@ -4010,9 +5968,9 @@
}
} else {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI,
- "Include schemaLocation attribute missing\n",
- NULL, NULL);
+ XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI,
+ "<include>: The attribute \"schemaLocation\" is missing.\n",
+ NULL, NULL);
return (-1);
}
@@ -4025,7 +5983,7 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD,
- "Include has unexpected content\n", NULL, NULL);
+ "<include> has unexpected content.\n", NULL, NULL);
return (-1);
}
@@ -4037,7 +5995,7 @@
if (doc == NULL) {
xmlSchemaPErr(ctxt, NULL,
XML_SCHEMAP_FAILED_LOAD,
- "xmlSchemaParse: could not load %s\n",
+ "<include>: failed to load the document \"%s\".\n",
ctxt->URL, NULL);
return(-1);
}
@@ -4048,8 +6006,9 @@
root = xmlDocGetRootElement(doc);
if (root == NULL) {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
- XML_SCHEMAP_NOROOT,
- "schemas %s has no root", schemaLocation, NULL);
+ XML_SCHEMAP_NOROOT,
+ "<include>: The included document \"%s\" has no document "
+ "element.\n", schemaLocation, NULL);
xmlFreeDoc(doc);
return (-1);
}
@@ -4064,12 +6023,45 @@
*/
if (!IS_SCHEMA(root, "schema")) {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
- XML_SCHEMAP_NOT_SCHEMA,
- "File %s is not a schema", schemaLocation, NULL);
+ XML_SCHEMAP_NOT_SCHEMA,
+ "<include>: The document \"%s\" is not a schema document.\n",
+ schemaLocation, NULL);
xmlFreeDoc(doc);
return (-1);
}
-
+
+ targetNamespace = xmlSchemaGetProp(ctxt, node, "targetNamespace");
+ /*
+ * 2.1 SII has a targetNamespace [attribute], and its ·actual
+ * value· is identical to the ·actual value· of the targetNamespace
+ * [attribute] of SIIÂ’ (which must have such an [attribute]).
+ */
+ if (targetNamespace != NULL) {
+ if (schema->targetNamespace == NULL) {
+ xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
+ XML_SCHEMAP_SRC_INCLUDE,
+ "<include>: The target namespace of the included schema "
+ "\"%s\" has to be absent, since the including schema "
+ "has no target namespace.\n",
+ schemaLocation, NULL);
+ xmlFreeDoc(doc);
+ return (-1);
+ } else if (!xmlStrEqual(targetNamespace, schema->targetNamespace)) {
+ xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
+ XML_SCHEMAP_SRC_INCLUDE,
+ "<include>: The target namespace \"%s\" of the included "
+ "schema \"%s\" is different from \"%s\" of the including "
+ "schema.\n",
+ schemaLocation, NULL);
+ xmlFreeDoc(doc);
+ return (-1);
+ }
+ } else if (schema->targetNamespace != NULL) {
+ if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
+ schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
+ } else
+ wasConvertingNs = 1;
+ }
/*
* register the include
*/
@@ -4086,13 +6078,22 @@
include->next = schema->includes;
schema->includes = include;
-
/*
* parse the declarations in the included file like if they
* were in the original file.
- */
+ */
+ /*
+ * TODO FIXME URGENT: The validation of the <schema> element is not done here.
+ * Additionally the default values (e.g. "blockDefault", "elementFormDefault")
+ * are not set. We need to store the current values here, set them to the
+ * values of the included schema and recover the old ones afterwards.
+ */
xmlSchemaParseSchemaTopLevel(ctxt, schema, root->children);
-
+ /*
+ * Remove the converting flag.
+ */
+ if (wasConvertingNs == 0)
+ schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
return (1);
}
@@ -4167,8 +6168,8 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_CHOICE_CHILD,
- "Choice %s has unexpected content\n", type->name,
- NULL);
+ "<choice> has unexpected content.\n",
+ NULL, NULL);
}
return (type);
@@ -4246,8 +6247,8 @@
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
- "Sequence %s has unexpected content\n", type->name,
- NULL);
+ "<sequence> has unexpected content.\n",
+ NULL, NULL);
}
return (type);
@@ -4290,7 +6291,7 @@
(ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT)) {
xmlSchemaPErr2(ctxt, node, child,
XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
- "Restriction \"%s\" must have a \"base\" attribute.\n",
+ "<restriction>: The attribute \"base\" is missing.\n",
type->name, NULL);
}
ctxt->container = name;
@@ -4347,6 +6348,11 @@
/*
* Add the facets to the parent simpleType/complexType.
*/
+ /*
+ * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
+ * Simple Type Definition Schema Representation Constraint:
+ * *Single Facet Value*
+ */
while ((IS_SCHEMA(child, "minInclusive")) ||
(IS_SCHEMA(child, "minExclusive")) ||
(IS_SCHEMA(child, "maxInclusive")) ||
@@ -4400,7 +6406,7 @@
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
- "Restriction \"%s\" has unexpected content.\n",
+ "<restriction> has unexpected content.\n",
type->name, NULL);
}
ctxt->container = oldcontainer;
@@ -4444,7 +6450,8 @@
type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
if (type->base == NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_EXTENSION_NO_BASE,
- "Extension %s has no base\n", type->name, NULL);
+ "<extension>: The attribute \"base\" is missing.\n",
+ type->name, NULL);
}
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -4471,9 +6478,9 @@
child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD,
- "Extension %s has unexpected content\n", type->name,
- NULL);
+ XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD,
+ "<extension> has unexpected content.\n", type->name,
+ NULL);
}
ctxt->container = oldcontainer;
return (type);
@@ -4528,9 +6535,9 @@
type->subtypes = subtype;
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD,
- "SimpleContent %s has unexpected content\n",
- type->name, NULL);
+ XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD,
+ "<simpleContent> has unexpected content.\n",
+ NULL, NULL);
}
return (type);
}
@@ -4584,9 +6591,9 @@
type->subtypes = subtype;
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD,
- "ComplexContent %s has unexpected content\n",
- type->name, NULL);
+ XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD,
+ "<complexContent> has unexpected content.\n",
+ NULL, NULL);
}
return (type);
}
@@ -4631,7 +6638,7 @@
if (type == NULL) {
return (NULL);
}
- if (xmlGetBooleanProp(ctxt, node, "mixed", 0))
+ if (xmlGetBooleanProp(ctxt, NULL, type, node, "mixed", 0))
type->flags |= XML_SCHEMAS_TYPE_MIXED;
type->node = node;
@@ -4681,9 +6688,9 @@
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD,
- "ComplexType %s has unexpected content\n",
- type->name, NULL);
+ XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD,
+ "Complex type definition \"%s\" has unexpected content.\n",
+ type->name, NULL);
}
if (type->attributeWildcard != NULL)
type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
@@ -4707,9 +6714,9 @@
xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
xmlSchemaPtr schema = NULL;
- xmlNodePtr child = NULL;
const xmlChar *val;
int nberrors;
+ xmlAttrPtr attr;
if ((ctxt == NULL) || (node == NULL))
return (NULL);
@@ -4720,23 +6727,33 @@
schema = xmlSchemaNewSchema(ctxt);
if (schema == NULL)
return (NULL);
- val = xmlSchemaGetProp(ctxt, node, "targetNamespace");
- if (val != NULL) {
+ attr = xmlSchemaGetPropNode(node, "targetNamespace");
+ if (attr != NULL) {
+ xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), &val);
+ /*
+ * TODO: Should we proceed with an invalid target namespace?
+ */
schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
} else {
schema->targetNamespace = NULL;
}
+ /* TODO: Check id. */
schema->id = xmlSchemaGetProp(ctxt, node, "id");
- schema->version = xmlSchemaGetProp(ctxt, node, "version");
+ xmlSchemaPValAttr(ctxt, NULL, NULL, node, "version",
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &(schema->version));
+
val = xmlSchemaGetProp(ctxt, node, "elementFormDefault");
if (val != NULL) {
if (xmlStrEqual(val, BAD_CAST "qualified"))
schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
- "Invalid value %s for elementFormDefault\n",
- val, NULL);
+ xmlSchemaPErr(ctxt, node,
+ XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
+ "Element \"schema\": The value \"%s\" of the attribute "
+ "\"elementFormDefault\" is not valid. Expected is "
+ "(qualified | unqualified).\n",
+ val, NULL);
}
} else {
/* Removed, since the default value for elementFormDefault
@@ -4749,56 +6766,47 @@
if (xmlStrEqual(val, BAD_CAST "qualified"))
schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
- "Invalid value %s for attributeFormDefault\n",
- val, NULL);
+ xmlSchemaPErr(ctxt, node,
+ XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
+ "Element \"schema\": The value \"%s\" of the attribute "
+ "\"attributeFormDefault\" is not valid. Expected is "
+ "(qualified | unqualified).\n",
+ val, NULL);
}
}
-
+
val = xmlSchemaGetProp(ctxt, node, "finalDefault");
if (val != NULL) {
- if (xmlStrEqual(val, BAD_CAST "#all")) {
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_LIST;
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_UNION;
- } else {
- const xmlChar *end, *cur = val;
- xmlChar *item;
-
- do {
- while (IS_BLANK_CH(*cur))
- cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK_CH(*end))))
- end++;
- if (end == cur)
- break;
- item = xmlStrndup(cur, end - cur);
- if (xmlStrEqual(item, BAD_CAST "extension")) {
- if ((schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) == 0)
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
- } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
- if ((schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) == 0)
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
- } else if (xmlStrEqual(item, BAD_CAST "list")) {
- if ((schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) == 0)
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_LIST;
- } else if (xmlStrEqual(item, BAD_CAST "union")) {
- if ((schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) == 0)
- schema->flags |= XML_SCHEMAS_FINAL_DEFAULT_UNION;
- } else {
- xmlSchemaPErr(ctxt, node,
- XML_SCHEMAS_ERR_INTERNAL,
- "Invalid value for the attribute \"finalDefault\".\n",
- NULL, NULL);
- }
- if (item != NULL)
- xmlFree(item);
- cur = end;
- } while (*cur != 0);
- }
+ if (xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
+ XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
+ XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
+ -1,
+ XML_SCHEMAS_FINAL_DEFAULT_LIST,
+ XML_SCHEMAS_FINAL_DEFAULT_UNION) != 0) {
+ xmlSchemaPErr(ctxt, node,
+ XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
+ "Element \"schema\": The value \"%s\" of the attribute "
+ "\"finalDefault\" is not valid. Expected is "
+ "(#all | List of (extension | restriction | list | "
+ "union)).\n",
+ val, NULL);
+ }
+ }
+
+ val = xmlSchemaGetProp(ctxt, node, "blockDefault");
+ if (val != NULL) {
+ if (xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
+ XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
+ XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
+ XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1) != 0) {
+ xmlSchemaPErr(ctxt, node,
+ XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
+ "Element \"schema\": The value \"%s\" of the attribute "
+ "\"blockDefault\" is not valid. Expected is "
+ "(#all | List of (extension | restriction | "
+ "substitution)).\n",
+ val, NULL);
+ }
}
xmlSchemaParseSchemaTopLevel(ctxt, schema, node->children);
@@ -4810,11 +6818,11 @@
if ((doc != NULL) && (doc->URL != NULL)) {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
XML_SCHEMAP_NOT_SCHEMA,
- "File %s is not a schemas", doc->URL, NULL);
+ "The file \"%s\" is not a XML schema.\n", doc->URL, NULL);
} else {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
XML_SCHEMAP_NOT_SCHEMA,
- "File is not a schemas", NULL, NULL);
+ "The file is not a XML schema.\n", NULL, NULL);
}
return(NULL);
}
@@ -4864,7 +6872,7 @@
ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schama parser context",
+ xmlSchemaPErrMemory(NULL, "allocating schema parser context",
NULL);
return (NULL);
}
@@ -4895,7 +6903,7 @@
ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schama parser context",
+ xmlSchemaPErrMemory(NULL, "allocating schema parser context",
NULL);
return (NULL);
}
@@ -4981,17 +6989,113 @@
return;
}
switch (type->type) {
- case XML_SCHEMA_TYPE_ANY:
- /* TODO : handle the namespace too */
- /* TODO : make that a specific transition type */
- /* Daniel says: use xmlAutomataNewTransition2 */
- TODO ctxt->state =
- xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL,
- BAD_CAST "*", NULL);
- break;
- case XML_SCHEMA_TYPE_ELEMENT:{
- xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
+ case XML_SCHEMA_TYPE_ANY: {
+ xmlAutomataStatePtr start, end;
+ xmlSchemaWildcardPtr wild;
+ xmlSchemaWildcardNsPtr ns;
+ wild = type->attributeWildcard;
+
+ if (wild == NULL) {
+ xmlSchemaPErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaBuildAContentModel, "
+ "no wildcard on xsd:any.\n", NULL, NULL);
+ return;
+ }
+
+ start = ctxt->state;
+ end = xmlAutomataNewState(ctxt->am);
+
+ if (type->maxOccurs == 1) {
+ if (wild->any == 1) {
+ /*
+ * We need to add both transitions:
+ *
+ * 1. the {"*", "*"} for elements in a namespace.
+ */
+ ctxt->state =
+ xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ /*
+ * 2. the {"*"} for elements in no namespace.
+ */
+ ctxt->state =
+ xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", NULL, type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+
+ } else if (wild->nsSet != NULL) {
+ ns = wild->nsSet;
+ do {
+ ctxt->state = start;
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+ ctxt->state, NULL, BAD_CAST "*", ns->value, type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ ns = ns->next;
+ } while (ns != NULL);
+
+ } else if (wild->negNsSet != NULL) {
+ xmlAutomataStatePtr deadEnd;
+
+ deadEnd = xmlAutomataNewState(ctxt->am);
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+ start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type);
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ }
+ } else {
+ int counter;
+ xmlAutomataStatePtr hop;
+ int maxOccurs =
+ type->maxOccurs == UNBOUNDED ? UNBOUNDED : type->maxOccurs - 1;
+ int minOccurs =
+ type->minOccurs < 1 ? 0 : type->minOccurs - 1;
+
+ counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
+ hop = xmlAutomataNewState(ctxt->am);
+ if (wild->any == 1) {
+ ctxt->state =
+ xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ ctxt->state =
+ xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", NULL, type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ } else if (wild->nsSet != NULL) {
+ ns = wild->nsSet;
+ do {
+ ctxt->state =
+ xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", ns->value, type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ ns = ns->next;
+ } while (ns != NULL);
+
+ } else if (wild->negNsSet != NULL) {
+ xmlAutomataStatePtr deadEnd;
+
+ deadEnd = xmlAutomataNewState(ctxt->am);
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+ start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type);
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+ start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ }
+ xmlAutomataNewCountedTrans(ctxt->am, hop, start, counter);
+ xmlAutomataNewCounterTrans(ctxt->am, hop, end, counter);
+ }
+ if (type->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am, start, end);
+ }
+ ctxt->state = end;
+ break;
+ }
+ case XML_SCHEMA_TYPE_ELEMENT:{
+ xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
+
/* TODO : handle the namespace too */
xmlAutomataStatePtr oldstate = ctxt->state;
@@ -5017,9 +7121,11 @@
name);
} else {
ctxt->state =
- xmlAutomataNewTransition(ctxt->am,
+ xmlAutomataNewTransition2(ctxt->am,
ctxt->state, NULL,
- elem->name, type);
+ elem->name,
+ elem->targetNamespace,
+ type);
}
tmp = ctxt->state;
xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
@@ -5037,9 +7143,11 @@
name);
} else {
ctxt->state =
- xmlAutomataNewTransition(ctxt->am,
+ xmlAutomataNewTransition2(ctxt->am,
ctxt->state, NULL,
- elem->name, type);
+ elem->name,
+ elem->targetNamespace,
+ type);
}
xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
oldstate);
@@ -5066,10 +7174,11 @@
elem->refDecl, ctxt,
elem->refDecl->name);
} else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
ctxt->state,
NULL,
elem->name,
+ elem->targetNamespace,
type);
}
tmp = ctxt->state;
@@ -5090,10 +7199,11 @@
elem->refDecl, ctxt,
elem->refDecl->name);
} else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am,
ctxt->state,
NULL,
elem->name,
+ elem->targetNamespace,
type);
}
if (elem->minOccurs == 0) {
@@ -5267,10 +7377,7 @@
case XML_SCHEMA_TYPE_ALL:{
xmlAutomataStatePtr start;
xmlSchemaTypePtr subtypes;
- /*
- * Changed, since type in not an xmlSchemaElement here.
- */
- /* xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type; */
+
xmlSchemaElementPtr elem;
int lax;
@@ -5317,10 +7424,11 @@
xmlSchemaTypePtr subtypes;
if (type->recurse) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- "Schemas: extension type %s is recursive\n",
- type->name, NULL);
+ /* TODO: Change the error code. */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_UNKNOWN_BASE_TYPE,
+ NULL, type, type->node,
+ "This item is circular", NULL);
return;
}
type->recurse = 1;
@@ -5341,10 +7449,11 @@
rgroup = xmlSchemaGetGroup(ctxt->schema, type->ref,
type->refNs);
if (rgroup == NULL) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_UNKNOWN_REF,
- "Schemas: group %s reference %s is not found",
- name, type->ref);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, NULL,
+ "ref", type->ref, type->refNs,
+ XML_SCHEMA_TYPE_GROUP, NULL);
return;
}
xmlSchemaBuildAContentModel(rgroup, ctxt, name);
@@ -5407,12 +7516,13 @@
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
elem->contModel = xmlAutomataCompile(ctxt->am);
if (elem->contModel == NULL) {
- xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_INTERNAL,
- "failed to compile %s content model\n", name, NULL);
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAS_ERR_INTERNAL,
+ NULL, (xmlSchemaTypePtr) elem, NULL,
+ "Failed to compile the content model", NULL);
} else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
- xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_NOTDETERMINIST,
- "Content model of %s is not determinist:\n", name,
- NULL);
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAS_ERR_NOTDETERMINIST,
+ NULL, (xmlSchemaTypePtr) elem, NULL,
+ "The content model is not determinist", NULL);
} else {
#ifdef DEBUG_CONTENT_REGEXP
xmlGenericError(xmlGenericErrorContext,
@@ -5430,62 +7540,86 @@
* @elem: the schema element context
* @ctxt: the schema parser context
*
- * Free the resources associated to the schema parser context
+ * Resolves the references of an element declaration
+ * or particle, which has an element declaration as it's
+ * term.
*/
static void
xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
xmlSchemaParserCtxtPtr ctxt,
- const xmlChar * name,
+ const xmlChar * name ATTRIBUTE_UNUSED,
const xmlChar * context ATTRIBUTE_UNUSED,
const xmlChar * namespace ATTRIBUTE_UNUSED)
{
- if ((ctxt == NULL) || (elem == NULL))
+ if ((ctxt == NULL) || (elem == NULL) ||
+ ((elem != NULL) && (elem->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
return;
-
+ elem->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
if (elem->ref != NULL) {
xmlSchemaElementPtr elemDecl;
- if (elem->subtypes != NULL) {
- xmlSchemaPErr(ctxt, elem->node,
- XML_SCHEMAP_INVALID_REF_AND_SUBTYPE,
- "Schemas: element %s has both ref and subtype\n",
- name, NULL);
- return;
- }
+ /*
+ * TODO: Evaluate, what errors could occur if the declaration is not
+ * found. It might be possible that the "typefixup" might crash if
+ * no ref declaration was found.
+ */
elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs, 0);
-
- if (elemDecl == NULL) {
- xmlSchemaPErr(ctxt, elem->node,
+ if (elemDecl == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- "Element \"%s\": the QName \"%s\" of the attribute "
- "\"ref\" does not resolve to a schema "
- "component.\n",
- name, elem->ref);
- return;
- }
- elem->refDecl = elemDecl;
- } else if (elem->namedType != NULL) {
- xmlSchemaTypePtr typeDecl;
-
- if (elem->subtypes != NULL) {
- xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_TYPE_AND_SUBTYPE,
- "Schemas: element %s has both type and subtype\n",
- name, NULL);
- return;
- }
- typeDecl = xmlSchemaGetType(ctxt->schema, elem->namedType,
- elem->namedTypeNs);
-
- if (typeDecl == NULL) {
- xmlSchemaPErr(ctxt, elem->node,
- XML_SCHEMAP_SRC_RESOLVE,
- "Element \"%s\": the QName \"%s\" of the attribute "
- "\"type\" does not resolve to a schema "
- "component.\n", name, elem->namedType);
- return;
- }
- elem->subtypes = typeDecl;
- }
+ NULL, (xmlSchemaTypePtr) elem, elem->node,
+ "ref", elem->ref, elem->refNs,
+ XML_SCHEMA_TYPE_ELEMENT, NULL);
+ } else
+ elem->refDecl = elemDecl;
+ } else {
+ if ((elem->subtypes == NULL) && (elem->namedType != NULL)) {
+ xmlSchemaTypePtr type;
+
+ /* (type definition) ... otherwise the type definition ·resolved·
+ * to by the ·actual value· of the type [attribute] ...
+ */
+ type = xmlSchemaGetType(ctxt->schema, elem->namedType,
+ elem->namedTypeNs);
+ if (type == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, (xmlSchemaTypePtr) elem, elem->node,
+ "type", elem->namedType, elem->namedTypeNs,
+ XML_SCHEMA_TYPE_BASIC, "type definition");
+ } else
+ elem->subtypes = type;
+ }
+ if (elem->substGroup != NULL) {
+ xmlSchemaElementPtr substHead;
+
+ /*
+ * FIXME TODO: Do we need a new field in _xmlSchemaElement for
+ * substitutionGroup?
+ */
+ substHead = xmlSchemaGetElem(ctxt->schema, elem->substGroup,
+ elem->substGroupNs, 0);
+ if (substHead == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, (xmlSchemaTypePtr) elem, NULL,
+ "substitutionGroup", elem->substGroup, elem->substGroupNs,
+ XML_SCHEMA_TYPE_ELEMENT, NULL);
+ } else {
+ xmlSchemaRefFixupCallback(substHead, ctxt, NULL, NULL, NULL);
+ /*
+ * (type definition)...otherwise the {type definition} of the
+ * element declaration ·resolved· to by the ·actual value· of
+ * the substitutionGroup [attribute], if present
+ */
+ if (elem->subtypes == NULL)
+ elem->subtypes = substHead->subtypes;
+ }
+ }
+ if ((elem->subtypes == NULL) && (elem->namedType == NULL) &&
+ (elem->substGroup == NULL))
+ elem->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ }
}
/**
@@ -5498,32 +7632,32 @@
static void
xmlSchemaParseListRefFixup(xmlSchemaTypePtr type, xmlSchemaParserCtxtPtr ctxt)
{
- /*
- * src-list-itemType-or-simpleType
- * Either the itemType [attribute] or the <simpleType> [child] of
- * the <list> element must be present, but not both.
- */
+
if (((type->base == NULL) &&
(type->subtypes == NULL)) ||
((type->base != NULL) &&
(type->subtypes != NULL))) {
- /*
- * src-restriction-base-or-simpleType
- * Either the base [attribute] or the simpleType [child] of the
- * <restriction> element must be present, but not both.
+ /*
+ * src-list-itemType-or-simpleType
+ * Either the itemType [attribute] or the <simpleType> [child] of
+ * the <list> element must be present, but not both.
*/
- xmlSchemaPErr(ctxt, type->node,
+ /*
+ * TODO: Move this to the parse function.
+ */
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE,
- "List \"%s\": "
- "Either the \"base\" attribute or the <simpleType> child "
- "must be present, but not both.\n",
- type->name, NULL);
+ NULL, type, type->node,
+ "The attribute 'itemType' and the <simpleType> child "
+ "are mutually exclusive", NULL);
} else if (type->base!= NULL) {
type->subtypes = xmlSchemaGetType(ctxt->schema, type->base, type->baseNs);
if (type->subtypes == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_UNKNOWN_TYPE,
- "List \"%s\" references an unknown item type: \"%s\"\n",
- type->name, type->base);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, type->node,
+ "itemType", type->base, type->baseNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
}
}
if ((type->subtypes != NULL) &&
@@ -5543,12 +7677,9 @@
xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type,
xmlSchemaParserCtxtPtr ctxt)
{
- const xmlChar *cur, *end, *prefix, *ncName, *namespace;
- xmlChar *tmp;
+
xmlSchemaTypeLinkPtr link, lastLink = NULL, prevLink, subLink, newLink;
xmlSchemaTypePtr memberType, ctxtType;
- xmlNsPtr ns;
- int len;
/* 1 If the <union> alternative is chosen, then [Definition:]
* define the explicit members as the type definitions ·resolved·
@@ -5573,21 +7704,21 @@
*/
if ((type->base == NULL) &&
(type->subtypes == NULL)) {
- /*
- * src-restriction-base-or-simpleType
- * Either the base [attribute] or the simpleType [child] of the
- * <restriction> element must be present, but not both.
- */
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
- "Union \"%s\": "
- "Either the \"memberTypes\" attribute must be non-empty "
- "or there must be at least one <simpleType> child.\n",
- type->name, NULL);
+ NULL, NULL, type->node,
+ "Either the attribute 'memberTypes' must be non-empty "
+ "or there must be at least one <simpleType> child", NULL);
}
ctxtType = ctxt->ctxtType;
if (type->base != NULL) {
+ xmlAttrPtr attr;
+ const xmlChar *cur, *end;
+ xmlChar *tmp;
+ const xmlChar *localName, *uri;
+
+ attr = xmlSchemaGetPropNode(type->node, "memberTypes");
cur = type->base;
do {
while (IS_BLANK_CH(*cur))
@@ -5598,30 +7729,14 @@
if (end == cur)
break;
tmp = xmlStrndup(cur, end - cur);
- ncName = xmlSplitQName3(tmp, &len);
- if (ncName != NULL) {
- prefix = xmlDictLookup(ctxt->dict, tmp, len);
- } else {
- prefix = NULL;
- ncName = tmp;
- }
- ns = xmlSearchNs(type->node->doc, type->node, prefix);
- if (ns == NULL) {
- if (prefix != NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_PREFIX_UNDEFINED,
- "Union \"%s\": the namespace prefix of member type "
- "\"%s\" is undefined\n",
- type->name, (const xmlChar *) tmp);
- }
- namespace = NULL;
- } else {
- namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
- }
- memberType = xmlSchemaGetType(ctxt->schema, ncName, namespace);
+ xmlSchemaPValAttrNodeQNameValue(ctxt, ctxt->schema, NULL,
+ NULL, attr, BAD_CAST tmp, &uri, NULL, &localName);
+ memberType = xmlSchemaGetType(ctxt->schema, localName, uri);
if (memberType == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
- "Union \"%s\" references an unknown member type \"%s\".\n",
- type->name, (const xmlChar *) tmp);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
+ NULL, NULL, type->node, "memberTypes", localName, uri,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
} else {
if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
xmlSchemaTypeFixup(memberType, ctxt, NULL);
@@ -5703,48 +7818,6 @@
}
/**
- * xmlSchemaGetOnymousTypeName:
- * @attr: the attribute declaration/use
- *
- * Returns the name of the attribute; if the attribute
- * is a reference, the name of the referenced global type will be returned.
- */
-static const xmlChar *
-xmlSchemaGetOnymousAttrName(xmlSchemaAttributePtr attr)
-{
- if (attr->ref != NULL)
- return(attr->ref);
- else
- return(attr->name);
-}
-
-/**
- * xmlSchemaGetOnymousTargetNsURI:
- * @type: the type (element or attribute)
- *
- * Returns the target namespace URI of the type; if the type is a reference,
- * the target namespace of the referenced type will be returned.
- */
-static const xmlChar *
-xmlSchemaGetOnymousTargetNsURI(xmlSchemaTypePtr type)
-{
- if (type->type == XML_SCHEMA_TYPE_ELEMENT) {
- if (type->ref != NULL)
- return(((xmlSchemaElementPtr)((xmlSchemaElementPtr)
- type)->subtypes)->targetNamespace);
- else
- return(((xmlSchemaElementPtr) type)->targetNamespace);
- } else if (type->type == XML_SCHEMA_TYPE_ATTRIBUTE) {
- if (type->ref != NULL)
- return(((xmlSchemaAttributePtr)((xmlSchemaAttributePtr)
- type)->subtypes)->targetNamespace);
- else
- return(((xmlSchemaAttributePtr) type)->targetNamespace);
- } else
- return (NULL);
-}
-
-/**
* xmlSchemaIsDerivedFromBuiltInType:
* @ctxt: the schema parser context
* @type: the type definition
@@ -6087,7 +8160,7 @@
*/
xmlSchemaPErr(ctxt, completeWild->node,
XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
- "The union of the wilcard is not expressible\n",
+ "The union of the wilcard is not expressible.\n",
NULL, NULL);
return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
} else if ((!nsFound) && (!absentFound)) {
@@ -6324,7 +8397,7 @@
(curWild->negNsSet->value != NULL)) {
xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
- "The intersection of the wilcard is not expressible\n",
+ "The intersection of the wilcard is not expressible.\n",
NULL, NULL);
return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
}
@@ -6351,10 +8424,8 @@
* subset of @wildB, 0 otherwise.
*/
static int
-xmlSchemaIsWildcardNsConstraintSubset(
- xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
- xmlSchemaWildcardPtr wildA,
- xmlSchemaWildcardPtr wildB)
+xmlSchemaIsWildcardNsConstraintSubset(xmlSchemaWildcardPtr wildA,
+ xmlSchemaWildcardPtr wildB)
{
/*
@@ -6525,6 +8596,7 @@
xmlSchemaAttributePtr attrs;
xmlSchemaTypePtr anyType;
int baseIsAnyType = 0;
+ xmlChar *str = NULL;
anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
/*
@@ -6542,20 +8614,11 @@
if (type->baseType == NULL) {
xmlSchemaPErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaBuildAttributeValidation: "
- "complex type \"%s\" has no base type.\n",
+ "complex type '%s' has no base type.\n",
type->name, NULL);
return (-1);
}
-
baseType = type->baseType;
- if (baseType == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaBuildAttributeValidation: "
- "type has no base type.\n",
- NULL, NULL);
- return (-1);
- }
-
if (baseType == anyType)
baseIsAnyType = 1;
/*
@@ -6644,19 +8707,25 @@
* Derivation Valid (Restriction, Complex)
* 4.1 The {base type definition} must also have one.
*/
- if (baseType->attributeWildcard == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
- "The derived type \"%s\" has an attribute wildcard, "
- "but the base type \"%s\" does not have one.\n",
- type->name, baseType->name);
+ if (baseType->attributeWildcard == NULL) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
+ NULL, type, NULL,
+ "The type has an attribute wildcard, "
+ "but the base type %s does not have one",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (1);
- } else if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
+ } else if (xmlSchemaIsWildcardNsConstraintSubset(
type->attributeWildcard, baseType->attributeWildcard) == 0) {
/* 4.2 */
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
- "The wildcard in the derived type \"%s\" is not a valid "
- "subset of the one in the base type \"%s\".\n",
- type->name, baseType->name);
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
+ NULL, type, NULL,
+ "The attribute wildcard is not a valid "
+ "subset of the wildcard in the base type %s",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (1);
}
/* 4.3 Unless the {base type definition} is the ·ur-type
@@ -6669,11 +8738,13 @@
if ((type->baseType != anyType) &&
(type->attributeWildcard->processContents <
baseType->attributeWildcard->processContents)) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
- "The process contents of the wildcard in the "
- "derived type \"%s\" is weaker than "
- "that in the base type \"%s\".\n",
- type->name, baseType->name);
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
+ NULL, type, NULL,
+ "The 'process contents' of the attribute wildcard is weaker than "
+ "the one in the base type %s",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (1);
}
}
@@ -6686,12 +8757,15 @@
if ((baseType->attributeWildcard != NULL) &&
(baseType->attributeWildcard != type->attributeWildcard)) {
/* 1.3 */
- if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
+ if (xmlSchemaIsWildcardNsConstraintSubset(
baseType->attributeWildcard, type->attributeWildcard) == 0) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_COS_CT_EXTENDS_1_3,
- "The wildcard in the derived type \"%s\" is not a valid "
- "superset of the one in the base type \"%s\".\n",
- type->name, baseType->name);
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_3,
+ NULL, type, NULL,
+ "The attribute wildcard is not a valid "
+ "superset of the one in the base type %s",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (1);
}
}
@@ -6717,14 +8791,20 @@
while (cur != NULL) {
tmp = cur->next;
while (tmp != NULL) {
- if ((xmlStrEqual(xmlSchemaGetOnymousAttrName(cur->attr),
- xmlSchemaGetOnymousAttrName(tmp->attr))) &&
- (xmlStrEqual(xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) cur->attr ),
- xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) tmp->attr)))) {
-
- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_4,
- "ct-props-correct.4: Duplicate attribute use with the name \"%s\" specified\n",
- xmlSchemaGetOnymousAttrName(cur->attr), NULL);
+ if ((xmlStrEqual(xmlSchemaGetAttrName(cur->attr),
+ xmlSchemaGetAttrName(tmp->attr))) &&
+ (xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr ),
+ xmlSchemaGetAttrTargetNsURI(tmp->attr)))) {
+
+ xmlSchemaPAttrUseErr(ctxt,
+ XML_SCHEMAP_CT_PROPS_CORRECT_4,
+ NULL, type, NULL, cur->attr,
+ "Duplicate attribute use %s specified",
+ xmlSchemaFormatNsUriLocal(&str,
+ xmlSchemaGetAttrTargetNsURI(tmp->attr),
+ xmlSchemaGetAttrName(tmp->attr))
+ );
+ FREE_AND_NULL(str)
break;
}
tmp = tmp->next;
@@ -6746,35 +8826,36 @@
found = 0;
base = type->attributeUses;
while (base != NULL) {
- if ((xmlStrEqual(xmlSchemaGetOnymousAttrName(cur->attr),
- xmlSchemaGetOnymousAttrName(base->attr))) &&
- (xmlStrEqual(xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) cur->attr),
- xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) base->attr)))) {
+ if (xmlStrEqual(xmlSchemaGetAttrName(cur->attr),
+ xmlSchemaGetAttrName(base->attr)) &&
+ xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr),
+ xmlSchemaGetAttrTargetNsURI(base->attr))) {
- found = 1;
+ found = 1;
if ((cur->attr->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
(base->attr->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) {
/*
* derivation-ok-restriction 2.1.1
- */
- xmlSchemaPErr(ctxt, cur->attr->node,
+ */
+ xmlSchemaPAttrUseErr(ctxt,
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
- "derivation-ok-restriction.2.1.1: "
- "The \"optional\" attribute "
- "use \"%s\" is inconsistent with a matching "
- "\"required\" attribute use of the base type\n",
- xmlSchemaGetOnymousAttrName(cur->attr), NULL);
+ NULL, type, NULL, cur->attr,
+ "The 'optional' use is inconsistent with a matching "
+ "'required' use of the base type", NULL);
} else if ((cur->attr->occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) &&
(base->attr->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) {
/*
* derivation-ok-restriction 3
*/
- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
- "derivation-ok-restriction.3: "
- "The \"required\" attribute use \"%s\" of the base type "
- "does not have a matching attribute use in the derived type\n",
- xmlSchemaGetOnymousAttrName(cur->attr), NULL);
-
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
+ NULL, type, NULL,
+ "A matching attribute use for the 'required' "
+ "attribute use %s of the base type is missing",
+ xmlSchemaFormatNsUriLocal(&str,
+ xmlSchemaGetAttrTargetNsURI(base->attr),
+ xmlSchemaGetAttrName(base->attr)));
+ FREE_AND_NULL(str)
} else {
/*
* Override the attribute use.
@@ -6801,11 +8882,12 @@
found = 1;
if (!found) {
- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
- "derivation-ok-restriction.2.2: "
- "The attribute use \"%s\" has neither a matching attribute use, "
- "nor a matching wildcard in the base type\n",
- xmlSchemaGetOnymousAttrName(cur->attr), NULL);
+ xmlSchemaPAttrUseErr(ctxt,
+ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
+ NULL, type, NULL, cur->attr,
+ "Neither a matching attribute use, "
+ "nor a matching wildcard in the base type does exist",
+ NULL);
} else {
/*
* Add the attribute use.
@@ -6871,14 +8953,15 @@
if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) {
tmp = cur->next;
while (tmp != NULL) {
- if ((xmlStrEqual(xmlSchemaGetOnymousAttrName(cur->attr),
- xmlSchemaGetOnymousAttrName(tmp->attr))) &&
- (xmlStrEqual(xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) cur->attr ),
- xmlSchemaGetOnymousTargetNsURI((xmlSchemaTypePtr) tmp->attr)))) {
+ if ((xmlStrEqual(xmlSchemaGetAttrName(cur->attr),
+ xmlSchemaGetAttrName(tmp->attr))) &&
+ (xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr ),
+ xmlSchemaGetAttrTargetNsURI(tmp->attr)))) {
- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_4,
- "ct-props-correct.4: Duplicate attribute use with the name \"%s\" specified\n",
- xmlSchemaGetOnymousAttrName(cur->attr), NULL);
+ xmlSchemaPAttrUseErr(ctxt,
+ XML_SCHEMAP_CT_PROPS_CORRECT_4,
+ NULL, type, NULL, tmp->attr,
+ "Duplicate attribute use specified", NULL);
break;
}
tmp = tmp->next;
@@ -6891,11 +8974,13 @@
if ((cur->attr->subtypes != NULL) &&
(xmlSchemaIsDerivedFromBuiltInType(ctxt, (xmlSchemaTypePtr) cur->attr, XML_SCHEMAS_ID))) {
if (id != NULL) {
- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_5,
- "ct-props-correct.5: Two attribute declarations, "
- "\"%s\" and \"%s\" have types which derived from ID\n",
- xmlSchemaGetOnymousAttrName(id->attr),
- xmlSchemaGetOnymousAttrName(cur->attr));
+ xmlSchemaPAttrUseErr(ctxt,
+ XML_SCHEMAP_CT_PROPS_CORRECT_5,
+ NULL, type, NULL, cur->attr,
+ "There must not exist more than one attribute use, "
+ "declared of type 'ID' or derived from it",
+ NULL);
+ FREE_AND_NULL(str)
}
id = cur;
}
@@ -6927,7 +9012,7 @@
(baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) {
xmlSchemaPErr(ctxt, baseType->node, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaBuildAttributeValidation: "
- "attribute uses not builded on base type \"%s\".\n",
+ "attribute uses not builded on base type '%s'.\n",
baseType->name, NULL);
}
return (0);
@@ -7129,7 +9214,9 @@
{
xmlSchemaTypePtr baseType = type->baseType, anySimpleType,
anyType;
+ xmlChar *str = NULL;
+ /* STATE: error funcs converted. */
/*
* Schema Component Constraint: Simple Type Definition Properties Correct
*
@@ -7148,29 +9235,32 @@
* otherwise the Simple Type Definition for anySimpleType (§4.1.6).
*/
if (baseType == NULL) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
- "Simple type \"%s\" does not have a base type.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "No base type existent", NULL);
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
if ((baseType->type != XML_SCHEMA_TYPE_SIMPLE) &&
((baseType->type != XML_SCHEMA_TYPE_BASIC) ||
(baseType == anyType))) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
- "Simple type \"%s\": its base type \"%s\" is not a simple "
- "type.\n",
- type->name, baseType->name);
+ NULL, type, NULL,
+ "The base type %s is not a simple type",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
if ((baseType != anySimpleType) &&
(type->subtypes->type != XML_SCHEMA_TYPE_RESTRICTION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
- "Simple type \"%s\" (not derived by restriction) must have"
- "the simple ur-type definition as base type, not \"%s\".\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "A type, derived by list or union, must have"
+ "the simple ur-type definition as base type, not %s",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
/*
@@ -7179,13 +9269,13 @@
if (((type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
((type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0) &&
((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
- "Simple type \"%s\" has an absent variety.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "The variety is absent", NULL);
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
- /* TODO: Finish this. */
+ /* TODO: Finish this. Hmm, is this finished? */
/*
* 2 All simple type definitions must be derived ultimately from the ·simple
@@ -7200,11 +9290,10 @@
if (baseType == anySimpleType)
break;
else if (baseType == type) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_ST_PROPS_CORRECT_2,
- "Simple type \"%s\" is not derived from the simple "
- "ur-type definition (circular definitions are disallowed).\n",
- type->name, NULL);
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_ST_PROPS_CORRECT_2,
+ NULL, type, NULL,
+ "The definition is circular", NULL);
return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
}
baseType = baseType->baseType;
@@ -7214,11 +9303,13 @@
*/
if (xmlSchemaTypeFinalContains(ctxt->schema, baseType,
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_3,
- "Simple type \"%s\": the \"final\" of its base type "
- "\"%s\" must not contain \"restriction\".\n",
- type->name, baseType->name);
+ NULL, type, NULL,
+ "The 'final' of its base type %s must not contain "
+ "'restriction'",
+ xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
}
return (0);
@@ -7237,14 +9328,17 @@
*/
static int
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaTypePtr type)
+ xmlSchemaTypePtr type)
{
+ xmlChar *str = NULL;
+
+ /* STATE: error funcs converted. */
if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
- "xmlSchemaCheckDerivationValidSimpleRestriction: the given "
- "type \"%s\" is not a user-derived simpleType.\n",
+ "xmlSchemaCheckDerivationValidSimpleRestriction: The given "
+ "type '%s' is not a user-derived simpleType.\n",
type->name, NULL);
return (-1);
}
@@ -7256,24 +9350,26 @@
* type definition or a built-in primitive datatype.
*/
if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
- "Atomic simple type \"%s\": "
- "its base type \"%s\" is not an atomic simple type.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "The base type %s is not an atomic simple type",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
}
/* 1.2 The {final} of the {base type definition} must not contain
* restriction.
*/
- /* OPTIMIZE: This is already done in xmlSchemaCheckStPropsCorrect */
+ /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
- "Atomic simple type \"%s\": the \"final\" of its base type "
- "\"%s\" must not contain \"restriction\".\n",
- type->name, type->baseType->name);
+ NULL, type, NULL,
+ "The final of its base type %s must not contain 'restriction'",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
}
@@ -7291,30 +9387,22 @@
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
"xmlSchemaCheckDerivationValidSimpleRestriction: failed "
- "to get primitive type of type \"%s\".\n",
+ "to get primitive type of type '%s'.\n",
type->name, NULL);
return (-1);
}
facet = type->facets;
do {
if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
- xmlSchemaPErrExt(ctxt, type->node,
+ ok = 0;
+ xmlSchemaPIllegalFacetAtomicErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
- NULL, NULL, NULL,
- "Atomic simple type \"%s\": the facet \"%s\" "
- "is not allowed on primitive type \"%s\".\n",
- type->name,
- (const xmlChar *)
- xmlSchemaFacetTypeToString(facet->type),
- BAD_CAST primitive->name, NULL, NULL);
-
- ok = 0;
+ NULL, type, primitive, facet);
}
facet = facet->next;
} while (facet != NULL);
if (ok == 0)
- return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
-
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
}
/*
* TODO: 1.3.2 (facet derivation)
@@ -7327,7 +9415,7 @@
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
"Internal error: xmlSchemaCheckDerivationValidSimpleRestriction: "
- "failed to evaluate the item type of type \"%s\".\n",
+ "failed to evaluate the item type of type '%s'.\n",
type->name, NULL);
return (-1);
}
@@ -7338,11 +9426,12 @@
*/
if (((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
- "List simple type \"%s\": its item type \"%s\" "
- "is not an atomic or union simple type.\n",
- type->name, itemType->name);
+ NULL, type, NULL,
+ "The item type %s must have a variety of atomic or union",
+ xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
} else if (itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
xmlSchemaTypeLinkPtr member;
@@ -7351,13 +9440,13 @@
while (member != NULL) {
if ((member->type->flags &
XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
- "List simple type \"%s\": its item type "
- "is a union simple type, but the member type "
- "\"%s\" of this item type is not an \"atomic\" "
- "simple type.\n",
- type->name, member->type->name);
+ NULL, type, NULL,
+ "The item type is a union type, but the "
+ "member type %s of this item type is not atomic",
+ xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
}
member = member->next;
@@ -7376,11 +9465,12 @@
*/
if (xmlSchemaTypeFinalContains(ctxt->schema,
itemType, XML_SCHEMAS_TYPE_FINAL_LIST)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
- "List simple type \"%s\": the \"final\" of its item type "
- "\"%s\" must not contain \"list\".\n",
- type->name, itemType->name);
+ NULL, type, NULL,
+ "The final of its item type %s must not contain 'list'",
+ xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
}
/*
@@ -7390,13 +9480,10 @@
if (type->facets != NULL) {
facet = type->facets;
do {
- if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
- xmlSchemaPErr(ctxt, type->node,
+ if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
+ xmlSchemaPIllegalFacetListUnionErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
- "List simple type \"%s\": the facet \"%s\" "
- "is not allowed.\n",
- type->name,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type));
+ NULL, type, facet);
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
}
facet = facet->next;
@@ -7418,11 +9505,12 @@
* 2.3.2.1 The {base type definition} must have a {variety} of list.
*/
if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
- "List simple type \"%s\": its base type \"%s\" must "
- "have a variety of list.\n",
- type->name, type->baseType->name);
+ NULL, type, NULL,
+ "The base type %s must be a list type",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
}
/*
@@ -7431,11 +9519,12 @@
*/
if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
- "List simple type \"%s\": its base type \"%s\" must not "
- "have a \"final\" containing \"restriction\".\n",
- type->name, type->baseType->name);
+ NULL, type, NULL,
+ "The final of the base type %s must not contain 'restriction'",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
}
/*
@@ -7451,22 +9540,27 @@
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
"xmlSchemaCheckDerivationValidSimpleRestriction: "
- "List simple type \"%s\": failed to "
- "evaluate the item type of its base type \"%s\".\n",
+ "List simple type '%s': Failed to "
+ "evaluate the item type of its base type '%s'.\n",
type->name, type->baseType->name);
return (-1);
}
if ((itemType != baseItemType) &&
(xmlSchemaCheckCOSSTDerivedOK(ctxt->schema, itemType,
baseItemType, 0) != 0)) {
- xmlSchemaPErrExt(ctxt, type->node,
- XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, NULL, NULL, NULL,
- "List simple type \"%s\": its item type \"%s\" is not "
- "validly derived from the item type \"%s\" of the "
- "base type \"%s\" as defined in Type Derivation OK "
- "(Simple).\n",
- type->name, itemType->name, baseItemType->name,
- type->baseType->name, NULL);
+ xmlChar *strBIT = NULL, *strBT = NULL;
+ xmlSchemaPCustomErrExt(ctxt,
+ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
+ NULL, type, NULL,
+ "The item type %s is not validly derived from the "
+ "item type %s of the base type %s",
+ xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1),
+ xmlSchemaFormatItemForReport(&strBIT, NULL, baseItemType, NULL, 1),
+ xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1));
+
+ FREE_AND_NULL(str)
+ FREE_AND_NULL(strBIT)
+ FREE_AND_NULL(strBT)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
}
}
@@ -7493,12 +9587,9 @@
case XML_SCHEMA_FACET_ENUMERATION:
break;
default: {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPIllegalFacetListUnionErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
- "List simple type \"%s\": the facet \"%s\" "
- "is not allowed.\n",
- type->name,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type));
+ NULL, type, facet);
/*
* We could return, but it's nicer to report all
* invalid facets.
@@ -7533,11 +9624,12 @@
XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
((member->type->flags &
XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
- "Union simple type \"%s\": the member type "
- "\"%s\" is not an \"atomic\" simple type.\n",
- type->name, member->type->name);
+ NULL, type, NULL,
+ "The member type %s is neither an atomic, nor a list type",
+ xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
}
member = member->next;
@@ -7555,11 +9647,12 @@
while (member != NULL) {
if (xmlSchemaTypeFinalContains(ctxt->schema, member->type,
XML_SCHEMAS_TYPE_FINAL_UNION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
- "Union simple type \"%s\": the \"final\" of member type "
- "\"%s\" contains \"union\".\n",
- type->name, member->type->name);
+ NULL, type, NULL,
+ "The final of member type %s contains 'union'",
+ xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
}
member = member->next;
@@ -7568,10 +9661,10 @@
* 3.3.1.2 The {facets} must be empty.
*/
if (type->facetSet != NULL) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
- "Union simple type \"%s\": the facets must be empty.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "No facets allowed", NULL);
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
}
} else {
@@ -7579,11 +9672,12 @@
* 3.3.2.1 The {base type definition} must have a {variety} of union.
*/
if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
- "Union simple type \"%s\": its base type \"%s\" has not a "
- "variety of union.\n",
- type->name, type->baseType->name);
+ NULL, type, NULL,
+ "The base type %s is not a union type",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
}
/*
@@ -7591,11 +9685,12 @@
*/
if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
- "Union simple type \"%s\": the \"final\" of its base "
- "type \"%s\" must not contain \"restriction\".\n",
- type->name, type->baseType->name);
+ NULL, type, NULL,
+ "The final of its base type %s must not contain 'restriction'",
+ xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
}
/*
@@ -7626,7 +9721,7 @@
XML_SCHEMAS_ERR_INTERNAL,
"Internal error: "
"xmlSchemaCheckDerivationValidSimpleRestriction "
- "(3.3.2.3), union simple type \"%s\", unequal number "
+ "(3.3.2.3), union simple type '%s', unequal number "
"of member types in the base type\n",
type->name, NULL);
}
@@ -7636,24 +9731,26 @@
XML_SCHEMAS_ERR_INTERNAL,
"Internal error: "
"xmlSchemaCheckDerivationValidSimpleRestriction "
- "(3.3.2.3), union simple type \"%s\", unequal number "
- "of member types in the base type\n",
+ "(3.3.2.3), union simple type '%s', unequal number "
+ "of member types in the base type.\n",
type->name, NULL);
}
if ((member->type != baseMember->type) &&
(xmlSchemaCheckCOSSTDerivedOK(ctxt->schema,
member->type, baseMember->type, 0) != 0)) {
- xmlSchemaPErrExt(ctxt, type->node,
- XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, NULL,
- NULL, NULL,
- "Union simple type \"%s\": its member type "
- "\"%s\" is not validly derived from its "
- "corresponding member type \"%s\" of the base "
- "type \"%s\" as defined in Type Derivation OK "
- "(Simple).\n",
- type->name, member->type->name,
- baseMember->type->name,
- type->baseType->name, NULL);
+ xmlChar *strBMT = NULL, *strBT = NULL;
+
+ xmlSchemaPCustomErrExt(ctxt,
+ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
+ NULL, type, NULL,
+ "The member type %s is not validly derived from its "
+ "corresponding member type %s of the base type %s",
+ xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1),
+ xmlSchemaFormatItemForReport(&strBMT, NULL, baseMember->type, NULL, 1),
+ xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1));
+ FREE_AND_NULL(str)
+ FREE_AND_NULL(strBMT)
+ FREE_AND_NULL(strBT)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
}
member = member->next;
@@ -7673,12 +9770,9 @@
do {
if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
- "Union simple type \"%s\": the facet \"%s\" "
- "is not allowed.\n",
- type->name,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type));
+ xmlSchemaPIllegalFacetListUnionErr(ctxt,
+ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
+ NULL, type, facet);
ok = 0;
}
facet = facet->next;
@@ -7721,7 +9815,7 @@
xmlSchemaPErr(ctxt, type->node,
XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaCheckSRCSimpleType, "
- "no subtype on simple type \"%s\".\n",
+ "no subtype on simple type '%s'.\n",
type->name, NULL);
return (-1);
}
@@ -7740,7 +9834,7 @@
/*
xmlSchemaPErr(ctxt, type->node,
XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
- "Simple type \"%s\" does not satisfy the constraints "
+ "Simple type '%s' does not satisfy the constraints "
"on simple type definitions.\n",
type->name, NULL);
*/
@@ -7759,13 +9853,11 @@
((type->subtypes->base != NULL) &&
(type->subtypes->subtypes != NULL) &&
(type->subtypes->subtypes->type == XML_SCHEMA_TYPE_SIMPLE))) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_SIMPLE_TYPE_2,
- "Simple type \"%s\": "
- "The <restriction> alternative is chosen, thus either the "
- "\"base\" attribute or the <simpleType> child "
- "must be present, but not both.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "Either the attribute 'base' or the <simpleType> child "
+ "must be present on the <restriction> child ", NULL);
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_2);
}
} else if (type->subtypes->type == XML_SCHEMA_TYPE_LIST) {
@@ -7779,13 +9871,11 @@
(type->baseType == NULL)) ||
((type->subtypes->base != NULL) &&
(type->subtypes->baseType != NULL))) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_SIMPLE_TYPE_3,
- "Simple type \"%s\": "
- "The <list> alternative is chosen, thus either the "
- "\"itemType\" attribute or the <simpleType> child "
- "must be present, but not both.\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "Either the attribute 'itemType' or the <simpleType> child "
+ "must be present on the <list> child ", NULL);
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_3);
}
@@ -7810,15 +9900,14 @@
if (ancestor == anySimpleType)
break;
else if (ancestor == type) {
- xmlSchemaPErr(ctxt, type->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
- "Simple type \"%s\" is not derived from the simple "
- "ur-type definition (circular definitions are disallowed).\n",
- type->name, NULL);
+ NULL, type, NULL,
+ "The definition is circular", NULL);
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
} else if (ancestor->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
/*
- * TODO: Although a list simple type must not have a union ST
+ * TODO, FIXME: Although a list simple type must not have a union ST
* type as item type, which in turn has a list ST as member
* type, we will assume this here as well, since this check
* was not yet performed.
@@ -7829,7 +9918,6 @@
}
member = member->next;
}
-
}
return (0);
@@ -7895,12 +9983,11 @@
xmlSchemaGetType(ctxt->schema, typeDecl->base,
typeDecl->baseNs);
if (base == NULL) {
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_SRC_RESOLVE,
- "Restriction \"%s\": the QName \"%s\" of the "
- "attribute \"base\" does not resolve to a schema "
- "component.\n",
- name, typeDecl->base);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, typeDecl, typeDecl->node,
+ "base", typeDecl->base, typeDecl->baseNs,
+ XML_SCHEMA_TYPE_BASIC, "type definition");
} else if (base->contentType ==
XML_SCHEMA_CONTENT_UNKNOWN) {
/*
@@ -7972,11 +10059,12 @@
* src-restriction-base-or-simpleType
* Either the base [attribute] or the simpleType [child] of the
* <restriction> element must be present, but not both.
+ * TODO: Move this to the parse function.
*/
xmlSchemaPErr(ctxt, typeDecl->node,
XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
- "Restriction \"%s\": "
- "Either the \"base\" attribute or the <simpleType> child "
+ "<restriction>: "
+ "Either the 'base' attribute or the <simpleType> child "
"must be present, but not both.\n",
typeDecl->name, NULL);
}
@@ -7994,10 +10082,10 @@
XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
if (typeDecl->recurse) {
/* TODO: The word "recursive" should be changed to "circular" here. */
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- "Schemas: extension type %s is recursive\n",
- name, NULL);
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_UNKNOWN_BASE_TYPE,
+ NULL, typeDecl, typeDecl->node,
+ "This item is circular", NULL);
return;
}
if (typeDecl->base != NULL) {
@@ -8005,12 +10093,11 @@
xmlSchemaGetType(ctxt->schema, typeDecl->base,
typeDecl->baseNs);
if (base == NULL) {
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_SRC_RESOLVE,
- "Extension \"%s\": the QName \"%s\" of the "
- "attribute \"base\" does not resolve to a schema "
- "component.\n",
- name, typeDecl->base);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, typeDecl, typeDecl->node,
+ "base", typeDecl->base, typeDecl->baseNs,
+ XML_SCHEMA_TYPE_BASIC, "type definition");
} else if (base->contentType ==
XML_SCHEMA_CONTENT_UNKNOWN) {
typeDecl->recurse = 1;
@@ -8405,7 +10492,7 @@
xmlSchemaPErr(ctxt, typeDecl->node,
XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaCheckFacet, "
- "the type \"%s\" has no base type.\n",
+ "the type '%s' has no base type.\n",
typeDecl->name, NULL);
return (-1);
}
@@ -8423,8 +10510,8 @@
typeDecl->name, NULL);
return (-1);
}
- vctxt->type = base;
- ret = xmlSchemaValidateSimpleTypeValue(vctxt, facet->value, 0, 1);
+ vctxt->type = base;
+ ret = xmlSchemaValidateSimpleTypeValue(vctxt, facet->value, 0, 1, 1);
facet->val = vctxt->value;
vctxt->value = NULL;
if (ret > 0) {
@@ -8433,8 +10520,8 @@
xmlSchemaPErrExt(ctxt, facet->node,
XML_SCHEMAP_INVALID_FACET,
NULL, NULL, NULL,
- "Type \"%s\": the value \"%s\" of the "
- "facet \"%s\" is invalid.\n",
+ "Type definition '%s': The value '%s' of the "
+ "facet '%s' is not valid.\n",
name, facet->value,
BAD_CAST xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
@@ -8445,8 +10532,8 @@
XML_SCHEMAS_ERR_INTERNAL,
NULL, NULL, NULL,
"Internal error: xmlSchemaCheckFacet, "
- "failed to validate the value \"%s\" name of the "
- "facet \"%s\" against the base type \"%s\".\n",
+ "failed to validate the value '%s' name of the "
+ "facet '%s' against the base type '%s'.\n",
facet->value,
BAD_CAST xmlSchemaFacetTypeToString(facet->type),
base->name, NULL, NULL);
@@ -8455,61 +10542,13 @@
xmlSchemaFreeValidCtxt(vctxt);
break;
}
- /*
- * Removed, since added to the case above.
- *
- case XML_SCHEMA_FACET_ENUMERATION:{
- *
- * Okay we need to validate the value
- * at that point.
- *
- xmlSchemaValidCtxtPtr vctxt;
- int tmp;
- xmlSchemaTypePtr base;
-
- * 4.3.5.5 Constraints on enumeration Schema Components
- * Schema Component Constraint: enumeration valid restriction
- * It is an ·error· if any member of {value} is not in the
- * ·value space· of {base type definition}.
- *
- vctxt = xmlSchemaNewValidCtxt(NULL);
- if (vctxt == NULL)
- break;
- base = typeDecl->baseType;
- if (base == NULL) {
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaCheckFacet, "
- "the type \"%s\" has no base type.\n",
- typeDecl->name, NULL);
- return (-1);
- }
- vctxt->type = base;
- tmp = xmlSchemaValidateSimpleTypeValue(vctxt, facet->value, 0, 1);
- * tmp = xmlSchemaValidateSimpleValue(vctxt, typeDecl,
- facet->value);
- *
- if (tmp != 0) {
- if (ctxt != NULL) {
- xmlSchemaPErr(ctxt, facet->node,
- XML_SCHEMAP_INVALID_ENUM,
- "Type \"%s\": the value \"%s\" of the "
- "facet \"enumeration\" is invalid.\n",
- name, facet->value);
- }
- ret = -1;
- }
- xmlSchemaFreeValidCtxt(vctxt);
- break;
- }
- */
case XML_SCHEMA_FACET_PATTERN:
facet->regexp = xmlRegexpCompile(facet->value);
if (facet->regexp == NULL) {
xmlSchemaPErr(ctxt, typeDecl->node,
XML_SCHEMAP_REGEXP_INVALID,
- "Type \"%s\": the value \"%s\" of the "
- "facet \"pattern\" is invalid.\n",
+ "Type definition '%s': The value '%s' of the "
+ "facet 'pattern' is not valid.\n",
name, facet->value);
ret = -1;
}
@@ -8531,8 +10570,8 @@
xmlSchemaPErrExt(ctxt, facet->node,
XML_SCHEMAP_INVALID_FACET_VALUE,
NULL, NULL, NULL,
- "Type \"%s\": the value \"%s\" of the "
- "facet \"%s\" is invalid.\n",
+ "Type definition '%s': The value '%s' of the "
+ "facet '%s' is not valid.\n",
name, facet->value,
BAD_CAST xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
@@ -8552,8 +10591,8 @@
if (ctxt != NULL) {
xmlSchemaPErr(ctxt, facet->node,
XML_SCHEMAP_INVALID_WHITE_SPACE,
- "Type \"%s\": the value \"%s\" of the "
- "facet \"whiteSpace\" is invalid.\n",
+ "Type definition '%s': The value '%s' of the "
+ "facet 'whiteSpace' is not valid.\n",
name, facet->value);
}
ret = -1;
@@ -8611,31 +10650,20 @@
if (attrgrp->ref != NULL) {
xmlSchemaAttributeGroupPtr ref;
- ref = xmlSchemaGetAttributeGroup(ctxt->schema, attrgrp->ref, attrgrp->refNs);
+ ref = xmlSchemaGetAttributeGroup(ctxt->schema, attrgrp->ref,
+ attrgrp->refNs);
if (ref == NULL) {
- xmlSchemaPErr(ctxt, attrgrp->node,
+ xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- "Attribute group \"%s\": the QName \"%s\" of the attribute "
- "\"ref\" does not resolve to a schema "
- "component.\n",
- name, attrgrp->ref);
+ NULL, (xmlSchemaTypePtr) attrgrp, attrgrp->node,
+ "ref", attrgrp->ref, attrgrp->refNs,
+ XML_SCHEMA_TYPE_ATTRIBUTEGROUP, NULL);
return;
}
xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
attrgrp->attributes = ref->attributes;
attrgrp->attributeWildcard = ref->attributeWildcard;
}
- /*
- * Removed, since a global attribute group does not need to hold any
- * attributes or wildcard
- */
- /*
- else {
- xmlSchemaPErr(ctxt, attrgrp->node, XML_SCHEMAP_NOATTR_NOREF,
- "Schemas: attribute group %s has no attributes nor reference\n",
- name, NULL);
- }
- */
}
/**
@@ -8650,12 +10678,18 @@
xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
+ /*
+ * TODO: If including this is done twice (!) for every attribute.
+ */
/*
* The simple type definition corresponding to the <simpleType> element
* information item in the [children], if present, otherwise the simple
* type definition ·resolved· to by the ·actual value· of the type
* [attribute], if present, otherwise the ·simple ur-type definition·.
*/
+ if (attrDecl->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
+ return;
+ attrDecl->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
if (name == NULL)
name = attrDecl->name;
if (attrDecl->subtypes != NULL)
@@ -8666,25 +10700,28 @@
type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
attrDecl->typeNs);
if (type == NULL) {
- xmlSchemaPErr(ctxt, attrDecl->node,
+ xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- "Attribute \"%s\": the QName \"%s\" of the attribute "
- "\"type\" does not resolve to a schema "
- "component.\n",
- name, attrDecl->typeName);
+ NULL, (xmlSchemaTypePtr) attrDecl, attrDecl->node,
+ "type", attrDecl->typeName, attrDecl->typeNs,
+ XML_SCHEMA_TYPE_BASIC, "type definition");
}
attrDecl->subtypes = type;
} else if (attrDecl->ref != NULL) {
xmlSchemaAttributePtr ref;
+ /*
+ * TODO: Evaluate, what errors could occur if the declaration is not
+ * found. It might be possible that the "typefixup" might crash if
+ * no ref declaration was found.
+ */
ref = xmlSchemaGetAttribute(ctxt->schema, attrDecl->ref, attrDecl->refNs);
if (ref == NULL) {
- xmlSchemaPErr(ctxt, attrDecl->node,
- XML_SCHEMAP_SRC_RESOLVE,
- "Attribute \"%s\": the QName \"%s\" of the attribute "
- "\"ref\" does not resolve to a schema "
- "component.\n",
- name, attrDecl->ref);
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, (xmlSchemaTypePtr) attrDecl, attrDecl->node,
+ "ref", attrDecl->ref, attrDecl->refNs,
+ XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
return;
}
xmlSchemaAttrFixup(ref, ctxt, NULL);
@@ -8733,7 +10770,7 @@
if (doc == NULL) {
xmlSchemaPErr(ctxt, NULL,
XML_SCHEMAP_FAILED_LOAD,
- "xmlSchemaParse: could not load %s\n",
+ "xmlSchemaParse: could not load '%s'.\n",
ctxt->URL, NULL);
return (NULL);
}
@@ -8743,7 +10780,7 @@
if (doc == NULL) {
xmlSchemaPErr(ctxt, NULL,
XML_SCHEMAP_FAILED_PARSE,
- "xmlSchemaParse: could not parse\n",
+ "xmlSchemaParse: could not parse.\n",
NULL, NULL);
return (NULL);
}
@@ -8755,7 +10792,7 @@
} else {
xmlSchemaPErr(ctxt, NULL,
XML_SCHEMAP_NOTHING_TO_PARSE,
- "xmlSchemaParse: could not parse\n",
+ "xmlSchemaParse: could not parse.\n",
NULL, NULL);
return (NULL);
}
@@ -8767,7 +10804,7 @@
if (root == NULL) {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
XML_SCHEMAP_NOROOT,
- "schemas has no root", NULL, NULL);
+ "The schema has no document element.\n", NULL, NULL);
if (!preserve) {
xmlFreeDoc(doc);
}
@@ -8791,14 +10828,9 @@
}
ret->doc = doc;
ret->preserve = preserve;
-
- /*
- * Then fix all the references.
- */
ctxt->schema = ret;
- xmlHashScanFull(ret->elemDecl,
- (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
-
+ ctxt->ctxtType = NULL;
+ ctxt->parentItem = NULL;
/*
* Then fixup all attributes declarations
*/
@@ -8812,10 +10844,14 @@
/*
* Then fixup all types properties
- */
- ctxt->ctxtType = NULL;
- ctxt->parentItem = NULL;
- xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
+ */
+ xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
+
+ /*
+ * Then fix references of element declaration; apply constraints.
+ */
+ xmlHashScanFull(ret->elemDecl,
+ (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
/*
* Then build the content model for all elements
@@ -8829,6 +10865,7 @@
xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults,
ctxt);
+
if (ctxt->nberrors != 0) {
xmlSchemaFree(ret);
ret = NULL;
@@ -8900,10 +10937,106 @@
return ("Internal Error");
}
+static xmlChar *
+xmlSchemaWhiteSpaceReplace(const xmlChar *value) {
+ const xmlChar *cur = value;
+ xmlChar *ret = NULL, *mcur;
+
+ if (value == NULL)
+ return(NULL);
+
+ while ((*cur != 0) &&
+ (((*cur) != 0xd) && ((*cur) != 0x9) && ((*cur) != 0xa))) {
+ cur++;
+ }
+ if (*cur == 0)
+ return (NULL);
+ ret = xmlStrdup(value);
+ /* TODO FIXME: I guess gcc will bark at this. */
+ mcur = (xmlChar *) (ret + (cur - value));
+ do {
+ if ( ((*mcur) == 0xd) || ((*mcur) == 0x9) || ((*mcur) == 0xa) )
+ *mcur = ' ';
+ mcur++;
+ } while (*mcur != 0);
+ return(ret);
+}
+
+static int
+xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
+{
+ xmlSchemaTypePtr anc;
+
+ /*
+ * The normalization type can be changed only for types which are derived
+ * from xsd:string.
+ */
+ if (type->type == XML_SCHEMA_TYPE_BASIC) {
+ if ((type->builtInType == XML_SCHEMAS_STRING) &&
+ (type->builtInType == XML_SCHEMAS_NORMSTRING))
+
+ return(XML_SCHEMAS_VAL_WTSP_PRESERVE);
+ else {
+ /*
+ * For all ·atomic· datatypes other than string (and types ·derived·
+ * by ·restriction· from it) the value of whiteSpace is fixed to
+ * collapse
+ */
+ return(XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ }
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ /*
+ * For list types the facet "whiteSpace" is fixed to "collapse".
+ */
+ return (XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ return (-1);
+ } else if (type->facetSet != NULL) {
+ xmlSchemaTypePtr anyST;
+ xmlSchemaFacetLinkPtr lin;
+
+ /*
+ * Atomic types.
+ */
+ anyST = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ anc = type->baseType;
+ do {
+ /*
+ * For all ·atomic· datatypes other than string (and types ·derived·
+ * by ·restriction· from it) the value of whiteSpace is fixed to
+ * collapse
+ */
+ if ((anc->type == XML_SCHEMA_TYPE_BASIC) &&
+ (anc->builtInType == XML_SCHEMAS_STRING)) {
+
+ lin = type->facetSet;
+ do {
+ if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
+ if (lin->facet->whitespace ==
+ XML_SCHEMAS_FACET_COLLAPSE) {
+ return(XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ } else if (lin->facet->whitespace ==
+ XML_SCHEMAS_FACET_REPLACE) {
+ return(XML_SCHEMAS_VAL_WTSP_REPLACE);
+ } else
+ return(XML_SCHEMAS_VAL_WTSP_PRESERVE);
+ break;
+ }
+ lin = lin->next;
+ } while (lin != NULL);
+ break;
+ }
+ anc = anc->baseType;
+ } while (anc != anyST);
+ return (XML_SCHEMAS_VAL_WTSP_COLLAPSE);
+ }
+ return (-1);
+}
+
/**
* xmlSchemaValidateFacetsInternal:
* @ctxt: a schema validation context
- * @base: the base type
+ * @type: the type holding the facets
* @facets: the list of facets to check
* @value: the lexical repr of the value to validate
* @val: the precomputed value
@@ -8917,46 +11050,152 @@
*/
static int
xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr base,
- xmlSchemaFacetLinkPtr facets,
- const xmlChar * value, int fireErrors)
+ xmlSchemaTypePtr type,
+ const xmlChar * value,
+ unsigned long length,
+ int fireErrors)
{
int ret = 0;
- int tmp = 0;
- xmlSchemaTypeType type;
- xmlSchemaFacetLinkPtr facetLink = facets;
+ xmlSchemaTypePtr biType; /* The build-in type. */
+ xmlSchemaTypePtr tmpType;
+ xmlSchemaFacetLinkPtr facetLink;
+ int retFacet, hasFacet;
+ xmlSchemaFacetPtr facet;
+ unsigned long len = 0;
- while (facetLink != NULL) {
- type = facetLink->facet->type;
- if (type == XML_SCHEMA_FACET_ENUMERATION) {
- tmp = 1;
-
- while (facetLink != NULL) {
- tmp =
- xmlSchemaValidateFacet(base, facetLink->facet, value,
- ctxt->value);
- if (tmp == 0) {
- return 0;
- }
- facetLink = facetLink->next;
- }
- } else
- tmp = xmlSchemaValidateFacet(base, facetLink->facet, value,
- ctxt->value);
-
- if (tmp != 0) {
- ret = tmp;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur, tmp,
- "The value failed to validate against the facet \"%s\".\n",
- (const xmlChar *) xmlSchemaFacetTypeToString(type),
- NULL);
-
+#ifdef DEBUG_UNION_VALIDATION
+ printf("Facets of type: '%s'\n", (const char *) type->name);
+ printf(" fireErrors: %d\n", fireErrors);
+#endif
+
+ /*
+ * NOTE: Do not jump away, if the facetSet of the given type is
+ * empty: until now, "pattern" facets of the *base types* need to
+ * be checked as well.
+ */
+ biType = type->baseType;
+ while ((biType != NULL) && (biType->type != XML_SCHEMA_TYPE_BASIC))
+ biType = biType->baseType;
+ if (biType == NULL) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateFacetsInternal, "
+ "the base type axis of the given type '%s' does not resolve to "
+ "a built-in type.\n",
+ type->name, NULL);
+ return (-1);
+ }
+
+ if (type->facetSet != NULL) {
+ facetLink = type->facetSet;
+ while (facetLink != NULL) {
+ facet = facetLink->facet;
+ /*
+ * Skip the pattern "whiteSpace": it is used to
+ * format the character content beforehand.
+ */
+ switch (facet->type) {
+ case XML_SCHEMA_FACET_WHITESPACE:
+ case XML_SCHEMA_FACET_PATTERN:
+ case XML_SCHEMA_FACET_ENUMERATION:
+ break;
+ case XML_SCHEMA_FACET_LENGTH:
+ case XML_SCHEMA_FACET_MINLENGTH:
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ ret = xmlSchemaValidateListSimpleTypeFacet(facet,
+ value, length, 0);
+ len = length;
+ } else
+ ret = xmlSchemaValidateLengthFacet(biType, facet,
+ value, ctxt->value, &len);
+ break;
+ default:
+ ret = xmlSchemaValidateFacet(biType, facet, value,
+ ctxt->value);
}
- }
- if (facetLink != NULL)
- facetLink = facetLink->next;
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateFacetsInternal, "
+ "validating facet of type '%s'.\n",
+ type->name, NULL);
+ break;
+ } else if ((ret > 0) && (fireErrors)) {
+ xmlSchemaVFacetErr(ctxt, ret, ctxt->cur, value, len,
+ type, facet, NULL, NULL, NULL, NULL);
+ }
+
+ facetLink = facetLink->next;
+ }
+ if (ret >= 0) {
+ /*
+ * Process enumerations.
+ */
+ retFacet = 0;
+ facetLink = type->facetSet;
+ while (facetLink != NULL) {
+ if (facetLink->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
+ retFacet = xmlSchemaValidateFacet(biType, facetLink->facet,
+ value, ctxt->value);
+ if (retFacet <= 0)
+ break;
+ }
+ facetLink = facetLink->next;
+ }
+ if (retFacet > 0) {
+ ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
+ if (fireErrors)
+ xmlSchemaVFacetErr(ctxt, ret, ctxt->cur,
+ value, 0, type, NULL, NULL, NULL, NULL, NULL);
+ } else if (retFacet < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateFacetsInternal, "
+ "validating facet of type '%s'.\n",
+ BAD_CAST "enumeration", NULL);
+ ret = -1;
+ }
+ }
}
+ if (ret >= 0) {
+ /*
+ * Process patters. Pattern facets are ORed at type level
+ * and ANDed if derived. Walk the base type axis.
+ */
+ hasFacet = 0;
+ tmpType = type;
+ facet = NULL;
+ do {
+ retFacet = 0;
+ for (facetLink = tmpType->facetSet; facetLink != NULL;
+ facetLink = facetLink->next) {
+ if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
+ continue;
+ retFacet = xmlSchemaValidateFacet(biType, facetLink->facet,
+ value, ctxt->value);
+ if (retFacet <= 0)
+ break;
+ else
+ /* Save the last non-validating facet. */
+ facet = facetLink->facet;
+ }
+ if (retFacet != 0)
+ break;
+ tmpType = tmpType->baseType;
+ } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
+ if (retFacet < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating 'pattern' facets of type '%s'.\n",
+ tmpType->name, NULL);
+ ret = -1;
+ } else if (retFacet > 0) {
+ ret = XML_SCHEMAV_CVC_PATTERN_VALID;
+ if (fireErrors) {
+ xmlSchemaVFacetErr(ctxt, ret, ctxt->cur, value, 0, type, facet,
+ NULL, NULL, NULL, NULL);
+ }
+ }
+ }
+
return (ret);
}
@@ -8965,211 +11204,7 @@
* Simple type validation *
* *
************************************************************************/
-#if 0 /* Not currently used. */
-/**
- * xmlSchemaValidateSimpleValueUnion:
- * @ctxt: a schema validation context
- * @type: the type declaration
- * @value: the value to validate
- *
- * Validates a value against a union.
- *
- * Returns 0 if the value is valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleValueUnion(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type, const xmlChar * value)
-{
- int ret = 0;
- const xmlChar *cur, *end, *prefix, *ncName;
- xmlChar *tmp;
- xmlSchemaTypePtr subtype;
- xmlNsPtr ns;
- int len;
-
- /* Process referenced memberTypes. */
- cur = type->ref;
- do {
- while (IS_BLANK_CH(*cur))
- cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK_CH(*end))))
- end++;
- if (end == cur)
- break;
- tmp = xmlStrndup(cur, end - cur);
- ncName = xmlSplitQName3(tmp, &len);
- if (ncName != NULL) {
- prefix = xmlStrndup(tmp, len);
- /* prefix = xmlDictLookup(ctxt->doc->dict, tmp, len); */
- } else {
- prefix = NULL;
- ncName = tmp;
- }
- /* We won't do additional checks here,
- * since they have been performed during parsing. */
- ns = xmlSearchNs(type->node->doc, type->node, prefix);
- /* namespace = xmlDictLookup(ctxt->doc->dict, ns->href, -1); */
- subtype = xmlSchemaGetType(ctxt->schema, ncName, ns->href);
- if (tmp != NULL)
- xmlFree(tmp);
- if (prefix != NULL)
- xmlFree((void *)prefix);
- ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
- if ((ret == 0) || (ret == -1)) {
- return (ret);
- }
- cur = end;
- } while (*cur != 0);
-
- if (type->subtypes != NULL) {
- subtype = type->subtypes;
- do {
- ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
- if ((ret == 0) || (ret == -1)) {
- return (ret);
- }
- subtype = subtype->next;
- } while (subtype != NULL);
- }
- return (ret);
-}
-
-/**
- * xmlSchemaValidateSimpleValue:
- * @ctxt: a schema validation context
- * @type: the type declaration
- * @value: the value to validate
- *
- * Validate a value against a simple type
- *
- * Returns 0 if the value is valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type, const xmlChar * value)
-{
- return (xmlSchemaValidateSimpleValueInternal(ctxt, type, value, 1));
-}
-
-/**
- * xmlSchemaValidateSimpleValue:
- * @ctxt: a schema validation context
- * @type: the type declaration
- * @value: the value to validate
- * @fireErrors: if 0, only internal errors will be fired;
- * otherwise all errors will be fired.
- *
- * Validate a value against a simple type
- *
- * Returns 0 if the value is valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type,
- const xmlChar * value,
- int fireErrors)
-{
- int ret = 0;
-
- /*
- * First normalize the value accordingly to Schema Datatype
- * 4.3.6 whiteSpace definition of the whiteSpace facet of type
- *
- * Then check the normalized value against the lexical space of the
- * type.
- */
- if (type->type == XML_SCHEMA_TYPE_BASIC) {
- if (ctxt->value != NULL) {
- xmlSchemaFreeValue(ctxt->value);
- ctxt->value = NULL;
- }
- ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
- ctxt->cur);
- if ((fireErrors) && (ret != 0)) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE,
- "Failed to validate basic type %s\n",
- type->name, NULL);
- }
- } else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
- xmlSchemaTypePtr base;
-
- base = type->baseType;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValueInternal(ctxt, base,
- value, fireErrors);
- } else if (type->subtypes != NULL) {
- TODO
- }
-
- /*
- * Do not validate facets or attributes when working on
- * building the Schemas
- */
- if (ctxt->schema != NULL) {
- xmlSchemaFacetLinkPtr facetLink;
-
- if ((ret == 0) && (type->facetSet != NULL)) {
- facetLink = type->facetSet;
- ret = xmlSchemaValidateFacetsInternal(ctxt, base, facetLink,
- value, fireErrors);
- }
- }
- } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
- xmlSchemaTypePtr base;
-
- base = type->subtypes;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValueInternal(ctxt, base,
- value, fireErrors);
- } else {
- TODO}
- } else if (type->type == XML_SCHEMA_TYPE_LIST) {
- xmlSchemaTypePtr base;
- const xmlChar *cur, *end;
- xmlChar *tmp;
- int ret2;
-
- base = type->subtypes;
- if (base == NULL) {
- xmlSchemaVErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal: List type %s has no base type\n",
- type->name, NULL);
- return (-1);
- }
- cur = value;
- do {
- while (IS_BLANK_CH(*cur))
- cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK_CH(*end))))
- end++;
- if (end == cur)
- break;
- tmp = xmlStrndup(cur, end - cur);
- ret2 = xmlSchemaValidateSimpleValueInternal(ctxt, base,
- tmp, fireErrors);
- xmlFree(tmp);
- if (ret2 != 0)
- ret = 1;
- cur = end;
- } while (*cur != 0);
- } else if (type->type == XML_SCHEMA_TYPE_UNION) {
- ret = xmlSchemaValidateSimpleValueUnion(ctxt, type, value);
- if ((fireErrors) && (ret != 0)) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE,
- "Failed to validate type %s\n", type->name, NULL);
- }
- } else {
- TODO
- }
- return (ret);
-}
-#endif
/************************************************************************
* *
@@ -9228,12 +11263,12 @@
attrs = attrs->next;
continue;
}
- tmp = (xmlSchemaAttrStatePtr)
- xmlMalloc(sizeof(xmlSchemaAttrState));
- if (tmp == NULL) {
- xmlSchemaVErrMemory(ctxt, "registering attributes", NULL);
- return (-1);
- }
+ tmp = (xmlSchemaAttrStatePtr)
+ xmlMalloc(sizeof(xmlSchemaAttrState));
+ if (tmp == NULL) {
+ xmlSchemaVErrMemory(ctxt, "registering attributes", NULL);
+ return (-1);
+ }
tmp->attr = attrs;
tmp->state = XML_SCHEMAS_ATTR_UNKNOWN;
tmp->next = NULL;
@@ -9248,127 +11283,6 @@
}
/**
- * xmlSchemaCheckAttributes:
- * @ctxt: a schema validation context
- * @node: the node carrying it.
- *
- * Check that the registered set of attributes on the current node
- * has been properly validated.
- *
- * Returns 0 if validity constraints are met, 1 otherwise.
- */
-static int
-xmlSchemaCheckAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
-{
- int ret = 0;
- xmlSchemaAttrStatePtr cur;
-
- cur = ctxt->attr;
- while ((cur != NULL) && (cur != ctxt->attrTop->next)) {
- if (cur->state != XML_SCHEMAS_ATTR_CHECKED) {
- ret = 1;
- if (cur->state == XML_SCHEMAS_ATTR_UNKNOWN)
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRUNKNOWN,
- "Attribute \"%s\" is not allowed.\n",
- cur->attr->name, NULL);
- else if (cur->state == XML_SCHEMAS_ATTR_PROHIBITED)
- /*
- * TODO: This won't ever be touched so remove it.
- */
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRUNKNOWN,
- "Attribute \"%s\" is prohibited.\n",
- cur->attr->name, NULL);
- else if (cur->state == XML_SCHEMAS_ATTR_INVALID_VALUE) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRINVALID,
- "Attribute \"%s\": the value is not valid.\n",
- cur->attr->name, node->name);
- } else if (cur->state == XML_SCHEMAS_ATTR_MISSING) {
- if (cur->decl->ref != NULL)
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
- "Attribute \"%s\" is required but missing.\n",
- cur->decl->ref, NULL);
- else
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
- "Attribute \"%s\" is required but missing.\n",
- cur->decl->name, NULL);
- }
- }
- cur = cur->next;
- }
-
- return (ret);
-}
-
-#if 0 /* Not currently used - remove if ever needed */
-/**
- * xmlSchemaValidateSimpleContent:
- * @ctxt: a schema validation context
- * @elem: an element
- * @type: the type declaration
- *
- * Validate the content of an element expected to be a simple type
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr node ATTRIBUTE_UNUSED)
-{
- xmlNodePtr child;
- xmlSchemaTypePtr type, base;
- xmlChar *value;
- int ret = 0;
-
- child = ctxt->node;
- type = ctxt->type;
-
- /*
- * Validation Rule: Element Locally Valid (Type): 3.1.3
- */
- value = xmlNodeGetContent(child);
- /* xmlSchemaValidateSimpleValue(ctxt, type, value); */
- switch (type->type) {
- case XML_SCHEMA_TYPE_RESTRICTION:{
- xmlSchemaFacetPtr facet;
-
- base = type->baseType;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
- } else {
- TODO}
- if (ret == 0) {
- facet = type->facets;
- ret =
- xmlSchemaValidateFacets(ctxt, base, facet, value);
- }
- /*
- * This should attempt to validate the attributes even
- * when validation of the value failed.
- */
- /*
- if (type->attributes != NULL) {
- ret = xmlSchemaValidateAttributes(ctxt, node,
- type->attributes);
- }
- */
- break;
- }
- case XML_SCHEMA_TYPE_EXTENSION:{
- TODO
- break;
- }
- default:
- TODO
- }
- if (value != NULL)
- xmlFree(value);
-
- return (ret);
-}
-#endif
-
-/**
* xmlSchemaValidateCheckNodeList
* @nodelist: the list of nodes
*
@@ -9419,63 +11333,11 @@
#endif
ctxt->type = type;
ctxt->node = node;
- xmlSchemaValidateContent(ctxt, node);
+ xmlSchemaValidateContent(ctxt, node);
ctxt->type = oldtype;
ctxt->node = oldnode;
}
-
-#if 0
-
-/**
- * xmlSchemaValidateSimpleRestrictionType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of a restriction type.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleRestrictionType(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr node)
-{
- xmlNodePtr child;
- xmlSchemaTypePtr type;
- int ret;
-
- child = ctxt->node;
- type = ctxt->type;
-
- if ((ctxt == NULL) || (type == NULL)) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleRestrictionType %s\n",
- node->name, NULL);
- return (-1);
- }
- /*
- * Only text and text based entities references shall be found there
- */
- ret = xmlSchemaValidateCheckNodeList(child);
- if (ret < 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleRestrictionType %s content\n",
- node->name, NULL);
- return (-1);
- } else if (ret == 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTSIMPLE,
- "Element %s content is not a simple type\n",
- node->name, NULL);
- return (-1);
- }
- ctxt->type = type->subtypes;
- xmlSchemaValidateContent(ctxt, node);
- ctxt->type = type;
- return (ret);
-}
-#endif
-
#if 0 /* Not used any more */
/**
* xmlSchemaValidateSimpleType:
@@ -9565,14 +11427,7 @@
if (base != NULL) {
ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
} else {
- TODO}
-
- /* Removed due to changes of attribute validation:
- if ((ret == 0) && (variety->attributes != NULL)) {
- ret = xmlSchemaValidateAttributes(ctxt, node,
- variety->attributes);
- }
- */
+ TODO}
break;
}
case XML_SCHEMA_TYPE_LIST:
@@ -9603,37 +11458,52 @@
}
#endif
+
+
/**
* xmlSchemaValidateSimpleTypeValue:
* @ctxt: a schema validation context
* @value: the value to be validated
* @fireErrors: shall errors be reported?
* @applyFacets: shall facets be applied?
+ * @normalize: shall the value be normalized?
*
* Validates a value by the given type (user derived or built-in).
*
* Returns 0 if the value is valid, a positive error code
* number otherwise and -1 in case of an internal or API error.
- * Note on reported errors: Although it might be nice to report
- * the name of the simple/complex type, used to validate the content
- * of a node, it is quite unnecessary: for global defined types
- * the local name of the element is equal to the NCName of the type,
- * for local defined types it makes no sense to output the internal
- * computed name of the type. TODO: Instead, one should attach the
- * struct of the type involved to the error handler - this allows
- * the report of any additional information by the user.
- * TODO: Correct character normalization of union simple types.
*/
static int
xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
const xmlChar *value,
int fireErrors,
- int applyFacets)
+ int applyFacets,
+ int normalize)
{
xmlSchemaTypePtr type;
- int ret = 0;
- type = ctxt->type;
-
+ int ret = 0;
+ xmlChar *normValue = NULL;
+ int wtsp;
+
+ type = ctxt->type;
+ wtsp = ctxt->valueWS;
+ /*
+ * Normalize the value.
+ */
+ if (normalize &&
+ (ctxt->valueWS != XML_SCHEMAS_VAL_WTSP_COLLAPSE)) {
+ int norm = xmlSchemaGetWhiteSpaceFacetValue(type);
+
+ if ((norm != -1) && (norm > ctxt->valueWS)) {
+ if (norm == XML_SCHEMAS_VAL_WTSP_COLLAPSE)
+ normValue = xmlSchemaCollapseString(value);
+ else
+ normValue = xmlSchemaWhiteSpaceReplace(value);
+ ctxt->valueWS = norm;
+ if (normValue != NULL)
+ value = (const xmlChar *) normValue;
+ }
+ }
if (type->type == XML_SCHEMA_TYPE_BASIC) {
xmlNodePtr child;
@@ -9644,113 +11514,115 @@
child = ctxt->node;
while (child != NULL) {
switch (child->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- TODO break;
- case XML_ELEMENT_NODE:
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INVALIDELEM,
- "Element \"%s\": child \"%s\" should not be present.\n",
- ctxt->cur->name, child->name);
- return (ctxt->err);
- case XML_ATTRIBUTE_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
+ break;
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ TODO break;
+ case XML_ELEMENT_NODE: {
+ xmlChar *strE = NULL;
+
+ xmlSchemaVErrExt(ctxt, ctxt->cur,
+ XML_SCHEMAS_ERR_INVALIDELEM,
+ "Element '%s': The child '%s' should "
+ "not be present.\n",
+ xmlSchemaFormatNsPrefixLocal(&strE,
+ ctxt->cur->parent->ns, ctxt->cur->parent->name),
+ child->name, NULL, NULL, NULL);
+ FREE_AND_NULL(strE);
+ return (ctxt->err);
+ }
+ case XML_ATTRIBUTE_NODE:
+ case XML_DOCUMENT_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ case XML_NOTATION_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DTD_NODE:
+ case XML_ELEMENT_DECL:
+ case XML_ATTRIBUTE_DECL:
+ case XML_ENTITY_DECL:
+ case XML_NAMESPACE_DECL:
#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INVALIDELEM,
- "Element \"%s\": node type of node unexpected here.\n",
- ctxt->cur->name, NULL);
- return (ctxt->err);
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ {
+ xmlChar *strE = NULL, *strA = NULL;
+
+ if (ctxt->cur->type == XML_ATTRIBUTE_NODE) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INVALIDELEM,
+ "Element '%s', attribute '%s': The type of node is "
+ "unexpected here.\n",
+ xmlSchemaFormatNsPrefixLocal(&strE, ctxt->cur->parent->ns,
+ ctxt->cur->parent->name),
+ xmlSchemaFormatNsPrefixLocal(&strA, ctxt->cur->ns,
+ ctxt->cur->name));
+ } else {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INVALIDELEM,
+ "Element '%s': The type of node is unexpected here.\n",
+ xmlSchemaFormatNsPrefixLocal(&strE, ctxt->cur->ns,
+ ctxt->cur->name), NULL);
+ }
+ FREE_AND_NULL(strE);
+ FREE_AND_NULL(strA);
+ return (ctxt->err);
+ }
}
child = child->next;
- }
- ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
- ctxt->cur);
- if (ret > 0) {
+
+ }
+ ret = xmlSchemaValPredefTypeNodeNoNorm(type, value, &(ctxt->value), ctxt->cur);
+ if (ret > 0) {
if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
else
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
- if (fireErrors) {
- if (ctxt->cur->type == XML_ATTRIBUTE_NODE)
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- "The value of attribute \"%s\" is not valid.\n",
- ctxt->cur->name, NULL);
- else
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- "The value is not valid.\n",
- NULL, NULL);
- }
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
} else if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating built-in type \"%s\"\n",
- type->name, NULL);
+ "validating built-in type '%s'\n", type->name, NULL);
}
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) {
/* 1.2.1 if {variety} is ·atomic· then the string must ·match·
* a literal in the ·lexical space· of {base type definition}
*/
ctxt->type = type->baseType;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 0);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 0, 0);
+ ctxt->type = type;
if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating atomic simple type \"%s\"\n",
+ "validating atomic simple type '%s'\n",
type->name, NULL);
- } else if (ret > 0) {
+ } else if (ret > 0) {
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- "The value is not valid.\n",
- NULL, NULL);
- }
-
- } else if ((applyFacets) &&
- (type->facetSet != NULL)) {
- xmlSchemaTypePtr builtIn;
-
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
+ } else if ((applyFacets) && (type->facetSet != NULL)) {
/*
- * Check facets. Be sure to pass the built-in type to
- * xmlSchemaValidateFacetsInternal.
+ * Check facets.
*/
- builtIn = type->baseType;
- while (builtIn->type != XML_SCHEMA_TYPE_BASIC)
- builtIn = builtIn->baseType;
- ret = xmlSchemaValidateFacetsInternal(ctxt, builtIn,
- type->facetSet, value, fireErrors);
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating facets of atomic simple type \"%s\"\n",
+ "validating facets of atomic simple type '%s'\n",
type->name, NULL);
} else if (ret > 0) {
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- "The value is not valid.\n",
- NULL, NULL);
- }
+ /*
+ Disabled, since the facet validation already reports errors.
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
+ */
}
}
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
@@ -9758,14 +11630,14 @@
xmlSchemaTypePtr tmpType;
const xmlChar *cur, *end;
xmlChar *tmp;
- int len = 0;
+ unsigned long len = 0;
/* 1.2.2 if {variety} is ·list· then the string must be a sequence
* of white space separated tokens, each of which ·match·es a literal
* in the ·lexical space· of {item type definition}
*/
- tmpType = xmlSchemaGetListSimpleTypeItemType(type);
+ tmpType = xmlSchemaGetListSimpleTypeItemType(type);
cur = value;
do {
while (IS_BLANK_CH(*cur))
@@ -9778,19 +11650,21 @@
tmp = xmlStrndup(cur, end - cur);
len++;
ctxt->type = tmpType;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, tmp, 0, 1);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, tmp, 0, 1, 0);
+ ctxt->type = type;
xmlFree(tmp);
- if (ret > 0) {
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating an item of list simple type '%s'\n",
+ type->name, NULL);
+ break;
+ } else if (ret > 0) {
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2,
- "The value is not valid.\n",
- NULL, NULL);
- }
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
break;
- } else if (ret < 0)
- break;
+ }
cur = end;
} while (*cur != 0);
/*
@@ -9799,132 +11673,25 @@
if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating list simple type \"%s\"\n",
+ "validating list simple type '%s'\n",
type->name, NULL);
- } else if ((ret == 0) && (applyFacets) &&
- (type->facetSet != NULL)) {
- int okFacet = 0, hasFacet = 0;
- unsigned long expLen;
- xmlSchemaFacetPtr facet;
- xmlSchemaFacetLinkPtr facetLink;
- xmlChar *collapsedValue = NULL;
-
- /*
- * The value of ·whiteSpace· is fixed to the value collapse.
- */
- collapsedValue = xmlSchemaCollapseString((const xmlChar *) value);
- if (collapsedValue != NULL)
- value = (const xmlChar *) collapsedValue;
- facetLink = type->facetSet;
- do {
- facet = facetLink->facet;
- /*
- * List types need a special facet treatment.
- * Skip whiteSpace, since it is fixed to "collapse".
- */
- if ((facet->type != XML_SCHEMA_FACET_WHITESPACE) &&
- (facet->type != XML_SCHEMA_FACET_PATTERN)) {
- ret = xmlSchemaValidateListSimpleTypeFacet(facet, value,
- len, &expLen);
- if (facet->type == XML_SCHEMA_FACET_ENUMERATION) {
- hasFacet = 1;
- if (ret == 0)
- okFacet = 1;
- } else if ((ret > 0) && (fireErrors)) {
- char l[25], fl[25];
- /* FIXME: What is the max expected string length of the
- * length value?
- */
- snprintf(l, 24, "%d", len);
- snprintf(fl, 24, "%lu", expLen);
- if (ret == XML_SCHEMAV_CVC_LENGTH_VALID) {
- xmlSchemaVErr(ctxt, ctxt->cur, ret,
- "The value with length \"%s\" is not "
- "facet-valid with respect to length = \"%s\".\n",
- (const xmlChar *)l, (const xmlChar *)fl);
- } else if (ret == XML_SCHEMAV_CVC_MINLENGTH_VALID) {
- xmlSchemaVErr(ctxt, ctxt->cur, ret,
- "The value with length \"%s\" is not "
- "facet-valid with respect to minLength = \"%s\".\n",
- (const xmlChar *)l, (const xmlChar *)fl);
- } else if (ret == XML_SCHEMAV_CVC_MAXLENGTH_VALID) {
- xmlSchemaVErr(ctxt, ctxt->cur, ret,
- "The value with length \"%s\" is not "
- "facet-valid with respect to maxLength = \"%s\".\n",
- (const xmlChar *)l, (const xmlChar *)fl);
- } else {
- xmlSchemaVErr(ctxt, ctxt->cur, ret,
- "The value is not valid with respect "
- "to the facet \"%s\".\n",
- (const xmlChar *)
- xmlSchemaFacetTypeToString(facet->type),
- NULL);
- }
- } else if (ret < 0) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating facets of list simple type \"%s\"\n",
- type->name, NULL);
- break;
- }
- }
- facetLink = facetLink->next;
- } while (facetLink != NULL);
- if (ret >= 0) {
- if ((hasFacet) && (okFacet == 0)) {
- ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
- if (fireErrors) {
- /*
- * TODO: Try to create a report that outputs all the enumeration
- * values in use.
- */
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_CVC_ENUMERATION_VALID,
- "The value is not valid with respect "
- "to the \"enumeration\" facet(s).\n",
- NULL, NULL);
- }
-
- }
+ } else if ((ret == 0) && (applyFacets)) {
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ value, len, fireErrors);
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating facets of list simple type '%s'\n",
+ type->name, NULL);
+ } else if (ret > 0) {
+ ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
/*
- * Pattern facets are ORed at type level and ANDed
- * if derived. Walk the base axis.
+ Disabled, since the facet validation already reports errors.
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
*/
- hasFacet = 0;
- tmpType = type;
- do {
- okFacet = 0;
- for (facetLink = tmpType->facetSet; facetLink != NULL;
- facetLink = facetLink->next) {
- if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
- continue;
- okFacet = xmlSchemaValidateListSimpleTypeFacet(
- facetLink->facet, value, len, &expLen);
- if (okFacet <= 0)
- break;
- }
- if (okFacet != 0)
- break;
- tmpType = tmpType->baseType;
- } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
- if (okFacet < 0) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating \"pattern\" facets of type \"%s\"\n",
- type->name, NULL);
- } else if (okFacet > 0) {
- ret = XML_SCHEMAV_CVC_PATTERN_VALID;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_CVC_ENUMERATION_VALID,
- "The value is not valid with respect "
- "to the \"pattern\" facet(s) of type "
- "\"%s\".\n",
- tmpType->name, NULL);
- }
- }
- }
-
- if (collapsedValue != NULL)
- xmlFree(collapsedValue);
+ }
+
}
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
xmlSchemaTypeLinkPtr memberLink;
@@ -9945,69 +11712,85 @@
* literal in the ·lexical space· of at least one member of
* {member type definitions}
*/
+#ifdef DEBUG_UNION_VALIDATION
+ printf("Union ST : '%s'\n", (const char *) type->name);
+ printf(" fireErrors : %d\n", fireErrors);
+ printf(" applyFacets: %d\n", applyFacets);
+#endif
memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
if (memberLink == NULL) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "union simple type \"%s\" has no member types\n",
+ "union simple type '%s' has no member types\n",
type->name, NULL);
ret = -1;
}
if (ret == 0) {
while (memberLink != NULL) {
ctxt->type = memberLink->type;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 1);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 1, 1);
if ((ret <= 0) || (ret == 0))
break;
memberLink = memberLink->next;
}
- if (ret > 0) {
- ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3,
- "The value is not valid.\n",
- NULL, NULL);
- }
- } else if (ret < 0) {
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating members of union simple type \"%s\"\n",
- type->name, NULL);
- }
- }
- /*
- * Apply facets (pattern, enumeration).
- */
- if ((ret == 0) && (applyFacets) &&
- (type->facetSet != NULL)) {
- xmlSchemaTypePtr anySimpleType;
- /*
- * Check facets. Be sure to pass the built-in type (the
- * simple ur-type in this case) to xmlSchemaValidateFacetsInternal.
- */
- anySimpleType = type->baseType;
- while (anySimpleType->type != XML_SCHEMA_TYPE_BASIC)
- anySimpleType = anySimpleType->baseType;
- ret = xmlSchemaValidateFacetsInternal(ctxt, anySimpleType,
- type->facetSet, value, fireErrors);
+ ctxt->type = type;
if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating facets of union simple type \"%s\"\n",
+ "validating members of union simple type '%s'\n",
type->name, NULL);
} else if (ret > 0) {
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
- if (fireErrors) {
- xmlSchemaVErr(ctxt, ctxt->cur,
- XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
- "The value is not valid.\n",
- NULL, NULL);
- }
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
+ }
+ }
+ /*
+ * Apply facets (pattern, enumeration).
+ */
+ if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) {
+ int mws;
+ /*
+ * The normalization behavior of ·union· types is controlled by
+ * the value of whiteSpace on that one of the ·memberTypes·
+ * against which the ·union· is successfully validated.
+ */
+ if (normValue != NULL) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "the value was already normalized for the union simple "
+ "type '%s'.\n", type->name, NULL);
+ }
+ mws = xmlSchemaGetWhiteSpaceFacetValue(memberLink->type);
+ if (mws > ctxt->valueWS) {
+ if (mws == XML_SCHEMAS_VAL_WTSP_COLLAPSE)
+ normValue = xmlSchemaCollapseString(value);
+ else
+ normValue = xmlSchemaWhiteSpaceReplace(value);
+ if (normValue != NULL)
+ value = (const xmlChar *) normValue;
+ }
+
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ value, 0, fireErrors);
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating facets of union simple type '%s'\n",
+ type->name, NULL);
+ } else if (ret > 0) {
+ ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
+ /*
+ if (fireErrors)
+ xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type);
+ */
}
}
- }
+ }
ctxt->type = type;
+ ctxt->valueWS = wtsp;
+ if (normValue != NULL)
+ xmlFree(normValue);
return (ret);
}
@@ -10055,7 +11838,7 @@
* information item [children].
*/
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_TYPE_3_1_2,
- "Element \"%s\" must have no element children.\n",
+ "Element '%s' must have no element children.\n",
node->name, NULL);
return (-1);
}
@@ -10073,7 +11856,7 @@
(attr->name, BAD_CAST "noNamespaceSchemaLocation")))) {
xmlSchemaVErr(ctxt, node,
XML_SCHEMAV_CVC_TYPE_3_1_1,
- "The attributes of element \"%s\" must be empty, excepting "
+ "The attributes of element '%s' must be empty, excepting "
"those whose namespace name is identical to "
"http://www.w3.org/2001/XMLSchema-instance and whose local "
"name is one of type, nil, schemaLocation or "
@@ -10084,7 +11867,7 @@
attr = attr->next;
}
value = xmlNodeGetContent(child);
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1);
if (value != NULL)
xmlFree(value);
@@ -10107,7 +11890,6 @@
xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
xmlNodePtr child;
- xmlSchemaTypePtr type;
xmlRegExecCtxtPtr oldregexp; /* cont model of the parent */
xmlSchemaElementPtr decl;
int ret;
@@ -10126,19 +11908,19 @@
oldregexp = ctxt->regexp;
child = ctxt->node;
- type = ctxt->type;
+ decl = (xmlSchemaElementPtr) ctxt->type;
- if ((ctxt == NULL) || (type == NULL)) {
+ if ((ctxt == NULL) || (decl == NULL)) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateElementType\n",
node->name, NULL);
return (-1);
}
if (child == NULL) {
- if (type->minOccurs > 0) {
+ if (decl->minOccurs > 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
"Element %s: missing child %s\n",
- node->name, type->name);
+ node->name, decl->name);
}
return (ctxt->err);
}
@@ -10146,27 +11928,37 @@
/*
* Verify the element matches
*/
- if (!xmlStrEqual(child->name, type->name)) {
+ if (!xmlStrEqual(child->name, decl->name)) {
xmlSchemaVErr3(ctxt, node, XML_SCHEMAS_ERR_WRONGELEM,
"Element %s: missing child %s found %s\n",
- node->name, type->name, child->name);
+ node->name, decl->name, child->name);
return (ctxt->err);
}
/*
* Verify the attributes
*/
-
+ /*
+ * TODO: This "attrTop" thing is not needed any more.
+ */
attrs = ctxt->attr;
- attrTop = ctxt->attrTop;
-
- xmlSchemaRegisterAttributes(ctxt, child->properties);
+ attrTop = ctxt->attrTop;
+ xmlSchemaRegisterAttributes(ctxt, child->properties);
+ xmlSchemaValidateAttributes(ctxt, child, decl->subtypes);
+ if (ctxt->attr != NULL)
+ xmlSchemaFreeAttributeStates(ctxt->attr);
+ ctxt->attr = attrs;
+ ctxt->attrTop = attrTop;
/*
* Verify the element content recursively
- */
- decl = (xmlSchemaElementPtr) type;
+ */
oldregexp = ctxt->regexp;
- if (decl->contModel != NULL) {
+ /*
+ * FIXME TODO: This one creates a regexp even if no content
+ * model was defined. Somehow ->contModel is always not NULL
+ * for complex types, even if they are empty.
+ */
+ if (decl->contModel != NULL) {
ctxt->regexp = xmlRegNewExecCtxt(decl->contModel,
(xmlRegExecCallbacks)
xmlSchemaValidateCallback, ctxt);
@@ -10174,8 +11966,7 @@
xmlGenericError(xmlGenericErrorContext, "====> %s\n", node->name);
#endif
}
- xmlSchemaValidateType(ctxt, child, (xmlSchemaElementPtr) type,
- type->subtypes);
+ xmlSchemaValidateType(ctxt, child, decl, decl->subtypes);
if (decl->contModel != NULL) {
ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
@@ -10184,13 +11975,11 @@
"====> %s : %d\n", node->name, ret);
#endif
if (ret == 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT,
- "Element %s content check failed\n",
- node->name, NULL);
+ xmlSchemaVCustomErr(ctxt, XML_SCHEMAS_ERR_ELEMCONT,
+ node, "The element content is not valid", NULL);
} else if (ret < 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT,
- "Element %s content check failure\n",
- node->name, NULL);
+ xmlSchemaVCustomErr(ctxt, XML_SCHEMAS_ERR_ELEMCONT,
+ node, "The element content is not valid", NULL);
#ifdef DEBUG_CONTENT
} else {
xmlGenericError(xmlGenericErrorContext,
@@ -10201,17 +11990,9 @@
}
xmlRegFreeExecCtxt(ctxt->regexp);
}
- /*
- * Verify that all attributes were Schemas-validated
- */
- xmlSchemaCheckAttributes(ctxt, node);
- if (ctxt->attr != NULL)
- xmlSchemaFreeAttributeStates(ctxt->attr);
- ctxt->attr = attrs;
- ctxt->attrTop = attrTop;
ctxt->regexp = oldregexp;
ctxt->node = child;
- ctxt->type = type;
+ ctxt->type = (xmlSchemaTypePtr) decl;
return (ctxt->err);
}
@@ -10316,6 +12097,90 @@
#endif
/**
+ * xmlSchemaValidateAnyInternal:
+ * @ctxt: a schema validation context
+ * @node: the top node.
+ *
+ * Represents the recursive portion of xmlSchemaValidateAny. Not
+ * intended to be used by other functions.
+ *
+ * Returns 0 if the element is valid, a positive error code
+ * number otherwise and -1 in case of an internal error.
+ */
+static int
+xmlSchemaValidateAnyInternal(xmlSchemaValidCtxtPtr ctxt,
+ xmlSchemaWildcardPtr wild,
+ xmlNodePtr node)
+{
+ const xmlChar *uri;
+ int ret = 0;
+ xmlNodePtr child;
+
+ if (wild->processContents != XML_SCHEMAS_ANY_SKIP) {
+ xmlSchemaElementPtr decl = NULL;
+
+ if (node->ns != NULL)
+ decl = xmlHashLookup3(ctxt->schema->elemDecl,
+ node->name, node->ns->href, NULL);
+ else
+ decl = xmlHashLookup3(ctxt->schema->elemDecl, node->name, NULL, NULL);
+ if (decl != NULL) {
+ ctxt->node = node;
+ ctxt->type = (xmlSchemaTypePtr) decl;
+ ret = xmlSchemaValidateElementType(ctxt, node->parent);
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateAnyInternal, "
+ "validating an element in the context of a wildcard.",
+ NULL, NULL);
+ } else if (ret > 0)
+ return (ret);
+ } else if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
+ /* TODO: Change to proper error code. */
+ xmlSchemaVWildcardErr(ctxt, XML_SCHEMAS_ERR_UNDECLAREDELEM,
+ node, wild, "No matching element declaration found.");
+ return (ctxt->err);
+ }
+ }
+ if (node->children != NULL) {
+ child = node->children;
+ do {
+ if (child->type == XML_ELEMENT_NODE) {
+ if (child->ns != NULL)
+ uri = child->ns->href;
+ else
+ uri = NULL;
+ if (xmlSchemaMatchesWildcardNs(wild, uri) == 0) {
+ xmlSchemaVWildcardErr(ctxt, XML_SCHEMAS_ERR_ELEMCONT,
+ child, wild,
+ "The namespace of the element is not allowed.");
+ return (ctxt->err);
+ }
+ ret = xmlSchemaValidateAnyInternal(ctxt, wild, child);
+ if (ret != 0)
+ return (ret);
+ }
+ child = child->next;
+ } while (child != NULL);
+ }
+ return (0);
+}
+
+/**
+ * xmlSchemaValidateAny:
+ * @ctxt: a schema validation context
+ *
+ * Returns 0 if the element is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaValidateAny(xmlSchemaValidCtxtPtr ctxt)
+{
+ return(xmlSchemaValidateAnyInternal(ctxt,
+ ctxt->type->attributeWildcard, ctxt->cur));
+}
+
+/**
* xmlSchemaValidateComplexType:
* @ctxt: a schema validation context
* @node: the top node.
@@ -10341,6 +12206,7 @@
xmlNodePtr child;
xmlSchemaTypePtr type;
int ret = 0;
+ const xmlChar *nsUri;
child = ctxt->node;
type = ctxt->type;
@@ -10383,9 +12249,13 @@
case XML_SCHEMA_CONTENT_MIXED:
while (child != NULL) {
if (child->type == XML_ELEMENT_NODE) {
- ret = xmlRegExecPushString(ctxt->regexp,
- child->name, child);
-#ifdef DEBUG_AUTOMATA
+ if (child->ns != NULL)
+ nsUri = child->ns->href;
+ else
+ nsUri = NULL;
+ ret = xmlRegExecPushString2(ctxt->regexp,
+ child->name, nsUri, child);
+#ifdef DEBUG_AUTOMATA
if (ret < 0)
xmlGenericError(xmlGenericErrorContext,
" --> %s Error\n", child->name);
@@ -10443,8 +12313,8 @@
(base->type != XML_SCHEMA_TYPE_BASIC)))) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateComplexType, "
- "Element \"%s\": the base type of the corresponding "
- "complex type \"%s\" is not a user derived or a "
+ "Element '%s': The base type of the corresponding "
+ "complex type '%s' is not a user derived or a "
"built-in simple type.\n",
node->name, type->name);
return (-1);
@@ -10478,7 +12348,7 @@
else
value = xmlNodeGetContent(node);
ctxt->type = base;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1);
ctxt->type = type;
if (ret > 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
@@ -10489,8 +12359,8 @@
} else if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateComplexType, "
- "Element \"%s\": error while validating character "
- "content against complex type \"%s\".\n",
+ "Element '%s': Error while validating character "
+ "content against complex type '%s'.\n",
node->name, type->name);
return (-1);
}
@@ -10504,20 +12374,9 @@
* are used, or if the facets, defined by this complex type,
* are to be used only. This here applies both facet sets.
*/
- while (base->type != XML_SCHEMA_TYPE_BASIC)
- base = base->baseType;
- if (base == NULL) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateComplexType, "
- "Element \"%s\": error while validating character "
- "content against complex type \"%s\"; failed to "
- "compute the built-in simple type for facet "
- "validation.\n",
- node->name, type->name);
- return (-1);
- }
- ret = xmlSchemaValidateFacetsInternal(ctxt, base,
- type->facetSet, value, 1);
+
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ value, 0, 1);
if (ret > 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
"The character value "
@@ -10527,8 +12386,8 @@
} else if (ret < 0) {
xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: xmlSchemaValidateComplexType, "
- "Element \"%s\": error while validating character "
- "content against complex type \"%s\"; failed to "
+ "Element '%s': Error while validating character "
+ "content against complex type '%s'; failed to "
"apply facets.\n",
type->name, NULL);
}
@@ -10538,34 +12397,11 @@
/* TODO: facets */
break;
}
- /*
- case XML_SCHEMA_CONTENT_SIMPLE:{
- if (type->subtypes != NULL) {
- ctxt->type = type->subtypes;
- xmlSchemaValidateComplexType(ctxt, node);
- }
- if (type->baseType != NULL) {
- ctxt->type = type->baseType;
- xmlSchemaValidateComplexType(ctxt, node);
- }
- * Removed due to changes of attribute validation:
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node,
- type->attributes);
- }
- *
- ctxt->type = type;
- break;
- }
- */
default:
TODO xmlGenericError(xmlGenericErrorContext,
"unimplemented content type %d\n",
type->contentType);
}
- if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
- xmlSchemaValidateAttributes(ctxt, node, type);
- }
ctxt->cur = node;
return (ctxt->err);
}
@@ -10584,20 +12420,16 @@
static int
xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
- xmlNodePtr child;
xmlSchemaTypePtr type;
- child = ctxt->node;
type = ctxt->type;
ctxt->cur = node;
- ctxt->cur = node;
-
switch (type->type) {
case XML_SCHEMA_TYPE_ANY:
- /* Any type will do it, fine */
- TODO /* handle recursivity */
- break;
+ xmlSchemaValidateAny(ctxt);
+ ctxt->type = type;
+ break;
case XML_SCHEMA_TYPE_COMPLEX:
xmlSchemaValidateComplexType(ctxt, node);
break;
@@ -10777,6 +12609,15 @@
*
* Validate the attributes of an element.
*
+ * 1. Existent, invalid attributes are reported in the form
+ * "prefix:localName".
+ * Reason: readability - it is easier to find the actual XML
+ * representation of the attributes QName.
+ * 2. Missing attributes are reported in the form
+ * {"URI", "localName"}.
+ * This is necessary, since the the prefix need not to be declared
+ * at all, and thus is not computable.
+ *
* Returns 0 if the element is schemas valid, a positive error code
* number otherwise and -1 in case of internal or API error.
*/
@@ -10794,19 +12635,17 @@
#ifdef DEBUG_ATTR_VALIDATION
int redundant = 0;
#endif
- if (type->type != XML_SCHEMA_TYPE_COMPLEX) {
- xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateAttributes: "
- "given type \"%s\"is not a complexType\n",
- type->name, NULL);
- return(-1);
- }
- if ((type->attributeUses == NULL) && (type->attributeWildcard == NULL))
- return (0);
-
+ /*
+ * NOTE: This one uses attr->subtypes to get the type decl. - regardless
+ * if we have an attribute reference or an attribute declaration.
+ */
+ /*
+ * Allow all attributes if the type is anyType.
+ */
+ if (type == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE))
+ return (0);
attrUse = type->attributeUses;
-
while (attrUse != NULL) {
found = 0;
attrDecl = attrUse->attr;
@@ -10879,19 +12718,14 @@
if (attrDecl->subtypes == NULL) {
curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED;
curState->decl = attrDecl;
- /*
- * This could be put into "xmlSchemaCheckAttributes" as well, but
- * since it reports an internal error, it better stays here to ease
- * debugging.
- */
xmlSchemaVErr(ctxt, (xmlNodePtr) attr, XML_SCHEMAS_ERR_INTERNAL,
"Internal error: attribute %s type not resolved\n",
attr->name, NULL);
continue;
}
value = xmlNodeListGetString(elem->doc, attr->children, 1);
- ctxt->type = attrDecl->subtypes;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 1);
+ ctxt->type = attrDecl->subtypes;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1);
ctxt->type = type;
if (ret != 0)
curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
@@ -10942,7 +12776,7 @@
ctxt->attrTop->next = reqAttrStates;
}
ctxt->attrTop = reqAttrStatesTop;
- }
+ }
/*
* Process wildcards.
*/
@@ -11003,8 +12837,10 @@
attr->name, nsURI);
if (attrDecl != NULL) {
value = xmlNodeListGetString(elem->doc, attr->children, 1);
+ ctxt->cur = (xmlNodePtr) attr;
+ ctxt->node = attr->children;
ctxt->type = attrDecl->subtypes;
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1);
ctxt->type = type;
if (ret != 0)
curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
@@ -11026,6 +12862,24 @@
curState = curState->next;
}
}
+ /*
+ * Report missing and illegal attributes.
+ */
+ if (ctxt->attr != NULL) {
+ curState = ctxt->attr;
+ while ((curState != NULL) && (curState != ctxt->attrTop->next)) {
+ if (curState->state != XML_SCHEMAS_ATTR_CHECKED) {
+ attr = curState->attr;
+ if (curState->state == XML_SCHEMAS_ATTR_MISSING)
+ xmlSchemaVMissingAttrErr(ctxt, elem, curState->decl);
+ else if ((curState->state == XML_SCHEMAS_ATTR_UNKNOWN) ||
+ /* TODO: "prohibited" won't ever be touched!. */
+ (curState->state == XML_SCHEMAS_ATTR_PROHIBITED))
+ xmlSchemaVIllegalAttrErr(ctxt, attr);
+ }
+ curState = curState->next;
+ }
+ }
#ifdef DEBUG_ATTR_VALIDATION
if (redundant)
xmlGenericError(xmlGenericErrorContext,
@@ -11059,7 +12913,10 @@
elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
elem->name, NULL, NULL);
}
- /* This one is called by xmlSchemaValidateDocument only. */
+ /*
+ * This one is called by xmlSchemaValidateDocument and
+ * xmlSchemaValidateAnyInernal.
+ */
/*
* 3.3.4 : 1
@@ -11080,6 +12937,11 @@
attrs = ctxt->attr;
attrTop = ctxt->attrTop;
xmlSchemaRegisterAttributes(ctxt, elem->properties);
+ xmlSchemaValidateAttributes(ctxt, elem, elemDecl->subtypes);
+ if (ctxt->attr != NULL)
+ xmlSchemaFreeAttributeStates(ctxt->attr);
+ ctxt->attr = attrs;
+ ctxt->attrTop = attrTop;
/*
* Verify the element content recursively
*/
@@ -11098,16 +12960,14 @@
xmlGenericError(xmlGenericErrorContext,
"====> %s : %d\n", elem->name, ret);
#endif
- if (ret == 0) {
- xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT,
- "Element %s content check failed\n",
- elem->name, NULL);
+ if (ret == 0) {
+ xmlSchemaVCustomErr(ctxt, XML_SCHEMAS_ERR_ELEMCONT,
+ elem, "The element content is not valid", NULL);
} else if (ret < 0) {
- xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT,
- "Element %s content check failed\n",
- elem->name, NULL);
+ xmlSchemaVCustomErr(ctxt, XML_SCHEMAS_ERR_ELEMCONT,
+ elem, "The element content is not valid", NULL);
#ifdef DEBUG_CONTENT
- } else {
+ else {
xmlGenericError(xmlGenericErrorContext,
"Element %s content check succeeded\n",
elem->name);
@@ -11116,15 +12976,6 @@
}
xmlRegFreeExecCtxt(ctxt->regexp);
}
- /*
- * Verify that all attributes were Schemas-validated
- */
- xmlSchemaCheckAttributes(ctxt, elem);
- if (ctxt->attr != NULL)
- xmlSchemaFreeAttributeStates(ctxt->attr);
- ctxt->attr = attrs;
- ctxt->attrTop = attrTop;
-
return (ctxt->err);
}
@@ -11218,29 +13069,9 @@
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaValidCtxt));
- ret->schema = schema;
- /*
- * Removed due to changes of the attribute state list.
- */
- /* ret->attrNr = 0; */
- /* ret->attrMax = 10; */
- /* ret->attrBase = NULL; */
+ ret->schema = schema;
ret->attrTop = NULL;
ret->attr = NULL;
- /*
- * Removed due to changes of the attribute state list.
- *
- ret->attr = (xmlSchemaAttrStatePtr) xmlMalloc(ret->attrMax *
- sizeof
- (xmlSchemaAttrState));
- if (ret->attr == NULL) {
- xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
- free(ret);
- return (NULL);
- }
- memset(ret->attr, 0, ret->attrMax * sizeof(xmlSchemaAttrState));
- */
-
return (ret);
}