applied Schemas patches from Kasimier Buchcik, there is still one open
* xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h
include/libxml/schemasInternals.h include/libxml/xmlschemastypes.h:
applied Schemas patches from Kasimier Buchcik, there is still
one open issue about referencing freed memory.
* test/schemas/* result/schemas/*: updated with new tests from
Kasimier
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index 30dba1f..7f1b519 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -12,6 +12,9 @@
* - when types are redefined in includes, check that all
* types in the redef list are equal
* -> need a type equality operation.
+ * - if we don't intend to use the schema for schemas, we
+ * need to validate all schema attributes (ref, type, name)
+ * against their types.
*/
#define IN_LIBXML
#include "libxml.h"
@@ -102,6 +105,8 @@
xmlDictPtr dict; /* dictionnary for interned string names */
int includes; /* the inclusion level, 0 for root or imports */
+ xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
+ xmlSchemaTypePtr parentItem; /* The current parent schema item */
};
@@ -184,18 +189,32 @@
* 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);
+static const char *
+xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
+static int
+xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
+ const xmlChar *value,
+ int fireErrors,
+ int applyFacets);
/************************************************************************
* *
@@ -274,7 +293,7 @@
xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
}
-#if 0
+
/**
* xmlSchemaPErrExt:
* @ctxt: the parsing context
@@ -316,7 +335,7 @@
(const char *) strData3, 0, 0, msg, str1, str2,
str3, str4, str5);
}
-#endif
+
/**
* xmlSchemaVTypeErrMemory:
@@ -579,7 +598,7 @@
* xmlSchemaFreeWildcardNsSet:
* set: a schema wildcard namespace
*
- * Deallocate a list of wildcard constraint structures.
+ * Deallocates a list of wildcard constraint structures.
*/
static void
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
@@ -595,11 +614,11 @@
/**
* xmlSchemaFreeWildcard:
- * @schema: a schema attribute group structure
+ * @wildcard: a wildcard structure
*
- * Deallocate a Schema Attribute Group structure.
+ * Deallocates a wildcard structure.
*/
-static void
+void
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
{
if (wildcard == NULL)
@@ -635,7 +654,7 @@
/**
* xmlSchemaFreeAttributeUseList:
- * @attrUse: a schema attribute link structure
+ * @attrUse: an attribute link
*
* Deallocate a list of schema attribute uses.
*/
@@ -652,6 +671,24 @@
}
/**
+ * xmlSchemaFreeTypeLinkList:
+ * @alink: a type link
+ *
+ * Deallocate a list of types.
+ */
+static void
+xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
+{
+ xmlSchemaTypeLinkPtr next;
+
+ while (link != NULL) {
+ next = link->next;
+ xmlFree(link);
+ link = next;
+ }
+}
+
+/**
* xmlSchemaFreeElement:
* @schema: a schema element structure
*
@@ -715,6 +752,7 @@
if (type->type != XML_SCHEMA_TYPE_BASIC) {
if (type->attributeUses != NULL)
xmlSchemaFreeAttributeUseList(type->attributeUses);
+ /* TODO: There must be a way more simple than this. */
if ((type->attributeWildcard != NULL) &&
((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
@@ -722,6 +760,29 @@
xmlSchemaFreeWildcard(type->attributeWildcard);
}
}
+ if (type->memberTypes != NULL)
+ xmlSchemaFreeTypeLinkList(type->memberTypes);
+ if (type->facetSet != NULL) {
+ xmlSchemaFacetLinkPtr next, link;
+
+ link = type->facetSet;
+ do {
+ next = link->next;
+ xmlFree(link);
+ link = next;
+ } while (link != NULL);
+ }
+
+ if ((type->subtypes != NULL) && (type->type != XML_SCHEMA_TYPE_SEQUENCE)) {
+ switch (type->subtypes->type) {
+ case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
+ case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
+ case XML_SCHEMA_TYPE_RESTRICTION:
+ case XML_SCHEMA_TYPE_EXTENSION:
+ case XML_SCHEMA_TYPE_UNION:
+ xmlSchemaFreeType(type->subtypes);
+ }
+ }
xmlFree(type);
}
@@ -951,9 +1012,12 @@
case XML_SCHEMA_CONTENT_MIXED:
fprintf(output, "mixed ");
break;
+ /* Removed, since not used. */
+ /*
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
fprintf(output, "mixed_or_elems ");
break;
+ */
case XML_SCHEMA_CONTENT_BASIC:
fprintf(output, "basic ");
break;
@@ -1031,6 +1095,36 @@
* *
************************************************************************/
+xmlAttrPtr
+xmlSchemaGetPropNode(xmlNodePtr node, const xmlChar *name)
+{
+ xmlAttrPtr prop;
+
+ if ((node == NULL) || (name == NULL)) return(NULL);
+ prop = node->properties;
+ while (prop != NULL) {
+ if ((xmlStrEqual(prop->name, name)) &&
+ (prop->ns == NULL))
+ return(prop);
+ prop = prop->next;
+ }
+ return (NULL);
+}
+
+static const xmlChar *
+xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
+{
+ xmlChar *val;
+ const xmlChar *ret;
+
+ val = xmlNodeGetContent(node);
+ if (val == NULL)
+ return(NULL);
+ ret = xmlDictLookup(ctxt->dict, val, -1);
+ xmlFree(val);
+ return(ret);
+}
+
/**
* xmlSchemaGetProp:
* @ctxt: the parser context
@@ -1648,12 +1742,12 @@
/**
* xmlSchemaAddType:
- * @ctxt: a schema validation context
+ * @ctxt: a schema parser context
* @schema: the schema being built
* @name: the item name
* @namespace: the namespace
*
- * Add an XML schema Simple Type definition
+ * Add an XML schema item
* *WARNING* this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
@@ -1721,6 +1815,174 @@
}
/**
+ * xmlSchemaNewItemInternal:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the restriction
+ *
+ * Createa an schema item
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewItemInternal(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret = NULL;
+
+ if ((ctxt == NULL) || (name == NULL))
+ return (NULL);
+
+#ifdef DEBUG
+ fprintf(stderr, "Creating item %s\n", name);
+#endif
+ ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating item", NULL);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaType));
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
+ ret->minOccurs = 1;
+ ret->maxOccurs = 1;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewRestriction:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the restriction
+ *
+ * Create a <restriction> item
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewRestriction(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_RESTRICTION;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewExtension:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the extension
+ *
+ * Create an <extension> item
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewExtension(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_EXTENSION;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewSimpleContent:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the simpleContent
+ *
+ * Create a <simpleContent> item
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewSimpleContent(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewComplexContent:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the complexContent
+ *
+ * Create a <complexContent> item
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewComplexContent(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewUnion:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the union
+ *
+ * Create an <union> item
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewUnion(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_UNION;
+
+ return (ret);
+}
+
+/**
+ * xmlSchemaNewList:
+ * @ctxt: the schema parser context
+ * @name: the internal name of the union
+ *
+ * Create an <union> item
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new structure or NULL in case of an error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaNewList(xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name)
+{
+ xmlSchemaTypePtr ret;
+
+ ret = xmlSchemaNewItemInternal(ctxt, name);
+ if (ret != NULL)
+ ret->type = XML_SCHEMA_TYPE_LIST;
+
+ return (ret);
+}
+
+/**
* xmlSchemaAddGroup:
* @ctxt: a schema validation context
* @schema: the schema being built
@@ -1872,7 +2134,7 @@
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",
+ "Attribute \"%s\": the QName prefix \"%s\" is undefined\n",
(const xmlChar *) name, prefix);
} else {
*namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
@@ -2035,6 +2297,101 @@
xmlSchemaPtr schema, xmlNodePtr node);
/**
+ * xmlSchemaParseSchemaAttrValue:
+ *
+ * @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
+ *
+ * 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
+xmlSchemaParseSchemaAttrValue(xmlSchemaParserCtxtPtr ctxt,
+ xmlAttrPtr attr,
+ xmlSchemaTypePtr type)
+{
+ const xmlChar *value;
+ int ret;
+
+ if ((ctxt == NULL) || (type == NULL) || (attr == 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 *uri = 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);
+ }
+ break;
+ default: {
+ xmlSchemaPErr(ctxt, (xmlNodePtr) attr,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaParseSchemaAttrValue, validation "
+ "using this type in not implemented yet\"%s\".\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);
+ }
+ }
+ }
+ return (ret);
+}
+
+/**
* xmlSchemaParseAttrDecls:
* @ctxt: a schema validation context
* @schema: the schema being built
@@ -2182,6 +2539,17 @@
}
facet->id = xmlSchemaGetProp(ctxt, node, "id");
facet->value = value;
+ if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
+ (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
+ const xmlChar *fixed;
+
+ fixed = xmlSchemaGetProp(ctxt, node, "fixed");
+ if (fixed != NULL) {
+ if (xmlStrEqual(fixed, BAD_CAST "true"))
+ facet->fixed = 1;
+ }
+ }
+
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -2318,18 +2686,18 @@
processContents = xmlSchemaGetProp(ctxt, node, "processContents");
if ((processContents == NULL)
|| (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
- ret->processContents = XML_SCHEMAS_ANYATTR_STRICT;
+ ret->processContents = XML_SCHEMAS_ANY_STRICT;
} else if (xmlStrEqual(processContents, (const xmlChar *) "skip")) {
- ret->processContents = XML_SCHEMAS_ANYATTR_SKIP;
+ ret->processContents = XML_SCHEMAS_ANY_SKIP;
} else if (xmlStrEqual(processContents, (const xmlChar *) "lax")) {
- ret->processContents = XML_SCHEMAS_ANYATTR_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_ANYATTR_STRICT;
+ ret->processContents = XML_SCHEMAS_ANY_STRICT;
}
/*
* Build the namespace constraints.
@@ -2967,13 +3335,12 @@
snprintf((char *) name, 30, "union %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ type = xmlSchemaNewUnion(ctxt, name);
if (type == NULL)
return (NULL);
type->node = node;
- type->type = XML_SCHEMA_TYPE_UNION;
type->id = xmlSchemaGetProp(ctxt, node, "id");
- type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
+ type->base = xmlSchemaGetProp(ctxt, node, "memberTypes");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -3022,6 +3389,7 @@
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
xmlChar name[30];
+ xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -3033,20 +3401,33 @@
type->node = node;
type->type = XML_SCHEMA_TYPE_LIST;
type->id = xmlSchemaGetProp(ctxt, node, "id");
- type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
-
+ /*
+ * Check type of "itemType".
+ */
+ attr = xmlSchemaGetPropNode(node, "itemType");
+ if (attr != NULL) {
+ type->base = xmlGetQNameProp(ctxt, node, "itemType", &(type->baseNs));
+ xmlSchemaParseSchemaAttrValue(ctxt, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME));
+
+ }
subtype = NULL;
- if (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- child = child->next;
- type->subtypes = subtype;
+ if (IS_SCHEMA(child, "simpleType")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ type->subtypes = subtype;
+ /*
+ * This is a hack to save the information that a local
+ * simple type was defined.
+ */
+ type->baseType = subtype;
+ child = child->next;
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_LIST_CHILD,
@@ -3072,23 +3453,38 @@
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- xmlSchemaTypePtr type, subtype;
+ xmlSchemaTypePtr type, subtype, ctxtType;
xmlNodePtr child = NULL;
- const xmlChar *name;
+ const xmlChar *propVal;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
-
- name = xmlSchemaGetProp(ctxt, node, "name");
- if (name == NULL) {
+ ctxtType = ctxt->ctxtType;
+ propVal = xmlSchemaGetProp(ctxt, node, "name");
+ if (propVal == NULL) {
char buf[100];
snprintf(buf, 99, "simpleType %d", ctxt->counter++ + 1);
type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
} else {
- /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
- type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace);
+ 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);
+ return (NULL);
+ }
+ /*
+ * "name" has to be of type NCName.
+ * TODO: Actually this should be validated by the schema for schemas.
+ */
+ 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);
@@ -3097,13 +3493,57 @@
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);
+ }
+ if (item != NULL)
+ xmlFree(item);
+ cur = end;
+ } while (*cur != 0);
+ }
+ }
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;
if (IS_SCHEMA(child, "restriction")) {
subtype = (xmlSchemaTypePtr)
xmlSchemaParseRestriction(ctxt, schema, child, 1);
@@ -3118,19 +3558,23 @@
child = child->next;
}
type->subtypes = subtype;
- if (subtype == NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD,
- "SimpleType %s does not define a variety\n",
- type->name, NULL);
- }
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD,
- "SimpleType %s has unexpected content\n",
+ 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);
+ }
}
+ ctxt->ctxtType = ctxtType;
+
return (type);
}
@@ -3347,8 +3791,6 @@
schemaLocation, NULL);
xmlSchemaFreeParserCtxt(newctxt);
- if (import->schemaLocation != NULL)
- xmlFree((xmlChar *)import->schemaLocation);
xmlFree(import);
return NULL;
}
@@ -3688,6 +4130,8 @@
child = child->next;
}
}
+ ctxt->parentItem = NULL;
+ ctxt->ctxtType = NULL;
}
/**
@@ -3802,7 +4246,7 @@
if (!IS_SCHEMA(root, "schema")) {
xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
XML_SCHEMAP_NOT_SCHEMA,
- "File %s is not a schemas", schemaLocation, NULL);
+ "File %s is not a schema", schemaLocation, NULL);
xmlFreeDoc(doc);
return (-1);
}
@@ -4006,8 +4450,7 @@
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int simple)
{
- xmlSchemaTypePtr type, subtype;
- xmlSchemaFacetPtr facet, lastfacet = NULL;
+ xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
xmlChar name[30];
const xmlChar *oldcontainer;
@@ -4018,17 +4461,18 @@
oldcontainer = ctxt->container;
snprintf((char *) name, 30, "restriction %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ type = xmlSchemaNewRestriction(ctxt, name);
if (type == NULL)
return (NULL);
type->node = node;
- type->type = XML_SCHEMA_TYPE_RESTRICTION;
type->id = xmlSchemaGetProp(ctxt, node, "id");
type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
- if ((!simple) && (type->base == NULL)) {
+ if ((type->base == NULL) &&
+ (ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT)) {
xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
- "Restriction %s has no base\n", type->name, NULL);
+ XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
+ "Restriction \"%s\" must have a \"base\" attribute.\n",
+ type->name, NULL);
}
ctxt->container = name;
@@ -4039,71 +4483,107 @@
}
subtype = NULL;
- if (IS_SCHEMA(child, "all")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "group")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseGroup(ctxt, schema, child, 0);
- child = child->next;
- type->subtypes = subtype;
- } else {
- if (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- child = child->next;
- type->baseType = subtype;
- }
- /*
- * Facets
- */
- while ((IS_SCHEMA(child, "minInclusive")) ||
- (IS_SCHEMA(child, "minExclusive")) ||
- (IS_SCHEMA(child, "maxInclusive")) ||
- (IS_SCHEMA(child, "maxExclusive")) ||
- (IS_SCHEMA(child, "totalDigits")) ||
- (IS_SCHEMA(child, "fractionDigits")) ||
- (IS_SCHEMA(child, "pattern")) ||
- (IS_SCHEMA(child, "enumeration")) ||
- (IS_SCHEMA(child, "whiteSpace")) ||
- (IS_SCHEMA(child, "length")) ||
- (IS_SCHEMA(child, "maxLength")) ||
- (IS_SCHEMA(child, "minLength"))) {
- facet = xmlSchemaParseFacet(ctxt, schema, child);
- if (facet != NULL) {
- if (lastfacet == NULL) {
- type->facets = facet;
- lastfacet = facet;
- } else {
- lastfacet->next = facet;
- lastfacet = facet;
- }
- lastfacet->next = NULL;
- }
- child = child->next;
- }
- }
- /* TODO: a restriction of simpleType does not contain any
- * attribute declarations.
- */
- child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
+ if (ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+ if (IS_SCHEMA(child, "all")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseAll(ctxt, schema, child);
+ child = child->next;
+ type->subtypes = subtype;
+ } else if (IS_SCHEMA(child, "choice")) {
+ subtype = xmlSchemaParseChoice(ctxt, schema, child);
+ child = child->next;
+ type->subtypes = subtype;
+ } else if (IS_SCHEMA(child, "sequence")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseSequence(ctxt, schema, child);
+ child = child->next;
+ type->subtypes = subtype;
+ } else if (IS_SCHEMA(child, "group")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseGroup(ctxt, schema, child, 0);
+ child = child->next;
+ type->subtypes = subtype;
+ }
+ } else if ((ctxt->ctxtType->type == XML_SCHEMA_TYPE_SIMPLE) ||
+ (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
+ xmlSchemaFacetPtr facet, lastfacet = NULL;
+
+ if (IS_SCHEMA(child, "simpleType")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ /*
+ * For the simple type this serves as the base type.
+ */
+ type->baseType = subtype;
+ /*
+ * For the complex type this serves as information for the
+ * definition of the content type.
+ * Additionally this is a hack for the simple type, to save
+ * the information that a local simple type was defined; thus
+ * allowing to check: src-restriction-base-or-simpleType.
+ */
+ type->subtypes = subtype;
+ child = child->next;
+ }
+ /*
+ * Add the facets to the parent simpleType/complexType.
+ */
+ while ((IS_SCHEMA(child, "minInclusive")) ||
+ (IS_SCHEMA(child, "minExclusive")) ||
+ (IS_SCHEMA(child, "maxInclusive")) ||
+ (IS_SCHEMA(child, "maxExclusive")) ||
+ (IS_SCHEMA(child, "totalDigits")) ||
+ (IS_SCHEMA(child, "fractionDigits")) ||
+ (IS_SCHEMA(child, "pattern")) ||
+ (IS_SCHEMA(child, "enumeration")) ||
+ (IS_SCHEMA(child, "whiteSpace")) ||
+ (IS_SCHEMA(child, "length")) ||
+ (IS_SCHEMA(child, "maxLength")) ||
+ (IS_SCHEMA(child, "minLength"))) {
+ facet = xmlSchemaParseFacet(ctxt, schema, child);
+ if (facet != NULL) {
+ if (lastfacet == NULL)
+ ctxt->ctxtType->facets = facet;
+ else
+ lastfacet->next = facet;
+ lastfacet = facet;
+ lastfacet->next = NULL;
+ }
+ child = child->next;
+ }
+ /*
+ * Create links for derivation and validation.
+ */
+ if (lastfacet != NULL) {
+ xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
+
+ facet = ctxt->ctxtType->facets;
+ do {
+ facetLink = (xmlSchemaFacetLinkPtr) xmlMalloc(sizeof(xmlSchemaFacetLink));
+ if (facetLink == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocation a facet link", NULL);
+ xmlFree(facetLink);
+ return (NULL);
+ }
+ facetLink->facet = facet;
+ facetLink->next = NULL;
+ if (lastFacetLink == NULL)
+ ctxt->ctxtType->facetSet = facetLink;
+ else
+ lastFacetLink->next = facetLink;
+ lastFacetLink = facetLink;
+ facet = facet->next;
+ } while (facet != NULL);
+ }
+ }
+ if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX)
+ child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
- "Restriction %s has unexpected content\n",
- type->name, NULL);
- }
+ xmlSchemaPErr2(ctxt, node, child,
+ XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
+ "Restriction \"%s\" has unexpected content.\n",
+ type->name, NULL);
+ }
ctxt->container = oldcontainer;
return (type);
}
@@ -4134,11 +4614,10 @@
oldcontainer = ctxt->container;
snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ type = xmlSchemaNewExtension(ctxt, name);
if (type == NULL)
return (NULL);
type->node = node;
- type->type = XML_SCHEMA_TYPE_EXTENSION;
type->id = xmlSchemaGetProp(ctxt, node, "id");
ctxt->container = name;
@@ -4203,11 +4682,10 @@
return (NULL);
snprintf((char *) name, 30, "simpleContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ type = xmlSchemaNewSimpleContent(ctxt, name);
if (type == NULL)
return (NULL);
type->node = node;
- type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
type->id = xmlSchemaGetProp(ctxt, node, "id");
child = node->children;
@@ -4215,7 +4693,8 @@
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- subtype = NULL;
+ ctxt->parentItem = type;
+ subtype = NULL;
if (IS_SCHEMA(child, "restriction")) {
subtype = (xmlSchemaTypePtr)
xmlSchemaParseRestriction(ctxt, schema, child, 0);
@@ -4257,13 +4736,11 @@
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
-
snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ type = xmlSchemaNewComplexContent(ctxt, name);
if (type == NULL)
return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
+ type->node = node;
type->id = xmlSchemaGetProp(ctxt, node, "id");
child = node->children;
@@ -4271,6 +4748,7 @@
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
+ ctxt->parentItem = type;
subtype = NULL;
if (IS_SCHEMA(child, "restriction")) {
subtype = (xmlSchemaTypePtr)
@@ -4306,7 +4784,7 @@
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- xmlSchemaTypePtr type, subtype;
+ xmlSchemaTypePtr type, subtype, ctxtType;
xmlNodePtr child = NULL;
const xmlChar *name;
const xmlChar *oldcontainer;
@@ -4315,6 +4793,8 @@
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
+ ctxtType = ctxt->ctxtType;
+
oldcontainer = ctxt->container;
name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
@@ -4344,6 +4824,7 @@
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
+ ctxt->ctxtType = type;
if (IS_SCHEMA(child, "simpleContent")) {
/* 3.4.3 : 2.2
* Specifying mixed='true' when the <simpleContent>
@@ -4385,6 +4866,7 @@
if (type->attributeWildcard != NULL)
type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
ctxt->container = oldcontainer;
+ ctxt->ctxtType = ctxtType;
return (type);
}
@@ -4435,7 +4917,10 @@
val, NULL);
}
} else {
- schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
+ /* Removed, since the default value for elementFormDefault
+ * is "unqualified".
+ */
+ /* schema->flags |= XML_SCHEMAS_QUALIF_ELEM; */
}
val = xmlSchemaGetProp(ctxt, node, "attributeFormDefault");
if (val != NULL) {
@@ -4449,6 +4934,51 @@
}
}
+ 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);
+ }
+ }
+
xmlSchemaParseSchemaTopLevel(ctxt, schema, node->children);
} else {
xmlDocPtr doc;
@@ -4632,6 +5162,7 @@
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);
@@ -5102,9 +5633,12 @@
elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs, 0);
if (elemDecl == NULL) {
- xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_REF,
- "Schemas: element %s ref to %s not found\n",
- name, elem->ref);
+ xmlSchemaPErr(ctxt, elem->node,
+ 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;
@@ -5121,9 +5655,11 @@
elem->namedTypeNs);
if (typeDecl == NULL) {
- xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_TYPE,
- "Schemas: element %s type %s not found\n", name,
- elem->namedType);
+ 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;
@@ -5139,29 +5675,38 @@
*/
static void
xmlSchemaParseListRefFixup(xmlSchemaTypePtr type, xmlSchemaParserCtxtPtr ctxt)
-{
- const xmlChar *itemType, *namespace;
- xmlSchemaTypePtr subtype;
-
- /* Handle the "itemType" attribute. */
- itemType = xmlGetQNameProp(ctxt, type->node, "itemType", &namespace);
- if (itemType != NULL) {
- /* Do not allow more that one item type. */
- if (type->subtypes != NULL) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE,
- "List %s has more than one item type defined\n",
- type->name, NULL);
- }
- subtype = xmlSchemaGetType(ctxt->schema, itemType, namespace);
- if (subtype == NULL) {
+{
+ /*
+ * 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.
+ */
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ } 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, xmlSchemaGetProp(ctxt, type->node,
- "itemType"));
- } else
- type->subtypes = subtype;
- }
+ "List \"%s\" references an unknown item type: \"%s\"\n",
+ type->name, type->base);
+ }
+ }
+ if ((type->subtypes != NULL) &&
+ (type->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN))
+ xmlSchemaTypeFixup(type->subtypes, ctxt, NULL);
}
/**
@@ -5169,60 +5714,170 @@
* @typeDecl: the schema type definition
* @ctxt: the schema parser context
*
- * Checks the memberTypes references of the union type.
+ * Checks and builds the memberTypes of the union type.
+ * Returns -1 in case of an internal error, 0 otherwise.
*/
-static void
+static int
xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type,
xmlSchemaParserCtxtPtr ctxt)
{
const xmlChar *cur, *end, *prefix, *ncName, *namespace;
xmlChar *tmp;
- xmlSchemaTypePtr subtype;
+ xmlSchemaTypeLinkPtr link, lastLink = NULL, prevLink, subLink, newLink;
+ xmlSchemaTypePtr memberType, ctxtType;
xmlNsPtr ns;
int len;
- if ((type->type != XML_SCHEMA_TYPE_UNION) || (type->ref == NULL))
- return;
+ /* 1 If the <union> alternative is chosen, then [Definition:]
+ * define the explicit members as the type definitions ·resolved·
+ * to by the items in the ·actual value· of the memberTypes [attribute],
+ * if any, followed by the type definitions corresponding to the
+ * <simpleType>s among the [children] of <union>, if any.
+ */
- 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 = 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);
- }
- /* Lookup the referenced type */
- subtype = xmlSchemaGetType(ctxt->schema, ncName, namespace);
- if (subtype == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
- "Union %s references an unknown member type %s\n",
- type->name, (const xmlChar *) tmp);
- }
- xmlFree(tmp);
- cur = end;
- } while (*cur != 0);
+ if (type->type != XML_SCHEMA_TYPE_UNION)
+ return (-1);
+ if (ctxt->ctxtType == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaParseUnionRefCheck, no parent type "
+ "available", NULL, NULL);
+ return (-1);
+ }
+ /*
+ * src-union-memberTypes-or-simpleTypes
+ * Either the memberTypes [attribute] of the <union> element must
+ * be non-empty or there must be at least one simpleType [child].
+ */
+ 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,
+ 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);
+ }
+
+ ctxtType = ctxt->ctxtType;
+ if (type->base != NULL) {
+ cur = type->base;
+ 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 = 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);
+ 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);
+ } else {
+ if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
+ xmlSchemaTypeFixup(memberType, ctxt, NULL);
+ link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
+ if (link == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
+ return (-1);
+ }
+ link->type = memberType;
+ link->next = NULL;
+ if (lastLink == NULL)
+ ctxtType->memberTypes = link;
+ else
+ lastLink->next = link;
+ lastLink = link;
+ }
+ xmlFree(tmp);
+ cur = end;
+ } while (*cur != 0);
+ }
+ /*
+ * Add local simple types,
+ */
+ memberType = type->subtypes;
+ while (memberType != NULL) {
+ if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
+ xmlSchemaTypeFixup(memberType, ctxt, NULL);
+ link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
+ if (link == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
+ return (-1);
+ }
+ link->type = memberType;
+ link->next = NULL;
+ if (lastLink == NULL)
+ ctxtType->memberTypes = link;
+ else
+ lastLink->next = link;
+ lastLink = link;
+ memberType = memberType->next;
+ }
+ /*
+ * The actual value is then formed by replacing any union type
+ * definition in the ·explicit members· with the members of their
+ * {member type definitions}, in order.
+ */
+ link = ctxtType->memberTypes;
+ while (link != NULL) {
+ if (link->type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ subLink = link->type->memberTypes;
+ if (subLink != NULL) {
+ link->type = subLink->type;
+ if (subLink->next != NULL) {
+ lastLink = link->next;
+ subLink = subLink->next;
+ prevLink = link;
+ while (subLink != NULL) {
+ newLink = (xmlSchemaTypeLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaTypeLink));
+ if (newLink == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating a type link",
+ NULL);
+ return (-1);
+ }
+ newLink->type = memberType;
+ prevLink->next = newLink;
+ prevLink = newLink;
+ newLink->next = lastLink;
+
+ subLink = subLink->next;
+ }
+ }
+ }
+ }
+ link = link->next;
+ }
+
+ return (0);
}
/**
@@ -5282,9 +5937,9 @@
xmlSchemaTypePtr type, int valType)
{
/* TODO: Check if this works in every case. */
- if ((type->type == XML_SCHEMA_TYPE_BASIC) &&
+ if ((type->type == XML_SCHEMA_TYPE_BASIC) &&
(type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
- if (type->flags == valType)
+ if (type->builtInType == valType)
return(1);
} else if (type->type == XML_SCHEMA_TYPE_ATTRIBUTE) {
if (((xmlSchemaAttributePtr) type)->subtypes != NULL)
@@ -5308,6 +5963,26 @@
}
/**
+ * xmlSchemaIsDerivedFromBuiltInType:
+ * @type: the simpleType definition
+ *
+ * Returns the primitive type of the given type or
+ * NULL in case of error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
+{
+ while (type != NULL) {
+ if (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)
+ return (type);
+ type = type->baseType;
+ }
+
+ return (NULL);
+}
+
+
+/**
* xmlSchemaBuildAttributeUsesOwned:
* @ctxt: the schema parser context
* @type: the complex type definition
@@ -6026,8 +6701,10 @@
xmlSchemaAttributeLinkPtr cur, base, tmp, id = NULL, prev = NULL, uses = NULL,
lastUse = NULL, lastBaseUse = NULL;
xmlSchemaAttributePtr attrs;
+ xmlSchemaTypePtr anyType;
int baseIsAnyType = 0;
+ anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
/*
* Complex Type Definition with complex content Schema Component.
*
@@ -6035,29 +6712,37 @@
*/
if (type->attributeUses != NULL) {
xmlSchemaPErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaParseBuildAttributeUses: "
+ "Internal error: xmlSchemaBuildAttributeValidation: "
"attribute uses already builded.\n",
NULL, NULL);
return (-1);
}
+ if (type->baseType == NULL) {
+ xmlSchemaPErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaBuildAttributeValidation: "
+ "complex type \"%s\" has no base type.\n",
+ type->name, NULL);
+ return (-1);
+ }
if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) ||
(type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) {
-
+
+ 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;
/*
* Inherit the attribute uses of the base type.
*/
- baseType = type->subtypes->subtypes->baseType;
/*
- * TODO: URGENT: This is not nice, but currently
- * xmlSchemaTypeAnyTypeDef is static in xmlschematypes.c.
- */
- if ((baseType->type == XML_SCHEMA_TYPE_BASIC) &&
- xmlStrEqual(baseType->name, BAD_CAST "anyType")) {
- baseIsAnyType = 1;
- }
- /*
- * TODO: Does the spec state that it is an error to "extend" the
- * anyType?
+ * NOTE: It is allowed to "extend" the anyType complex type.
*/
if (!baseIsAnyType) {
if (baseType != NULL) {
@@ -6079,26 +6764,45 @@
}
}
}
- attrs = type->subtypes->subtypes->attributes;
+ if ((type->subtypes != NULL) &&
+ ((type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) ||
+ (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT))) {
+ attrs = type->subtypes->subtypes->attributes;
+ type->attributeWildcard = type->subtypes->subtypes->attributeWildcard;
+ } else {
+ /* Short hand form of the complexType. */
+ attrs = type->attributes;
+ }
/*
* Handle attribute wildcards.
*/
- type->attributeWildcard = type->subtypes->subtypes->attributeWildcard;
-
if (xmlSchemaBuildCompleteAttributeWildcard(ctxt,
- attrs, &type->attributeWildcard) == -1) {
+ attrs, &type->attributeWildcard) == -1) {
if ((type->attributeWildcard != NULL) &&
- (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard))
+ /* Either we used the short hand form... */
+ ((type->subtypes == NULL) ||
+ /* Or complexType -> restriction/extension */
+ (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)))
type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
return (-1);
}
+ /*
+ * TODO: This "onwed_attr_wildcard" is quite sensless: we should
+ * create the wildcard right from the start on the complexType,
+ * rather than on the <restriction>/<extension>.
+ */
if ((type->attributeWildcard != NULL) &&
- (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard))
+ /* Either we used the short hand form... */
+ ((type->subtypes == NULL) ||
+ /* Or complexType -> restriction/extension */
+ (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)))
type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) &&
- (baseType != NULL) && (baseType->type == XML_SCHEMA_TYPE_COMPLEX) &&
- (baseType->attributeWildcard != NULL)) {
+ ((baseIsAnyType) ||
+ ((baseType != NULL) &&
+ (baseType->type == XML_SCHEMA_TYPE_COMPLEX) &&
+ (baseType->attributeWildcard != NULL)))) {
if (type->attributeWildcard != NULL) {
/*
* Union the complete wildcard with the base wildcard.
@@ -6113,70 +6817,75 @@
type->attributeWildcard = baseType->attributeWildcard;
}
}
- if (!baseIsAnyType) {
- if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
- if (type->attributeWildcard != NULL) {
- /*
- * 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);
- return (1);
- } else if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
- 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);
- return (1);
- }
- /* 4.3 Unless the {base type definition} is the ·ur-type
- * definition·, the complex type definition's {attribute
- * wildcard}'s {process contents} must be identical to or
- * stronger than the {base type definition}'s {attribute
- * wildcard}'s {process contents}, where strict is stronger
- * than lax is stronger than skip.
- */
- if (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);
- return (1);
- }
- }
- } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) {
- /*
- * Derivation Valid (Extension)
- * At this point the type and the base have both, either
- * no wildcard or a wildcard.
+
+ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
+ if (type->attributeWildcard != NULL) {
+ /*
+ * Derivation Valid (Restriction, Complex)
+ * 4.1 The {base type definition} must also have one.
*/
- if ((baseType->attributeWildcard != NULL) &&
- (baseType->attributeWildcard != type->attributeWildcard)) {
- /* 1.3 */
- if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
- 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);
- return (1);
- }
- }
+ 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);
+ return (1);
+ } else if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
+ 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);
+ return (1);
+ }
+ /* 4.3 Unless the {base type definition} is the ·ur-type
+ * definition·, the complex type definition's {attribute
+ * wildcard}'s {process contents} must be identical to or
+ * stronger than the {base type definition}'s {attribute
+ * wildcard}'s {process contents}, where strict is stronger
+ * than lax is stronger than skip.
+ */
+ 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);
+ return (1);
+ }
}
- }
- } else {
- /*
+ } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) {
+ /*
+ * Derivation Valid (Extension)
+ * At this point the type and the base have both, either
+ * no wildcard or a wildcard.
+ */
+ if ((baseType->attributeWildcard != NULL) &&
+ (baseType->attributeWildcard != type->attributeWildcard)) {
+ /* 1.3 */
+ if (xmlSchemaIsWildcardNsConstraintSubset(ctxt,
+ 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);
+ return (1);
+ }
+ }
+ }
+ }
+ /*
+ * Removed, since anyType was plugged into the derivation hierarchy.
+ */
+ /*
+ else {
+ *
* Although the complexType is implicitely derived by "restriction"
* from the ur-type, this is not (yet?) reflected by libxml2.
- */
+ *
baseType = NULL;
attrs = type->attributes;
if (attrs != NULL) {
@@ -6191,7 +6900,7 @@
((type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD) == 0))
type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
}
- }
+ } */
/*
* Gather attribute uses defined by this type.
*/
@@ -6384,11 +7093,7 @@
* not have {type definition}s which are or are derived from ID.
*/
if ((cur->attr->subtypes != NULL) &&
- /*
- * TODO: FIXME: XML_SCHEMAS_ID should be used instead of "23" !!!,
- * but the xmlSchemaValType is not made public yet.
- */
- (xmlSchemaIsDerivedFromBuiltInType(ctxt, (xmlSchemaTypePtr) cur->attr, 23))) {
+ (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, "
@@ -6425,7 +7130,7 @@
(baseType->type == XML_SCHEMA_TYPE_COMPLEX) &&
(baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) {
xmlSchemaPErr(ctxt, baseType->node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaParseBuildAttributeUses: "
+ "Internal error: xmlSchemaBuildAttributeValidation: "
"attribute uses not builded on base type \"%s\".\n",
baseType->name, NULL);
}
@@ -6433,6 +7138,906 @@
}
/**
+ * xmlSchemaTypeFinalContains:
+ * @schema: the schema
+ * @type: the type definition
+ * @final: the final
+ *
+ * Evaluates if a type definition contains the given "final".
+ * This does take "finalDefault" into account as well.
+ *
+ * Returns 1 if the type does containt the given "final",
+ * 0 otherwise.
+ */
+static int
+xmlSchemaTypeFinalContains(xmlSchemaPtr schema, xmlSchemaTypePtr type, int final)
+{
+ int tfinal = final, tflags = type->flags;
+
+ if (type == NULL)
+ return (0);
+ if (type->flags & XML_SCHEMAS_TYPE_FINAL_DEFAULT) {
+ switch (final) {
+ case XML_SCHEMAS_TYPE_FINAL_RESTRICTION:
+ tfinal = XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
+ break;
+ case XML_SCHEMAS_TYPE_FINAL_EXTENSION:
+ tfinal = XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
+ break;
+ case XML_SCHEMAS_TYPE_FINAL_LIST:
+ tfinal = XML_SCHEMAS_FINAL_DEFAULT_LIST;
+ break;
+ case XML_SCHEMAS_TYPE_FINAL_UNION:
+ tfinal = XML_SCHEMAS_FINAL_DEFAULT_UNION;
+ break;
+ }
+ tflags = schema->flags;
+ }
+ if (tflags & tfinal)
+ return (1);
+ else
+ return (0);
+
+}
+
+/**
+ * xmlSchemaGetUnionSimpleTypeMemberTypes:
+ * @type: the Union Simple Type
+ *
+ * Returns a list of member types of @type if existing,
+ * returns NULL otherwise.
+ */
+xmlSchemaTypeLinkPtr
+xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
+{
+ while (type != NULL) {
+ if (type->memberTypes != NULL)
+ return (type->memberTypes);
+ else
+ type = type->baseType;
+ }
+ return (NULL);
+}
+
+/**
+ * xmlSchemaGetListSimpleTypeItemType:
+ * @type: the simple type definition
+ *
+ * Returns the item type definition of the list simple type.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetListSimpleTypeItemType(xmlSchemaTypePtr type)
+{
+ if ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)
+ return (NULL);
+ /*
+ * Note: In libxml2, the built-in types do not reflect
+ * the datatype hierarchy (yet?) - we have to treat them
+ * in a special way.
+ */
+ if (type->type == XML_SCHEMA_TYPE_BASIC)
+ return (xmlSchemaGetBuiltInListSimpleTypeItemType(type));
+ if (type->subtypes->type == XML_SCHEMA_TYPE_LIST)
+ /* 1 If the <list> alternative is chosen, then the type
+ * definition ·resolved· to by the ·actual value· of the
+ * itemType [attribute] of <list>, if present, otherwise
+ * the type definition corresponding to the <simpleType>
+ * among the [children] of <list>.
+ */
+ return (type->subtypes->subtypes);
+ else {
+ /* 2 If the <restriction> option is chosen, then the
+ * {item type definition} of the {base type definition}.
+ */
+ return (xmlSchemaGetListSimpleTypeItemType(type->baseType));
+ }
+}
+
+/**
+ * xmlSchemaCheckCOSSTDerivedOK:
+ * @type: the derived simple type definition
+ * @baseType: the base type definition
+ *
+ * Checks wheter @type can be validly
+ * derived from @baseType.
+ *
+ * Returns 0 on success, an positive error code otherwise.
+ */
+static int
+xmlSchemaCheckCOSSTDerivedOK(xmlSchemaPtr schema,
+ xmlSchemaTypePtr type,
+ xmlSchemaTypePtr baseType,
+ int subset)
+{
+ /*
+ * Schema Component Constraint: Type Derivation OK (Simple)
+ *
+ *
+ * 1 They are the same type definition.
+ * TODO: The identy check might have to be more complex than this.
+ */
+ if (type == baseType)
+ return (0);
+ /*
+ * 2.1 restriction is not in the subset, or in the {final}
+ * of its own {base type definition};
+ */
+ if ((subset & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) ||
+ (xmlSchemaTypeFinalContains(schema,
+ type->baseType, XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
+ return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
+ }
+ /* 2.2 */
+ if (type->baseType == baseType) {
+ /*
+ * 2.2.1 D's ·base type definition· is B.
+ */
+ return (0);
+ }
+ /*
+ * 2.2.2 D's ·base type definition· is not the ·ur-type definition·
+ * and is validly derived from B given the subset, as defined by this
+ * constraint.
+ */
+ if ((type->baseType != xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE)) &&
+ (xmlSchemaCheckCOSSTDerivedOK(schema, type->baseType, baseType, subset) == 0)) {
+ return (0);
+ }
+ /*
+ * 2.2.3 D's {variety} is list or union and B is the ·simple ur-type
+ * definition·.
+ */
+ if (((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) ||
+ (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)) &&
+ (baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE))) {
+ return (0);
+ }
+ /*
+ * 2.2.4 B's {variety} is union and D is validly derived from a type
+ * definition in B's {member type definitions} given the subset, as
+ * defined by this constraint.
+ *
+ * NOTE: This seems not to involve built-in types, since there is no
+ * built-in Union Simple Type.
+ */
+ if (baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ xmlSchemaTypeLinkPtr cur;
+
+ cur = baseType->memberTypes;
+ while (cur != NULL) {
+ if (xmlSchemaCheckCOSSTDerivedOK(schema, type,
+ cur->type, subset) == 0)
+ return (0);
+ cur = cur->next;
+ }
+ }
+
+ return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
+}
+
+
+/**
+ * xmlSchemaCheckSTPropsCorrect:
+ * @ctxt: the schema parser context
+ * @type: the simple type definition
+ *
+ * Checks st-props-correct.
+ *
+ * Returns 0 if the properties are correct,
+ * if not, a positive error code and -1 on internal
+ * errors.
+ */
+static int
+xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
+{
+ xmlSchemaTypePtr baseType = type->baseType, anySimpleType,
+ anyType;
+
+ /*
+ * Schema Component Constraint: Simple Type Definition Properties Correct
+ *
+ * NOTE: This is somehow redundant, since we actually built a simple type
+ * to have all the needed information; this acts as an self test.
+ */
+ anySimpleType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ /*
+ * TODO: 1 The values of the properties of a simple type definition must be as
+ * described in the property tableau in Datatype definition, modulo the
+ * impact of Missing Sub-components (§5.3).
+ */
+ /* Base type: If the datatype has been ·derived· by ·restriction·
+ * then the Simple Type Definition component from which it is ·derived·,
+ * otherwise the Simple Type Definition for anySimpleType (§4.1.6).
+ */
+ if (baseType == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAP_ST_PROPS_CORRECT_1,
+ "Simple type \"%s\" does not have a base type.\n",
+ type->name, 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,
+ XML_SCHEMAP_ST_PROPS_CORRECT_1,
+ "Simple type \"%s\": its base type \"%s\" is not a simple "
+ "type.\n",
+ type->name, baseType->name);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+ }
+ if ((baseType != anySimpleType) &&
+ (type->subtypes->type != XML_SCHEMA_TYPE_RESTRICTION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+ }
+ /*
+ * Variety: One of {atomic, list, union}.
+ */
+ 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,
+ XML_SCHEMAP_ST_PROPS_CORRECT_1,
+ "Simple type \"%s\" has an absent variety.\n",
+ type->name, NULL);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+ }
+ /* TODO: Finish this. */
+
+ /*
+ * 2 All simple type definitions must be derived ultimately from the ·simple
+ * ur-type definition (so· circular definitions are disallowed). That is, it
+ * must be possible to reach a built-in primitive datatype or the ·simple
+ * ur-type definition· by repeatedly following the {base type definition}.
+ */
+ baseType = type->baseType;
+ while ((baseType != NULL) && (baseType->type != XML_SCHEMA_TYPE_BASIC)) {
+ if (baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
+ xmlSchemaTypeFixup(baseType, ctxt, NULL);
+ 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);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
+ }
+ baseType = baseType->baseType;
+ }
+ /*
+ * 3 The {final} of the {base type definition} must not contain restriction.
+ */
+ if (xmlSchemaTypeFinalContains(ctxt->schema, baseType,
+ XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
+ }
+ return (0);
+}
+
+/**
+ * xmlSchemaCheckDerivationValidSimpleRestriction:
+ * @ctxt: the schema parser context
+ * @type: the simple type definition
+ *
+ * Checks if the given @type (simpleType) is derived
+ * validly by restriction.
+ *
+ * Returns -1 on internal errors, 0 if the type is validly derived,
+ * a positive error code otherwise.
+ */
+static int
+xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
+{
+
+ 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",
+ type->name, NULL);
+ return (-1);
+ }
+
+ if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) {
+ xmlSchemaTypePtr primitive;
+ /*
+ * 1.1 The {base type definition} must be an atomic simple
+ * type definition or a built-in primitive datatype.
+ */
+ if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ 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 */
+ if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
+ XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
+ }
+
+ /*
+ * 1.3.1 DF must be an allowed constraining facet for the {primitive
+ * type definition}, as specified in the appropriate subsection of 3.2
+ * Primitive datatypes.
+ */
+ if (type->facets != NULL) {
+ xmlSchemaFacetPtr facet;
+ int ok = 1;
+
+ primitive = xmlSchemaGetPrimitiveType(type);
+ if (primitive == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_ERR_INTERNAL_ERROR,
+ "xmlSchemaCheckDerivationValidSimpleRestriction: failed "
+ "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,
+ 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,
+ xmlSchemaFacetTypeToString(facet->type),
+ primitive->name, NULL, NULL);
+
+ ok = 0;
+ }
+ facet = facet->next;
+ } while (facet != NULL);
+ if (ok == 0)
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
+
+ }
+ /*
+ * TODO: 1.3.2 (facet derivation)
+ */
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ xmlSchemaTypePtr itemType = NULL;
+
+ itemType = xmlSchemaGetListSimpleTypeItemType(type);
+ if (itemType == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_ERR_INTERNAL_ERROR,
+ "Internal error: xmlSchemaCheckDerivationValidSimpleRestriction: "
+ "failed to evaluate the item type of type \"%s\".\n",
+ type->name, NULL);
+ return (-1);
+ }
+ /*
+ * 2.1 The {item type definition} must have a {variety} of atomic or
+ * union (in which case all the {member type definitions}
+ * must be atomic).
+ */
+ if (((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
+ ((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
+ } else if (itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ xmlSchemaTypeLinkPtr member;
+
+ member = itemType->memberTypes;
+ while (member != NULL) {
+ if ((member->type->flags &
+ XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
+ }
+ member = member->next;
+ }
+ }
+
+ if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) {
+ xmlSchemaFacetPtr facet;
+ /*
+ * This is the case if we have: <simpleType><list ..
+ */
+ /*
+ * 2.3.1
+ * 2.3.1.1 The {final} of the {item type definition} must not
+ * contain list.
+ */
+ if (xmlSchemaTypeFinalContains(ctxt->schema,
+ itemType, XML_SCHEMAS_TYPE_FINAL_LIST)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
+ }
+ /*
+ * 2.3.1.2 The {facets} must only contain the whiteSpace
+ * facet component.
+ */
+ if (type->facets != NULL) {
+ facet = type->facets;
+ do {
+ if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
+ "List simple type \"%s\": the facet \"%s\" "
+ "is not allowed.\n",
+ type->name, xmlSchemaFacetTypeToString(facet->type));
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
+ }
+ facet = facet->next;
+ } while (facet != NULL);
+ }
+ /*
+ * TODO: Datatypes states:
+ * A ·list· datatype can be ·derived· from an ·atomic· datatype
+ * whose ·lexical space· allows space (such as string or anyURI)or
+ * a ·union· datatype any of whose {member type definitions}'s
+ * ·lexical space· allows space.
+ */
+ } else {
+ /*
+ * This is the case if we have: <simpleType><restriction ...
+ */
+ /*
+ * 2.3.2
+ * 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,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
+ }
+ /*
+ * 2.3.2.2 The {final} of the {base type definition} must not
+ * contain restriction.
+ */
+ if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
+ XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
+ }
+ /*
+ * 2.3.2.3 The {item type definition} must be validly derived
+ * from the {base type definition}'s {item type definition} given
+ * the empty set, as defined in Type Derivation OK (Simple) (§3.14.6).
+ */
+ {
+ xmlSchemaTypePtr baseItemType;
+
+ baseItemType = xmlSchemaGetListSimpleTypeItemType(type->baseType);
+ if (baseItemType == NULL) {
+ 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",
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
+ }
+ }
+
+ if (type->facets != NULL) {
+ xmlSchemaFacetPtr facet;
+ int ok = 1;
+ /*
+ * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
+ * and enumeration facet components are allowed among the {facets}.
+ */
+ facet = type->facets;
+ do {
+ switch (facet->type) {
+ case XML_SCHEMA_FACET_LENGTH:
+ case XML_SCHEMA_FACET_MINLENGTH:
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ case XML_SCHEMA_FACET_WHITESPACE:
+ /*
+ * TODO: 2.5.1.2 List datatypes
+ * The value of ·whiteSpace· is fixed to the value collapse.
+ */
+ case XML_SCHEMA_FACET_PATTERN:
+ case XML_SCHEMA_FACET_ENUMERATION:
+ break;
+ default: {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
+ "List simple type \"%s\": the facet \"%s\" "
+ "is not allowed.\n",
+ type->name,
+ xmlSchemaFacetTypeToString(facet->type));
+ /*
+ * We could return, but it's nicer to report all
+ * invalid facets.
+ */
+ ok = 0;
+ }
+ }
+ facet = facet->next;
+ } while (facet != NULL);
+ if (ok == 0)
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
+ /*
+ * TODO: 2.3.2.5 For each facet in the {facets} (call this DF), if there
+ * is a facet of the same kind in the {facets} of the {base type
+ * definition} (call this BF),then the DF's {value} must be a valid
+ * restriction of BF's {value} as defined in [XML Schemas: Datatypes].
+ */
+ }
+
+
+ }
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ /*
+ * 3.1 The {member type definitions} must all have {variety} of
+ * atomic or list.
+ */
+ xmlSchemaTypeLinkPtr member;
+
+ member = type->memberTypes;
+ while (member != NULL) {
+ if (((member->type->flags &
+ XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
+ ((member->type->flags &
+ XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
+ }
+ member = member->next;
+ }
+ /*
+ * 3.3.1 If the {base type definition} is the ·simple ur-type
+ * definition·
+ */
+ if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) {
+ /*
+ * 3.3.1.1 All of the {member type definitions} must have a
+ * {final} which does not contain union.
+ */
+ member = type->memberTypes;
+ while (member != NULL) {
+ if (xmlSchemaTypeFinalContains(ctxt->schema, member->type,
+ XML_SCHEMAS_TYPE_FINAL_UNION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
+ }
+ member = member->next;
+ }
+ /*
+ * 3.3.1.2 The {facets} must be empty.
+ */
+ if (type->facetSet != NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
+ "Union simple type \"%s\": the facets must be empty.\n",
+ type->name, NULL);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
+ }
+ } else {
+ /*
+ * 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,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
+ }
+ /*
+ * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
+ */
+ if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType,
+ XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
+ }
+ /*
+ * 3.3.2.3 The {member type definitions}, in order, must be validly
+ * derived from the corresponding type definitions in the {base
+ * type definition}'s {member type definitions} given the empty set,
+ * as defined in Type Derivation OK (Simple) (§3.14.6).
+ */
+ {
+ xmlSchemaTypeLinkPtr baseMember;
+
+ /*
+ * OPTIMIZE: if the type is restricting, it has no local defined
+ * member types and inherits the member types of the base type;
+ * thus a check for equality can be skipped.
+ */
+ /*
+ * TODO: Even worse: I cannot see a scenario where a restricting
+ * union simple type can have other member types as the member
+ * types of it's base type. This check seems not necessary with
+ * respect to the derivation process in libxml2.
+ */
+ if (type->memberTypes != NULL) {
+ member = type->memberTypes;
+ baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
+ if ((member == NULL) && (baseMember != NULL)) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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",
+ type->name, NULL);
+ }
+ while (member != NULL) {
+ if (baseMember == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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",
+ 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);
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
+ }
+ member = member->next;
+ baseMember = baseMember->next;
+ }
+ }
+ }
+ /*
+ * 3.3.2.4 Only pattern and enumeration facet components are
+ * allowed among the {facets}.
+ */
+ if (type->facets != NULL) {
+ xmlSchemaFacetPtr facet;
+ int ok = 1;
+
+ facet = type->facets;
+ 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,
+ xmlSchemaFacetTypeToString(facet->type));
+ ok = 0;
+ }
+ facet = facet->next;
+ } while (facet != NULL);
+ if (ok == 0)
+ return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
+
+ }
+ /*
+ * TODO: 3.3.2.5 (facet derivation)
+ */
+ }
+ }
+
+ return (0);
+}
+
+/**
+ * xmlSchemaCheckSRCSimpleType:
+ * @ctxt: the schema parser context
+ * @type: the simple type definition
+ *
+ * Checks crc-simple-type constraints.
+ *
+ * Returns 0 if the constraints are satisfied,
+ * if not a positive error code and -1 on internal
+ * errors.
+ */
+static int
+xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
+{
+ /*
+ * NOTE: src-simple-type 2-4 are redundant, since the checks
+ * were are done for the corresponding <restriction>, <list> and <union>
+ * elements, but W3C wants a <simpleType> error as well, so it gets one.
+ * Maby this can be skipped in the future, if we get sure it's not needed.
+ */
+ if (type->subtypes == NULL) {
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaCheckSRCSimpleType, "
+ "no subtype on simple type \"%s\".\n",
+ type->name, NULL);
+ return (-1);
+ }
+ /*
+ * src-simple-type.1 The corresponding simple type definition, if any,
+ * must satisfy the conditions set out in Constraints on Simple Type
+ * Definition Schema Components (§3.14.6).
+ */
+ if ((xmlSchemaCheckSTPropsCorrect(ctxt, type) != 0) ||
+ (xmlSchemaCheckCOSSTRestricts(ctxt, type) != 0)) {
+ /*
+ * TODO: Removed this, since it got annoying to get an
+ * extra error report, if anything failed until now.
+ * Enable this if needed.
+ */
+ /*
+ xmlSchemaPErr(ctxt, type->node,
+ XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+ "Simple type \"%s\" does not satisfy the constraints "
+ "on simple type definitions.\n",
+ type->name, NULL);
+ */
+ return (XML_SCHEMAP_SRC_SIMPLE_TYPE_1);
+ }
+
+ if (type->subtypes->type == XML_SCHEMA_TYPE_RESTRICTION) {
+ /*
+ * src-simple-type.2 If the <restriction> alternative is chosen,
+ * either it must have a base [attribute] or a <simpleType> among its
+ * [children], but not both.
+ */
+ if (((type->subtypes->base == NULL) &&
+ ((type->subtypes->subtypes == NULL) ||
+ (type->subtypes->subtypes->type != XML_SCHEMA_TYPE_SIMPLE))) ||
+ ((type->subtypes->base != NULL) &&
+ (type->subtypes->subtypes != NULL) &&
+ (type->subtypes->subtypes->type == XML_SCHEMA_TYPE_SIMPLE))) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_SRC_SIMPLE_TYPE_2);
+ }
+ } else if (type->subtypes->type == XML_SCHEMA_TYPE_LIST) {
+ /* src-simple-type.3 If the <list> alternative is chosen, either it must have
+ * an itemType [attribute] or a <simpleType> among its [children],
+ * but not both.
+ * NOTE: baseType is set to the local simple type definiton,
+ * if existent, at parse time. This is a hack and not nice.
+ */
+ if (((type->subtypes->base == NULL) &&
+ (type->baseType == NULL)) ||
+ ((type->subtypes->base != NULL) &&
+ (type->subtypes->baseType != NULL))) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ return (XML_SCHEMAP_SRC_SIMPLE_TYPE_3);
+ }
+
+
+ } else if (type->subtypes->type == XML_SCHEMA_TYPE_UNION) {
+ xmlSchemaTypeLinkPtr member;
+ xmlSchemaTypePtr ancestor, anySimpleType;
+
+ anySimpleType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+
+ /* src-simple-type.4 Circular union type definition is disallowed. That is, if
+ * the <union> alternative is chosen, there must not be any entries
+ * in the memberTypes [attribute] at any depth which resolve to the
+ * component corresponding to the <simpleType>.
+ */
+ member = type->memberTypes;
+ while (member != NULL) {
+ ancestor = member->type;
+ while ((ancestor != NULL) && (ancestor->type != XML_SCHEMA_TYPE_BASIC)) {
+ if (ancestor->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
+ xmlSchemaTypeFixup(ancestor, ctxt, NULL);
+ if (ancestor == anySimpleType)
+ break;
+ else if (ancestor == type) {
+ xmlSchemaPErr(ctxt, type->node,
+ 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);
+ 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
+ * 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.
+ */
+
+ }
+ ancestor = ancestor->baseType;
+ }
+ member = member->next;
+ }
+
+ }
+
+ return (0);
+}
+
+/**
* xmlSchemaTypeFixup:
* @typeDecl: the schema type definition
* @ctxt: the schema parser context
@@ -6443,35 +8048,46 @@
xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
+ xmlSchemaTypePtr ctxtType;
+
if (typeDecl == NULL)
return;
if (name == NULL)
name = typeDecl->name;
if (typeDecl->contentType == XML_SCHEMA_CONTENT_UNKNOWN) {
switch (typeDecl->type) {
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
- if (typeDecl->subtypes != NULL)
+ case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{
+ if (typeDecl->subtypes != NULL) {
+ if (typeDecl->subtypes->contentType ==
+ XML_SCHEMA_CONTENT_UNKNOWN) {
+ xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
+ NULL);
+ }
typeDecl->contentType =
typeDecl->subtypes->contentType;
+ }
break;
}
case XML_SCHEMA_TYPE_RESTRICTION:{
+ xmlSchemaTypePtr base = NULL;
+
+ ctxt->ctxtType->flags |=
+ XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
if (typeDecl->subtypes != NULL)
xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
if (typeDecl->base != NULL) {
- xmlSchemaTypePtr baseType;
-
- baseType =
+ base =
xmlSchemaGetType(ctxt->schema, typeDecl->base,
typeDecl->baseNs);
- if (baseType == NULL) {
+ if (base == NULL) {
xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- "Schemas: type %s base type %s not found\n",
- name, typeDecl->base);
- } else if (baseType->contentType ==
+ XML_SCHEMAP_SRC_RESOLVE,
+ "Restriction \"%s\": the QName \"%s\" of the "
+ "attribute \"base\" does not resolve to a schema "
+ "component.\n",
+ name, typeDecl->base);
+ } else if (base->contentType ==
XML_SCHEMA_CONTENT_UNKNOWN) {
/*
* The base type might be not "type fixed" yet,
@@ -6480,94 +8096,89 @@
* TODO: Is a check for circular derivation already
* done?
*/
- xmlSchemaTypeFixup(baseType, ctxt, NULL);
- }
- typeDecl->baseType = baseType;
+ xmlSchemaTypeFixup(base, ctxt, NULL);
+ }
}
- if (typeDecl->subtypes == NULL)
- if (typeDecl->baseType != NULL) {
+ if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX) {
+ /*
+ * ComplexType restriction.
+ */
+ /*
+ * Base type: The type definition ·resolved· to by the ·actual
+ * value· of the base [attribute]
+ */
+ ctxt->ctxtType->baseType = base;
+ /*
+ * Content type.
+ */
+ if (typeDecl->subtypes == NULL)
+ /* 1.1.1 */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ else if ((typeDecl->subtypes->subtypes == NULL) &&
+ ((typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_ALL)
+ || (typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_SEQUENCE)))
+ /* 1.1.2 */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ else if ((typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_CHOICE)
+ && (typeDecl->subtypes->subtypes == NULL))
+ /* 1.1.3 */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ else {
+ /* 1.2 and 2.X are applied at the other layer */
typeDecl->contentType =
- typeDecl->baseType->contentType;
+ XML_SCHEMA_CONTENT_ELEMENTS;
+ }
+ } else {
+ /*
+ * SimpleType restriction.
+ */
+ /* Base type:
+ * The Simple Type Definition component resolved to by
+ * the actual value of the base [attribute] or the
+ * <simpleType> [children], whichever is present.
+ */
+ if ((base == NULL) && (typeDecl->subtypes != NULL)) {
+ base = typeDecl->subtypes;
+ ctxt->ctxtType->baseType = base;
+ if (base->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
+ xmlSchemaTypeFixup(base, ctxt, NULL);
} else
- /* 1.1.1 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->subtypes == NULL) &&
- ((typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_ALL)
- || (typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_CHOICE)
- && (typeDecl->subtypes->subtypes == NULL))
- /* 1.1.3 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else {
- /* 1.2 and 2.X are applied at the other layer */
- typeDecl->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
- }
+ ctxt->ctxtType->baseType = base;
+
+ if (((typeDecl->base == NULL) &&
+ ((typeDecl->subtypes == NULL) ||
+ (typeDecl->subtypes->type != XML_SCHEMA_TYPE_SIMPLE))) ||
+ ((typeDecl->base != NULL) &&
+ (typeDecl->subtypes != NULL) &&
+ (typeDecl->subtypes->type == XML_SCHEMA_TYPE_SIMPLE))) {
+ /*
+ * 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, typeDecl->node,
+ XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
+ "Restriction \"%s\": "
+ "Either the \"base\" attribute or the <simpleType> child "
+ "must be present, but not both.\n",
+ typeDecl->name, NULL);
+ }
+ }
break;
}
case XML_SCHEMA_TYPE_EXTENSION:{
- xmlSchemaContentType explicitContentType;
- xmlSchemaTypePtr base;
-
- if (typeDecl->base != NULL) {
- xmlSchemaTypePtr baseType;
-
- baseType =
- xmlSchemaGetType(ctxt->schema, typeDecl->base,
- typeDecl->baseNs);
- if (baseType == NULL) {
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- "Schemas: type %s base type %s not found\n",
- name, typeDecl->base);
- } else if (baseType->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN) {
- /*
- * The base type might be not "type fixed" yet,
- * so do it now. */
- /*
- * TODO: Is a check for circular derivation already
- * done?
- */
- xmlSchemaTypeFixup(baseType, ctxt, NULL);
- }
- typeDecl->baseType = baseType;
- }
- if (typeDecl->subtypes != NULL)
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
-
- explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
- if (typeDecl->subtypes == NULL)
- /* 1.1.1 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->subtypes == NULL) &&
- ((typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_ALL)
- || (typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_CHOICE)
- && (typeDecl->subtypes->subtypes == NULL))
- /* 1.1.3 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
-
- base = xmlSchemaGetType(ctxt->schema, typeDecl->base,
- typeDecl->baseNs);
- if (base == NULL) {
- xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- "Schemas: base type %s of type %s not found\n",
- typeDecl->base, name);
- return;
- }
- if (typeDecl->recurse) {
+ xmlSchemaTypePtr base = NULL;
+ xmlSchemaContentType explicitContentType;
+
+ /*
+ * An extension does exist on a complexType only.
+ */
+ ctxt->ctxtType->flags |=
+ 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,
@@ -6575,59 +8186,113 @@
name, NULL);
return;
}
- typeDecl->recurse = 1;
- xmlSchemaTypeFixup(base, ctxt, NULL);
- typeDecl->recurse = 0;
- if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) {
- /* 2.1 */
- typeDecl->contentType = base->contentType;
- } else if (base->contentType ==
- XML_SCHEMA_CONTENT_EMPTY) {
- /* 2.2 imbitable ! */
- typeDecl->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
- } else {
- /* 2.3 imbitable pareil ! */
- typeDecl->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
+ if (typeDecl->base != NULL) {
+ base =
+ 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);
+ } else if (base->contentType ==
+ XML_SCHEMA_CONTENT_UNKNOWN) {
+ typeDecl->recurse = 1;
+ xmlSchemaTypeFixup(base, ctxt, NULL);
+ typeDecl->recurse = 0;
+ }
+ /*
+ * The type definition ·resolved· to by the ·actual
+ * value· of the base [attribute]
+ */
+ ctxt->ctxtType->baseType = base;
+ /*
+ * TODO: This one is still needed for computation of
+ * the content model by xmlSchemaBuildAContentModel.
+ * Try to get rid of it.
+ */
+ typeDecl->baseType = base;
}
+ if ((typeDecl->subtypes != NULL) &&
+ (typeDecl->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN))
+ xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
+
+ explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
+ if (typeDecl->subtypes == NULL)
+ /* 1.1.1 */
+ explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
+ else if ((typeDecl->subtypes->subtypes == NULL) &&
+ ((typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_ALL)
+ || (typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_SEQUENCE)))
+ /* 1.1.2 */
+ explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
+ else if ((typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_CHOICE)
+ && (typeDecl->subtypes->subtypes == NULL))
+ /* 1.1.3 */
+ explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
+ if (base != NULL) {
+ /* It will be reported later, if the base is missing. */
+ if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) {
+ /* 2.1 */
+ typeDecl->contentType = base->contentType;
+ } else if (base->contentType ==
+ XML_SCHEMA_CONTENT_EMPTY) {
+ /* 2.2 imbitable ! */
+ typeDecl->contentType =
+ XML_SCHEMA_CONTENT_ELEMENTS;
+ } else {
+ /* 2.3 imbitable pareil ! */
+ typeDecl->contentType =
+ XML_SCHEMA_CONTENT_ELEMENTS;
+ }
+ }
break;
}
case XML_SCHEMA_TYPE_COMPLEX:{
+ if ((typeDecl->subtypes == NULL) ||
+ ((typeDecl->subtypes->type !=
+ XML_SCHEMA_TYPE_SIMPLE_CONTENT) &&
+ (typeDecl->subtypes->type !=
+ XML_SCHEMA_TYPE_COMPLEX_CONTENT))) {
+ /*
+ * This case is understood as shorthand for complex
+ * content restricting the ur-type definition, and
+ * the details of the mappings should be modified as
+ * necessary.
+ */
+ typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ typeDecl->flags |=
+ XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
+ }
if (typeDecl->subtypes == NULL) {
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
-
+ typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
typeDecl->contentType =
- XML_SCHEMA_CONTENT_MIXED;
+ XML_SCHEMA_CONTENT_MIXED;
} else {
+ if ((typeDecl->subtypes != NULL) &&
+ (typeDecl->subtypes->contentType ==
+ XML_SCHEMA_CONTENT_UNKNOWN)) {
+ ctxtType = ctxt->ctxtType;
+ ctxt->ctxtType = typeDecl;
+ xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
+ NULL);
+ ctxt->ctxtType = ctxtType;
+ }
if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED) {
typeDecl->contentType =
XML_SCHEMA_CONTENT_MIXED;
- } else {
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
- NULL);
- if (typeDecl->subtypes != NULL)
+ } else {
+ if (typeDecl->subtypes != NULL) {
typeDecl->contentType =
typeDecl->subtypes->contentType;
- }
- /* Evaluate the derivation method. */
- if ((typeDecl->subtypes != NULL) &&
- ((typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_COMPLEX_CONTENT) ||
- (typeDecl->subtypes->type ==
- XML_SCHEMA_TYPE_SIMPLE_CONTENT)) &&
- (typeDecl->subtypes->subtypes != NULL)) {
- if (typeDecl->subtypes->subtypes->type ==
- XML_SCHEMA_TYPE_EXTENSION) {
- typeDecl->flags |=
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
- } else if (typeDecl->subtypes->subtypes->type ==
- XML_SCHEMA_TYPE_RESTRICTION) {
- typeDecl->flags |=
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
- }
- }
+ }
+ }
}
xmlSchemaBuildAttributeValidation(ctxt, typeDecl);
break;
@@ -6660,23 +8325,149 @@
}
break;
}
+ case XML_SCHEMA_TYPE_SIMPLE:
+ /*
+ * Simple Type Definition Schema Component
+ *
+ */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ if (typeDecl->subtypes->contentType ==
+ XML_SCHEMA_CONTENT_UNKNOWN) {
+ ctxtType = ctxt->ctxtType;
+ ctxt->ctxtType = typeDecl;
+ xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
+ ctxt->ctxtType = ctxtType;
+ }
+ /* Fixup base type */
+ if ((typeDecl->baseType != NULL) &&
+ (typeDecl->baseType->contentType ==
+ XML_SCHEMA_CONTENT_UNKNOWN)) {
+ /* OPTIMIZE: Actually this one will never by hit, since
+ * the base type is already type-fixed in <restriction>.
+ */
+ ctxtType = ctxt->ctxtType;
+ ctxt->ctxtType = typeDecl;
+ xmlSchemaTypeFixup(typeDecl->baseType, ctxt, NULL);
+ ctxt->ctxtType = ctxtType;
+ }
+ /* Base type:
+ * 2 If the <list> or <union> alternative is chosen,
+ * then the ·simple ur-type definition·.
+ */
+ if (typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_LIST) {
+ typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+ } else if (typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_UNION) {
+ typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+ } else if (typeDecl->subtypes->type ==
+ XML_SCHEMA_TYPE_RESTRICTION) {
+ xmlSchemaFacetLinkPtr facet, cur, last = NULL;
+
+ /*
+ * Variety
+ * If the <restriction> alternative is chosen, then the
+ * {variety} of the {base type definition}.
+ */
+ if (typeDecl->baseType != NULL) {
+ if (typeDecl->baseType->flags &
+ XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
+ typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
+ else if (typeDecl->baseType->flags &
+ XML_SCHEMAS_TYPE_VARIETY_LIST)
+ typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+ else if (typeDecl->baseType->flags &
+ XML_SCHEMAS_TYPE_VARIETY_UNION)
+ typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+ /*
+ * Schema Component Constraint: Simple Type Restriction
+ * (Facets)
+ * NOTE: Satisfaction of 1 and 2 arise from the fixup
+ * applied beforehand.
+ *
+ * 3 The {facets} of R are the union of S and the {facets}
+ * of B, eliminating duplicates. To eliminate duplicates,
+ * when a facet of the same kind occurs in both S and the
+ * {facets} of B, the one in the {facets} of B is not
+ * included, with the exception of enumeration and pattern
+ * facets, for which multiple occurrences with distinct values
+ * are allowed.
+ */
+ if (typeDecl->baseType->facetSet != NULL) {
+ last = typeDecl->facetSet;
+ if (last != NULL)
+ while (last->next != NULL)
+ last = last->next;
+ cur = typeDecl->baseType->facetSet;
+ for (; cur != NULL; cur = cur->next) {
+ /*
+ * Base patterns won't be add here:
+ * they are ORed in a type and
+ * ANDed in derived types. This will
+ * happed at validation level by
+ * walking the base axis of the type.
+ */
+ if (cur->facet->type ==
+ XML_SCHEMA_FACET_PATTERN)
+ continue;
+ facet = NULL;
+ if ((typeDecl->facetSet != NULL) &&
+ (cur->facet->type !=
+ XML_SCHEMA_FACET_PATTERN) &&
+ (cur->facet->type !=
+ XML_SCHEMA_FACET_ENUMERATION)) {
+ facet = typeDecl->facetSet;
+ do {
+ if (cur->facet->type ==
+ facet->facet->type)
+ break;
+ facet = facet->next;
+ } while (facet != NULL);
+ }
+ if (facet == NULL) {
+ facet = (xmlSchemaFacetLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaFacetLink));
+ if (facet == NULL) {
+ xmlSchemaPErrMemory(ctxt,
+ "fixing simpleType", NULL);
+ return;
+ }
+ facet->facet = cur->facet;
+ facet->next = NULL;
+ if (last == NULL)
+ typeDecl->facetSet = facet;
+ else
+ last->next = facet;
+ last = facet;
+ }
+ }
+ }
+ }
+ }
+ /*
+ * Check constraints.
+ */
+ xmlSchemaCheckSRCSimpleType(ctxt, typeDecl);
+ break;
case XML_SCHEMA_TYPE_SEQUENCE:
case XML_SCHEMA_TYPE_GROUP:
case XML_SCHEMA_TYPE_ALL:
case XML_SCHEMA_TYPE_CHOICE:
typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
break;
- case XML_SCHEMA_TYPE_LIST:
+ case XML_SCHEMA_TYPE_LIST:
xmlSchemaParseListRefFixup(typeDecl, ctxt);
- /* no break on purpose */
- case XML_SCHEMA_TYPE_UNION:
- if (typeDecl->type == XML_SCHEMA_TYPE_UNION)
- xmlSchemaParseUnionRefCheck(typeDecl, ctxt);
- /* no break on purpose */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ break;
+ case XML_SCHEMA_TYPE_UNION:
+ xmlSchemaParseUnionRefCheck(typeDecl, ctxt);
+ typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ break;
case XML_SCHEMA_TYPE_BASIC:
case XML_SCHEMA_TYPE_ANY:
case XML_SCHEMA_TYPE_FACET:
- case XML_SCHEMA_TYPE_SIMPLE:
case XML_SCHEMA_TYPE_UR:
case XML_SCHEMA_TYPE_ELEMENT:
case XML_SCHEMA_TYPE_ATTRIBUTE:
@@ -6726,9 +8517,12 @@
case XML_SCHEMA_CONTENT_MIXED:
xmlGenericError(xmlGenericErrorContext, "mixed\n");
break;
+ /* Removed, since not used. */
+ /*
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
break;
+ */
case XML_SCHEMA_CONTENT_BASIC:
xmlGenericError(xmlGenericErrorContext, "basic\n");
break;
@@ -6761,8 +8555,7 @@
if (nonNegativeIntegerType == NULL) {
nonNegativeIntegerType =
- xmlSchemaGetPredefinedType(BAD_CAST "nonNegativeInteger",
- xmlSchemaNs);
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER);
}
switch (facet->type) {
case XML_SCHEMA_FACET_MININCLUSIVE:
@@ -6774,21 +8567,44 @@
* at that point.
*/
xmlSchemaValidCtxtPtr vctxt;
-
+ xmlSchemaTypePtr base;
+
+ /*
+ * TODO: Try to avoid creating a new context.
+ */
vctxt = xmlSchemaNewValidCtxt(NULL);
if (vctxt == NULL)
- break;
- xmlSchemaValidateSimpleValue(vctxt, typeDecl,
+ break;
+ /* xmlSchemaValidateSimpleValue(vctxt, typeDecl,
facet->value);
+ */
+ /* The value ·must· be in the
+ * ·value space· of the ·base type·.
+ */
+ 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;
+ xmlSchemaValidateSimpleTypeValue(vctxt, facet->value, 0, 1);
facet->val = vctxt->value;
vctxt->value = NULL;
if (facet->val == NULL) {
/* error code */
if (ctxt != NULL) {
- xmlSchemaPErr(ctxt, facet->node,
- XML_SCHEMAP_INVALID_FACET,
- "Schemas: type %s facet value %s invalid\n",
- name, facet->value);
+ xmlSchemaPErrExt(ctxt, facet->node,
+ XML_SCHEMAP_INVALID_FACET,
+ NULL, NULL, NULL,
+ "Type \"%s\": the value \"%s\" of the "
+ "facet \"%s\" is invalid.\n",
+ name, facet->value,
+ xmlSchemaFacetTypeToString(facet->type),
+ NULL, NULL);
}
ret = -1;
}
@@ -6802,18 +8618,37 @@
*/
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;
- tmp = xmlSchemaValidateSimpleValue(vctxt, typeDecl,
+ 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,
- "Schemas: type %s enumeration value %s invalid\n",
- name, facet->value);
+ XML_SCHEMAP_INVALID_ENUM,
+ "Type \"%s\": the value \"%s\" of the "
+ "facet \"enumeration\" is invalid.\n",
+ name, facet->value);
}
ret = -1;
}
@@ -6824,9 +8659,10 @@
facet->regexp = xmlRegexpCompile(facet->value);
if (facet->regexp == NULL) {
xmlSchemaPErr(ctxt, typeDecl->node,
- XML_SCHEMAP_REGEXP_INVALID,
- "Schemas: type %s facet regexp %s invalid\n",
- name, facet->value);
+ XML_SCHEMAP_REGEXP_INVALID,
+ "Type \"%s\": the value \"%s\" of the "
+ "facet \"pattern\" is invalid.\n",
+ name, facet->value);
ret = -1;
}
break;
@@ -6844,10 +8680,14 @@
if (tmp != 0) {
/* error code */
if (ctxt != NULL) {
- xmlSchemaPErr(ctxt, facet->node,
- XML_SCHEMAP_INVALID_FACET_VALUE,
- "Schemas: type %s facet value %s invalid\n",
- name, facet->value);
+ xmlSchemaPErrExt(ctxt, facet->node,
+ XML_SCHEMAP_INVALID_FACET_VALUE,
+ NULL, NULL, NULL,
+ "Type \"%s\": the value \"%s\" of the "
+ "facet \"%s\" is invalid.\n",
+ name, facet->value,
+ xmlSchemaFacetTypeToString(facet->type),
+ NULL, NULL);
}
ret = -1;
}
@@ -6863,9 +8703,10 @@
} else {
if (ctxt != NULL) {
xmlSchemaPErr(ctxt, facet->node,
- XML_SCHEMAP_INVALID_WHITE_SPACE,
- "Schemas: type %s whiteSpace value %s invalid\n",
- name, facet->value);
+ XML_SCHEMAP_INVALID_WHITE_SPACE,
+ "Type \"%s\": the value \"%s\" of the "
+ "facet \"whiteSpace\" is invalid.\n",
+ name, facet->value);
}
ret = -1;
}
@@ -6888,17 +8729,19 @@
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
if (name == NULL)
- name = typeDecl->name;
- if (typeDecl->type == XML_SCHEMA_TYPE_RESTRICTION) {
- if (typeDecl->facets != NULL) {
- xmlSchemaFacetPtr facet = typeDecl->facets;
-
- while (facet != NULL) {
- xmlSchemaCheckFacet(facet, typeDecl, ctxt, name);
- facet = facet->next;
- }
- }
- }
+ name = typeDecl->name;
+ /*
+ * NOTE: It is intended to use the facets list, instead
+ * of facetSet.
+ */
+ if (typeDecl->facets != NULL) {
+ xmlSchemaFacetPtr facet = typeDecl->facets;
+
+ while (facet != NULL) {
+ xmlSchemaCheckFacet(facet, typeDecl, ctxt, name);
+ facet = facet->next;
+ }
+ }
}
/**
@@ -6923,9 +8766,11 @@
ref = xmlSchemaGetAttributeGroup(ctxt->schema, attrgrp->ref, attrgrp->refNs);
if (ref == NULL) {
xmlSchemaPErr(ctxt, attrgrp->node,
- XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP,
- "Schemas: attribute group %s reference %s not found\n",
- name, attrgrp->ref);
+ 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);
return;
}
xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
@@ -6957,6 +8802,12 @@
xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
+ /*
+ * 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 (name == NULL)
name = attrDecl->name;
if (attrDecl->subtypes != NULL)
@@ -6964,30 +8815,34 @@
if (attrDecl->typeName != NULL) {
xmlSchemaTypePtr type;
- type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
- attrDecl->typeNs);
- if (type == NULL) {
- xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_TYPE,
- "Schemas: attribute %s type %s not found\n",
- name, attrDecl->typeName);
- }
+ type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
+ attrDecl->typeNs);
+ if (type == NULL) {
+ xmlSchemaPErr(ctxt, attrDecl->node,
+ XML_SCHEMAP_SRC_RESOLVE,
+ "Attribute \"%s\": the QName \"%s\" of the attribute "
+ "\"type\" does not resolve to a schema "
+ "component.\n",
+ name, attrDecl->typeName);
+ }
attrDecl->subtypes = type;
} else if (attrDecl->ref != NULL) {
xmlSchemaAttributePtr ref;
ref = xmlSchemaGetAttribute(ctxt->schema, attrDecl->ref, attrDecl->refNs);
if (ref == NULL) {
- xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_REF,
- "Schemas: attribute %s reference %s not found\n",
- name, attrDecl->ref);
+ 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);
return;
}
xmlSchemaAttrFixup(ref, ctxt, NULL);
attrDecl->subtypes = ref->subtypes;
} else {
- xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_NOTYPE_NOREF,
- "Schemas: attribute %s has no type nor reference\n",
- name, NULL);
+ attrDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
}
}
@@ -7213,41 +9068,44 @@
static int
xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr base,
- xmlSchemaFacetPtr facets,
+ xmlSchemaFacetLinkPtr facets,
const xmlChar * value, int fireErrors)
{
int ret = 0;
int tmp = 0;
xmlSchemaTypeType type;
- xmlSchemaFacetPtr facet = facets;
+ xmlSchemaFacetLinkPtr facetLink = facets;
- while (facet != NULL) {
- type = facet->type;
+ while (facetLink != NULL) {
+ type = facetLink->facet->type;
if (type == XML_SCHEMA_FACET_ENUMERATION) {
tmp = 1;
- while (facet != NULL) {
+ while (facetLink != NULL) {
tmp =
- xmlSchemaValidateFacet(base, facet, value,
+ xmlSchemaValidateFacet(base, facetLink->facet, value,
ctxt->value);
if (tmp == 0) {
return 0;
}
- facet = facet->next;
+ facetLink = facetLink->next;
}
} else
- tmp = xmlSchemaValidateFacet(base, facet, value, ctxt->value);
+ tmp = xmlSchemaValidateFacet(base, facetLink->facet, value,
+ ctxt->value);
if (tmp != 0) {
ret = tmp;
- if (fireErrors)
- xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET,
- "Failed to validate type with facet %s\n",
- (const xmlChar *) xmlSchemaFacetTypeToString(type),
- NULL);
+ if (fireErrors) {
+ xmlSchemaVErr(ctxt, ctxt->cur, tmp,
+ "The value failed to validate against the facet \"%s\".\n",
+ (const xmlChar *) xmlSchemaFacetTypeToString(type),
+ NULL);
+
+ }
}
- if (facet != NULL)
- facet = facet->next;
+ if (facetLink != NULL)
+ facetLink = facetLink->next;
}
return (ret);
}
@@ -7268,7 +9126,7 @@
static int
xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr base,
- xmlSchemaFacetPtr facets, const xmlChar * value)
+ xmlSchemaFacetLinkPtr facets, const xmlChar * value)
{
return(xmlSchemaValidateFacetsInternal(ctxt, base, facets, value, 1));
}
@@ -7278,7 +9136,7 @@
* Simple type validation *
* *
************************************************************************/
-
+#if 0 /* Not currently used. */
/**
* xmlSchemaValidateSimpleValueUnion:
* @ctxt: a schema validation context
@@ -7410,7 +9268,6 @@
}
} else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
xmlSchemaTypePtr base;
- xmlSchemaFacetPtr facet;
base = type->baseType;
if (base != NULL) {
@@ -7425,9 +9282,11 @@
* building the Schemas
*/
if (ctxt->schema != NULL) {
- if (ret == 0) {
- facet = type->facets;
- ret = xmlSchemaValidateFacetsInternal(ctxt, base, facet,
+ xmlSchemaFacetLinkPtr facetLink;
+
+ if ((ret == 0) && (type->facetSet != NULL)) {
+ facetLink = type->facetSet;
+ ret = xmlSchemaValidateFacetsInternal(ctxt, base, facetLink,
value, fireErrors);
}
}
@@ -7481,6 +9340,7 @@
}
return (ret);
}
+#endif
/************************************************************************
* *
@@ -7580,25 +9440,28 @@
ret = 1;
if (cur->state == XML_SCHEMAS_ATTR_UNKNOWN)
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRUNKNOWN,
- "Attribute %s on %s is unknown\n",
- cur->attr->name, node->name);
+ "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 on %s is prohibited\n",
- cur->attr->name, node->name);
- else if (cur->state == XML_SCHEMAS_ATTR_INVALID_VALUE)
+ "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 on %s does not match type\n",
+ "Attribute \"%s\": the value is not valid.\n",
cur->attr->name, node->name);
- else if (cur->state == XML_SCHEMAS_ATTR_MISSING) {
+ } else if (cur->state == XML_SCHEMAS_ATTR_MISSING) {
if (cur->decl->ref != NULL)
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
- "Attribute %s on %s is required but missing\n",
- cur->decl->ref, node->name);
+ "Attribute \"%s\" is required but missing.\n",
+ cur->decl->ref, NULL);
else
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
- "Attribute %s on %s is required but missing\n",
- cur->decl->name, node->name);
+ "Attribute \"%s\" is required but missing.\n",
+ cur->decl->name, NULL);
}
}
cur = cur->next;
@@ -7718,16 +9581,13 @@
xmlSchemaSkipIgnored(xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
xmlSchemaTypePtr type, xmlNodePtr node)
{
- int mixed = 0;
-
/*
* TODO complete and handle entities
*/
- mixed = ((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
- (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS));
while ((node != NULL) &&
((node->type == XML_COMMENT_NODE) ||
- ((mixed == 1) && (node->type == XML_TEXT_NODE)) ||
+ ((type->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+ (node->type == XML_TEXT_NODE)) ||
(((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) &&
(node->type == XML_TEXT_NODE) && (IS_BLANK_NODE(node)))))) {
node = node->next;
@@ -7800,7 +9660,7 @@
ret = xmlSchemaValidateCheckNodeList(child);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleType %s content\n",
+ "Internal error: xmlSchemaValidateSimpleRestrictionType %s content\n",
node->name, NULL);
return (-1);
} else if (ret == 0) {
@@ -7816,6 +9676,7 @@
}
#endif
+#if 0 /* Not used any more */
/**
* xmlSchemaValidateSimpleType:
* @ctxt: a schema validation context
@@ -7900,18 +9761,12 @@
value = xmlNodeGetContent(child);
switch (variety->type) {
case XML_SCHEMA_TYPE_RESTRICTION:{
- xmlSchemaFacetPtr facet;
-
base = variety->baseType;
if (base != NULL) {
ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
} else {
- TODO}
- if (ret == 0) {
- facet = variety->facets;
- ret =
- xmlSchemaValidateFacets(ctxt, base, facet, value);
- }
+ TODO}
+
/* Removed due to changes of attribute validation:
if ((ret == 0) && (variety->attributes != NULL)) {
ret = xmlSchemaValidateAttributes(ctxt, node,
@@ -7933,6 +9788,9 @@
ret = ctxt->err;
}
}
+ if ((ret == 0) && (variety->facetSet != NULL)) {
+ ret = xmlSchemaValidateFacets(ctxt, base, variety->facetSet, value);
+ }
if (value != NULL)
xmlFree(value);
@@ -7943,6 +9801,494 @@
ctxt->type = type;
return (ret);
}
+#endif
+
+/**
+ * xmlSchemaValidateSimpleTypeValue:
+ * @ctxt: a schema validation context
+ * @value: the value to be validated
+ * @fireErrors: shall errors be reported?
+ * @applyFacets: shall facets be applied?
+ *
+ * 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)
+{
+ xmlSchemaTypePtr type;
+ int ret = 0;
+ type = ctxt->type;
+
+ if (type->type == XML_SCHEMA_TYPE_BASIC) {
+ xmlNodePtr child;
+
+ if (ctxt->value != NULL) {
+ xmlSchemaFreeValue(ctxt->value);
+ ctxt->value = NULL;
+ }
+ 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:
+#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);
+ }
+ child = child->next;
+ }
+ ret = xmlSchemaValPredefTypeNode(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);
+ }
+ } else if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "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);
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating 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);
+ }
+
+ } else if ((applyFacets) &&
+ (type->facetSet != NULL)) {
+ xmlSchemaTypePtr builtIn;
+
+ /*
+ * Check facets. Be sure to pass the built-in type to
+ * xmlSchemaValidateFacetsInternal.
+ */
+ builtIn = type->baseType;
+ while (builtIn->type != XML_SCHEMA_TYPE_BASIC)
+ builtIn = builtIn->baseType;
+ ret = xmlSchemaValidateFacetsInternal(ctxt, builtIn,
+ type->facetSet, value, fireErrors);
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "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);
+ }
+ }
+ }
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+
+ xmlSchemaTypePtr tmpType;
+ const xmlChar *cur, *end;
+ xmlChar *tmp;
+ int 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);
+ 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);
+ len++;
+ ctxt->type = tmpType;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, tmp, 0, 1);
+ xmlFree(tmp);
+ 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);
+ }
+ break;
+ } else if (ret < 0)
+ break;
+ cur = end;
+ } while (*cur != 0);
+ /*
+ * Check facets.
+ */
+ if (ret < 0) {
+ xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "validating list simple type \"%s\"\n",
+ type->name, NULL);
+ } else if ((ret == 0) && (applyFacets) &&
+ (type->facetSet != NULL)) {
+ int expLen, okFacet = 0, hasFacet = 0;
+ 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, "%d", 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",
+ l, 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",
+ l, 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",
+ l, fl);
+ } else {
+ xmlSchemaVErr(ctxt, ctxt->cur, ret,
+ "The value is not valid with respect "
+ "to the facet \"%s\".\n",
+ 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);
+ }
+
+ }
+ /*
+ * Pattern facets are ORed at type level and ANDed
+ * if derived. Walk the base axis.
+ */
+ 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;
+
+ /*
+ * TODO: For all datatypes ·derived· by ·union· whiteSpace does
+ * not apply directly; however, 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.
+ *
+ * This means that the value is normalized by the first validating
+ * member type, then the facets of the union type are applied. This
+ * needs changing of the value!
+ */
+
+ /*
+ * 1.2.3 if {variety} is ·union· then the string must ·match· a
+ * literal in the ·lexical space· of at least one member of
+ * {member type definitions}
+ */
+ 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",
+ type->name, NULL);
+ ret = -1;
+ }
+ if (ret == 0) {
+ while (memberLink != NULL) {
+ ctxt->type = memberLink->type;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 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);
+ 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) {
+ xmlSchemaVErr(ctxt, ctxt->cur,
+ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1,
+ "The value is not valid.\n",
+ NULL, NULL);
+ }
+ }
+ }
+ }
+ ctxt->type = type;
+ return (ret);
+}
+
+/**
+ * xmlSchemaValidateSimpleTypeElement:
+ * @ctxt: a schema validation context
+ * @node: the element node to be validated.
+ *
+ * Validate the element against a simple type.
+ *
+ * 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
+xmlSchemaValidateSimpleTypeElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
+{
+ xmlNodePtr child;
+ xmlSchemaTypePtr type;
+ xmlAttrPtr attr;
+ int ret;
+ xmlChar *value;
+
+
+ child = ctxt->node;
+ type = ctxt->type;
+
+ if ((ctxt == NULL) || (type == NULL)) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeElement %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: xmlSchemaValidateSimpleTypeElement %s content\n",
+ node->name, NULL);
+ return (-1);
+ } else if (ret == 0) {
+ /* 3.1.2 The element information item must have no element
+ * information item [children].
+ */
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_TYPE_3_1_2,
+ "Element \"%s\" must have no element children.\n",
+ node->name, NULL);
+ return (-1);
+ }
+ /*
+ * Validation Rule: Element Locally Valid (Type): 3.1.1
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if ((attr->ns == NULL) ||
+ (!xmlStrEqual(attr->ns->href, xmlSchemaInstanceNs)) ||
+ ((!xmlStrEqual(attr->name, BAD_CAST "type")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "nil")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation")) &&
+ (!xmlStrEqual
+ (attr->name, BAD_CAST "noNamespaceSchemaLocation")))) {
+ xmlSchemaVErr(ctxt, node,
+ XML_SCHEMAV_CVC_TYPE_3_1_1,
+ "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 "
+ "noNamespaceSchemaLocation.\n",
+ node->name, attr->name);
+ return (ctxt->err);
+ }
+ attr = attr->next;
+ }
+ value = xmlNodeGetContent(child);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ if (value != NULL)
+ xmlFree(value);
+
+ ctxt->type = type;
+ return (ret);
+}
/**
* xmlSchemaValidateElementType:
@@ -7965,6 +10311,7 @@
int ret;
xmlSchemaAttrStatePtr attrs = NULL, attrTop = NULL;
+ /* This one is called by xmlSchemaValidateContent only. */
/*
* TODO: Look into "xmlSchemaValidateElement" for missing parts, which should
* go in here as well.
@@ -8010,13 +10357,7 @@
attrs = ctxt->attr;
attrTop = ctxt->attrTop;
- xmlSchemaRegisterAttributes(ctxt, child->properties);
-
- /*
- * An element declaration does not hold any information about
- * attributes; thus, the following was removed.
- */
- /* xmlSchemaValidateAttributes(ctxt, child, type->attributes); */
+ xmlSchemaRegisterAttributes(ctxt, child->properties);
/*
* Verify the element content recursively
@@ -8072,6 +10413,7 @@
return (ctxt->err);
}
+#if 0 /* Not currently used. */
/**
* xmlSchemaValidateBasicType:
* @ctxt: a schema validation context
@@ -8099,6 +10441,13 @@
node->name, NULL);
return (-1);
}
+ if (type->type != XML_SCHEMA_TYPE_BASIC) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
+ "Internal error: xmlSchemaValidateBasicType, "
+ "the given type is not a built-in type.\n",
+ node->name, NULL);
+ return (-1);
+ }
/*
* First check the content model of the node.
*/
@@ -8150,9 +10499,11 @@
xmlSchemaFreeValue(ctxt->value);
ctxt->value = NULL;
}
+
ret = xmlSchemaValidatePredefinedType(type, value, &(ctxt->value));
+
if (value != NULL)
- xmlFree(value);
+ xmlFree(value);
if (ret != 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_VALUE,
"Element %s: failed to validate basic type %s\n",
@@ -8160,6 +10511,7 @@
}
return (ret);
}
+#endif
/**
* xmlSchemaValidateComplexType:
@@ -8171,112 +10523,221 @@
* Validation Rule: Element Locally Valid (Complex Type)
*
* Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
+ * number otherwise and -1 in case of 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.
*/
static int
xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
xmlNodePtr child;
- xmlSchemaTypePtr type, subtype;
- int ret;
-
- /* TODO: Handle xsd:restriction & xsd:extension */
+ xmlSchemaTypePtr type;
+ int ret = 0;
child = ctxt->node;
type = ctxt->type;
ctxt->cur = node;
switch (type->contentType) {
- case XML_SCHEMA_CONTENT_EMPTY:
- if (type->baseType != NULL) {
- } else if (child != NULL) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTEMPTY,
- "Element %s is supposed to be empty\n",
- node->name, NULL);
- }
- /* Removed due to changes of attribute validation:
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
- }
+ case XML_SCHEMA_CONTENT_EMPTY: {
+ /*
+ * 1 If the {content type} is empty, then the element information
+ * item has no character or element information item [children].
*/
- subtype = type->subtypes;
- while (subtype != NULL) {
- ctxt->type = subtype;
- xmlSchemaValidateComplexType(ctxt, node);
- subtype = subtype->next;
- }
- break;
- case XML_SCHEMA_CONTENT_ELEMENTS:
- case XML_SCHEMA_CONTENT_MIXED:
- case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
- /*
- * Skip ignorable nodes in that context
- */
- /* ComplexType, ComplexContent */
+ /* TODO: Hmm, Xerces reports nodes like Comment to be invalid
+ * content, but XSV does not.
+ */
+ /*
+ * TODO: Is the entity stuff correct?
+ */
+ while (child != NULL) {
+ if ((child->type == XML_ELEMENT_NODE) ||
+ /*
+ * TODO: Ask Daniel if this are all character nodes.
+ */
+ (child->type == XML_TEXT_NODE) ||
+ (child->type == XML_CDATA_SECTION_NODE) ||
+ (child->type == XML_ENTITY_REF_NODE) ||
+ (child->type == XML_ENTITY_NODE)) {
+ break;
+ }
+ child = child->next;
+ }
if (child != NULL) {
- child = xmlSchemaSkipIgnored(ctxt, type, child);
- while (child != NULL) {
- if (child->type == XML_ELEMENT_NODE) {
- ret = xmlRegExecPushString(ctxt->regexp,
- child->name, child);
-#ifdef DEBUG_AUTOMATA
- if (ret < 0)
- xmlGenericError(xmlGenericErrorContext,
- " --> %s Error\n", child->name);
- else
- xmlGenericError(xmlGenericErrorContext,
- " --> %s\n", child->name);
-#endif
- }
- child = child->next;
- /*
- * Skip ignorable nodes in that context
- */
- child = xmlSchemaSkipIgnored(ctxt, type, child);
- }
- }
-
- if (((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
- (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS)) &&
- (type->subtypes != NULL)) {
- TODO
- }
-
- /* Removed due to changes of attribute validation:
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
- }
- */
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1,
+ "Character or element children are not allowed, "
+ "because the content type is empty.\n",
+ NULL, NULL);
+ }
break;
- case XML_SCHEMA_CONTENT_BASIC:{
- if (type->subtypes != NULL) {
- ctxt->type = type->subtypes;
- xmlSchemaValidateComplexType(ctxt, node);
- }
- if (type->baseType != NULL) {
- ctxt->type = type->baseType;
- if (type->baseType->type == XML_SCHEMA_TYPE_BASIC)
- xmlSchemaValidateBasicType(ctxt, node);
- else if (type->baseType->type == XML_SCHEMA_TYPE_COMPLEX)
- xmlSchemaValidateComplexType(ctxt, node);
- /* TODO: This might be incorrect. */
- else if (type->baseType->type == XML_SCHEMA_TYPE_SIMPLE)
- xmlSchemaValidateSimpleType(ctxt, node);
+ }
+ case XML_SCHEMA_CONTENT_ELEMENTS:
+ 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 (ret < 0)
+ xmlGenericError(xmlGenericErrorContext,
+ " --> %s Error\n", child->name);
else
xmlGenericError(xmlGenericErrorContext,
- "unexpected content type of base: %d\n",
- type->contentType);
- }
- /* Removed due to changes of attribute validation:
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node,
- type->attributes);
- }
+ " --> %s\n", child->name);
+#endif
+ } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) &&
+ /*
+ * TODO: Ask Daniel if this are all character nodes.
+ */
+ (((child->type == XML_TEXT_NODE) && (!IS_BLANK_NODE(child))) ||
+ (child->type == XML_ENTITY_NODE) ||
+ (child->type == XML_ENTITY_REF_NODE) ||
+ (child->type == XML_CDATA_SECTION_NODE))) {
+ /*
+ * 2.3 If the {content type} is element-only, then the
+ * element information item has no character information
+ * item [children] other than those whose [character
+ * code] is defined as a white space in [XML 1.0 (Second
+ * Edition)].
+ */
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3,
+ "Character children are not allowed, "
+ "because the content type is element-only.\n",
+ NULL, NULL);
+ break;
+ }
+ child = child->next;
+ }
+ break;
+ case XML_SCHEMA_CONTENT_SIMPLE:
+ case XML_SCHEMA_CONTENT_BASIC:{
+ xmlSchemaTypePtr base, anyType;
+ xmlChar *value = NULL;
+ /*
+ * We hit a complexType with a simpleContent resolving
+ * to a user derived or built-in simple type.
+ */
+ anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ /*
+ * Internal check for integrity of the base type.
+ */
+ base = type->baseType;
+ while ((base != NULL) &&
+ (base->type != XML_SCHEMA_TYPE_SIMPLE) &&
+ (base->type != XML_SCHEMA_TYPE_BASIC) &&
+ (base != anyType)) {
+ base = base->baseType;
+ }
+ if ((base == NULL) ||
+ (((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) &&
+ (base->type != XML_SCHEMA_TYPE_SIMPLE)) ||
+ ((type->contentType == XML_SCHEMA_CONTENT_BASIC) &&
+ (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 "
+ "built-in simple type.\n",
+ node->name, type->name);
+ return (-1);
+ }
+ /*
+ * 2.2 If the {content type} is a simple type definition,
+ * then the element information item has no element
+ * information item [children], and the ·normalized value·
+ * of the element information item is ·valid· with respect
+ * to that simple type definition as defined by String
+ * Valid (§3.14.4).
+ */
+ child = node->children;
+ while (child != NULL) {
+ if (child->type == XML_ELEMENT_NODE) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
+ "Element children are not allowed, because "
+ "the content type is a simple type.\n",
+ NULL, NULL);
+ ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
+ break;
+ }
+ child = child->next;
+ }
+ if (ret == 0) {
+ /*
+ * Validate the character content against a simple type.
*/
- ctxt->type = type;
- break;
- }
- case XML_SCHEMA_CONTENT_SIMPLE:{
+ if (ctxt->node == NULL)
+ value = NULL;
+ else
+ value = xmlNodeGetContent(node);
+ ctxt->type = base;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ ctxt->type = type;
+ if (ret > 0) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
+ "The character value "
+ "is not valid with respect to the simple type.\n",
+ NULL, NULL);
+ ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
+ } 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",
+ node->name, type->name);
+ return (-1);
+ }
+ }
+ if (ret == 0) {
+ /*
+ * Apply facets of the complexType. Be sure to pass the
+ * built-in type to xmlSchemaValidateFacetsInternal.
+ */
+ /* TODO: I don't know yet if the facets of the simple type
+ * 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);
+ if (ret > 0) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
+ "The character value "
+ "is not valid with respect to the simple type.\n",
+ NULL, NULL);
+ ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
+ } 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 "
+ "apply facets.\n",
+ type->name, NULL);
+ }
+ }
+ if (value != NULL)
+ xmlFree(value);
+ /* TODO: facets */
+ break;
+ }
+ /*
+ case XML_SCHEMA_CONTENT_SIMPLE:{
if (type->subtypes != NULL) {
ctxt->type = type->subtypes;
xmlSchemaValidateComplexType(ctxt, node);
@@ -8285,22 +10746,25 @@
ctxt->type = type->baseType;
xmlSchemaValidateComplexType(ctxt, node);
}
- /* Removed due to changes of attribute validation:
+ * 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)
+ if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
xmlSchemaValidateAttributes(ctxt, node, type);
+ }
+ ctxt->cur = node;
return (ctxt->err);
}
@@ -8325,10 +10789,6 @@
type = ctxt->type;
ctxt->cur = node;
- /*
- * Removed, since redundant.
- */
- /* xmlSchemaValidateAttributes(ctxt, node, type->attributes); */
ctxt->cur = node;
switch (type->type) {
@@ -8361,13 +10821,11 @@
break;
}
case XML_SCHEMA_TYPE_BASIC:
- xmlSchemaValidateBasicType(ctxt, node);
+ case XML_SCHEMA_TYPE_SIMPLE:
+ xmlSchemaValidateSimpleTypeElement(ctxt, node);
break;
case XML_SCHEMA_TYPE_FACET:
- TODO break;
- case XML_SCHEMA_TYPE_SIMPLE:
- xmlSchemaValidateSimpleType(ctxt, node);
- break;
+ TODO break;
case XML_SCHEMA_TYPE_SEQUENCE:
TODO break;
case XML_SCHEMA_TYPE_CHOICE:
@@ -8424,10 +10882,6 @@
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
TODO break;
}
- /*
- * Removed, since redundant.
- */
- /* xmlSchemaValidateAttributes(ctxt, node, type->attributes); */
if (ctxt->node == NULL)
return (ctxt->err);
@@ -8508,11 +10962,7 @@
ctxt->type = elemDecl->subtypes;
ctxt->node = elem->children;
- xmlSchemaValidateContent(ctxt, elem);
- /* Removed, since an element declaration does not hold any attribute
- * declarations */
- /* xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes); */
-
+ xmlSchemaValidateContent(ctxt, elem);
return (ctxt->err);
}
@@ -8622,6 +11072,7 @@
#endif
found = 1;
ctxt->cur = (xmlNodePtr) attr;
+ ctxt->node = attr->children;
if (attrDecl->subtypes == NULL) {
curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED;
@@ -8637,8 +11088,9 @@
continue;
}
value = xmlNodeListGetString(elem->doc, attr->children, 1);
- ret = xmlSchemaValidateSimpleValue(ctxt, attrDecl->subtypes,
- value);
+ ctxt->type = attrDecl->subtypes;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 1);
+ ctxt->type = type;
if (ret != 0)
curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
else
@@ -8749,8 +11201,9 @@
attr->name, nsURI);
if (attrDecl != NULL) {
value = xmlNodeListGetString(elem->doc, attr->children, 1);
- ret = xmlSchemaValidateSimpleValue(ctxt, attrDecl->subtypes,
- value);
+ ctxt->type = attrDecl->subtypes;
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1);
+ ctxt->type = type;
if (ret != 0)
curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
else
@@ -8804,22 +11257,7 @@
elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
elem->name, NULL, NULL);
}
- /*
- * special case whe elementFormDefault is unqualified for top-level elem.
- */
- /*
- * This was removed, since elementFormDefault does not apply to top-level
- * element declarations.
- */
- /*
- if ((elemDecl == NULL) && (elem->ns != NULL) &&
- (elem->parent != NULL) && (elem->parent->type != XML_ELEMENT_NODE) &&
- (xmlStrEqual(ctxt->schema->targetNamespace, elem->ns->href)) &&
- ((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
- elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
- elem->name, NULL, NULL);
- }
- */
+ /* This one is called by xmlSchemaValidateDocument only. */
/*
* 3.3.4 : 1
@@ -8903,7 +11341,7 @@
{
xmlNodePtr root;
xmlSchemaElementPtr elemDecl;
-
+
root = xmlDocGetRootElement(doc);
if (root == NULL) {
xmlSchemaVErr(ctxt, (xmlNodePtr) doc, XML_SCHEMAS_ERR_NOROOT,