summaryrefslogtreecommitdiff
path: root/xmlschemas.c
diff options
context:
space:
mode:
authorMike Hommey <glandium@debian.org>2005-04-04 18:23:13 +0000
committerMike Hommey <glandium@debian.org>2005-04-04 18:23:13 +0000
commit0fc063df3ab2ad380d532d210dd1001de473e51b (patch)
tree6f88f0a0f845dd6aec7807b18cb5618d93e159ac /xmlschemas.c
parent50e5b428562964b1eb2f876370058b34b47c5e90 (diff)
downloadlibxml2-0fc063df3ab2ad380d532d210dd1001de473e51b.tar.gz
Load /tmp/tmp.98zkCi/libxml2-2.6.19 intoupstream/2.6.19
packages/libxml2/branches/upstream/current.
Diffstat (limited to 'xmlschemas.c')
-rw-r--r--xmlschemas.c7615
1 files changed, 4573 insertions, 3042 deletions
diff --git a/xmlschemas.c b/xmlschemas.c
index 41add1c..34bd48d 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -15,6 +15,12 @@
* - if we don't intend to use the schema for schemas, we
* need to validate all schema attributes (ref, type, name)
* against their types.
+ * - Eliminate item creation for: ??
+ *
+ * NOTES:
+ * - Elimated item creation for: <restriction>, <extension>,
+ * <simpleContent>, <complexContent>, <list>, <union>
+ *
*/
#define IN_LIBXML
#include "libxml.h"
@@ -52,15 +58,11 @@
/* #define DEBUG_UNION_VALIDATION 1 */
-#define ELEM_INFO_ENABLED 1
-
-#define IDC_ENABLED 1
-
-#define IDC_VALUE_SUPPORT 1
+/* #define DEBUG_IDC 1 */
-#define IDC_XPATH_SUPPORT 1
+/* #define DEBUG_INCLUDES 1 */
-/* #define DEBUG_IDC 1 */
+#define DUMP_CONTENT_MODEL
#define UNBOUNDED (1 << 30)
@@ -94,8 +96,10 @@ static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
"complex type";
static const xmlChar *xmlSchemaElemModelGrDef = (const xmlChar *)
"Model group";
+#if 0
static const xmlChar *xmlSchemaElemModelGrRef = (const xmlChar *)
"Model group ref.";
+#endif
#define IS_SCHEMA(node, type) \
((node != NULL) && (node->ns != NULL) && \
@@ -109,8 +113,8 @@ static const xmlChar *xmlSchemaElemModelGrRef = (const xmlChar *)
}
#define IS_ANYTYPE(item) \
- ((item->type == XML_SCHEMA_TYPE_BASIC) && \
- (item->builtInType == XML_SCHEMAS_ANYTYPE))
+ ((item->type == XML_SCHEMA_TYPE_BASIC) && \
+ (item->builtInType == XML_SCHEMAS_ANYTYPE))
#define IS_COMPLEX_TYPE(item) \
((item->type == XML_SCHEMA_TYPE_COMPLEX) || \
@@ -121,6 +125,30 @@ static const xmlChar *xmlSchemaElemModelGrRef = (const xmlChar *)
((item->type == XML_SCHEMA_TYPE_BASIC) && \
(item->builtInType != XML_SCHEMAS_ANYTYPE)))
+#define IS_ANY_SIMPLE_TYPE(item) \
+ ((item->type == XML_SCHEMA_TYPE_BASIC) && \
+ (item->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
+
+#define IS_NOT_TYPEFIXED(item) \
+ ((item->type != XML_SCHEMA_TYPE_BASIC) && \
+ ((item->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
+
+#define HAS_COMPLEX_CONTENT(item) \
+ ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
+ (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
+ (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
+
+#define GET_NODE(item) xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) item)
+
+#define IS_MODEL_GROUP(item) \
+ ((item->type == XML_SCHEMA_TYPE_SEQUENCE) || \
+ (item->type == XML_SCHEMA_TYPE_CHOICE) || \
+ (item->type == XML_SCHEMA_TYPE_ALL))
+
+#if 0
+#define WXS_GET_NEXT(item) xmlSchemaGetNextComponent((xmlSchemaBasicItemPtr) item)
+#endif
+
/*
#define XML_SCHEMAS_VAL_WTSP_PRESERVE 0
#define XML_SCHEMAS_VAL_WTSP_REPLACE 1
@@ -151,9 +179,13 @@ typedef enum {
} xmlSchemaParserOption;
*/
-typedef struct _xmlSchemaAssemble xmlSchemaAssemble;
+typedef struct _xmlSchemaItemList xmlSchemaAssemble;
typedef xmlSchemaAssemble *xmlSchemaAssemblePtr;
-struct _xmlSchemaAssemble {
+
+typedef struct _xmlSchemaItemList xmlSchemaItemList;
+typedef xmlSchemaItemList *xmlSchemaItemListPtr;
+
+struct _xmlSchemaItemList {
void **items; /* used for dynamic addition of schemata */
int nbItems; /* used for dynamic addition of schemata */
int sizeItems; /* used for dynamic addition of schemata */
@@ -223,21 +255,113 @@ struct _xmlSchemaAttrState {
const xmlChar *value;
};
+/**
+ * xmlSchemaBasicItem:
+ *
+ * The abstract base type for schema components.
+ */
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
struct _xmlSchemaBasicItem {
xmlSchemaTypeType type;
+};
+
+/**
+ * xmlSchemaAnnotItem:
+ *
+ * The abstract base type for annotated schema components.
+ * (Extends xmlSchemaBasicItem)
+ */
+typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
+typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
+struct _xmlSchemaAnnotItem {
+ xmlSchemaTypeType type;
xmlSchemaAnnotPtr annot;
};
-typedef struct _xmlSchemaItemQNRef xmlSchemaItemQNRef;
-typedef xmlSchemaItemQNRef *xmlSchemaItemQNRefPtr;
-struct _xmlSchemaItemQNRef {
+/**
+ * xmlSchemaTreeItem:
+ *
+ * The abstract base type for tree-like structured schema components.
+ * (Extends xmlSchemaAnnotItem)
+ */
+typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
+typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
+struct _xmlSchemaTreeItem {
+ xmlSchemaTypeType type;
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTreeItemPtr next;
+ xmlSchemaTreeItemPtr children;
+};
+
+/**
+ * xmlSchemaQNameRef:
+ *
+ * A component reference item (not a schema component)
+ * (Extends xmlSchemaBasicItem)
+ */
+typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
+typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
+struct _xmlSchemaQNameRef {
+ xmlSchemaTypeType type;
xmlSchemaBasicItemPtr item;
+ xmlSchemaTypeType itemType;
const xmlChar *name;
const xmlChar *targetNamespace;
};
+/**
+ * xmlSchemaParticle:
+ *
+ * A particle component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaParticle xmlSchemaParticle;
+typedef xmlSchemaParticle *xmlSchemaParticlePtr;
+struct _xmlSchemaParticle {
+ xmlSchemaTypeType type;
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTreeItemPtr next; /* next particle (OR "element decl" OR "wildcard") */
+ xmlSchemaTreeItemPtr children; /* the "term" ("model group" OR "group definition") */
+ int minOccurs;
+ int maxOccurs;
+ xmlNodePtr node;
+};
+
+/**
+ * xmlSchemaModelGroup:
+ *
+ * A model group component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
+typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
+struct _xmlSchemaModelGroup {
+ xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTreeItemPtr next; /* not used */
+ xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
+ xmlNodePtr node;
+};
+
+/**
+ * xmlSchemaModelGroupDef:
+ *
+ * A model group definition component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
+typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
+struct _xmlSchemaModelGroupDef {
+ xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTreeItemPtr next; /* not used */
+ xmlSchemaTreeItemPtr children; /* the "model group" */
+ const xmlChar *name;
+ const xmlChar *targetNamespace;
+ xmlNodePtr node;
+};
+
typedef struct _xmlSchemaIDC xmlSchemaIDC;
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
@@ -261,6 +385,7 @@ struct _xmlSchemaIDCSelect {
* xmlSchemaIDC:
*
* The identity-constraint definition component.
+ * (Extends xmlSchemaAnnotItem)
*/
struct _xmlSchemaIDC {
@@ -273,7 +398,7 @@ struct _xmlSchemaIDC {
xmlSchemaIDCSelectPtr selector;
xmlSchemaIDCSelectPtr fields;
int nbFields;
- xmlSchemaItemQNRefPtr ref;
+ xmlSchemaQNameRefPtr ref;
};
/**
@@ -286,7 +411,7 @@ typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
struct _xmlSchemaIDCAug {
xmlSchemaIDCAugPtr next; /* next in a list */
xmlSchemaIDCPtr def; /* the IDC definition */
- int bubbleDepth; /* the lowest level to which IDC
+ int bubbleDepth; /* the lowest tree level to which IDC
tables need to be bubbled upwards */
};
@@ -408,12 +533,13 @@ struct _xmlSchemaNodeInfo {
element */
};
+#define XML_SCHEMA_VALID_INVALID_NEG_WILDCARD 1<<0
+
/**
* xmlSchemaValidCtxt:
*
* A Schemas validation context
*/
-
struct _xmlSchemaValidCtxt {
void *userData; /* user specific data block */
xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
@@ -446,14 +572,13 @@ struct _xmlSchemaValidCtxt {
xmlNodePtr validationRoot;
xmlSchemaParserCtxtPtr pctxt;
int xsiAssemble;
-#ifdef ELEM_INFO_ENABLED
+
int depth;
xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
int sizeElemInfos;
xmlSchemaNodeInfoPtr nodeInfo; /* the current element information */
xmlSchemaNodeInfoPtr attrInfo; /* node infor for the current attribute */
-#endif
-#ifdef IDC_ENABLED
+
xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
@@ -466,7 +591,8 @@ struct _xmlSchemaValidCtxt {
xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
int nbIdcKeys;
int sizeIdcKeys;
-#endif
+
+ int flags;
};
/*
@@ -494,36 +620,6 @@ struct _xmlSchemaInclude {
const xmlChar *targetNamespace;
};
-typedef struct _xmlSchemaParticle xmlSchemaParticle;
-typedef xmlSchemaParticle *xmlSchemaParticlePtr;
-struct _xmlSchemaParticle {
- xmlSchemaTypeType type;
- xmlSchemaParticlePtr next; /* the next particle if in a list */
- int minOccurs;
- int maxOccurs;
- xmlSchemaTypePtr term;
-};
-
-
-typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
-typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
-struct _xmlSchemaModelGroup {
- xmlSchemaTypeType type;
- int compositor; /* one of all, choice or sequence */
- xmlSchemaParticlePtr particles; /* list of particles */
- xmlSchemaAnnotPtr annot;
-};
-
-typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
-typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
-struct _xmlSchemaModelGroupDef {
- xmlSchemaTypeType type;
- const xmlChar *name;
- const xmlChar *targetNamespace;
- xmlSchemaModelGroupPtr modelGroup;
- xmlSchemaAnnotPtr annot;
-};
-
/************************************************************************
* *
* Some predeclarations *
@@ -551,17 +647,34 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaElementPtr elemDecl);
static int
xmlSchemaValidateElementByWildcard(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type);
+ xmlSchemaWildcardPtr wild);
static int
xmlSchemaHasElemOrCharContent(xmlNodePtr node);
static int
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node);
static void
-xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
- xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
+xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
+ xmlSchemaParserCtxtPtr ctxt);
static void
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
+static int
+xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
+ xmlSchemaTypePtr type,
+ const xmlChar *value,
+ xmlSchemaValPtr *val);
+static xmlSchemaTypePtr
+xmlSchemaGetSimpleContentType(xmlSchemaTypePtr complexType);
+static int
+xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlNodePtr node, xmlSchemaTypeType type,
+ int withParticle);
+static const xmlChar *
+xmlSchemaCompTypeToString(xmlSchemaTypeType type);
+static xmlSchemaTypeLinkPtr
+xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
/************************************************************************
* *
@@ -824,6 +937,90 @@ xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
}
/**
+ * xmlSchemaGetComponentNode:
+ * @item: a schema component
+ *
+ * Returns node associated with the schema component.
+ * NOTE that such a node need not be available; plus, a component's
+ * node need not to reflect the component directly, since there is no
+ * one-to-one relationship between the XML Schema representation and
+ * the component representation.
+ */
+static xmlNodePtr
+xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
+{
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return (((xmlSchemaElementPtr) item)->node);
+ case XML_SCHEMA_TYPE_ATTRIBUTE:
+ return (((xmlSchemaAttributePtr) item)->node);
+ case XML_SCHEMA_TYPE_COMPLEX:
+ case XML_SCHEMA_TYPE_SIMPLE:
+ return (((xmlSchemaTypePtr) item)->node);
+ case XML_SCHEMA_TYPE_ANY:
+ case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+ return (((xmlSchemaWildcardPtr) item)->node);
+ case XML_SCHEMA_TYPE_PARTICLE:
+ return (((xmlSchemaParticlePtr) item)->node);
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL:
+ return (((xmlSchemaModelGroupPtr) item)->node);
+ case XML_SCHEMA_TYPE_GROUP:
+ return (((xmlSchemaModelGroupDefPtr) item)->node);
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+ return (((xmlSchemaAttributeGroupPtr) item)->node);
+ case XML_SCHEMA_TYPE_IDC_UNIQUE:
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ return (((xmlSchemaIDCPtr) item)->node);
+ default:
+ return (NULL);
+ }
+}
+
+#if 0
+/**
+ * xmlSchemaGetNextComponent:
+ * @item: a schema component
+ *
+ * Returns the next sibling of the schema component.
+ */
+static xmlSchemaBasicItemPtr
+xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
+{
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
+ case XML_SCHEMA_TYPE_ATTRIBUTE:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
+ case XML_SCHEMA_TYPE_COMPLEX:
+ case XML_SCHEMA_TYPE_SIMPLE:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
+ case XML_SCHEMA_TYPE_ANY:
+ case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+ return (NULL);
+ case XML_SCHEMA_TYPE_PARTICLE:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL:
+ return (NULL);
+ case XML_SCHEMA_TYPE_GROUP:
+ return (NULL);
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
+ case XML_SCHEMA_TYPE_IDC_UNIQUE:
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
+ default:
+ return (NULL);
+ }
+}
+#endif
+
+/**
* xmlSchemaGetAttrName:
* @attr: the attribute declaration/use
*
@@ -945,6 +1142,71 @@ xmlSchemaFormatQName(xmlChar **buf,
return ((const xmlChar *) *buf);
}
+static const xmlChar *
+xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
+{
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return (((xmlSchemaElementPtr) item)->name);
+ case XML_SCHEMA_TYPE_ATTRIBUTE:
+ return (((xmlSchemaAttributePtr) item)->name);
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+ return (((xmlSchemaAttributeGroupPtr) item)->name);
+ case XML_SCHEMA_TYPE_SIMPLE:
+ case XML_SCHEMA_TYPE_COMPLEX:
+ return (((xmlSchemaTypePtr) item)->name);
+ case XML_SCHEMA_TYPE_GROUP:
+ return (((xmlSchemaModelGroupDefPtr) item)->name);
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ case XML_SCHEMA_TYPE_IDC_UNIQUE:
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ return (((xmlSchemaIDCPtr) item)->name);
+ default:
+ /*
+ * Other components cannot have names.
+ */
+ break;
+ }
+ return (NULL);
+}
+
+static const xmlChar *
+xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
+{
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return (((xmlSchemaElementPtr) item)->targetNamespace);
+ case XML_SCHEMA_TYPE_ATTRIBUTE:
+ return (((xmlSchemaAttributePtr) item)->targetNamespace);
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+ return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
+ case XML_SCHEMA_TYPE_SIMPLE:
+ case XML_SCHEMA_TYPE_COMPLEX:
+ return (((xmlSchemaTypePtr) item)->targetNamespace);
+ case XML_SCHEMA_TYPE_GROUP:
+ return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ case XML_SCHEMA_TYPE_IDC_UNIQUE:
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ return (((xmlSchemaIDCPtr) item)->targetNamespace);
+ default:
+ /*
+ * Other components cannot have names.
+ */
+ break;
+ }
+ return (NULL);
+}
+
+static const xmlChar*
+xmlSchemaGetComponentQName(xmlChar **buf,
+ void *item)
+{
+ return (xmlSchemaFormatQName(buf,
+ xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
+ xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
+}
+
/**
* xmlSchemaWildcardPCToString:
* @pc: the type of processContents
@@ -1097,6 +1359,7 @@ xmlSchemaFormatItemForReport(xmlChar **buf,
*buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
*buf = xmlStrcat(*buf, BAD_CAST "'");
break;
+ case XML_SCHEMA_TYPE_ANY:
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
*buf = xmlStrdup(xmlSchemaWildcardPCToString(
((xmlSchemaWildcardPtr) item)->processContents));
@@ -1121,19 +1384,24 @@ xmlSchemaFormatItemForReport(xmlChar **buf,
case XML_SCHEMA_TYPE_NOTATION:
*buf = xmlStrdup(BAD_CAST "notation");
break;
- case XML_SCHEMA_TYPE_GROUP:
- if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+ case XML_SCHEMA_TYPE_GROUP: {
+ xmlChar *s = NULL;
+
*buf = xmlStrdup(xmlSchemaElemModelGrDef);
*buf = xmlStrcat(*buf, BAD_CAST " '");
- *buf = xmlStrcat(*buf, item->name);
- *buf = xmlStrcat(*buf, BAD_CAST "'");
- } else {
- *buf = xmlStrdup(xmlSchemaElemModelGrRef);
- *buf = xmlStrcat(*buf, BAD_CAST " '");
- *buf = xmlStrcat(*buf, item->ref);
+ *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&s,
+ ((xmlSchemaModelGroupDefPtr) item)->targetNamespace,
+ ((xmlSchemaModelGroupDefPtr) item)->name));
*buf = xmlStrcat(*buf, BAD_CAST "'");
+ FREE_AND_NULL(s)
}
break;
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL:
+ case XML_SCHEMA_TYPE_PARTICLE:
+ *buf = xmlStrdup(xmlSchemaCompTypeToString(item->type));
+ break;
default:
named = 0;
}
@@ -1192,6 +1460,59 @@ xmlSchemaPRequestItemDes(xmlChar **buf,
}
/**
+ * xmlSchemaGetCanonValueWhtsp:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ * @ws: the whitespace type of the value
+ *
+ * Get a the cononical representation of the value.
+ * The caller has to free the returned retValue.
+ *
+ * Returns 0 if the value could be built and -1 in case of
+ * API errors or if the value type is not supported yet.
+ */
+static int
+xmlSchemaGetCanonValueWhtsp(const xmlChar *value,
+ xmlSchemaValPtr val,
+ xmlSchemaWhitespaceValueType ws,
+ const xmlChar **retValue)
+{
+ xmlSchemaValType valType;
+
+ if ((retValue == NULL) || (value == NULL) || (val == NULL))
+ return (-1);
+ *retValue = NULL;
+ valType = xmlSchemaGetValType(val);
+ switch (valType) {
+ case XML_SCHEMAS_STRING:
+ if (value == NULL)
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+ else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ *retValue = xmlSchemaCollapseString(value);
+ else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
+ *retValue = xmlSchemaWhiteSpaceReplace(value);
+ if ((*retValue) == NULL)
+ *retValue = BAD_CAST xmlStrdup(value);
+ break;
+ case XML_SCHEMAS_NORMSTRING:
+ if (value == NULL)
+ *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+ else {
+ if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+ *retValue = xmlSchemaCollapseString(value);
+ else
+ *retValue = xmlSchemaWhiteSpaceReplace(value);
+ if ((*retValue) == NULL)
+ *retValue = BAD_CAST xmlStrdup(value);
+ }
+ break;
+ default:
+ return (xmlSchemaGetCanonValue(val, retValue));
+ }
+ return (0);
+}
+
+/**
* xmlSchemaFormatFacetEnumSet:
* @buf: the string buffer
* @type: the type holding the enumeration facets
@@ -1203,24 +1524,56 @@ xmlSchemaPRequestItemDes(xmlChar **buf,
static const xmlChar *
xmlSchemaFormatFacetEnumSet(xmlChar **buf, xmlSchemaTypePtr type)
{
- xmlSchemaFacetLinkPtr link;
+ xmlSchemaFacetPtr facet;
+ xmlSchemaWhitespaceValueType ws;
+ const xmlChar *value = NULL;
+ int res, found = 0;
if (*buf != NULL)
xmlFree(*buf);
*buf = NULL;
- for (link = type->facetSet; link != NULL; link = link->next) {
- if (link->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
+
+ do {
+ /*
+ * Use the whitespace type of the base type.
+ */
+ ws = (xmlSchemaWhitespaceValueType)
+ xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
+ for (facet = type->facets; facet != NULL; facet = facet->next) {
+ if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
+ continue;
+ found = 1;
+ res = xmlSchemaGetCanonValueWhtsp(facet->value, facet->val,
+ ws, &value);
+ if (res == -1) {
+ xmlSchemaVErr(NULL, NULL,
+ XML_SCHEMAV_INTERNAL,
+ "Internal error: xmlSchemaFormatFacetEnumSet, failed to "
+ "compute the canonical lexical representation.\n",
+ NULL, NULL);
+ if (*buf != NULL)
+ xmlFree(*buf);
+ *buf = NULL;
+ return (NULL);
+ }
if (*buf == NULL) {
*buf = xmlStrdup(BAD_CAST "'");
- *buf = xmlStrcat(*buf, link->facet->value);
+ *buf = xmlStrcat(*buf, value);
*buf = xmlStrcat(*buf, BAD_CAST "'");
} else {
*buf = xmlStrcat(*buf, BAD_CAST ", '");
- *buf = xmlStrcat(*buf, link->facet->value);
+ *buf = xmlStrcat(*buf, value);
*buf = xmlStrcat(*buf, BAD_CAST "'");
}
+ if (value != NULL) {
+ xmlFree((xmlChar *)value);
+ value = NULL;
+ }
}
- }
+ type = type->baseType;
+ } while ((! found) && (type != NULL) &&
+ (type->type != XML_SCHEMA_TYPE_BASIC));
+
return ((const xmlChar *) *buf);
}
@@ -1320,7 +1673,29 @@ xmlSchemaVFacetErr(xmlSchemaValidCtxtPtr ctxt,
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
"by the pattern '%s'.\n");
xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
- facet->value);
+ facet->value);
+ } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
+ "minimum value allowed ('%s').\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ facet->value);
+ } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
+ "maximum value allowed ('%s').\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ facet->value);
+#if 0
+ } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
+ "minimum exclusive value allowed ('%s').\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ facet->value);
+ } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
+ msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
+ "maximum exclusive value allowed ('%s').\n");
+ xmlSchemaVErr(ctxt, node, error, (const char *) msg, value,
+ facet->value);
+#endif
} else if (node->type == XML_ATTRIBUTE_NODE) {
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, NULL);
@@ -1560,26 +1935,34 @@ xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
*
* Returns the component name of a schema item.
*/
-static const char *
+static const xmlChar *
xmlSchemaCompTypeToString(xmlSchemaTypeType type)
{
switch (type) {
case XML_SCHEMA_TYPE_SIMPLE:
- return("simple type definition");
+ return(BAD_CAST "simple type definition");
case XML_SCHEMA_TYPE_COMPLEX:
- return("complex type definition");
+ return(BAD_CAST "complex type definition");
case XML_SCHEMA_TYPE_ELEMENT:
- return("element declaration");
+ return(BAD_CAST "element declaration");
case XML_SCHEMA_TYPE_ATTRIBUTE:
- return("attribute declaration");
+ return(BAD_CAST "attribute declaration");
case XML_SCHEMA_TYPE_GROUP:
- return("model group definition");
+ return(BAD_CAST "model group definition");
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
- return("attribute group definition");
+ return(BAD_CAST "attribute group definition");
case XML_SCHEMA_TYPE_NOTATION:
- return("notation declaration");
+ return(BAD_CAST "notation declaration");
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ return(BAD_CAST "model group (sequence)");
+ case XML_SCHEMA_TYPE_CHOICE:
+ return(BAD_CAST "model group (choice)");
+ case XML_SCHEMA_TYPE_ALL:
+ return(BAD_CAST "model group (all)");
+ case XML_SCHEMA_TYPE_PARTICLE:
+ return(BAD_CAST "particle");
default:
- return("Not a schema component");
+ return(BAD_CAST "Not a schema component");
}
}
/**
@@ -1619,7 +2002,7 @@ xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
} else
des = *ownerDes;
if (refTypeStr == NULL)
- refTypeStr = xmlSchemaCompTypeToString(refType);
+ refTypeStr = (const char *) xmlSchemaCompTypeToString(refType);
xmlSchemaPErrExt(ctxt, ownerElem, error,
NULL, NULL, NULL,
"%s, attribute '%s': The QName value %s does not resolve to a(n) "
@@ -2087,11 +2470,12 @@ xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
{
switch (item->type) {
case XML_SCHEMA_TYPE_COMPLEX:
- case XML_SCHEMA_TYPE_SIMPLE:
- case XML_SCHEMA_TYPE_GROUP:
+ case XML_SCHEMA_TYPE_SIMPLE:
if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
return(1);
break;
+ case XML_SCHEMA_TYPE_GROUP:
+ return (1);
case XML_SCHEMA_TYPE_ELEMENT:
if ( ((xmlSchemaElementPtr) item)->flags &
XML_SCHEMAS_ELEM_GLOBAL)
@@ -2510,10 +2894,6 @@ xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr)
return;
if (attr->annot != NULL)
xmlSchemaFreeAnnot(attr->annot);
- if ((attr->flags & XML_SCHEMAS_ATTRGROUP_GLOBAL) &&
- (attr->attributeWildcard != NULL))
- xmlSchemaFreeWildcard(attr->attributeWildcard);
-
xmlFree(attr);
}
@@ -2536,6 +2916,59 @@ xmlSchemaFreeAttributeUseList(xmlSchemaAttributeLinkPtr attrUse)
}
/**
+ * xmlSchemaFreeQNameRef:
+ * @item: a QName reference structure
+ *
+ * Deallocatea a QName reference structure.
+ */
+static void
+xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
+{
+ xmlFree(item);
+}
+
+static int
+xmlSchemaAddVolatile(xmlSchemaPtr schema,
+ xmlSchemaBasicItemPtr item)
+{
+ xmlSchemaItemListPtr list;
+
+ if (schema->volatiles == NULL) {
+ schema->volatiles = (void *) xmlMalloc(sizeof(xmlSchemaItemList));
+ if (schema->volatiles == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "allocating list of volatiles", NULL);
+ return (-1);
+ }
+ memset(schema->volatiles, 0, sizeof(xmlSchemaItemList));
+
+ }
+ list = (xmlSchemaItemListPtr) schema->volatiles;
+ if (list->items == NULL) {
+ list->items = (void **) xmlMalloc(
+ 20 * sizeof(xmlSchemaBasicItemPtr));
+ if (list->items == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "allocating new volatile item buffer", NULL);
+ return (-1);
+ }
+ list->sizeItems = 20;
+ } else if (list->sizeItems <= list->nbItems) {
+ list->sizeItems *= 2;
+ list->items = (void **) xmlRealloc(list->items,
+ list->sizeItems * sizeof(xmlSchemaTypePtr));
+ if (list->items == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "growing volatile item buffer", NULL);
+ list->sizeItems = 0;
+ return (-1);
+ }
+ }
+ ((xmlSchemaBasicItemPtr *) list->items)[list->nbItems++] = (void *) item;
+ return (0);
+}
+
+/**
* xmlSchemaFreeTypeLinkList:
* @alink: a type link
*
@@ -2553,7 +2986,6 @@ xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
}
}
-#ifdef IDC_ENABLED
static void
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
{
@@ -2583,9 +3015,7 @@ xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
if (idcDef == NULL)
return;
if (idcDef->annot != NULL)
- xmlSchemaFreeAnnot(idcDef->annot);
- if (idcDef->ref != NULL)
- xmlFree(idcDef->ref);
+ xmlSchemaFreeAnnot(idcDef->annot);
/* Selector */
if (idcDef->selector != NULL) {
if (idcDef->selector->xpathComp != NULL)
@@ -2605,7 +3035,6 @@ xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
}
xmlFree(idcDef);
}
-#endif /* IDC_ENABLED */
/**
* xmlSchemaFreeElement:
@@ -2672,17 +3101,7 @@ xmlSchemaFreeType(xmlSchemaTypePtr type)
}
if (type->type != XML_SCHEMA_TYPE_BASIC) {
if (type->attributeUses != NULL)
- xmlSchemaFreeAttributeUseList(type->attributeUses);
- if ((type->attributeWildcard != NULL) &&
- ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
- (type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD))) {
- /*
- * NOTE: The only case where an attribute wildcard
- * is not owned, is if a complex type inherits it
- * from a base type.
- */
- xmlSchemaFreeWildcard(type->attributeWildcard);
- }
+ xmlSchemaFreeAttributeUseList(type->attributeUses);
}
if (type->memberTypes != NULL)
xmlSchemaFreeTypeLinkList(type->memberTypes);
@@ -2702,6 +3121,106 @@ xmlSchemaFreeType(xmlSchemaTypePtr type)
}
/**
+ * xmlSchemaFreeModelGroupDef:
+ * @item: a schema model group definition
+ *
+ * Deallocates a schema model group definition.
+ */
+static void
+xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
+{
+ if (item->annot != NULL)
+ xmlSchemaFreeAnnot(item->annot);
+ xmlFree(item);
+}
+
+/**
+ * xmlSchemaFreeModelGroup:
+ * @item: a schema model group
+ *
+ * Deallocates a schema model group structure.
+ */
+static void
+xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
+{
+ if (item->annot != NULL)
+ xmlSchemaFreeAnnot(item->annot);
+ xmlFree(item);
+}
+
+/**
+ * xmlSchemaFreeParticle:
+ * @type: a schema type structure
+ *
+ * Deallocate a Schema Type structure.
+ */
+static void
+xmlSchemaFreeParticle(xmlSchemaParticlePtr item)
+{
+ if (item->annot != NULL)
+ xmlSchemaFreeAnnot(item->annot);
+ xmlFree(item);
+}
+
+/**
+ * xmlSchemaFreeMiscComponents:
+ * @item: a schema component
+ *
+ * Deallocates misc. schema component structures.
+ */
+static void
+xmlSchemaFreeMiscComponents(xmlSchemaTreeItemPtr item)
+{
+ if (item == NULL)
+ return;
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_PARTICLE:
+ xmlSchemaFreeParticle((xmlSchemaParticlePtr) item);
+ return;
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL:
+ xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
+ return;
+ case XML_SCHEMA_TYPE_ANY:
+ case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+ xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
+ break;
+ default:
+ /* TODO: This should never be hit. */
+ TODO
+ return;
+ }
+}
+
+static void
+xmlSchemaFreeVolatiles(xmlSchemaPtr schema)
+{
+ if (schema->volatiles == NULL)
+ return;
+ {
+ xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->volatiles;
+ xmlSchemaTreeItemPtr item;
+ int i;
+
+ for (i = 0; i < list->nbItems; i++) {
+ if (list->items[i] != NULL) {
+ item = (xmlSchemaTreeItemPtr) list->items[i];
+ switch (item->type) {
+ case XML_SCHEMA_EXTRA_QNAMEREF:
+ xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
+ break;
+ default:
+ xmlSchemaFreeMiscComponents(item);
+ }
+ }
+ }
+ if (list->items != NULL)
+ xmlFree(list->items);
+ xmlFree(list);
+ }
+}
+/**
* xmlSchemaFreeTypeList:
* @type: a schema type structure
*
@@ -2731,6 +3250,8 @@ xmlSchemaFree(xmlSchemaPtr schema)
if (schema == NULL)
return;
+ if (schema->volatiles != NULL)
+ xmlSchemaFreeVolatiles(schema);
if (schema->notaDecl != NULL)
xmlHashFree(schema->notaDecl,
(xmlHashDeallocator) xmlSchemaFreeNotation);
@@ -2748,12 +3269,10 @@ xmlSchemaFree(xmlSchemaPtr schema)
(xmlHashDeallocator) xmlSchemaFreeTypeList);
if (schema->groupDecl != NULL)
xmlHashFree(schema->groupDecl,
- (xmlHashDeallocator) xmlSchemaFreeType);
-#ifdef IDC_ENABLED
+ (xmlHashDeallocator) xmlSchemaFreeModelGroupDef);
if (schema->idcDef != NULL)
xmlHashFree(schema->idcDef,
(xmlHashDeallocator) xmlSchemaFreeIDC);
-#endif
if (schema->schemasImports != NULL)
xmlHashFree(schema->schemasImports,
(xmlHashDeallocator) xmlSchemaFreeImport);
@@ -2894,6 +3413,72 @@ xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
* Dump a SchemaType structure
*/
static void
+xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
+{
+ xmlChar *str = NULL;
+ xmlSchemaTreeItemPtr term;
+ char shift[100];
+ int i;
+
+ if (particle == NULL)
+ return;
+ for (i = 0;((i < depth) && (i < 25));i++)
+ shift[2 * i] = shift[2 * i + 1] = ' ';
+ shift[2 * i] = shift[2 * i + 1] = 0;
+ fprintf(output, shift);
+ if (particle->children == NULL) {
+ fprintf(output, "MISSING particle term\n");
+ return;
+ }
+ term = particle->children;
+ switch (term->type) {
+ case XML_SCHEMA_TYPE_ELEMENT:
+ fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
+ ((xmlSchemaElementPtr)term)->targetNamespace,
+ ((xmlSchemaElementPtr)term)->name));
+ break;
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ fprintf(output, "SEQUENCE");
+ break;
+ case XML_SCHEMA_TYPE_CHOICE:
+ fprintf(output, "CHOICE");
+ break;
+ case XML_SCHEMA_TYPE_ALL:
+ fprintf(output, "ALL");
+ break;
+ case XML_SCHEMA_TYPE_ANY:
+ fprintf(output, "ANY");
+ break;
+ default:
+ fprintf(output, "UNKNOWN\n");
+ return;
+ }
+ if (particle->minOccurs != 1)
+ fprintf(output, " min: %d", particle->minOccurs);
+ if (particle->maxOccurs >= UNBOUNDED)
+ fprintf(output, " max: unbounded");
+ else if (particle->maxOccurs != 1)
+ fprintf(output, " max: %d", particle->maxOccurs);
+ fprintf(output, "\n");
+ if (((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+ (term->type == XML_SCHEMA_TYPE_CHOICE) ||
+ (term->type == XML_SCHEMA_TYPE_ALL)) &&
+ (term->children != NULL)) {
+ xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
+ output, depth +1);
+ }
+ if (particle->next != NULL)
+ xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
+ output, depth);
+}
+/**
+ * xmlSchemaTypeDump:
+ * @output: the file output
+ * @type: a type structure
+ *
+ * Dump a SchemaType structure
+ */
+static void
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
{
if (type == NULL) {
@@ -2967,15 +3552,6 @@ xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
break;
}
fprintf(output, "\n");
- if ((type->minOccurs != 1) || (type->maxOccurs != 1)) {
- fprintf(output, " min: %d ", type->minOccurs);
- if (type->maxOccurs >= UNBOUNDED)
- fprintf(output, "max: unbounded\n");
- else if (type->maxOccurs != 1)
- fprintf(output, "max: %d\n", type->maxOccurs);
- else
- fprintf(output, "\n");
- }
if (type->base != NULL) {
fprintf(output, " base type: %s", type->base);
if (type->baseNs != NULL)
@@ -2985,17 +3561,13 @@ xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
}
if (type->annot != NULL)
xmlSchemaAnnotDump(output, type->annot);
- if (type->subtypes != NULL) {
- xmlSchemaTypePtr sub = type->subtypes;
-
- fprintf(output, " subtypes: ");
- while (sub != NULL) {
- fprintf(output, "%s ", sub->name);
- sub = sub->next;
- }
- fprintf(output, "\n");
+#ifdef DUMP_CONTENT_MODEL
+ if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
+ (type->subtypes != NULL)) {
+ xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
+ output, 1);
}
-
+#endif
}
/**
@@ -3033,7 +3605,6 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
(xmlHashScannerFull) xmlSchemaElementDump, output);
}
-#ifdef IDC_ENABLED
#ifdef DEBUG_IDC
/**
* xmlSchemaDebugDumpIDCTable:
@@ -3069,12 +3640,7 @@ xmlSchemaDebugDumpIDCTable(FILE * output,
for (j = 0; j < bind->definition->nbFields; j++) {
key = tab->keys[j];
if ((key != NULL) && (key->compValue != NULL)) {
-#ifdef IDC_VALUE_SUPPORT
res = xmlSchemaGetCanonValue(key->compValue, &value);
-#else
- value = xmlStrdup(BAD_CAST "dummy-value");
- res = 0;
-#endif
if (res >= 0)
fprintf(output, "\"%s\" ", value);
else
@@ -3092,7 +3658,6 @@ xmlSchemaDebugDumpIDCTable(FILE * output,
} while (bind != NULL);
}
#endif /* DEBUG_IDC */
-#endif /* IDC_ENABLED */
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
@@ -3261,9 +3826,9 @@ xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
#ifdef DEBUG
if (ret == NULL) {
if (namespace == NULL)
- fprintf(stderr, "Unable to lookup type %s", name);
+ fprintf(stderr, "Unable to lookup element decl. %s", name);
else
- fprintf(stderr, "Unable to lookup type %s:%s", name,
+ fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
namespace);
}
#endif
@@ -3446,12 +4011,7 @@ xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
if ((name == NULL) || (schema == NULL))
return (NULL);
-
ret = xmlHashLookup2(schema->groupDecl, name, namespace);
- if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL))
- return (ret);
- else
- ret = NULL;
/*
* Removed since imported components will be hold by the main schema only.
*
@@ -3479,6 +4039,34 @@ xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
return (ret);
}
+/**
+ * xmlSchemaGetNamedComponent:
+ * @schema: the schema
+ * @name: the name of the group
+ * @ns: the target namespace of the group
+ *
+ * Lookup a group in the schema or imported schemas
+ *
+ * Returns the group definition or NULL if not found.
+ */
+static xmlSchemaTreeItemPtr
+xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
+ xmlSchemaTypeType itemType,
+ const xmlChar *name,
+ const xmlChar *targetNs)
+{
+ switch (itemType) {
+ case XML_SCHEMA_TYPE_GROUP:
+ return ((xmlSchemaTreeItemPtr) xmlSchemaGetGroup(schema,
+ name, targetNs));
+ case XML_SCHEMA_TYPE_ELEMENT:
+ return ((xmlSchemaTreeItemPtr) xmlSchemaGetElem(schema,
+ name, targetNs));
+ default:
+ return (NULL);
+ }
+}
+
/************************************************************************
* *
* Parsing functions *
@@ -3889,6 +4477,7 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
prev->redef = ret;
}
}
+ ret->node = node;
ret->minOccurs = 1;
ret->maxOccurs = 1;
ret->attributeUses = NULL;
@@ -3898,6 +4487,142 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (ret);
}
+static xmlSchemaQNameRefPtr
+xmlSchemaNewQNameRef(xmlSchemaPtr schema,
+ xmlSchemaTypeType refType,
+ const xmlChar *refName,
+ const xmlChar *refNs)
+{
+ xmlSchemaQNameRefPtr ret;
+
+ ret = (xmlSchemaQNameRefPtr)
+ xmlMalloc(sizeof(xmlSchemaQNameRef));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(NULL, "allocating QName reference item",
+ NULL);
+ return (NULL);
+ }
+ ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
+ ret->name = refName;
+ ret->targetNamespace = refNs;
+ ret->item = NULL;
+ ret->itemType = refType;
+ /*
+ * Store the reference item in the schema.
+ */
+ xmlSchemaAddVolatile(schema, (xmlSchemaBasicItemPtr) ret);
+ return (ret);
+}
+
+/**
+ * xmlSchemaAddModelGroup:
+ * @ctxt: a schema parser context
+ * @schema: the schema being built
+ * @type: the "compositor" type of the model group
+ * @container: the internal component name
+ * @node: the node in the schema doc
+ *
+ * Adds a schema model group
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaModelGroupPtr
+xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlSchemaTypeType type, const xmlChar **container,
+ xmlNodePtr node)
+{
+ xmlSchemaModelGroupPtr ret = NULL;
+ xmlChar buf[30];
+
+ if ((ctxt == NULL) || (schema == NULL))
+ return (NULL);
+
+#ifdef DEBUG
+ fprintf(stderr, "Adding model group component\n");
+#endif
+ ret = (xmlSchemaModelGroupPtr)
+ xmlMalloc(sizeof(xmlSchemaModelGroup));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating model group component",
+ NULL);
+ return (NULL);
+ }
+ ret->type = type;
+ ret->annot = NULL;
+ ret->node = node;
+ ret->children = NULL;
+ ret->next = NULL;
+ if (type == XML_SCHEMA_TYPE_SEQUENCE) {
+ if (container != NULL)
+ snprintf((char *) buf, 29, "#seq%d", ctxt->counter++ + 1);
+ } else if (type == XML_SCHEMA_TYPE_CHOICE) {
+ if (container != NULL)
+ snprintf((char *) buf, 29, "#cho%d", ctxt->counter++ + 1);
+ } else {
+ if (container != NULL)
+ snprintf((char *) buf, 29, "#all%d", ctxt->counter++ + 1);
+ }
+ if (container != NULL)
+ *container = xmlDictLookup(ctxt->dict, BAD_CAST buf, -1);
+ /*
+ * Add to volatile items.
+ * TODO: this should be changed someday.
+ */
+ if (xmlSchemaAddVolatile(schema, (xmlSchemaBasicItemPtr) ret) != 0) {
+ xmlFree(ret);
+ return (NULL);
+ }
+ return (ret);
+}
+
+
+/**
+ * xmlSchemaAddParticle:
+ * @ctxt: a schema parser context
+ * @schema: the schema being built
+ * @node: the corresponding node in the schema doc
+ * @min: the minOccurs
+ * @max: the maxOccurs
+ *
+ * Adds an XML schema particle component.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaParticlePtr
+xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlNodePtr node, int min, int max)
+{
+ xmlSchemaParticlePtr ret = NULL;
+ if ((ctxt == NULL) || (schema == NULL))
+ return (NULL);
+
+#ifdef DEBUG
+ fprintf(stderr, "Adding particle component\n");
+#endif
+ ret = (xmlSchemaParticlePtr)
+ xmlMalloc(sizeof(xmlSchemaParticle));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(ctxt, "allocating particle component",
+ NULL);
+ return (NULL);
+ }
+ ret->type = XML_SCHEMA_TYPE_PARTICLE;
+ ret->annot = NULL;
+ ret->node = node;
+ ret->minOccurs = min;
+ ret->maxOccurs = max;
+ ret->next = NULL;
+ ret->children = NULL;
+
+ if (xmlSchemaAddVolatile(schema, (xmlSchemaBasicItemPtr) ret) != 0) {
+ xmlFree(ret);
+ return (NULL);
+ }
+ return (ret);
+}
+
/**
* xmlSchemaAddGroup:
* @ctxt: a schema validation context
@@ -3908,12 +4633,12 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*
* Returns the new struture or NULL in case of error
*/
-static xmlSchemaTypePtr
+static xmlSchemaModelGroupDefPtr
xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
const xmlChar *name, const xmlChar *namespaceName,
xmlNodePtr node)
{
- xmlSchemaTypePtr ret = NULL;
+ xmlSchemaModelGroupDefPtr ret = NULL;
int val;
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
@@ -3924,16 +4649,17 @@ xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (schema->groupDecl == NULL)
return (NULL);
- ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+ ret = (xmlSchemaModelGroupDefPtr) xmlMalloc(sizeof(xmlSchemaModelGroupDef));
if (ret == NULL) {
xmlSchemaPErrMemory(ctxt, "adding group", NULL);
return (NULL);
}
- memset(ret, 0, sizeof(xmlSchemaType));
+ memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
ret->name = xmlDictLookup(ctxt->dict, name, -1);
- val =
- xmlHashAddEntry2(schema->groupDecl, name, namespaceName,
- ret);
+ ret->type = XML_SCHEMA_TYPE_GROUP;
+ ret->node = node;
+ ret->targetNamespace = namespaceName;
+ val = xmlHashAddEntry2(schema->groupDecl, ret->name, namespaceName, ret);
if (val != 0) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_REDEFINED_GROUP,
@@ -3942,10 +4668,7 @@ xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
"exist", name);
xmlFree(ret);
return (NULL);
- }
- ret->targetNamespace = namespaceName;
- ret->minOccurs = 1;
- ret->maxOccurs = 1;
+ }
if (ctxt->assemble != NULL)
xmlSchemaAddAssembledItem(ctxt, (xmlSchemaTypePtr) ret);
return (ret);
@@ -3978,29 +4701,42 @@ xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
/**
* xmlSchemaAddWildcard:
* @ctxt: a schema validation context
- * Adds a wildcard. It corresponds to a
- * xsd:anyAttribute and is used as storage for namespace
- * constraints on a xsd:any.
+ * @schema: a schema
+ *
+ * Adds a wildcard.
+ * It corresponds to a xsd:anyAttribute and xsd:any.
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaWildcardPtr
-xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt)
+xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlSchemaTypeType type, xmlNodePtr node)
{
xmlSchemaWildcardPtr ret = NULL;
- if (ctxt == NULL)
+ if ((ctxt == NULL) || (schema == NULL))
return (NULL);
+#ifdef DEBUG
+ fprintf(stderr, "Adding wildcard component\n");
+#endif
+
ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
if (ret == NULL) {
xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaWildcard));
+ ret->type = type;
ret->minOccurs = 1;
ret->maxOccurs = 1;
+ if (xmlSchemaAddVolatile(schema, (xmlSchemaBasicItemPtr) ret) != 0) {
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, NULL, NULL, node,
+ "Failed to add a wildcard component to the list", NULL);
+ xmlFree(ret);
+ return (NULL);
+ }
return (ret);
}
@@ -4010,6 +4746,7 @@ xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt)
* *
************************************************************************/
+#if 0
/**
* xmlGetQNameProp:
* @ctxt: a schema validation context
@@ -4067,6 +4804,7 @@ xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
}
return (ret);
}
+#endif
/**
* xmlSchemaPValAttrNodeQNameValue:
@@ -4128,7 +4866,7 @@ xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
*/
*uri = schema->targetNamespace;
}
- *local = value;
+ *local = xmlDictLookup(ctxt->dict, value, -1);
return (0);
}
/*
@@ -4137,7 +4875,7 @@ xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
*local = xmlSplitQName3(value, &len);
*local = xmlDictLookup(ctxt->dict, *local, -1);
pref = xmlDictLookup(ctxt->dict, value, len);
- if (prefix != 0)
+ if (prefix != 0)
*prefix = pref;
ns = xmlSearchNs(attr->doc, attr->parent, pref);
if (ns == NULL) {
@@ -4220,6 +4958,8 @@ xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
attr = xmlSchemaGetPropNode(ownerElem, name);
if (attr == NULL) {
*local = NULL;
+ if (prefix != NULL)
+ *prefix = NULL;
*uri = NULL;
return (0);
}
@@ -4532,13 +5272,8 @@ static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
ctxt,
xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
+ xmlNodePtr node,
+ xmlSchemaTypeType parentType);
static xmlSchemaAttributePtr xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr
ctxt,
xmlSchemaPtr schema,
@@ -4548,9 +5283,6 @@ static xmlSchemaAttributeGroupPtr
xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node,
int topLevel);
-static xmlSchemaTypePtr xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema,
xmlNodePtr node);
@@ -4793,7 +5525,7 @@ static int
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
xmlSchemaPtr schema,
xmlNodePtr node,
- xmlSchemaTypePtr item,
+ xmlSchemaBasicItemPtr item,
const xmlChar *namespaceName)
{
if (xmlStrEqual(schema->targetNamespace, namespaceName))
@@ -4806,12 +5538,14 @@ xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
}
if (namespaceName == NULL)
xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_SRC_RESOLVE,
- NULL, item, node, "References from this schema to components in no "
+ NULL, (xmlSchemaTypePtr) item, node,
+ "References from this schema to components in no "
"namespace are not valid, since not indicated by an import "
"statement", NULL);
else
xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_SRC_RESOLVE,
- NULL, item, node, "References from this schema to components in the "
+ NULL, (xmlSchemaTypePtr) item, node,
+ "References from this schema to components in the "
"namespace '%s' are not valid, since not indicated by an import "
"statement", namespaceName);
return (0);
@@ -4822,7 +5556,7 @@ xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
* @ctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
- * @type: the hosting type
+ * @type: the hosting type where the attributes will be anchored
*
* parse a XML schema attrDecls declaration corresponding to
* <!ENTITY % attrDecls
@@ -4832,9 +5566,8 @@ static xmlNodePtr
xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr child, xmlSchemaTypePtr type)
{
- xmlSchemaAttributePtr lastattr, attr;
+ xmlSchemaAttributePtr lastattr = NULL, attr;
- lastattr = NULL;
while ((IS_SCHEMA(child, "attribute")) ||
(IS_SCHEMA(child, "attributeGroup"))) {
attr = NULL;
@@ -4849,7 +5582,7 @@ xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (type->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
((xmlSchemaAttributeGroupPtr) type)->attributes = attr;
else
- type->attributes = attr;
+ type->attributes = attr;
lastattr = attr;
} else {
lastattr->next = attr;
@@ -5110,12 +5843,12 @@ xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
wildc->processContents = XML_SCHEMAS_ANY_LAX;
} else {
xmlSchemaPSimpleTypeErr(ctxt,
- XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
NULL, NULL, node,
NULL, "(strict | skip | lax)", pc,
NULL, NULL, NULL);
wildc->processContents = XML_SCHEMAS_ANY_STRICT;
- ret = XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD;
+ ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
}
/*
* Build the namespace constraints.
@@ -5200,11 +5933,13 @@ xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
static int
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaTypePtr item,
+ xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
xmlNodePtr node,
int minOccurs,
int maxOccurs) {
+ if ((maxOccurs == 0) && ( minOccurs == 0))
+ return (0);
if (maxOccurs != UNBOUNDED) {
/*
* TODO: Maby we should better not create the particle,
@@ -5221,7 +5956,8 @@ xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
*/
xmlSchemaPCustomAttrErr(ctxt,
XML_SCHEMAP_P_PROPS_CORRECT_2_2,
- NULL, item, xmlSchemaGetPropNode(node, "maxOccurs"),
+ NULL, NULL,
+ xmlSchemaGetPropNode(node, "maxOccurs"),
"The value must be greater than or equal to 1");
return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
} else if (minOccurs > maxOccurs) {
@@ -5230,7 +5966,8 @@ xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
*/
xmlSchemaPCustomAttrErr(ctxt,
XML_SCHEMAP_P_PROPS_CORRECT_2_1,
- NULL, item, xmlSchemaGetPropNode(node, "minOccurs"),
+ NULL, NULL,
+ xmlSchemaGetPropNode(node, "minOccurs"),
"The value must not be greater than the value of 'maxOccurs'");
return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
}
@@ -5244,67 +5981,95 @@ xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
*
- * parse a XML schema Any declaration
+ * Parsea a XML schema <any> element. A particle and wildcard
+ * will be created (except if minOccurs==maxOccurs==0, in this case
+ * nothing will be created).
* *WARNING* this interface is highly subject to change
*
- * Returns the new type structure or NULL in case of error
+ * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
*/
-static xmlSchemaTypePtr
+static xmlSchemaParticlePtr
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
- xmlSchemaTypePtr type;
+ xmlSchemaParticlePtr particle;
xmlNodePtr child = NULL;
- xmlChar name[30];
- xmlSchemaWildcardPtr wildc;
- int minOccurs, maxOccurs;
+ xmlSchemaWildcardPtr wild;
+ int min, max;
+ xmlAttrPtr attr;
+ xmlSchemaAnnotPtr annot = NULL;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
- "(nonNegativeInteger | unbounded)");
- minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
- "nonNegativeInteger");
- if ((minOccurs == 0) && (maxOccurs == 0))
- return (NULL);
-
- snprintf((char *) name, 30, "#any%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_ANY;
-
/*
- * TODO: Use a particle component here.
+ * Check for illegal attributes.
*/
- wildc = xmlSchemaAddWildcard(ctxt);
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
- * Check min/max sanity.
+ * minOccurs/maxOccurs.
+ */
+ max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+ "(nonNegativeInteger | unbounded)");
+ min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
+ "nonNegativeInteger");
+ xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
+ /*
+ * Create & parse the wildcard.
*/
- type->maxOccurs = maxOccurs;
- type->minOccurs = minOccurs;
- xmlSchemaPCheckParticleCorrect_2(ctxt, type,
- node, type->minOccurs, type->maxOccurs);
+ wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
+ if (wild == NULL)
+ return (NULL);
+ xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
/*
- * This is not nice, since it is won't be used as a attribute wildcard,
- * but better than adding a field to the structure.
+ * And now for the children...
*/
- type->attributeWildcard = wildc;
- xmlSchemaParseWildcardNs(ctxt, schema, wildc, node);
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
- "Sequence %s has unexpected content\n", type->name,
- NULL);
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child,
+ NULL, "(annotation?)");
}
+ /*
+ * No component if minOccurs==maxOccurs==0.
+ */
+ if ((min == 0) && (max == 0)) {
+ /* Don't free the wildcard, since it's already on the list. */
+ return (NULL);
+ }
+ /*
+ * Create the particle.
+ */
+ particle = xmlSchemaAddParticle(ctxt, schema, node, min, max);
+ if (particle == NULL)
+ return (NULL);
+ particle->annot = annot;
+ particle->children = (xmlSchemaTreeItemPtr) wild;
- return (type);
+ return (particle);
}
/**
@@ -5353,9 +6118,10 @@ xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
child = child->next;
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_NOTATION_CHILD,
- "notation %s has unexpected content\n", name, NULL);
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child,
+ NULL, "(annotation?)");
}
return (ret);
@@ -5383,11 +6149,11 @@ xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- ret = xmlSchemaAddWildcard(ctxt);
+ ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+ node);
if (ret == NULL) {
return (NULL);
}
- ret->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE;
/*
* Check for illegal attributes.
*/
@@ -5413,10 +6179,8 @@ xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
/*
* Parse the namespace list.
*/
- if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) {
- xmlSchemaFreeWildcard(ret);
+ if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
return (NULL);
- }
/*
* And now for the children...
*/
@@ -5515,7 +6279,8 @@ xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
ret->refNs = refNs;
ret->refPrefix = refPrefix;
ret->ref = ref;
- xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaTypePtr) ret, refNs);
+ xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaBasicItemPtr) ret,
+ refNs);
/*
xmlSchemaFormatTypeRep(&repName, (xmlSchemaTypePtr) ret, NULL, NULL);
*/
@@ -5850,7 +6615,8 @@ xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
/* TODO: Is @refPrefix currently used? */
ret->refPrefix = refPrefix;
ret->node = node;
- xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaTypePtr) ret, refNs);
+ xmlSchemaCheckReference(ctxt, schema, node,
+ (xmlSchemaBasicItemPtr) ret, refNs);
}
/*
* Check for illegal attributes.
@@ -6026,7 +6792,6 @@ xmlSchemaPValAttrBlockFinal(const xmlChar *value,
return (ret);
}
-#ifdef IDC_ENABLED
static int
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaIDCPtr idc,
@@ -6098,6 +6863,9 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
nsArray[count * 2] = NULL;
xmlFree(nsList);
}
+ /*
+ * TODO: Differentiate between "selector" and "field".
+ */
if (isField)
selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
NULL, 1, nsArray);
@@ -6107,7 +6875,6 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
if (nsArray != NULL)
xmlFree((xmlChar **) nsArray);
-#ifdef IDC_XPATH_SUPPORT
if (selector->xpathComp == NULL) {
xmlSchemaPCustomErr(ctxt,
/* TODO: Adjust error code? */
@@ -6116,12 +6883,23 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
"The XPath expression '%s' could not be "
"compiled", selector->xpath);
return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
- }
-#endif
+ }
}
return (0);
}
+#define ADD_ANNOTATION(annot) \
+ xmlSchemaAnnotPtr cur = item->annot; \
+ if (item->annot == NULL) { \
+ item->annot = annot; \
+ return (annot); \
+ } \
+ cur = item->annot; \
+ if (cur->next != NULL) { \
+ cur = cur->next; \
+ } \
+ cur->next = annot;
+
/**
* xmlSchemaAssignAnnotation:
* @item: the schema component
@@ -6132,20 +6910,89 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
* Returns the given annotaion.
*/
static xmlSchemaAnnotPtr
-xmlSchemaAssignAnnotation(xmlSchemaBasicItemPtr item,
- xmlSchemaAnnotPtr annot)
-{
- xmlSchemaAnnotPtr cur = item->annot;
-
- if (item->annot == NULL) {
- item->annot = annot;
- return (annot);
- }
- cur = item->annot;
- if (cur->next != NULL) {
- cur = cur->next;
+xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
+ xmlSchemaAnnotPtr annot)
+{
+ if ((annItem == NULL) || (annot == NULL))
+ return (NULL);
+ switch (annItem->type) {
+ case XML_SCHEMA_TYPE_ELEMENT: {
+ xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_ATTRIBUTE: {
+ xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+ case XML_SCHEMA_TYPE_ANY: {
+ xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_PARTICLE:
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ case XML_SCHEMA_TYPE_IDC_UNIQUE: {
+ xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
+ xmlSchemaAttributeGroupPtr item =
+ (xmlSchemaAttributeGroupPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_NOTATION: {
+ xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_FACET_MININCLUSIVE:
+ case XML_SCHEMA_FACET_MINEXCLUSIVE:
+ case XML_SCHEMA_FACET_MAXINCLUSIVE:
+ case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+ case XML_SCHEMA_FACET_TOTALDIGITS:
+ case XML_SCHEMA_FACET_FRACTIONDIGITS:
+ case XML_SCHEMA_FACET_PATTERN:
+ case XML_SCHEMA_FACET_ENUMERATION:
+ case XML_SCHEMA_FACET_WHITESPACE:
+ case XML_SCHEMA_FACET_LENGTH:
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ case XML_SCHEMA_FACET_MINLENGTH: {
+ xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_SIMPLE:
+ case XML_SCHEMA_TYPE_COMPLEX: {
+ xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_GROUP: {
+ xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL: {
+ xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
+ ADD_ANNOTATION(annot)
+ }
+ break;
+ default:
+ xmlSchemaPCustomErr(NULL,
+ XML_SCHEMAP_INTERNAL,
+ NULL, NULL, NULL,
+ "Internal error: xmlSchemaAddAnnotation, "
+ "The item is not a annotated schema component", NULL);
+ break;
}
- cur->next = annot;
return (annot);
}
@@ -6236,7 +7083,7 @@ xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
/*
* Add the annotation to the parent IDC.
*/
- xmlSchemaAssignAnnotation((xmlSchemaBasicItemPtr) idc,
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
@@ -6362,19 +7209,16 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
/*
* Create a reference item.
*/
- item->ref = (xmlSchemaItemQNRefPtr) xmlMalloc(
- sizeof(xmlSchemaItemQNRef));
- if (item->ref == NULL) {
- xmlSchemaPErrMemory(ctxt,
- "allocating a QName reference item", NULL);
+ item->ref = xmlSchemaNewQNameRef(schema, XML_SCHEMA_TYPE_IDC_KEY,
+ NULL, NULL);
+ if (item->ref == NULL)
return (NULL);
- }
- memset(item->ref, 0, sizeof(xmlSchemaItemQNRef));
xmlSchemaPValAttrNodeQName(ctxt, schema,
NULL, NULL, attr,
&(item->ref->targetNamespace), 0,
&(item->ref->name));
- xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaTypePtr) item,
+ xmlSchemaCheckReference(ctxt, schema, node,
+ (xmlSchemaBasicItemPtr) item,
item->ref->targetNamespace);
}
}
@@ -6434,113 +7278,97 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
return (item);
}
-#endif
/**
* xmlSchemaParseElement:
* @ctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
+ * @topLevel: indicates if this is global declaration
*
- * parse a XML schema Element declaration
+ * Parses a XML schema element declaration.
* *WARNING* this interface is highly subject to change
*
- * Returns the parsed element declaration.
+ * Returns the element declaration or a particle; NULL in case
+ * of an error or if the particle has minOccurs==maxOccurs==0.
*/
-static xmlSchemaElementPtr
+static xmlSchemaBasicItemPtr
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
-{
- const xmlChar *name = NULL;
- const xmlChar *attrValue;
- xmlChar *repName = NULL;
- xmlSchemaElementPtr ret;
- xmlNodePtr child = NULL;
- const xmlChar *oldcontainer;
- xmlAttrPtr attr, nameAttr;
- int minOccurs, maxOccurs;
- int isRef = 0;
-#ifdef IDC_ENABLED
- xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
-#endif
+{
+ xmlSchemaElementPtr decl = NULL;
+ xmlSchemaParticlePtr particle = NULL;
+ xmlSchemaAnnotPtr annot = NULL;
+ xmlNodePtr child = NULL;
+ xmlAttrPtr attr, nameAttr;
+ int min, max, isRef = 0;
+ xmlChar *des = NULL;
/* 3.3.3 Constraints on XML Representations of Element Declarations */
/* TODO: Complete implementation of 3.3.6 */
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- oldcontainer = ctxt->container;
-
+ return (NULL);
+ /*
+ * If we get a "ref" attribute on a local <element> we will assume it's
+ * a reference - even if there's a "name" attribute; this seems to be more
+ * robust.
+ */
nameAttr = xmlSchemaGetPropNode(node, "name");
attr = xmlSchemaGetPropNode(node, "ref");
if ((topLevel) || (attr == NULL)) {
if (nameAttr == NULL) {
xmlSchemaPMissingAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_MISSING,
- (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, node,
- "name", NULL);
+ NULL, NULL, node, "name", NULL);
return (NULL);
- }
- name = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) nameAttr);
- } else {
+ }
+ } else
isRef = 1;
-
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+ child = node->children;
+ if (IS_SCHEMA(child, "annotation")) {
+ annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ child = child->next;
}
- /*
- * ... unless minOccurs=maxOccurs=0, in which case the item corresponds
- * to no component at all
- * TODO: It might be better to validate the element, even if it won't be
- * used.
- */
- minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
- maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)");
- if ((minOccurs == 0) && (maxOccurs == 0))
- return (NULL);
/*
- * If we get a "ref" attribute on a local <element> we will assume it's
- * a reference - even if there's a "name" attribute; this seems to be more
- * robust.
+ * Skip particle part if a global declaration.
*/
- if (isRef) {
- char buf[50];
- const xmlChar *refNs = NULL, *ref = NULL, *refPrefix;
+ if (topLevel)
+ goto declaration_part;
+ /*
+ * The particle part ==================================================
+ */
+ min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
+ max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)");
+ xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
+ particle = xmlSchemaAddParticle(ctxt, schema, node, min, max);
+ if (particle == NULL)
+ goto return_null;
+
+ /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
+ if (isRef) {
+ const xmlChar *refNs = NULL, *ref = NULL;
+ xmlSchemaQNameRefPtr refer = NULL;
/*
- * Parse as a particle.
+ * The reference part =============================================
*/
xmlSchemaPValAttrNodeQName(ctxt, schema,
- (xmlChar **) &xmlSchemaElemDesElemRef,
- NULL, attr, &refNs, &refPrefix, &ref);
-
- snprintf(buf, 49, "#eRef%d", ctxt->counter++ + 1);
- ret = xmlSchemaAddElement(ctxt, schema, (const xmlChar *) buf, NULL, node, 0);
- if (ret == NULL) {
- if (repName != NULL)
- xmlFree(repName);
- return (NULL);
- }
- ret->type = XML_SCHEMA_TYPE_ELEMENT;
- ret->node = node;
- ret->ref = ref;
- ret->refNs = refNs;
- ret->refPrefix = refPrefix;
- ret->flags |= XML_SCHEMAS_ELEM_REF;
- xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaTypePtr) ret, refNs);
+ NULL, NULL, attr, &refNs, NULL, &ref);
+ xmlSchemaCheckReference(ctxt, schema, node, NULL, refNs);
/*
- * Check for illegal attributes.
- */
- /*
- * 3.3.3 : 2.1
- * One of ref or name must be present, but not both
+ * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
*/
if (nameAttr != NULL) {
xmlSchemaPMutualExclAttrErr(ctxt,
XML_SCHEMAP_SRC_ELEMENT_2_1,
- &repName, (xmlSchemaTypePtr) ret, nameAttr,
- "ref", "name");
+ NULL, NULL, nameAttr, "ref", "name");
}
- /* 3.3.3 : 2.2 */
+ /*
+ * Check for illegal attributes.
+ */
attr = node->properties;
while (attr != NULL) {
if (attr->ns == NULL) {
@@ -6553,9 +7381,10 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
attr = attr->next;
continue;
} else {
+ /* SPEC (3.3.3 : 2.2) */
xmlSchemaPCustomAttrErr(ctxt,
XML_SCHEMAP_SRC_ELEMENT_2_2,
- &repName, (xmlSchemaTypePtr) ret, attr,
+ NULL, NULL, attr,
"Only the attributes 'minOccurs', 'maxOccurs' and "
"'id' are allowed in addition to 'ref'");
break;
@@ -6563,20 +7392,47 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &repName, (xmlSchemaTypePtr) ret, attr);
+ NULL, NULL, attr);
}
attr = attr->next;
- }
- } else {
- const xmlChar *ns = NULL, *fixed;
-
+ }
/*
- * Parse as an element declaration.
+ * No children except <annotation> expected.
*/
- if (xmlSchemaPValAttrNode(ctxt,
- (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, nameAttr,
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL, "(annotation?)");
+ }
+ if ((min == 0) && (max == 0))
+ goto return_null;
+ /*
+ * Create the reference item.
+ */
+ refer = xmlSchemaNewQNameRef(schema, XML_SCHEMA_TYPE_ELEMENT,
+ ref, refNs);
+ if (refer == NULL)
+ goto return_null;
+ particle->children = (xmlSchemaTreeItemPtr) refer;
+ particle->annot = annot;
+ /*
+ * Add to assembled items; the reference need to be resolved.
+ */
+ if (ctxt->assemble != NULL)
+ xmlSchemaAddAssembledItem(ctxt, (xmlSchemaTypePtr) particle);
+
+ return ((xmlSchemaBasicItemPtr) particle);
+ }
+ /*
+ * The declaration part ===============================================
+ */
+declaration_part:
+ {
+ const xmlChar *ns = NULL, *fixed, *name, *oldcontainer, *attrValue;
+ xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
+
+ if (xmlSchemaPValAttrNode(ctxt, NULL, NULL, nameAttr,
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
- return (NULL);
+ goto return_null;
/*
* Evaluate the target namespace.
*/
@@ -6591,22 +7447,20 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
xmlSchemaPSimpleTypeErr(ctxt,
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
- &repName, NULL, (xmlNodePtr) attr,
+ NULL, NULL, (xmlNodePtr) attr,
NULL, "(qualified | unqualified)",
attrValue, NULL, NULL, NULL);
}
} else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
ns = schema->targetNamespace;
}
- ret = xmlSchemaAddElement(ctxt, schema, name, ns, node, topLevel);
- if (ret == NULL) {
- if (repName != NULL)
- xmlFree(repName);
- return (NULL);
+ decl = xmlSchemaAddElement(ctxt, schema, name, ns, node, topLevel);
+ if (decl == NULL) {
+ goto return_null;
}
- ret->type = XML_SCHEMA_TYPE_ELEMENT;
- ret->node = node;
- ret->targetNamespace = ns;
+ decl->type = XML_SCHEMA_TYPE_ELEMENT;
+ decl->node = node;
+ decl->targetNamespace = ns;
/*
* Check for illegal attributes.
*/
@@ -6633,16 +7487,15 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* TODO: This one is redundant, since the S4S does
* prohibit this attribute on local declarations already;
* so why an explicit error code? Weird spec.
- * TODO: Move this to the proper constraint layer.
- * TODO: Or better wait for spec 1.1 to come.
+ * TODO: Think about hanling this equal to the other attributes.
*/
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_E_PROPS_CORRECT_3,
- &repName, (xmlSchemaTypePtr) ret, attr);
+ NULL, (xmlSchemaTypePtr) decl, attr);
} else {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &repName, (xmlSchemaTypePtr) ret, attr);
+ NULL, (xmlSchemaTypePtr) decl, attr);
}
}
} else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
@@ -6651,14 +7504,14 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &repName, (xmlSchemaTypePtr) ret, attr);
+ NULL, (xmlSchemaTypePtr) decl, attr);
}
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &repName, (xmlSchemaTypePtr) ret, attr);
+ NULL, (xmlSchemaTypePtr) decl, attr);
}
attr = attr->next;
}
@@ -6669,29 +7522,29 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Process top attributes of global element declarations here.
*/
- ret->flags |= XML_SCHEMAS_ELEM_GLOBAL;
- ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
- xmlSchemaPValAttrQName(ctxt, schema, &repName,
- (xmlSchemaTypePtr) ret, node, "substitutionGroup",
- &(ret->substGroupNs), NULL, &(ret->substGroup));
- if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret,
+ decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
+ decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
+ xmlSchemaPValAttrQName(ctxt, schema, NULL,
+ (xmlSchemaTypePtr) decl, node, "substitutionGroup",
+ &(decl->substGroupNs), NULL, &(decl->substGroup));
+ if (xmlGetBooleanProp(ctxt, NULL, (xmlSchemaTypePtr) decl,
node, "abstract", 0))
- ret->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
+ decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
/*
* Attribute "final".
*/
attr = xmlSchemaGetPropNode(node, "final");
if (attr == NULL) {
- ret->flags |= XML_SCHEMAS_ELEM_FINAL_ABSENT;
+ decl->flags |= XML_SCHEMAS_ELEM_FINAL_ABSENT;
} else {
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
- if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags),
+ if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
-1,
XML_SCHEMAS_ELEM_FINAL_EXTENSION,
XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
xmlSchemaPSimpleTypeErr(ctxt,
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
- &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ NULL, (xmlSchemaTypePtr) decl, (xmlNodePtr) attr,
NULL, "(#all | List of (extension | restriction))",
attrValue, NULL, NULL, NULL);
}
@@ -6702,90 +7555,67 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
attr = xmlSchemaGetPropNode(node, "block");
if (attr == NULL) {
- ret->flags |= XML_SCHEMAS_ELEM_BLOCK_ABSENT;
+ decl->flags |= XML_SCHEMAS_ELEM_BLOCK_ABSENT;
} else {
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
- if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags),
+ if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
-1,
XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
xmlSchemaPSimpleTypeErr(ctxt,
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
- &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr,
+ NULL, (xmlSchemaTypePtr) decl, (xmlNodePtr) attr,
NULL, "(#all | List of (extension | "
"restriction | substitution))", attrValue,
NULL, NULL, NULL);
}
}
- if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret,
+ if (xmlGetBooleanProp(ctxt, NULL, (xmlSchemaTypePtr) decl,
node, "nillable", 0))
- ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
+ decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
xmlSchemaPValAttrQName(ctxt, schema,
- &repName, (xmlSchemaTypePtr) ret, node,
- "type", &(ret->namedTypeNs), NULL, &(ret->namedType));
+ NULL, (xmlSchemaTypePtr) decl, node,
+ "type", &(decl->namedTypeNs), NULL, &(decl->namedType));
- ret->value = xmlSchemaGetProp(ctxt, node, "default");
+ decl->value = xmlSchemaGetProp(ctxt, node, "default");
attr = xmlSchemaGetPropNode(node, "fixed");
if (attr != NULL) {
fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
- if (ret->value != NULL) {
+ if (decl->value != NULL) {
/*
* 3.3.3 : 1
* default and fixed must not both be present.
*/
xmlSchemaPMutualExclAttrErr(ctxt,
XML_SCHEMAP_SRC_ELEMENT_1,
- &repName, (xmlSchemaTypePtr) ret, attr,
+ NULL, (xmlSchemaTypePtr) decl, attr,
"default", "fixed");
} else {
- ret->flags |= XML_SCHEMAS_ELEM_FIXED;
- ret->value = fixed;
+ decl->flags |= XML_SCHEMAS_ELEM_FIXED;
+ decl->value = fixed;
}
- }
- }
- /*
- * Extract/validate common attributes.
- */
- xmlSchemaPValAttrID(ctxt, NULL, (xmlSchemaTypePtr) ret,
- node, BAD_CAST "id");
- ret->minOccurs = minOccurs;
- ret->maxOccurs = maxOccurs;
- if (topLevel != 1)
- xmlSchemaPCheckParticleCorrect_2(ctxt, (xmlSchemaTypePtr) ret,
- node, minOccurs, maxOccurs);
- /*
- * And now for the children...
- */
- ctxt->container = ret->name;
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (isRef) {
- if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_SRC_ELEMENT_2_2,
- &repName, (xmlSchemaTypePtr) ret, node, child,
- NULL, "(annotation?)");
}
- } else {
+ /*
+ * And now for the children...
+ */
+ oldcontainer = ctxt->container;
+ ctxt->container = decl->name;
if (IS_SCHEMA(child, "complexType")) {
/*
* 3.3.3 : 3
* "type" and either <simpleType> or <complexType> are mutually
* exclusive
*/
- if (ret->namedType != NULL) {
+ if (decl->namedType != NULL) {
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_SRC_ELEMENT_3,
- &repName, (xmlSchemaTypePtr) ret, node, child,
+ NULL, (xmlSchemaTypePtr) decl, node, child,
"The attribute 'type' and the <complexType> child are "
"mutually exclusive", NULL);
} else
- ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0);
+ decl->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0);
child = child->next;
} else if (IS_SCHEMA(child, "simpleType")) {
/*
@@ -6793,59 +7623,66 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* "type" and either <simpleType> or <complexType> are
* mutually exclusive
*/
- if (ret->namedType != NULL) {
+ if (decl->namedType != NULL) {
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_SRC_ELEMENT_3,
- &repName, (xmlSchemaTypePtr) ret, node, child,
+ NULL, (xmlSchemaTypePtr) decl, node, child,
"The attribute 'type' and the <simpleType> child are "
"mutually exclusive", NULL);
} else
- ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ decl->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
child = child->next;
}
while ((IS_SCHEMA(child, "unique")) ||
(IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
-#ifdef IDC_ENABLED
if (IS_SCHEMA(child, "unique")) {
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
- XML_SCHEMA_TYPE_IDC_UNIQUE, ret->targetNamespace);
+ XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
} else if (IS_SCHEMA(child, "key")) {
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
- XML_SCHEMA_TYPE_IDC_KEY, ret->targetNamespace);
+ XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
} else if (IS_SCHEMA(child, "keyref")) {
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
- XML_SCHEMA_TYPE_IDC_KEYREF, ret->targetNamespace);
+ XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
}
if (lastIDC != NULL)
lastIDC->next = curIDC;
else
- ret->idcs = (void *) curIDC;
+ decl->idcs = (void *) curIDC;
lastIDC = curIDC;
-#else
- TODO
-#endif
child = child->next;
}
if (child != NULL) {
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- &repName, (xmlSchemaTypePtr) ret, node, child,
+ NULL, (xmlSchemaTypePtr) decl, node, child,
NULL, "(annotation?, ((simpleType | complexType)?, "
"(unique | key | keyref)*))");
- }
-
+ }
+ ctxt->container = oldcontainer;
+ decl->annot = annot;
}
- ctxt->container = oldcontainer;
- /*
- * Cleanup.
- */
- if (repName != NULL)
- xmlFree(repName);
/*
* NOTE: Element Declaration Representation OK 4. will be checked at a
* different layer.
*/
- return (ret);
+ FREE_AND_NULL(des)
+ if (topLevel)
+ return ((xmlSchemaBasicItemPtr) decl);
+ else {
+ particle->children = (xmlSchemaTreeItemPtr) decl;
+ return ((xmlSchemaBasicItemPtr) particle);
+ }
+
+return_null:
+ FREE_AND_NULL(des)
+ if (annot != NULL)
+ xmlSchemaFreeAnnot(annot);
+ if (particle != NULL)
+ xmlSchemaFreeParticle(particle);
+ if (decl != NULL)
+ xmlSchemaFreeElement(decl);
+ return (NULL);
}
/**
@@ -6857,27 +7694,26 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* parse a XML schema Union definition
* *WARNING* this interface is highly subject to change
*
- * Returns -1 in case of error, 0 if the declaration is improper and
- * 1 in case of success.
+ * Returns -1 in case of internal error, 0 in case of success and a positive
+ * error code otherwise.
*/
-static xmlSchemaTypePtr
+static int
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
- xmlSchemaTypePtr type, subtype, last = NULL;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
xmlAttrPtr attr;
+ const xmlChar *cur = NULL;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- snprintf((char *) name, 30, "#union%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->type = XML_SCHEMA_TYPE_UNION;
- type->node = node;
+ return (-1);
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
+ /*
+ * Mark the simple type as being of variety "union".
+ */
+ type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
/*
* Check for illegal attributes.
*/
@@ -6888,51 +7724,131 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
attr = attr->next;
}
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* Attribute "memberTypes". This is a list of QNames.
- * TODO: Validate the QNames.
+ * TODO: Check the value to contain anything.
*/
- type->base = xmlSchemaGetProp(ctxt, node, "memberTypes");
+ attr = xmlSchemaGetPropNode(node, "memberTypes");
+ if (attr != NULL) {
+ const xmlChar *end;
+ xmlChar *tmp;
+ const xmlChar *localName, *nsName;
+ xmlSchemaTypeLinkPtr link, lastLink = NULL;
+ xmlSchemaQNameRefPtr ref;
+
+ cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+ type->ref = cur;
+ 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);
+ if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, NULL,
+ NULL, attr, BAD_CAST tmp, &nsName, NULL, &localName) == 0) {
+ /*
+ * Create the member type link.
+ */
+ link = (xmlSchemaTypeLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaTypeLink));
+ if (link == NULL) {
+ xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
+ "allocating a type link", NULL);
+ return (-1);
+ }
+ link->type = NULL;
+ link->next = NULL;
+ if (lastLink == NULL)
+ type->memberTypes = link;
+ else
+ lastLink->next = link;
+ lastLink = link;
+ /*
+ * Create a reference item.
+ */
+ ref = xmlSchemaNewQNameRef(schema, XML_SCHEMA_TYPE_SIMPLE,
+ localName, nsName);
+ if (ref == NULL) {
+ FREE_AND_NULL(tmp)
+ return (-1);
+ }
+ /*
+ * Assign the reference to the link, it will be resolved
+ * later during fixup of the union simple type.
+ */
+ link->type = (xmlSchemaTypePtr) ref;
+ }
+ FREE_AND_NULL(tmp)
+ cur = end;
+ } while (*cur != 0);
+
+ }
/*
* And now for the children...
*/
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ /*
+ * Add the annotation to the simple type ancestor.
+ */
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- while (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
+ if (IS_SCHEMA(child, "simpleType")) {
+ xmlSchemaTypePtr subtype, last = NULL;
+
+ /*
+ * Anchor the member types in the "subtypes" field of the
+ * simple type.
+ */
+ while (IS_SCHEMA(child, "simpleType")) {
+ subtype = (xmlSchemaTypePtr)
+ xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ if (subtype != NULL) {
+ if (last == NULL) {
+ type->subtypes = subtype;
+ last = subtype;
+ } else {
+ last->next = subtype;
+ last = subtype;
+ }
+ last->next = NULL;
+ }
+ child = child->next;
+ }
}
if (child != NULL) {
- /* TODO: Think about the error code. */
xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_UNION_CHILD,
- NULL, type, node, child, NULL, "(annotation?, simpleType*)");
- }
- return (type);
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL, "(annotation?, simpleType*)");
+ }
+ if ((attr == NULL) && (type->subtypes == NULL)) {
+ /*
+ * 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].
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
+ NULL, NULL, node,
+ "Either the attribute 'memberTypes' or "
+ "at least one <simpleType> child must be present", NULL);
+ }
+ return (0);
}
/**
@@ -6951,21 +7867,18 @@ static xmlSchemaTypePtr
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
- xmlSchemaTypePtr type, subtype;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
-
- snprintf((char *) name, 30, "#list%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_LIST;
- xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
+ /*
+ * Mark the type as being of variety "list".
+ */
+ type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
/*
* Check for illegal attributes.
*/
@@ -6976,50 +7889,71 @@ xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
attr = attr->next;
}
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+
/*
- * Attribute "itemType".
+ * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
+ * fields for holding the reference to the itemType.
*/
xmlSchemaPValAttrQName(ctxt, schema, NULL, NULL,
- node, "itemType", &(type->baseNs), NULL, &(type->base));
+ node, "itemType", &(type->refNs), NULL, &(type->ref));
/*
* And now for the children...
*/
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- subtype = NULL;
if (IS_SCHEMA(child, "simpleType")) {
- if (type->base != 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->ref != NULL) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
- NULL, type, node,
+ NULL, NULL, node,
"The attribute 'itemType' and the <simpleType> child "
- "are mutually exclusive", NULL);
+ "are mutually exclusive", NULL);
} else {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- type->subtypes = subtype;
+ type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
}
child = child->next;
+ } else if (type->ref == NULL) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+ NULL, NULL, node,
+ "Either the attribute 'itemType' or the <simpleType> child "
+ "must be present", NULL);
}
if (child != NULL) {
- /* TODO: Think about the error code. */
xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_LIST_CHILD,
- NULL, type, node, child, NULL, "(annotation?, simpleType?)");
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL, "(annotation?, simpleType?)");
}
- return (type);
+ if ((type->ref == NULL) &&
+ (type->subtypes == NULL) &&
+ (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+ NULL, NULL, node,
+ "Either the attribute 'itemType' or the <simpleType> child "
+ "must be present", NULL);
+ }
+ return (NULL);
}
/**
@@ -7038,10 +7972,9 @@ static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- xmlSchemaTypePtr type, subtype, oldCtxtType, oldParentItem;
+ xmlSchemaTypePtr type, oldCtxtType, oldParentItem;
xmlNodePtr child = NULL;
const xmlChar *attrValue = NULL;
- xmlChar *des = NULL;
xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
@@ -7052,11 +7985,11 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (attr == NULL) {
xmlSchemaPMissingAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_MISSING,
- (xmlChar **) &xmlSchemaElemDesST, NULL, node,
+ NULL, NULL, node,
"name", NULL);
return (NULL);
} else if (xmlSchemaPValAttrNode(ctxt,
- (xmlChar **) &xmlSchemaElemDesST, NULL, attr,
+ NULL, NULL, attr,
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
return (NULL);
}
@@ -7083,12 +8016,12 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
attr = attr->next;
}
@@ -7115,12 +8048,12 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
(!xmlStrEqual(attr->name, BAD_CAST "final"))) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
attr = attr->next;
}
@@ -7139,7 +8072,7 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaPSimpleTypeErr(ctxt,
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
- &des, type, (xmlNodePtr) attr,
+ NULL, type, (xmlNodePtr) attr,
NULL, "(#all | List of (list | union | restriction)",
attrValue, NULL, NULL, NULL);
}
@@ -7159,285 +8092,222 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- subtype = NULL;
- if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child);
+ if (child == NULL) {
+ xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
+ NULL, type, node, child, NULL,
+ "(annotation?, (restriction | list | union))");
+ } else if (IS_SCHEMA(child, "restriction")) {
+ xmlSchemaParseRestriction(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SIMPLE);
child = child->next;
- } else if (IS_SCHEMA(child, "list")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseList(ctxt, schema, child);
+ } else if (IS_SCHEMA(child, "list")) {
+ xmlSchemaParseList(ctxt, schema, child);
child = child->next;
- } else if (IS_SCHEMA(child, "union")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseUnion(ctxt, schema, child);
+ } else if (IS_SCHEMA(child, "union")) {
+ xmlSchemaParseUnion(ctxt, schema, child);
child = child->next;
}
- type->subtypes = subtype;
- if ((child != NULL) || (subtype == NULL)) {
+ if (child != NULL) {
xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- &des, type, node, child, NULL,
+ NULL, type, node, child, NULL,
"(annotation?, (restriction | list | union))");
}
ctxt->parentItem = oldParentItem;
ctxt->ctxtType = oldCtxtType;
- FREE_AND_NULL(des)
return (type);
}
-
/**
- * xmlSchemaParseGroup:
+ * xmlSchemaParseModelGroupDefRef:
* @ctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
*
- * parse a XML schema Group definition
+ * Parses a XML schema particle (reference to a model group definition).
* *WARNING* this interface is highly subject to change
*
* Returns -1 in case of error, 0 if the declaration is improper and
* 1 in case of success.
*/
-static xmlSchemaTypePtr
-xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node, int topLevel)
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlNodePtr node)
{
- xmlSchemaTypePtr item;
+ xmlSchemaParticlePtr item;
xmlNodePtr child = NULL;
xmlAttrPtr attr;
+ const xmlChar *ref = NULL, *refNs = NULL;
+ int min, max;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- if (topLevel) {
- const xmlChar *name;
- /*
- * Parse as model group definition.
- */
- attr = xmlSchemaGetPropNode(node, "name");
- if (attr == NULL) {
- xmlSchemaPMissingAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_MISSING,
- NULL, NULL, node,
- "name", NULL);
- return (NULL);
- } else if (xmlSchemaPValAttrNode(ctxt,
- NULL, NULL, attr,
- xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
- return (NULL);
- }
- item = xmlSchemaAddGroup(ctxt, schema, name,
- schema->targetNamespace, node);
- if (item == NULL)
- return (NULL);
- item->node = node;
- item->type = XML_SCHEMA_TYPE_GROUP;
- item->flags |= XML_SCHEMAS_TYPE_GLOBAL;
- /*
- * Check for illegal attributes.
- */
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, item, attr);
- }
- } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, item, attr);
- }
- attr = attr->next;
- }
- xmlSchemaPValAttrID(ctxt, NULL, item, node, BAD_CAST "id");
- /*
- * And now for the children...
- */
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- item->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (IS_SCHEMA(child, "all")) {
- item->subtypes = (xmlSchemaTypePtr)
- xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "choice")) {
- item->subtypes = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "sequence")) {
- item->subtypes = xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- NULL, item, node, child, NULL,
- "(annotation?, (all | choice | sequence)?)");
- }
- } else {
- const xmlChar *ref = NULL, *refNs = NULL, *refPrefix = NULL;
- int minOccurs, maxOccurs;
- char buf[40];
-
- /*
- * Parse as particle.
- */
- attr = xmlSchemaGetPropNode(node, "ref");
- if (attr == NULL) {
- xmlSchemaPMissingAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_MISSING,
- NULL, NULL, node,
- "ref", NULL);
- return (NULL);
- } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, NULL,
- attr, &refNs, &refPrefix, &ref) != 0) {
- return (NULL);
- }
+ return (NULL);
- /*
- * TODO: Validate the element even if no item is created
- * (i.e. min/maxOccurs == 0).
- */
- minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
- maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
- "(nonNegativeInteger | unbounded)");
- if ((minOccurs == 0) && (maxOccurs == 0)) {
- return (NULL);
- }
-
- snprintf(buf, 39, "#grRef%d", ctxt->counter++ + 1);
- item = xmlSchemaAddGroup(ctxt, schema, (const xmlChar *)buf, NULL, node);
- if (item == NULL)
- return (NULL);
- item->node = node;
- item->type = XML_SCHEMA_TYPE_GROUP;
- item->ref = ref;
- item->refNs = refNs;
- xmlSchemaCheckReference(ctxt, schema, node, item, refNs);
- item->minOccurs = minOccurs;
- item->maxOccurs = maxOccurs;
- xmlSchemaPCheckParticleCorrect_2(ctxt, item,
- node, item->minOccurs, item->maxOccurs);
- /*
- * Check for illegal attributes.
- */
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, item, attr);
- }
- } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, item, attr);
+ attr = xmlSchemaGetPropNode(node, "ref");
+ if (attr == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ NULL, NULL, node,
+ "ref", NULL);
+ return (NULL);
+ } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, NULL,
+ attr, &refNs, NULL, &ref) != 0) {
+ return (NULL);
+ }
+ min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
+ max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+ "(nonNegativeInteger | unbounded)");
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
}
- attr = attr->next;
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
}
- xmlSchemaPValAttrID(ctxt, NULL, item, node, BAD_CAST "id");
+ attr = attr->next;
+ }
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+ item = xmlSchemaAddParticle(ctxt, schema, node, min, max);
+ if (item == NULL)
+ return (NULL);
+ /*
+ * Create a reference item as the term; it will be substituted for
+ * the model group after the reference has been resolved.
+ */
+ item->children = (xmlSchemaTreeItemPtr)
+ xmlSchemaNewQNameRef(schema, XML_SCHEMA_TYPE_GROUP, ref, refNs);
+ xmlSchemaCheckReference(ctxt, schema, node, (xmlSchemaBasicItemPtr) item, refNs);
+ xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
+ /*
+ * And now for the children...
+ */
+ child = node->children;
+ /* TODO: Is annotation even allowed for a model group reference? */
+ if (IS_SCHEMA(child, "annotation")) {
/*
- * And now for the children...
+ * TODO: What to do exactly with the annotation?
*/
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- item->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- NULL, item, node, child, NULL,
- "(annotation?, (all | choice | sequence)?)");
- }
+ item->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ child = child->next;
}
-
- return (item);
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?)");
+ }
+ /*
+ * Corresponds to no component at all if minOccurs==maxOccurs==0.
+ */
+ if ((min == 0) && (max == 0))
+ return (NULL);
+ if (ctxt->assemble != NULL)
+ xmlSchemaAddAssembledItem(ctxt, (xmlSchemaTypePtr) item);
+ return ((xmlSchemaTreeItemPtr) item);
}
/**
- * xmlSchemaParseAll:
+ * xmlSchemaParseModelGroupDefinition:
* @ctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
*
- * parse a XML schema All definition
+ * Parses a XML schema model group definition.
* *WARNING* this interface is highly subject to change
*
* Returns -1 in case of error, 0 if the declaration is improper and
* 1 in case of success.
*/
-static xmlSchemaTypePtr
-xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
+static xmlSchemaModelGroupDefPtr
+xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlNodePtr node)
{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
- const xmlChar *oldcontainer;
+ xmlSchemaModelGroupDefPtr item;
+ xmlNodePtr child = NULL;
+ xmlAttrPtr attr;
+ const xmlChar *name;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *) name, 30, "#all%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_ALL;
-
+ return (NULL);
+
+ attr = xmlSchemaGetPropNode(node, "name");
+ if (attr == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ NULL, NULL, node,
+ "name", NULL);
+ return (NULL);
+ } else if (xmlSchemaPValAttrNode(ctxt,
+ NULL, NULL, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+ return (NULL);
+ }
+ item = xmlSchemaAddGroup(ctxt, schema, name, schema->targetNamespace, node);
+ if (item == NULL)
+ return (NULL);
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
-
- type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
-
- oldcontainer = ctxt->container;
- ctxt->container = (const xmlChar *) name;
+ /*
+ * And now for the children...
+ */
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
+ item->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ child = child->next;
}
- while (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- if (subtype != NULL) {
- if (subtype->minOccurs > 1)
- xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MINOCCURS,
- "invalid value for minOccurs (must be 0 or 1).\n",
- NULL, NULL);
- if (subtype->maxOccurs > 1)
- xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MAXOCCURS,
- "invalid value for maxOccurs (must be 0 or 1).\n",
- NULL, NULL);
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
+ if (IS_SCHEMA(child, "all")) {
+ item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_ALL, 0);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "choice")) {
+ item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_CHOICE, 0);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "sequence")) {
+ item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SEQUENCE, 0);
+ child = child->next;
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ALL_CHILD,
- "<all> has unexpected content.\n", type->name,
- NULL);
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, (all | choice | sequence)?)");
}
- ctxt->container = oldcontainer;
- return (type);
+
+ return (item);
}
/**
@@ -7740,7 +8610,7 @@ xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaParseAttributeGroup(ctxt, schema, child, 1);
child = child->next;
} else if (IS_SCHEMA(child, "group")) {
- xmlSchemaParseGroup(ctxt, schema, child, 1);
+ xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
child = child->next;
} else if (IS_SCHEMA(child, "notation")) {
xmlSchemaParseNotation(ctxt, schema, child);
@@ -8147,6 +9017,7 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (IS_SCHEMA(child, "annotation")) {
/*
* the annotation here is simply discarded ...
+ * TODO: really?
*/
child = child->next;
}
@@ -8315,6 +9186,7 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
while (IS_SCHEMA(child, "annotation")) {
/*
* the annotations here are simply discarded ...
+ * TODO: really?
*/
child = child->next;
}
@@ -8350,15 +9222,9 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
if (xmlStrEqual(schema->targetNamespace,
include->targetNamespace)) {
- fprintf(stderr, "already included chameleon '%s', TNS '%s'\n",
- include->schemaLocation,
- include->origTargetNamespace);
goto check_targetNamespace;
}
} else {
- fprintf(stderr, "already included '%s', TNS '%s'\n",
- include->schemaLocation,
- include->origTargetNamespace);
goto check_targetNamespace;
}
}
@@ -8497,6 +9363,17 @@ check_targetNamespace:
*/
include->origTargetNamespace = targetNamespace;
include->targetNamespace = schema->targetNamespace;
+#ifdef DEBUG_INCLUDES
+ if (targetNamespace != schema->targetNamespace)
+ xmlGenericError(xmlGenericErrorContext,
+ "INCLUDING CHAMELEON '%s'\n orig TNS '%s'\n"
+ " into TNS '%s'\n", schemaLocation,
+ targetNamespace, schema->targetNamespace);
+ else
+ xmlGenericError(xmlGenericErrorContext,
+ "INCLUDING '%s'\n orig-TNS '%s'\n", schemaLocation,
+ targetNamespace);
+#endif
/*
* Compile the included schema.
*/
@@ -8526,226 +9403,193 @@ exit_failure:
xmlFreeDoc(doc);
}
return (-1);
-
}
/**
- * xmlSchemaParseChoice:
+ * xmlSchemaParseModelGroup:
* @ctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
+ * @type: the "compositor" type
+ * @particleNeeded: if a a model group with a particle
*
- * parse a XML schema Choice definition
+ * parse a XML schema Sequence definition
* *WARNING* this interface is highly subject to change
*
* Returns -1 in case of error, 0 if the declaration is improper and
* 1 in case of success.
*/
-static xmlSchemaTypePtr
-xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlNodePtr node, xmlSchemaTypeType type,
+ int withParticle)
{
- xmlSchemaTypePtr type, subtype, last = NULL;
+ xmlSchemaModelGroupPtr item;
+ xmlSchemaParticlePtr particle = NULL;
xmlNodePtr child = NULL;
- xmlChar name[30];
xmlAttrPtr attr;
- const xmlChar *oldcontainer;
+ const xmlChar *oldcontainer, *container;
+ int min, max;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *) name, 30, "#ch%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_CHOICE;
- /*
- * Check for illegal attributes.
+ return (NULL);
+ /*
+ * Create a model group with the given compositor.
*/
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
+ item = xmlSchemaAddModelGroup(ctxt, schema, type, &container, node);
+ if (item == NULL)
+ return (NULL);
+
+ if (withParticle) {
+ if (type == XML_SCHEMA_TYPE_ALL) {
+ min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
+ max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
+ } else {
+ /* choice + sequence */
+ min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
+ max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+ "(nonNegativeInteger | unbounded)");
+ }
+ /*
+ * Create a particle
+ */
+ particle = xmlSchemaAddParticle(ctxt, schema, node, min, max);
+ if (particle == NULL)
+ return (NULL);
+ particle->children = (xmlSchemaTreeItemPtr) item;
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
- } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ attr = attr->next;
}
- attr = attr->next;
- }
- /*
- * Extract and validate attributes.
- */
- xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
- type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
- "(nonNegativeInteger | unbounded)");
- /*
- * And now for the children...
- */
- oldcontainer = ctxt->container;
- ctxt->container = (const xmlChar *) name;
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "element")) ||
- (IS_SCHEMA(child, "group")) ||
- (IS_SCHEMA(child, "any")) ||
- (IS_SCHEMA(child, "choice")) ||
- (IS_SCHEMA(child, "sequence"))) {
- subtype = NULL;
- if (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "any")) {
- subtype = xmlSchemaParseAny(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- }
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
- }
- if (child != NULL) {
- /* TODO: error code. */
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_CHOICE_CHILD,
- NULL, type, node, child, NULL,
- "(annotation?, (element | group | choice | sequence | any)*)");
- }
- ctxt->container = oldcontainer;
- return (type);
-}
-
-/**
- * xmlSchemaParseSequence:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Sequence definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is improper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
- xmlAttrPtr attr;
- const xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- oldcontainer = ctxt->container;
- snprintf((char *) name, 30, "#seq%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_SEQUENCE;
- /*
- * Check for illegal attributes.
- */
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
+ } else {
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
- } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ attr = attr->next;
}
- attr = attr->next;
+
}
+
/*
* Extract and validate attributes.
*/
- xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
- type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
- "(nonNegativeInteger | unbounded)");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* And now for the children...
*/
- ctxt->container = (const xmlChar *) name;
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "element")) ||
- (IS_SCHEMA(child, "group")) ||
- (IS_SCHEMA(child, "any")) ||
- (IS_SCHEMA(child, "choice")) ||
- (IS_SCHEMA(child, "sequence"))) {
- subtype = NULL;
- if (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "any")) {
- subtype = xmlSchemaParseAny(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- }
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
+ item->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
child = child->next;
}
- if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
- NULL, type, node, child, NULL,
- "(annotation?, (element | group | choice | sequence | any)*)");
+ oldcontainer = ctxt->container;
+ ctxt->container = container;
+ if (type == XML_SCHEMA_TYPE_ALL) {
+ xmlSchemaParticlePtr part, last = NULL;
+
+ while (IS_SCHEMA(child, "element")) {
+ part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
+ schema, child, 0);
+ if (part != NULL) {
+ if (part->minOccurs > 1)
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INVALID_MINOCCURS,
+ NULL, NULL, child,
+ "Invalid value for minOccurs (must be 0 or 1)", NULL);
+ if (part->maxOccurs > 1)
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INVALID_MAXOCCURS,
+ NULL, NULL, child,
+ "Invalid value for maxOccurs (must be 0 or 1)",
+ NULL);
+ if (last == NULL)
+ item->children = (xmlSchemaTreeItemPtr) part;
+ else
+ last->next = (xmlSchemaTreeItemPtr) part;
+ last = part;
+ }
+ child = child->next;
+ }
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, (annotation?, element*)");
+ }
+ } else {
+ /* choice + sequence */
+ xmlSchemaTreeItemPtr part = NULL, last = NULL;
+
+ while ((IS_SCHEMA(child, "element")) ||
+ (IS_SCHEMA(child, "group")) ||
+ (IS_SCHEMA(child, "any")) ||
+ (IS_SCHEMA(child, "choice")) ||
+ (IS_SCHEMA(child, "sequence"))) {
+
+ if (IS_SCHEMA(child, "element")) {
+ part = (xmlSchemaTreeItemPtr)
+ xmlSchemaParseElement(ctxt, schema, child, 0);
+ } else if (IS_SCHEMA(child, "group")) {
+ part =
+ xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+ } else if (IS_SCHEMA(child, "any")) {
+ part = (xmlSchemaTreeItemPtr)
+ xmlSchemaParseAny(ctxt, schema, child);
+ } else if (IS_SCHEMA(child, "choice")) {
+ part = xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_CHOICE, 1);
+ } else if (IS_SCHEMA(child, "sequence")) {
+ part = xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SEQUENCE, 1);
+ }
+ if (part != NULL) {
+ if (last == NULL)
+ item->children = part;
+ else
+ last->next = part;
+ last = part;
+ }
+ child = child->next;
+ }
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, (element | group | choice | sequence | any)*)");
+ }
}
ctxt->container = oldcontainer;
-
- return (type);
+ if (withParticle)
+ return ((xmlSchemaTreeItemPtr) particle);
+ else
+ return ((xmlSchemaTreeItemPtr) item);
}
/**
@@ -8761,25 +9605,26 @@ xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
static xmlSchemaTypePtr
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
+ xmlNodePtr node, xmlSchemaTypeType parentType)
{
- xmlSchemaTypePtr type, subtype;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
- const xmlChar *oldcontainer;
+ char buf[30];
+ const xmlChar *oldcontainer, *container;
xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
-
- oldcontainer = ctxt->container;
-
- snprintf((char *) name, 30, "#restr%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->type = XML_SCHEMA_TYPE_RESTRICTION;
- type->node = node;
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
+ type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
+
+ /*
+ * TODO: Is the container needed at all? the anonymous
+ * items inside should generate unique names already.
+ */
+ snprintf(buf, 29, "#restr%d", ctxt->counter++ + 1);
+ container = xmlDictLookup(ctxt->dict, BAD_CAST buf, -1);
/*
* Check for illegal attributes.
*/
@@ -8790,12 +9635,12 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, type, attr);
+ NULL, NULL, attr);
}
attr = attr->next;
}
@@ -8804,48 +9649,36 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
- * Attribute "base".
+ * Attribute "base" - mandatory if inside a complex type.
*/
- type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
- if ((type->base == NULL) &&
- (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX)) {
- /* TODO: Think about the error code. */
+ if ((xmlSchemaPValAttrQName(ctxt, schema,
+ NULL, NULL, node, "base",
+ &(type->baseNs), NULL,
+ &(type->base)) == 0) &&
+ (type->base == NULL) &&
+ (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
xmlSchemaPMissingAttrErr(ctxt,
- XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
NULL, type, node, "base", NULL);
- }
+ }
/*
* And now for the children...
- */
- ctxt->container = name;
+ */
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ /*
+ * Add the annotation to the simple type ancestor.
+ */
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- subtype = NULL;
- 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) {
+ oldcontainer = ctxt->container;
+ ctxt->container = container;
+ if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
+ /*
+ * Corresponds to <simpleType><restriction><simpleType>.
+ */
if (IS_SCHEMA(child, "simpleType")) {
if (type->base != NULL) {
/*
@@ -8855,30 +9688,111 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
- NULL, NULL, type->node, child,
+ NULL, NULL, node, child,
"The attribute 'base' and the <simpleType> child are "
"mutually exclusive", NULL);
} else {
- subtype = (xmlSchemaTypePtr)
+ type->baseType = (xmlSchemaTypePtr)
xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- type->baseType = subtype;
}
child = child->next;
+ } else if (type->base == NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
+ NULL, NULL, node, child,
+ "Either the attribute 'base' or a <simpleType> child "
+ "must be present", NULL);
+ }
+ } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+ /*
+ * Corresponds to <complexType><complexContent><restriction>...
+ * followed by:
+ *
+ * Model groups <all>, <choice> and <sequence>.
+ */
+ if (IS_SCHEMA(child, "all")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_ALL, 1);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "choice")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt,
+ schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "sequence")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SEQUENCE, 1);
+ child = child->next;
+ /*
+ * Model group reference <group>.
+ */
+ } else if (IS_SCHEMA(child, "group")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+ child = child->next;
}
- } else if (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
+ } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
+ xmlSchemaTypePtr contType, baseType = NULL;
+ /*
+ * Corresponds to <complexType><simpleContent><restriction>...
+ *
+ * SPEC (content type):
+ * "1 If the type definition ·resolved· to by the ·actual value· of
+ * the base [attribute] is a complex type definition whose own
+ * {content type} is a simple type definition and the <restriction>
+ * alternative is chosen, then starting from either" ...
+ *
+ * "1.1 the simple type definition corresponding to the <simpleType>
+ * among the [children] of <restriction> if there is one;"
+ */
if (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
+
+ baseType = (xmlSchemaTypePtr)
xmlSchemaParseSimpleType(ctxt, schema, child, 0);
- type->subtypes = subtype;
+ if (baseType == NULL)
+ return (NULL);
child = child->next;
- }
+ }
+ /*
+ * SPEC
+ * "... a simple type definition which restricts the simple type
+ * definition identified in clause 1.1 or clause 1.2 with a set
+ * of facet components"
+ *
+ * Create the anonymous simple type, which will be the content type
+ * of the complex type.
+ * Note that we will use the same node as for the <restriction> to
+ * have it somehow anchored in the schema doc.
+ */
+ snprintf(buf, 29, "#scST%d", ctxt->counter++ + 1);
+ contType = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf,
+ container, node);
+ if (contType == NULL)
+ return (NULL);
+ contType->node = node;
+ contType->type = XML_SCHEMA_TYPE_SIMPLE;
+ contType->baseType = baseType;
+ type->contentTypeDef = contType;
}
- if ((ctxt->ctxtType->type == XML_SCHEMA_TYPE_SIMPLE) ||
- (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
- xmlSchemaFacetPtr facet, lastfacet = NULL;
+
+ if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
+ (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
+ xmlSchemaFacetPtr facet, lastfacet = NULL;
+ xmlSchemaTypePtr facetHolder;
+
+ if (parentType == XML_SCHEMA_TYPE_SIMPLE)
+ facetHolder = type;
+ else
+ facetHolder = type->contentTypeDef;
+ /*
+ * Corresponds to <complexType><simpleContent><restriction>...
+ * <simpleType><restriction>...
+ */
/*
- * Add the facets to the parent simpleType/complexType.
+ * Add the facets to the simple type ancestor.
*/
/*
* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
@@ -8900,7 +9814,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
facet = xmlSchemaParseFacet(ctxt, schema, child);
if (facet != NULL) {
if (lastfacet == NULL)
- ctxt->ctxtType->facets = facet;
+ facetHolder->facets = facet;
else
lastfacet->next = facet;
lastfacet = facet;
@@ -8911,12 +9825,13 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Create links for derivation and validation.
*/
- if (lastfacet != NULL) {
+ if (facetHolder->facets != NULL) {
xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
- facet = ctxt->ctxtType->facets;
+ facet = facetHolder->facets;
do {
- facetLink = (xmlSchemaFacetLinkPtr) xmlMalloc(sizeof(xmlSchemaFacetLink));
+ facetLink = (xmlSchemaFacetLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaFacetLink));
if (facetLink == NULL) {
xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
xmlFree(facetLink);
@@ -8925,7 +9840,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
facetLink->facet = facet;
facetLink->next = NULL;
if (lastFacetLink == NULL)
- ctxt->ctxtType->facetSet = facetLink;
+ facetHolder->facetSet = facetLink;
else
lastFacetLink->next = facetLink;
lastFacetLink = facetLink;
@@ -8933,25 +9848,31 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} while (facet != NULL);
}
}
- if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX) {
+ if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
+ /*
+ * Attribute uses/declarations.
+ */
child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
+ /*
+ * Attribute wildcard.
+ */
if (IS_SCHEMA(child, "anyAttribute")) {
- ctxt->ctxtType->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
+ type->attributeWildcard =
+ xmlSchemaParseAnyAttribute(ctxt, schema, child);
child = child->next;
}
}
if (child != NULL) {
- /* TODO: Think about the error code. */
- if (ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+ if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
- NULL, type, node, child, NULL,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
"annotation?, (group | all | choice | sequence)?, "
"((attribute | attributeGroup)*, anyAttribute?))");
- } else if (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
+ } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
- NULL, type, node, child, NULL,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
"(annotation?, (simpleType?, (minExclusive | minInclusive | "
"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
"length | minLength | maxLength | enumeration | whiteSpace | "
@@ -8959,8 +9880,8 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else {
/* Simple type */
xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
- NULL, type, node, child, NULL,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
"(annotation?, (simpleType?, (minExclusive | minInclusive | "
"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
"length | minLength | maxLength | enumeration | whiteSpace | "
@@ -8968,7 +9889,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
}
}
ctxt->container = oldcontainer;
- return (type);
+ return (NULL);
}
/**
@@ -8977,67 +9898,111 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
*
- * parse a XML schema Extension definition
- * *WARNING* this interface is highly subject to change
+ * Parses an <extension>, which is found inside a
+ * <simpleContent> or <complexContent>.
+ * *WARNING* this interface is highly subject to change.
*
- * Returns the type definition or NULL in case of error
+ * TODO: Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
+ xmlNodePtr node, xmlSchemaTypeType parentType)
{
- xmlSchemaTypePtr type, subtype;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
- const xmlChar *oldcontainer;
+ char buf[30];
+ const xmlChar *oldcontainer, *container;
+ xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
+ type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
- oldcontainer = ctxt->container;
-
- snprintf((char *) name, 30, "#ext%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->type = XML_SCHEMA_TYPE_EXTENSION;
- type->node = node;
+ snprintf(buf, 29, "#ext%d", ctxt->counter++ + 1);
+ container = xmlDictLookup(ctxt->dict, BAD_CAST buf, -1);
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
-
- ctxt->container = name;
-
- type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
- if (type->base == NULL) {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_EXTENSION_NO_BASE,
- "<extension>: The attribute \"base\" is missing.\n",
- type->name, NULL);
- }
+
+ /*
+ * Attribute "base" - mandatory.
+ */
+ if ((xmlSchemaPValAttrQName(ctxt, schema,
+ NULL, NULL, node, "base", &(type->baseNs), NULL,
+ &(type->base)) == 0) && (type->base == NULL)) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ NULL, NULL, node, "base", NULL);
+ }
+ /*
+ * And now for the children...
+ */
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ /*
+ * Add the annotation to the type ancestor.
+ */
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- subtype = NULL;
-
- if (IS_SCHEMA(child, "all")) {
- subtype = xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child, 0);
- child = child->next;
+ oldcontainer = ctxt->container;
+ ctxt->container = container;
+ if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+ /*
+ * Corresponds to <complexType><complexContent><extension>... and:
+ *
+ * Model groups <all>, <choice>, <sequence> and <group>.
+ */
+ if (IS_SCHEMA(child, "all")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema,
+ child, XML_SCHEMA_TYPE_ALL, 1);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "choice")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema,
+ child, XML_SCHEMA_TYPE_CHOICE, 1);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "sequence")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema,
+ child, XML_SCHEMA_TYPE_SEQUENCE, 1);
+ child = child->next;
+ } else if (IS_SCHEMA(child, "group")) {
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+ child = child->next;
+ }
}
- if (subtype != NULL)
- type->subtypes = subtype;
- if ((ctxt->ctxtType != NULL) &&
- (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX)) {
+ if (child != NULL) {
+ /*
+ * Attribute uses/declarations.
+ */
child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
+ /*
+ * Attribute wildcard.
+ */
if (IS_SCHEMA(child, "anyAttribute")) {
ctxt->ctxtType->attributeWildcard =
xmlSchemaParseAnyAttribute(ctxt, schema, child);
@@ -9045,13 +10010,24 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
}
}
if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD,
- "<extension> has unexpected content.\n", type->name,
- NULL);
+ if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+ /* Complex content extension. */
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, ((group | all | choice | sequence)?, "
+ "((attribute | attributeGroup)*, anyAttribute?)))");
+ } else {
+ /* Simple content extension. */
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, ((attribute | attributeGroup)*, "
+ "anyAttribute?))");
+ }
}
ctxt->container = oldcontainer;
- return (type);
+ return (NULL);
}
/**
@@ -9065,52 +10041,68 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*
* Returns the type definition or NULL in case of error
*/
-static xmlSchemaTypePtr
+static int
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node)
{
- xmlSchemaTypePtr type, subtype, oldParentItem;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
+ xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- snprintf((char *) name, 30, "#SC%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
- type->node = node;
+ return (-1);
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
+ type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ /*
+ * Check for illegal attributes.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+ /*
+ * And now for the children...
+ */
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ /*
+ * Add the annotation to the complex type ancestor.
+ */
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- oldParentItem = ctxt->parentItem;
- ctxt->parentItem = type;
- subtype = NULL;
if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child);
+ xmlSchemaParseRestriction(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SIMPLE_CONTENT);
child = child->next;
} else if (IS_SCHEMA(child, "extension")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseExtension(ctxt, schema, child);
+ xmlSchemaParseExtension(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SIMPLE_CONTENT);
child = child->next;
}
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD,
- "<simpleContent> has unexpected content.\n",
- NULL, NULL);
+ if (child != NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+ NULL, NULL, node, child, NULL,
+ "(annotation?, (restriction | extension))");
}
- ctxt->parentItem = oldParentItem;
- return (type);
+ return (0);
}
/**
@@ -9124,24 +10116,18 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
*
* Returns the type definition or NULL in case of error
*/
-static xmlSchemaTypePtr
+static int
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node)
{
- xmlSchemaTypePtr type, subtype, oldParentItem;
+ xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
- xmlChar name[30];
xmlAttrPtr attr;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- snprintf((char *) name, 30, "#CC%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name, NULL, node);
- if (type == NULL)
- return (NULL);
- type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
- type->node = node;
+ return (-1);
+ /* Not a component, don't create it. */
+ type = ctxt->ctxtType;
/*
* Check for illegal attributes.
*/
@@ -9166,38 +10152,37 @@ xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
- * Handle attribute 'mixed'.
+ * Set the 'mixed' on the complex type ancestor.
*/
- if (xmlGetBooleanProp(ctxt, NULL, type, node, "mixed", 0)) {
- if ((ctxt->ctxtType->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
- ctxt->ctxtType->flags |= XML_SCHEMAS_TYPE_MIXED;
+ if (xmlGetBooleanProp(ctxt, NULL, NULL, node, "mixed", 0)) {
+ if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
+ type->flags |= XML_SCHEMAS_TYPE_MIXED;
}
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
+ /*
+ * Add the annotation to the complex type ancestor.
+ */
+ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+ xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
- oldParentItem = ctxt->parentItem;
- ctxt->parentItem = type;
- subtype = NULL;
- if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child);
+ if (IS_SCHEMA(child, "restriction")) {
+ xmlSchemaParseRestriction(ctxt, schema, child,
+ XML_SCHEMA_TYPE_COMPLEX_CONTENT);
child = child->next;
} else if (IS_SCHEMA(child, "extension")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseExtension(ctxt, schema, child);
+ xmlSchemaParseExtension(ctxt, schema, child,
+ XML_SCHEMA_TYPE_COMPLEX_CONTENT);
child = child->next;
}
- type->subtypes = subtype;
if (child != NULL) {
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
NULL, NULL, node, child,
NULL, "(annotation?, (restriction | extension))");
}
- ctxt->parentItem = oldParentItem;
- return (type);
+ return (0);
}
/**
@@ -9215,10 +10200,9 @@ static xmlSchemaTypePtr
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int topLevel)
{
- xmlSchemaTypePtr type, subtype, ctxtType;
+ xmlSchemaTypePtr type, ctxtType;
xmlNodePtr child = NULL;
- const xmlChar *name = NULL;
- const xmlChar *oldcontainer;
+ const xmlChar *oldcontainer, *name = NULL;
xmlAttrPtr attr;
const xmlChar *attrValue;
xmlChar *des = NULL; /* The reported designation. */
@@ -9253,7 +10237,7 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL, node);
if (type == NULL)
return (NULL);
- name = (const xmlChar *) buf;
+ name = type->name;
type->node = node;
type->type = XML_SCHEMA_TYPE_COMPLEX;
/*
@@ -9362,13 +10346,7 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
&des, type, attr);
}
attr = attr->next;
- }
- /*
- * Set as default for attribute wildcards.
- * This will be only changed if a complex type
- * inherits an attribute wildcard from a base type.
- */
- type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
+ }
/*
* And now for the children...
*/
@@ -9388,31 +10366,45 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
type->flags ^= XML_SCHEMAS_TYPE_MIXED;
- type->subtypes = xmlSchemaParseSimpleContent(ctxt, schema, child);
+ xmlSchemaParseSimpleContent(ctxt, schema, child);
child = child->next;
} else if (IS_SCHEMA(child, "complexContent")) {
- type->subtypes = xmlSchemaParseComplexContent(ctxt, schema, child);
+ type->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ xmlSchemaParseComplexContent(ctxt, schema, child);
child = child->next;
} else {
- subtype = NULL;
+ /*
+ * SPEC
+ * "...the third alternative (neither <simpleContent> nor
+ * <complexContent>) is chosen. 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.
+ */
+ type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
/*
* Parse model groups.
*/
if (IS_SCHEMA(child, "all")) {
- subtype = xmlSchemaParseAll(ctxt, schema, child);
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_ALL, 1);
child = child->next;
} else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_CHOICE, 1);
child = child->next;
} else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroup(ctxt, schema, child,
+ XML_SCHEMA_TYPE_SEQUENCE, 1);
child = child->next;
} else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child, 0);
+ type->subtypes = (xmlSchemaTypePtr)
+ xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
child = child->next;
}
- if (subtype != NULL)
- type->subtypes = subtype;
/*
* Parse attribute decls/refs.
*/
@@ -9775,42 +10767,44 @@ xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
/**
* xmlSchemaBuildAContentModel:
- * @type: the schema type definition
* @ctxt: the schema parser context
- * @name: the element name whose content is being built
+ * @particle: the particle component
+ * @name: the complex type's name whose content is being built
*
* Generate the automata sequence needed for that type
*/
static void
-xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
- xmlSchemaParserCtxtPtr ctxt,
+xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaParticlePtr particle,
const xmlChar * name)
{
- if (type == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Found unexpected type = NULL in %s content model\n",
- name);
- return;
+ if (particle == NULL) {
+ xmlSchemaPErr(ctxt, NULL,
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaBuildAContentModel, "
+ "particle is NULL.\n", NULL, NULL);
+ return;
}
- switch (type->type) {
- case XML_SCHEMA_TYPE_ANY: {
+ if (particle->children == NULL) {
+ xmlSchemaPErr(ctxt, GET_NODE(particle),
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaBuildAContentModel, "
+ "no term on particle.\n", NULL, NULL);
+ return;
+ }
+
+ switch (particle->children->type) {
+ case XML_SCHEMA_TYPE_ANY: {
xmlAutomataStatePtr start, end;
xmlSchemaWildcardPtr wild;
xmlSchemaWildcardNsPtr ns;
- wild = type->attributeWildcard;
-
- if (wild == NULL) {
- xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaBuildAContentModel, "
- "no wildcard on xsd:any.\n", NULL, NULL);
- return;
- }
+ wild = (xmlSchemaWildcardPtr) particle->children;
start = ctxt->state;
end = xmlAutomataNewState(ctxt->am);
- if (type->maxOccurs == 1) {
+ if (particle->maxOccurs == 1) {
if (wild->any == 1) {
/*
* We need to add both transitions:
@@ -9819,14 +10813,14 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
*/
ctxt->state =
xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
/*
* 2. the {"*"} for elements in no namespace.
*/
ctxt->state =
xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", NULL, type);
+ start, NULL, BAD_CAST "*", NULL, wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
} else if (wild->nsSet != NULL) {
@@ -9834,7 +10828,7 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
do {
ctxt->state = start;
ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- ctxt->state, NULL, BAD_CAST "*", ns->value, type);
+ ctxt->state, NULL, BAD_CAST "*", ns->value, wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
ns = ns->next;
} while (ns != NULL);
@@ -9844,36 +10838,36 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
deadEnd = xmlAutomataNewState(ctxt->am);
ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type);
+ start, deadEnd, BAD_CAST "*", wild->negNsSet->value, wild);
ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
}
} else {
int counter;
xmlAutomataStatePtr hop;
int maxOccurs =
- type->maxOccurs == UNBOUNDED ? UNBOUNDED : type->maxOccurs - 1;
+ particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1;
int minOccurs =
- type->minOccurs < 1 ? 0 : type->minOccurs - 1;
+ particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
hop = xmlAutomataNewState(ctxt->am);
if (wild->any == 1) {
ctxt->state =
xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
ctxt->state =
xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", NULL, type);
+ start, NULL, BAD_CAST "*", NULL, wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
} else if (wild->nsSet != NULL) {
ns = wild->nsSet;
do {
ctxt->state =
xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", ns->value, type);
+ start, NULL, BAD_CAST "*", ns->value, wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
ns = ns->next;
} while (ns != NULL);
@@ -9883,15 +10877,15 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
deadEnd = xmlAutomataNewState(ctxt->am);
ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type);
+ start, deadEnd, BAD_CAST "*", wild->negNsSet->value, wild);
ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", type);
+ start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
}
xmlAutomataNewCountedTrans(ctxt->am, hop, start, counter);
xmlAutomataNewCounterTrans(ctxt->am, hop, end, counter);
}
- if (type->minOccurs == 0) {
+ if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(ctxt->am, start, end);
}
ctxt->state = end;
@@ -9899,35 +10893,10 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
}
case XML_SCHEMA_TYPE_ELEMENT:{
xmlAutomataStatePtr oldstate;
- xmlSchemaElementPtr particle, elemDecl;
+ xmlSchemaElementPtr elemDecl;
+
+ elemDecl = (xmlSchemaElementPtr) particle->children;
- /*
- * IMPORTANT: This puts element declarations
- * (and never element decl. references) into the
- * automaton. This is crucial and should not be changed,
- * since validating functions rely now on it.
- */
- particle = (xmlSchemaElementPtr) type;
- if (particle->ref != NULL) {
- if (particle->refDecl == NULL) {
- /*
- * Skip content model creation if the reference
- * did not resolve to a declaration.
- */
- break;
- } else {
- /*
- * Referenced global element declaration.
- */
- elemDecl = particle->refDecl;
- }
- } else {
- /*
- * Anonymous element declaration.
- */
- elemDecl = particle;
- }
-
oldstate = ctxt->state;
if (particle->maxOccurs >= UNBOUNDED) {
@@ -10011,41 +10980,39 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
break;
}
case XML_SCHEMA_TYPE_SEQUENCE:{
- xmlSchemaTypePtr subtypes;
+ xmlSchemaTreeItemPtr sub;
/*
* If max and min occurances are default (1) then
- * simply iterate over the subtypes
+ * simply iterate over the particles of the <sequence>.
*/
- if ((type->minOccurs == 1) && (type->maxOccurs == 1)) {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
+ if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
+ sub = particle->children->children;
+ while (sub != NULL) {
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
+ sub = sub->next;
}
} else {
xmlAutomataStatePtr oldstate = ctxt->state;
- if (type->maxOccurs >= UNBOUNDED) {
- if (type->minOccurs > 1) {
+ if (particle->maxOccurs >= UNBOUNDED) {
+ if (particle->minOccurs > 1) {
xmlAutomataStatePtr tmp;
int counter;
ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate,
- NULL);
+ oldstate, NULL);
oldstate = ctxt->state;
counter = xmlAutomataNewCounter(ctxt->am,
- type->
- minOccurs - 1,
- UNBOUNDED);
-
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt,
- name);
- subtypes = subtypes->next;
+ particle->minOccurs - 1, UNBOUNDED);
+
+ sub = particle->children->children;
+ while (sub != NULL) {
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
+ sub = sub->next;
}
tmp = ctxt->state;
xmlAutomataNewCountedTrans(ctxt->am, tmp,
@@ -10055,60 +11022,56 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
NULL, counter);
} else {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt,
- name);
- subtypes = subtypes->next;
+ sub = particle->children->children;
+ while (sub != NULL) {
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
+ sub = sub->next;
}
xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
oldstate);
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
+ if (particle->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am,
+ oldstate, ctxt->state);
}
}
- } else if ((type->maxOccurs > 1)
- || (type->minOccurs > 1)) {
+ } else if ((particle->maxOccurs > 1)
+ || (particle->minOccurs > 1)) {
xmlAutomataStatePtr tmp;
int counter;
ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate,
- NULL);
+ oldstate, NULL);
oldstate = ctxt->state;
counter = xmlAutomataNewCounter(ctxt->am,
- type->minOccurs -
- 1,
- type->maxOccurs -
- 1);
-
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt,
- name);
- subtypes = subtypes->next;
+ particle->minOccurs - 1,
+ particle->maxOccurs - 1);
+
+ sub = particle->children->children;
+ while (sub != NULL) {
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
+ sub = sub->next;
}
tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
+ xmlAutomataNewCountedTrans(ctxt->am,
+ tmp, oldstate, counter);
ctxt->state =
xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
counter);
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
+ if (particle->minOccurs == 0) {
+ xmlAutomataNewEpsilon(ctxt->am,
+ oldstate, ctxt->state);
}
-
} else {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt,
- name);
- subtypes = subtypes->next;
+ sub = particle->children->children;
+ while (sub != NULL) {
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
+ sub = sub->next;
}
- if (type->minOccurs == 0) {
+ if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(ctxt->am, oldstate,
ctxt->state);
}
@@ -10117,7 +11080,7 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
break;
}
case XML_SCHEMA_TYPE_CHOICE:{
- xmlSchemaTypePtr subtypes;
+ xmlSchemaTreeItemPtr sub;
xmlAutomataStatePtr start, end;
start = ctxt->state;
@@ -10127,21 +11090,22 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
* iterate over the subtypes and remerge the end with an
* epsilon transition
*/
- if (type->maxOccurs == 1) {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
+ if (particle->maxOccurs == 1) {
+ sub = particle->children->children;
+ while (sub != NULL) {
ctxt->state = start;
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
- subtypes = subtypes->next;
+ sub = sub->next;
}
} else {
int counter;
xmlAutomataStatePtr hop;
- int maxOccurs = type->maxOccurs == UNBOUNDED ?
- UNBOUNDED : type->maxOccurs - 1;
+ int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+ UNBOUNDED : particle->maxOccurs - 1;
int minOccurs =
- type->minOccurs < 1 ? 0 : type->minOccurs - 1;
+ particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
/*
* use a counter to keep track of the number of transtions
@@ -10152,19 +11116,20 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
maxOccurs);
hop = xmlAutomataNewState(ctxt->am);
- subtypes = type->subtypes;
- while (subtypes != NULL) {
+ sub = particle->children->children;
+ while (sub != NULL) {
ctxt->state = start;
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+ xmlSchemaBuildAContentModel(ctxt,
+ (xmlSchemaParticlePtr) sub, name);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
- subtypes = subtypes->next;
+ sub = sub->next;
}
xmlAutomataNewCountedTrans(ctxt->am, hop, start,
counter);
xmlAutomataNewCounterTrans(ctxt->am, hop, end,
counter);
}
- if (type->minOccurs == 0) {
+ if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(ctxt->am, start, end);
}
ctxt->state = end;
@@ -10172,46 +11137,40 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
}
case XML_SCHEMA_TYPE_ALL:{
xmlAutomataStatePtr start;
- xmlSchemaElementPtr elemDecl, particle;
+ xmlSchemaParticlePtr sub;
+ xmlSchemaElementPtr elemDecl;
int lax;
-
- particle = (xmlSchemaElementPtr) type->subtypes;
- if (particle == NULL)
+
+ sub = (xmlSchemaParticlePtr) particle->children->children;
+ if (sub == NULL)
break;
start = ctxt->state;
- while (particle != NULL) {
+ while (sub != NULL) {
ctxt->state = start;
- /*
- * Changed to put the element declaration and
- * never the element decl. reference into the
- * automaton. This fixes bug 139897 and bug 167754.
- */
- if (particle->ref != NULL) {
- if (particle->refDecl == NULL) {
- /*
- * TODO: Note that we break on missing
- * sub-components.
- */
- break;
- } else
- elemDecl = particle->refDecl;
- } else
- elemDecl = particle;
+
+ elemDecl = (xmlSchemaElementPtr) sub->children;
+ if (elemDecl == NULL) {
+ xmlSchemaPErr(ctxt, NULL,
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaBuildAContentModel, "
+ "<element> particle a NULL term.\n", NULL, NULL);
+ return;
+ };
/*
* NOTE: The {max occurs} of all the particles in the
* {particles} of the group must be 0 or 1; this is
* already ensured during the parse of the content of
* <all>.
*/
- if ((particle->minOccurs == 1) &&
- (particle->maxOccurs == 1)) {
+ if ((sub->minOccurs == 1) &&
+ (sub->maxOccurs == 1)) {
xmlAutomataNewOnceTrans2(ctxt->am, ctxt->state,
ctxt->state,
elemDecl->name,
elemDecl->targetNamespace,
1, 1, elemDecl);
- } else if ((particle->minOccurs == 0) &&
- (particle->maxOccurs == 1)) {
+ } else if ((sub->minOccurs == 0) &&
+ (sub->maxOccurs == 1)) {
xmlAutomataNewCountTrans2(ctxt->am, ctxt->state,
ctxt->state,
@@ -10221,125 +11180,42 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
1,
elemDecl);
}
- particle = (xmlSchemaElementPtr) particle->next;
+ sub = (xmlSchemaParticlePtr) sub->next;
}
- lax = type->minOccurs == 0;
+ lax = particle->minOccurs == 0;
ctxt->state =
- xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL,
- lax);
+ xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL, lax);
break;
}
- case XML_SCHEMA_TYPE_RESTRICTION:
- if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- case XML_SCHEMA_TYPE_EXTENSION:
- if (type->baseType != NULL) {
- xmlSchemaTypePtr subtypes;
-
- /*
- * TODO: Circular definitions will be checked at the
- * constraint level. So remove this when the complex type
- * constraints are implemented.
- */
- if (type->recurse) {
- /* TODO: Change the error code. */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- NULL, type, type->node,
- "This item is circular", NULL);
- return;
- }
- type->recurse = 1;
- xmlSchemaBuildAContentModel(type->baseType, ctxt, name);
- type->recurse = 0;
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- } else if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- case XML_SCHEMA_TYPE_GROUP:
- /*
- * Handle model group definition references.
- * NOTE: type->subtypes is the referenced model grop definition;
- * and type->subtypes->subtypes is the model group (i.e. <all> or
- * <choice> or <sequence>).
- */
- if ((type->ref != NULL) && (type->subtypes != NULL) &&
- (type->subtypes->subtypes != NULL)) {
- xmlSchemaTypePtr modelGr;
- xmlAutomataStatePtr start, end;
-
- modelGr = type->subtypes->subtypes;
- start = ctxt->state;
- end = xmlAutomataNewState(ctxt->am);
- if (type->maxOccurs == 1) {
- ctxt->state = start;
- xmlSchemaBuildAContentModel(modelGr, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
- } else {
- int counter;
- xmlAutomataStatePtr hop;
- int maxOccurs = type->maxOccurs == UNBOUNDED ?
- UNBOUNDED : type->maxOccurs - 1;
- int minOccurs =
- type->minOccurs < 1 ? 0 : type->minOccurs - 1;
-
- counter =
- xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
- hop = xmlAutomataNewState(ctxt->am);
- ctxt->state = start;
- xmlSchemaBuildAContentModel(modelGr, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
- xmlAutomataNewCountedTrans(ctxt->am, hop, start,
- counter);
- xmlAutomataNewCounterTrans(ctxt->am, hop, end,
- counter);
- }
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, start, end);
- }
- ctxt->state = end;
- break;
- }
- break;
- case XML_SCHEMA_TYPE_COMPLEX:
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
- if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
- break;
default:
xmlGenericError(xmlGenericErrorContext,
- "Found unexpected type %d in %s content model\n",
- type->type, name);
+ "Internal error: xmlSchemaBuildAContentModel, found "
+ "unexpected term of type %d in content model of complex "
+ "type '%s'.\n",
+ particle->children->type, name);
return;
}
}
/**
* xmlSchemaBuildContentModel:
- * @type: the type definition (or reference)
* @ctxt: the schema parser context
+ * @type: the complex type definition
* @name: the element name
*
* Builds the content model of the complex type.
*/
static void
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
- xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaParserCtxtPtr ctxt,
const xmlChar * name)
{
xmlAutomataStatePtr start;
- if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || (type->ref != NULL) ||
- (type->contentType == XML_SCHEMA_CONTENT_BASIC) ||
- (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
- (type->contModel != NULL))
+ if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
+ (type->contModel != NULL) ||
+ ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
+ (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
return;
#ifdef DEBUG_CONTENT
@@ -10350,11 +11226,11 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL) {
xmlGenericError(xmlGenericErrorContext,
- "Cannot create automata for complex tpye %s\n", name);
+ "Cannot create automata for complex type %s\n", name);
return;
}
start = ctxt->state = xmlAutomataGetInitState(ctxt->am);
- xmlSchemaBuildAContentModel(type, ctxt, name);
+ xmlSchemaBuildAContentModel(ctxt, (xmlSchemaParticlePtr) type->subtypes, name);
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
type->contModel = xmlAutomataCompile(ctxt->am);
if (type->contModel == NULL) {
@@ -10371,7 +11247,7 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
} else {
#ifdef DEBUG_CONTENT_REGEXP
xmlGenericError(xmlGenericErrorContext,
- "Content model of %s:\n", name);
+ "Content model of %s:\n", type->name);
xmlRegexpPrint(stderr, type->contModel);
#endif
}
@@ -10381,7 +11257,7 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
}
/**
- * xmlSchemaRefFixupCallback:
+ * xmlSchemaElementFixup:
* @elem: the schema element context
* @ctxt: the schema parser context
*
@@ -10390,7 +11266,7 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
* term.
*/
static void
-xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
+xmlSchemaElementFixup(xmlSchemaElementPtr elem,
xmlSchemaParserCtxtPtr ctxt,
const xmlChar * name ATTRIBUTE_UNUSED,
const xmlChar * context ATTRIBUTE_UNUSED,
@@ -10400,224 +11276,128 @@ xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
((elem != NULL) && (elem->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
return;
elem->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
- if (elem->ref != NULL) {
- xmlSchemaElementPtr elemDecl;
-
+
+ if ((elem->subtypes == NULL) && (elem->namedType != NULL)) {
+ xmlSchemaTypePtr type;
+
+ /* (type definition) ... otherwise the type definition ·resolved·
+ * to by the ·actual value· of the type [attribute] ...
+ */
+ type = xmlSchemaGetType(ctxt->schema, elem->namedType,
+ elem->namedTypeNs);
+ if (type == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, (xmlSchemaTypePtr) elem, elem->node,
+ "type", elem->namedType, elem->namedTypeNs,
+ XML_SCHEMA_TYPE_BASIC, "type definition");
+ } else
+ elem->subtypes = type;
+ }
+ if (elem->substGroup != NULL) {
+ xmlSchemaElementPtr substHead;
+
/*
- * TODO: Evaluate, what errors could occur if the declaration is not
- * found. It might be possible that the "typefixup" might crash if
- * no ref declaration was found.
+ * FIXME TODO: Do we need a new field in _xmlSchemaElement for
+ * substitutionGroup?
*/
- elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs);
- if (elemDecl == NULL) {
+ substHead = xmlSchemaGetElem(ctxt->schema, elem->substGroup,
+ elem->substGroupNs);
+ if (substHead == NULL) {
xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- NULL, (xmlSchemaTypePtr) elem, elem->node,
- "ref", elem->ref, elem->refNs,
+ NULL, (xmlSchemaTypePtr) elem, NULL,
+ "substitutionGroup", elem->substGroup, elem->substGroupNs,
XML_SCHEMA_TYPE_ELEMENT, NULL);
- } else
- elem->refDecl = elemDecl;
- } else {
- if ((elem->subtypes == NULL) && (elem->namedType != NULL)) {
- xmlSchemaTypePtr type;
-
- /* (type definition) ... otherwise the type definition ·resolved·
- * to by the ·actual value· of the type [attribute] ...
- */
- type = xmlSchemaGetType(ctxt->schema, elem->namedType,
- elem->namedTypeNs);
- if (type == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, (xmlSchemaTypePtr) elem, elem->node,
- "type", elem->namedType, elem->namedTypeNs,
- XML_SCHEMA_TYPE_BASIC, "type definition");
- } else
- elem->subtypes = type;
- }
- if (elem->substGroup != NULL) {
- xmlSchemaElementPtr substHead;
-
+ } else {
+ xmlSchemaElementFixup(substHead, ctxt, NULL, NULL, NULL);
/*
- * FIXME TODO: Do we need a new field in _xmlSchemaElement for
- * substitutionGroup?
+ * (type definition)...otherwise the {type definition} of the
+ * element declaration ·resolved· to by the ·actual value· of
+ * the substitutionGroup [attribute], if present
*/
- substHead = xmlSchemaGetElem(ctxt->schema, elem->substGroup,
- elem->substGroupNs);
- if (substHead == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, (xmlSchemaTypePtr) elem, NULL,
- "substitutionGroup", elem->substGroup, elem->substGroupNs,
- XML_SCHEMA_TYPE_ELEMENT, NULL);
- } else {
- xmlSchemaRefFixupCallback(substHead, ctxt, NULL, NULL, NULL);
- /*
- * (type definition)...otherwise the {type definition} of the
- * element declaration ·resolved· to by the ·actual value· of
- * the substitutionGroup [attribute], if present
- */
- if (elem->subtypes == NULL)
- elem->subtypes = substHead->subtypes;
- }
+ if (elem->subtypes == NULL)
+ elem->subtypes = substHead->subtypes;
}
- if ((elem->subtypes == NULL) && (elem->namedType == NULL) &&
- (elem->substGroup == NULL))
- elem->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
- }
-}
-
-/**
- * xmlSchemaParseListRefFixup:
- * @type: the schema type definition
- * @ctxt: the schema parser context
- *
- * Fixup of the itemType reference of the list type.
- */
-static void
-xmlSchemaParseListRefFixup(xmlSchemaTypePtr type, xmlSchemaParserCtxtPtr ctxt)
-{
-
- if (((type->base == NULL) &&
- (type->subtypes == NULL)) ||
- ((type->base != NULL) &&
- (type->subtypes != NULL))) {
- /*
- * src-list-itemType-or-simpleType
- * Either the itemType [attribute] or the <simpleType> [child] of
- * the <list> element must be present, but not both.
- */
- /*
- * TODO: Move this to the parse function.
- */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE,
- NULL, type, type->node,
- "The attribute 'itemType' and the <simpleType> child "
- "are mutually exclusive", NULL);
- } else if (type->base!= NULL) {
- type->subtypes = xmlSchemaGetType(ctxt->schema, type->base, type->baseNs);
- if (type->subtypes == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, type, type->node,
- "itemType", type->base, type->baseNs,
- XML_SCHEMA_TYPE_SIMPLE, NULL);
- }
- }
- if ((type->subtypes != NULL) &&
- (type->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN))
- xmlSchemaTypeFixup(type->subtypes, ctxt, NULL);
+ }
+ if ((elem->subtypes == NULL) && (elem->namedType == NULL) &&
+ (elem->substGroup == NULL))
+ elem->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
}
/**
- * xmlSchemaParseUnionRefCheck:
- * @typeDecl: the schema type definition
+ * xmlSchemaResolveUnionMemberTypes:
* @ctxt: the schema parser context
+ * @type: the schema simple type definition
*
- * Checks and builds the memberTypes of the union type.
+ * Checks and builds the memberTypes of the union simple type.
* Returns -1 in case of an internal error, 0 otherwise.
*/
static int
-xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type,
- xmlSchemaParserCtxtPtr ctxt)
+xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
{
- xmlSchemaTypeLinkPtr link, lastLink = NULL, prevLink, subLink, newLink;
- xmlSchemaTypePtr memberType, ctxtType;
+ xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
+ xmlSchemaTypePtr memberType;
/* 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.
- */
-
- if (type->type != XML_SCHEMA_TYPE_UNION)
- return (-1);
- if (ctxt->ctxtType == NULL) {
- xmlSchemaPErr(ctxt, type->node,
- XML_SCHEMAP_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].
+ * Resolve references.
*/
- if ((type->base == NULL) &&
- (type->subtypes == NULL)) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
- NULL, NULL, type->node,
- "Either the attribute 'memberTypes' must be non-empty "
- "or there must be at least one <simpleType> child", NULL);
- }
-
- ctxtType = ctxt->ctxtType;
- if (type->base != NULL) {
- xmlAttrPtr attr;
- const xmlChar *cur, *end;
- xmlChar *tmp;
- const xmlChar *localName, *uri;
+ link = type->memberTypes;
+ lastLink = NULL;
+ while (link != NULL) {
+ const xmlChar *name, *nsName;
- attr = xmlSchemaGetPropNode(type->node, "memberTypes");
- 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);
- xmlSchemaPValAttrNodeQNameValue(ctxt, ctxt->schema, NULL,
- NULL, attr, BAD_CAST tmp, &uri, NULL, &localName);
- memberType = xmlSchemaGetType(ctxt->schema, localName, uri);
- if (memberType == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
- NULL, NULL, type->node, "memberTypes", localName, uri,
- XML_SCHEMA_TYPE_SIMPLE, NULL);
- } else {
- if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
- xmlSchemaTypeFixup(memberType, ctxt, NULL);
- 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);
- }
+ name = ((xmlSchemaQNameRefPtr) link->type)->name;
+ nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
+
+ memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
+ if ((memberType == NULL) || (! IS_SIMPLE_TYPE(memberType))) {
+ xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, type->node, "memberTypes",
+ name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
+ /*
+ * Remove the member type link.
+ */
+ if (lastLink == NULL)
+ type->memberTypes = link->next;
+ else
+ lastLink->next = link->next;
+ newLink = link;
+ link = link->next;
+ xmlFree(newLink);
+ } else {
+ link->type = memberType;
+ if (IS_NOT_TYPEFIXED(memberType))
+ xmlSchemaTypeFixup(memberType, ctxt, NULL);
+
+ lastLink = link;
+ link = link->next;
+ }
+ }
/*
* Add local simple types,
*/
memberType = type->subtypes;
- while (memberType != NULL) {
- if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)
- xmlSchemaTypeFixup(memberType, ctxt, NULL);
+ while (memberType != NULL) {
link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
if (link == NULL) {
xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
return (-1);
}
+ if (IS_NOT_TYPEFIXED(memberType))
+ xmlSchemaTypeFixup(memberType, ctxt, NULL);
link->type = memberType;
link->next = NULL;
if (lastLink == NULL)
- ctxtType->memberTypes = link;
+ type->memberTypes = link;
else
lastLink->next = link;
lastLink = link;
@@ -10628,10 +11408,11 @@ xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type,
* definition in the ·explicit members· with the members of their
* {member type definitions}, in order.
*/
- link = ctxtType->memberTypes;
+ link = type->memberTypes;
while (link != NULL) {
+ /* TODO: type-fixup it. */
if (link->type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
- subLink = link->type->memberTypes;
+ subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
if (subLink != NULL) {
link->type = subLink->type;
if (subLink->next != NULL) {
@@ -10738,6 +11519,9 @@ xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
static xmlSchemaTypePtr
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
{
+ if ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) ||
+ (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION))
+ return (0);
while (type != NULL) {
if (type->type == XML_SCHEMA_TYPE_BASIC)
return (type);
@@ -10748,7 +11532,6 @@ xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
}
#endif
-
/**
* xmlSchemaBuildAttributeUsesOwned:
* @ctxt: the schema parser context
@@ -11417,24 +12200,20 @@ xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt,
if (*completeWild == NULL) {
/*
* Copy the first encountered wildcard as context, except for the annotation.
+ *
+ * Although the complete wildcard might not correspond to any
+ * node in the schema, we will save this context node.
*/
- *completeWild = xmlSchemaAddWildcard(ctxt);
- (*completeWild)->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE;
+ *completeWild = xmlSchemaAddWildcard(ctxt, ctxt->schema,
+ XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+ group->attributeWildcard->node);
if (xmlSchemaCloneWildcardNsConstraints(ctxt,
completeWild, group->attributeWildcard) == -1)
return (-1);
(*completeWild)->processContents = group->attributeWildcard->processContents;
- /*
- * Although the complete wildcard might not correspond to any
- * node in the schema, we will save this context node.
- * TODO: Hmm, is this sane?
- */
- (*completeWild)->node = group->attributeWildcard->node;
-
- } else if (xmlSchemaIntersectWildcards(ctxt, *completeWild, group->attributeWildcard) == -1) {
- xmlSchemaFreeWildcard(*completeWild);
+ (*completeWild)->node = group->attributeWildcard->node;
+ } else if (xmlSchemaIntersectWildcards(ctxt, *completeWild, group->attributeWildcard) == -1)
return (-1);
- }
}
}
attrs = attrs->next;
@@ -11624,8 +12403,6 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr
* NOTE: This is the only case where an attribute
* wildcard is shared.
*/
- if (type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD)
- type->flags ^= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
type->attributeWildcard = baseType->attributeWildcard;
}
}
@@ -11976,7 +12753,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr
*/
if ((baseType != NULL) && (!baseIsAnyType) &&
(baseType->type == XML_SCHEMA_TYPE_COMPLEX) &&
- (baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) {
+ (IS_NOT_TYPEFIXED(baseType))) {
xmlSchemaPErr(ctxt, baseType->node, XML_SCHEMAP_INTERNAL,
"Internal error: xmlSchemaBuildAttributeValidation: "
"attribute uses not builded on base type '%s'.\n",
@@ -12038,7 +12815,7 @@ xmlSchemaTypeFinalContains(xmlSchemaPtr schema, xmlSchemaTypePtr type, int final
static xmlSchemaTypeLinkPtr
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
{
- while (type != NULL) {
+ while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
if (type->memberTypes != NULL)
return (type->memberTypes);
else
@@ -12065,20 +12842,76 @@ xmlSchemaGetListSimpleTypeItemType(xmlSchemaTypePtr type)
*/
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));
- }
+ return (type->subtypes);
+}
+
+
+static int
+xmlSchemaGetParticleTotalRangeMin(xmlSchemaTreeItemPtr particle)
+{
+ if ((particle->children == NULL) ||
+ ( ((xmlSchemaParticlePtr) particle)->minOccurs == 0))
+ return (0);
+ if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
+ int min = 0, cur;
+ xmlSchemaTreeItemPtr part = particle->children->children;
+
+ if (part == NULL)
+ return (0);
+ if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+ (part->children->type == XML_SCHEMA_TYPE_ANY))
+ min = ((xmlSchemaParticlePtr) part)->minOccurs;
+ else
+ min = xmlSchemaGetParticleTotalRangeMin(part);
+ if (min == 0)
+ return (0);
+ part = part->next;
+ while (part != NULL) {
+ if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+ (part->children->type == XML_SCHEMA_TYPE_ANY))
+ cur = ((xmlSchemaParticlePtr) part)->minOccurs;
+ else
+ cur = xmlSchemaGetParticleTotalRangeMin(part);
+ if (cur == 0)
+ return (0);
+ if (min > cur)
+ min = cur;
+ part = part->next;
+ }
+ return (((xmlSchemaParticlePtr) particle)->minOccurs * min);
+ } else {
+ /* <all> and <sequence> */
+ int sum = 0;
+ xmlSchemaTreeItemPtr part = particle->children->children;
+
+ if (part == NULL)
+ return (0);
+ do {
+ if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+ (part->children->type == XML_SCHEMA_TYPE_ANY))
+ sum += ((xmlSchemaParticlePtr) part)->minOccurs;
+ else
+ sum += xmlSchemaGetParticleTotalRangeMin(part);
+ part = part->next;
+ } while (part != NULL);
+ return (((xmlSchemaParticlePtr) particle)->minOccurs * sum);
+ }
+}
+
+
+static int
+xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
+{
+ if ((particle == NULL) || (particle->minOccurs == 0) ||
+ (particle->children == NULL))
+ return (1);
+
+ if (IS_MODEL_GROUP(particle->children)) {
+ if (xmlSchemaGetParticleTotalRangeMin(
+ (xmlSchemaTreeItemPtr) particle) == 0)
+ return (1);
+ }
+ return (0);
}
/**
@@ -12163,6 +12996,70 @@ xmlSchemaCheckCOSSTDerivedOK(xmlSchemaPtr schema,
return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
}
+/**
+ * xmlSchemaCheckTypeDefCircularInternal:
+ * @pctxt: the schema parser context
+ * @ctxtType: the type definition
+ * @ancestor: an ancestor of @ctxtType
+ *
+ * Checks st-props-correct (2) + ct-props-correct (3).
+ * Circular type definitions are not allowed.
+ *
+ * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
+ * circular, 0 otherwise.
+ */
+static int
+xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaTypePtr ctxtType,
+ xmlSchemaTypePtr ancestor)
+{
+ int ret;
+
+ if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
+ return (0);
+
+ if (IS_NOT_TYPEFIXED(ancestor))
+ xmlSchemaTypeFixup(ancestor, pctxt, NULL);
+ if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
+ /*
+ * Avoid inifinite recursion on circular types not yet checked.
+ */
+ return (0);
+ }
+ if (ctxtType == ancestor) {
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_ST_PROPS_CORRECT_2,
+ NULL, ctxtType, GET_NODE(ctxtType),
+ "The definition is circular", NULL);
+ return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
+ }
+ ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
+ ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
+ ancestor->baseType);
+ ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
+ return (ret);
+}
+
+/**
+ * xmlSchemaCheckGroupDefCircular:
+ * @item: the complex/simple type definition
+ * @ctxt: the parser context
+ * @name: the name
+ *
+ * Checks for circular type definitions.
+ */
+static void
+xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ if ((item == NULL) ||
+ ((item->type != XML_SCHEMA_TYPE_COMPLEX) &&
+ (item->type != XML_SCHEMA_TYPE_SIMPLE)))
+ return;
+ xmlSchemaCheckTypeDefCircularInternal(ctxt, item, item->baseType);
+
+}
/**
* xmlSchemaCheckSTPropsCorrect:
@@ -12192,41 +13089,42 @@ xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
*/
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) {
+ /*
+ * TODO: Think about: "modulo the impact of Missing
+ * Sub-components (§5.3)."
+ */
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
NULL, type, NULL,
"No base type existent", NULL);
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+
}
- if ((baseType->type != XML_SCHEMA_TYPE_SIMPLE) &&
- ((baseType->type != XML_SCHEMA_TYPE_BASIC) ||
- (baseType == anyType))) {
+ if (! IS_SIMPLE_TYPE(baseType)) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
NULL, type, NULL,
- "The base type %s is not a simple type",
- xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ "The base type '%s' is not a simple type",
+ xmlSchemaGetComponentQName(&str, baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
- if ((baseType != anySimpleType) &&
- (type->subtypes->type != XML_SCHEMA_TYPE_RESTRICTION)) {
+ if ((baseType->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
+ ((type->flags &
+ XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) == 0) &&
+ ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) ||
+ (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION))) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
NULL, type, NULL,
"A type, derived by list or union, must have"
- "the simple ur-type definition as base type, not %s",
- xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ "the simple ur-type definition as base type, not '%s'",
+ xmlSchemaGetComponentQName(&str, baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
@@ -12243,52 +13141,47 @@ xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
/* TODO: Finish this. Hmm, is this finished? */
-
- /*
- * 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) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_ST_PROPS_CORRECT_2,
- NULL, type, NULL,
- "The definition is circular", NULL);
- return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
- }
- baseType = baseType->baseType;
- }
+
/*
* 3 The {final} of the {base type definition} must not contain restriction.
*/
- if (xmlSchemaTypeFinalContains(ctxt->schema, baseType,
+ if (xmlSchemaTypeFinalContains(ctxt->schema, baseType,
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_3,
NULL, type, NULL,
- "The 'final' of its base type %s must not contain "
+ "The 'final' of its base type '%s' must not contain "
"'restriction'",
- xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1));
+ xmlSchemaGetComponentQName(&str, baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
}
+
+ /*
+ * 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}.
+ *
+ * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
+ */
return (0);
}
/**
- * xmlSchemaCheckDerivationValidSimpleRestriction:
+ * xmlSchemaCheckCOSSTRestricts:
* @ctxt: the schema parser context
* @type: the simple type definition
*
* Checks if the given @type (simpleType) is derived
* validly by restriction.
+ * STATUS:
+ * missing:
+ * (3.3.2.5) facet derivation
+ * (1.3.2) facet derivation
+ * (2.3.2.5)
+ * (3.3.2.5) facet derivation
+ *
*
* Returns -1 on internal errors, 0 if the type is validly derived,
* a positive error code otherwise.
@@ -12299,12 +13192,10 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
{
xmlChar *str = NULL;
- /* STATE: error funcs converted. */
-
if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
- "xmlSchemaCheckDerivationValidSimpleRestriction: The given "
+ "xmlSchemaCheckCOSSTRestricts: The given "
"type '%s' is not a user-derived simpleType.\n",
type->name, NULL);
return (-1);
@@ -12320,8 +13211,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
NULL, type, NULL,
- "The base type %s is not an atomic simple type",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The base type '%s' is not an atomic simple type",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
}
@@ -12334,8 +13225,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
NULL, type, NULL,
- "The final of its base type %s must not contain 'restriction'",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The final of its base type '%s' must not contain 'restriction'",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
}
@@ -12353,7 +13244,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
if (primitive == NULL) {
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
- "xmlSchemaCheckDerivationValidSimpleRestriction: failed "
+ "xmlSchemaCheckCOSSTRestricts: failed "
"to get primitive type of type '%s'.\n",
type->name, NULL);
return (-1);
@@ -12377,15 +13268,17 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
xmlSchemaTypePtr itemType = NULL;
- itemType = xmlSchemaGetListSimpleTypeItemType(type);
- if (itemType == NULL) {
+ itemType = type->subtypes;
+ if ((itemType == NULL) || (! IS_SIMPLE_TYPE(itemType))) {
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
- "Internal error: xmlSchemaCheckDerivationValidSimpleRestriction: "
+ "Internal error: xmlSchemaCheckCOSSTRestricts: "
"failed to evaluate the item type of type '%s'.\n",
type->name, NULL);
return (-1);
}
+ if (IS_NOT_TYPEFIXED(itemType))
+ xmlSchemaTypeFixup(itemType, ctxt, NULL);
/*
* 2.1 The {item type definition} must have a {variety} of atomic or
* union (in which case all the {member type definitions}
@@ -12396,8 +13289,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
NULL, type, NULL,
- "The item type %s must have a variety of atomic or union",
- xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1));
+ "The item type '%s' does not have a variety of atomic or union",
+ xmlSchemaGetComponentQName(&str, itemType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
} else if (itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
@@ -12411,8 +13304,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
NULL, type, NULL,
"The item type is a union type, but the "
- "member type %s of this item type is not atomic",
- xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ "member type '%s' of this item type is not atomic",
+ xmlSchemaGetComponentQName(&str, member->type));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
}
@@ -12420,7 +13313,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
}
}
- if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) {
+ if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
xmlSchemaFacetPtr facet;
/*
* This is the case if we have: <simpleType><list ..
@@ -12435,8 +13328,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
NULL, type, NULL,
- "The final of its item type %s must not contain 'list'",
- xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1));
+ "The final of its item type '%s' must not contain 'list'",
+ xmlSchemaGetComponentQName(&str, itemType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
}
@@ -12457,7 +13350,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
} while (facet != NULL);
}
/*
- * TODO: Datatypes states:
+ * MABY TODO: (Hmm, not really) 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
@@ -12466,6 +13359,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
} else {
/*
* This is the case if we have: <simpleType><restriction ...
+ * I.e. the variety of "list" is inherited.
*/
/*
* 2.3.2
@@ -12475,8 +13369,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
NULL, type, NULL,
- "The base type %s must be a list type",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The base type '%s' must be a list type",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
}
@@ -12489,8 +13383,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
NULL, type, NULL,
- "The final of the base type %s must not contain 'restriction'",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The 'final' of the base type '%s' must not contain 'restriction'",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
}
@@ -12502,11 +13396,11 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
{
xmlSchemaTypePtr baseItemType;
- baseItemType = xmlSchemaGetListSimpleTypeItemType(type->baseType);
- if (baseItemType == NULL) {
+ baseItemType = type->baseType->subtypes;
+ if ((baseItemType == NULL) || (! IS_SIMPLE_TYPE(baseItemType))) {
xmlSchemaPErr(ctxt, type->node,
XML_ERR_INTERNAL_ERROR,
- "xmlSchemaCheckDerivationValidSimpleRestriction: "
+ "Internal error: xmlSchemaCheckCOSSTRestricts, "
"List simple type '%s': Failed to "
"evaluate the item type of its base type '%s'.\n",
type->name, type->baseType->name);
@@ -12519,11 +13413,11 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErrExt(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
NULL, type, NULL,
- "The item type %s is not validly derived from the "
- "item type %s of the base type %s",
- xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1),
- xmlSchemaFormatItemForReport(&strBIT, NULL, baseItemType, NULL, 1),
- xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1));
+ "The item type '%s' is not validly derived from the "
+ "item type '%s' of the base type '%s'",
+ xmlSchemaGetComponentQName(&str, itemType),
+ xmlSchemaGetComponentQName(&strBIT, baseItemType),
+ xmlSchemaGetComponentQName(&strBT, type->baseType));
FREE_AND_NULL(str)
FREE_AND_NULL(strBIT)
@@ -12587,6 +13481,9 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
member = type->memberTypes;
while (member != NULL) {
+ if (IS_NOT_TYPEFIXED(member->type))
+ xmlSchemaTypeFixup(member->type, ctxt, NULL);
+
if (((member->type->flags &
XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) &&
((member->type->flags &
@@ -12594,8 +13491,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
NULL, type, NULL,
- "The member type %s is neither an atomic, nor a list type",
- xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ "The member type '%s' is neither an atomic, nor a list type",
+ xmlSchemaGetComponentQName(&str, member->type));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
}
@@ -12605,7 +13502,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
* 3.3.1 If the {base type definition} is the ·simple ur-type
* definition·
*/
- if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) {
+ if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
/*
* 3.3.1.1 All of the {member type definitions} must have a
* {final} which does not contain union.
@@ -12617,8 +13514,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
NULL, type, NULL,
- "The final of member type %s contains 'union'",
- xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1));
+ "The 'final' of member type '%s' contains 'union'",
+ xmlSchemaGetComponentQName(&str, member->type));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
}
@@ -12637,13 +13534,14 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
} else {
/*
* 3.3.2.1 The {base type definition} must have a {variety} of union.
+ * I.e. the variety of "list" is inherited.
*/
if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
NULL, type, NULL,
- "The base type %s is not a union type",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The base type '%s' is not a union type",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
}
@@ -12655,8 +13553,8 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
NULL, type, NULL,
- "The final of its base type %s must not contain 'restriction'",
- xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1));
+ "The 'final' of its base type '%s' must not contain 'restriction'",
+ xmlSchemaGetComponentQName(&str, type->baseType));
FREE_AND_NULL(str)
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
}
@@ -12687,8 +13585,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
if ((member == NULL) && (baseMember != NULL)) {
xmlSchemaPErr(ctxt, type->node,
XML_SCHEMAP_INTERNAL,
- "Internal error: "
- "xmlSchemaCheckDerivationValidSimpleRestriction "
+ "Internal error: xmlSchemaCheckCOSSTRestricts, "
"(3.3.2.3), union simple type '%s', unequal number "
"of member types in the base type\n",
type->name, NULL);
@@ -12698,7 +13595,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPErr(ctxt, type->node,
XML_SCHEMAP_INTERNAL,
"Internal error: "
- "xmlSchemaCheckDerivationValidSimpleRestriction "
+ "xmlSchemaCheckCOSSTRestricts "
"(3.3.2.3), union simple type '%s', unequal number "
"of member types in the base type.\n",
type->name, NULL);
@@ -12713,9 +13610,9 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt,
NULL, type, NULL,
"The member type %s is not validly derived from its "
"corresponding member type %s of the base type %s",
- xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1),
- xmlSchemaFormatItemForReport(&strBMT, NULL, baseMember->type, NULL, 1),
- xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1));
+ xmlSchemaGetComponentQName(&str, member->type),
+ xmlSchemaGetComponentQName(&strBMT, baseMember->type),
+ xmlSchemaGetComponentQName(&strBT, type->baseType));
FREE_AND_NULL(str)
FREE_AND_NULL(strBMT)
FREE_AND_NULL(strBT)
@@ -12773,20 +13670,6 @@ 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_SCHEMAP_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
@@ -12809,7 +13692,7 @@ xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_1);
}
- if (type->subtypes->type == XML_SCHEMA_TYPE_RESTRICTION) {
+ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
/*
* src-simple-type.2 If the <restriction> alternative is chosen,
* either it must have a base [attribute] or a <simpleType> among its
@@ -12817,33 +13700,16 @@ xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
*/
/*
* XML_SCHEMAP_SRC_SIMPLE_TYPE_2
- * NOTE: This was removed, since this will be already handled
- * in the parse function for <restriction>.
+ * NOTE: This is checked in the parse function of <restriction>.
*/
- } else if (type->subtypes->type == XML_SCHEMA_TYPE_LIST) {
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_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.
- */
- /*
- * TODO: Remove this, and add the check to the parse function of <list>.
- */
- if (((type->subtypes->base == NULL) &&
- (type->baseType == NULL)) ||
- ((type->subtypes->base != NULL) &&
- (type->subtypes->baseType != NULL))) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_SIMPLE_TYPE_3,
- NULL, type, NULL,
- "Either the attribute 'itemType' or the <simpleType> child "
- "must be present on the <list> child ", NULL);
- return (XML_SCHEMAP_SRC_SIMPLE_TYPE_3);
- }
-
-
- } else if (type->subtypes->type == XML_SCHEMA_TYPE_UNION) {
+ *
+ * REMOVED: This is checked in the parse function of <list>.
+ */
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
xmlSchemaTypeLinkPtr member;
xmlSchemaTypePtr ancestor, anySimpleType;
@@ -12857,26 +13723,25 @@ xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
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) {
+ while ((ancestor != NULL) && (ancestor->type != XML_SCHEMA_TYPE_BASIC)) {
+ if (ancestor == type) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
NULL, type, NULL,
"The definition is circular", NULL);
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
- } else if (ancestor->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ }
+ if (IS_NOT_TYPEFIXED(ancestor))
+ xmlSchemaTypeFixup(ancestor, ctxt, NULL);
+ if (ancestor->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
/*
* TODO, FIXME: Although a list simple type must not have a union ST
* type as item type, which in turn has a list ST as member
* type, we will assume this here as well, since this check
* was not yet performed.
*/
-
}
+
ancestor = ancestor->baseType;
}
member = member->next;
@@ -12886,7 +13751,7 @@ xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
return (0);
}
-#if 0 /* Not yet used code for CT schema validation */
+#if 0 /* Not yet used code for ST schema validation */
static int
xmlSchemaCheckCVCSimpleType(xmlSchemaValidCtxtPtr ctxt,
const xmlChar * value,
@@ -12968,10 +13833,10 @@ xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
/**
* xmlSchemaCheckCOSValidDefault:
- * @ctxt: the schema parser context
+ * @pctxt: the schema parser context
+ * @vctxt: the temporary schema validation context
* @type: the simple type definition
* @value: the default value
- * @val: the precomputed value to be returned
* @node: an optional node (the holder of the value)
*
* Checks the "cos-valid-default" constraints.
@@ -13073,47 +13938,75 @@ xmlSchemaCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
return (ret);
}
-#if 0 /* Not yet used code for CT schema validation */
/**
- * xmlSchemaGetSTContentOfCT:
+ * xmlSchemaCheckCTPropsCorrect:
* @ctxt: the schema parser context
* @type: the complex type definition
*
+ *.(4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Complex Type Definition Properties Correct (ct-props-correct)
+ * STATUS: (seems) complete
*
- * Returns the corresponding simple type for the content of
- * the complex type.
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
*/
-static xmlSchemaTypePtr
-xmlSchemaGetSTContentOfCT(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaTypePtr type)
+static int
+xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaTypePtr type)
{
- xmlSchemaTypePtr orig = type, anyType;
-
- anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
- while ((type != NULL) && (type != anyType) &&
- (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
- if (type->type == XML_SCHEMA_TYPE_SIMPLE)
- return(type);
- type = type->baseType;
- }
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, orig, NULL,
- "Internal error: xmlSchemaGetSTContentTypeOfCT, "
- "no simple type for the content of complex type '%s' could be "
- "computed", orig->name);
- return (NULL);
+ /*
+ * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
+ *
+ * SPEC (1) "The values of the properties of a complex type definition must
+ * be as described in the property tableau in The Complex Type Definition
+ * Schema Component (§3.4.1), modulo the impact of Missing
+ * Sub-components (§5.3)."
+ */
+ if ((type->baseType != NULL) &&
+ (IS_SIMPLE_TYPE(type->baseType)) &&
+ ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) == 0)) {
+ /*
+ * SPEC (2) "If the {base type definition} is a simple type definition,
+ * the {derivation method} must be extension."
+ */
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_SRC_CT_1,
+ NULL, type, NULL,
+ "If the base type is a simple type, the derivation method must be "
+ "'extension'", NULL);
+ return (XML_SCHEMAP_SRC_CT_1);
+ }
+ /*
+ * SPEC (3) "Circular definitions are disallowed, except for the ·ur-type
+ * definition·. That is, it must be possible to reach the ·ur-type
+ * definition by repeatedly following the {base type definition}."
+ *
+ * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
+ *
+ * SPEC (4) "Two distinct attribute declarations in the {attribute uses}
+ * must not have identical {name}s and {target namespace}s."
+ * SPEC (5) "Two distinct attribute declarations in the {attribute uses}
+ * must not have {type definition}s which are or are derived from ID."
+ *
+ * NOTE (4) and (5) are done in xmlSchemaBuildAttributeValidation().
+ */
+ return (0);
}
-
-
-
/**
* xmlSchemaCheckCOSCTExtends:
* @ctxt: the schema parser context
* @type: the complex type definition
*
- * Schema Component Constraint: Derivation Valid (Extension)
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Derivation Valid (Extension) (cos-ct-extends)
+ *
+ * STATUS:
+ * missing:
+ * (1.5)
+ * (1.4.3.2.2.2) "Particle Valid (Extension)", which is not really needed.
*
* Returns 0 if the constraints are satisfied, a positive
* error code if not and -1 if an internal error occured.
@@ -13122,462 +14015,1082 @@ static int
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaTypePtr type)
{
- xmlSchemaTypePtr base;
+ xmlSchemaTypePtr base = type->baseType;
+ /*
+ * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
+ * temporarily only.
+ */
/*
- * 1 If the {base type definition} is a complex type definition,
- * then all of the following must be true:
+ * SPEC (1) "If the {base type definition} is a complex type definition,
+ * then all of the following must be true:"
*/
- base = type->baseType;
- if (base == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaCheckCOSCTExtends, "
- "the complex type '%s' has no base type", type->name);
- return (-1);
- }
if (base->type == XML_SCHEMA_TYPE_COMPLEX) {
/*
- * 1.1 The {final} of the {base type definition} must not
- * contain extension.
+ * SPEC (1.1) "The {final} of the {base type definition} must not
+ * contain extension."
*/
if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
NULL, type, NULL,
"The 'final' of the base type definition "
- "contains extension", NULL);
+ "contains 'extension'", NULL);
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
}
/*
- * 1.2 Its {attribute uses} must be a subset of the {attribute uses}
+ * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
+ * uses}
* of the complex type definition itself, that is, for every attribute
* use in the {attribute uses} of the {base type definition}, there
* must be an attribute use in the {attribute uses} of the complex
* type definition itself whose {attribute declaration} has the same
* {name}, {target namespace} and {type definition} as its attribute
- * declaration
+ * declaration"
*
- * NOTE: This will be already satisfied by the way the attribute uses
- * are extended in xmlSchemaBuildAttributeValidation; thus this check
- * is not needed.
+ * NOTE (1.2): This will be already satisfied by the way the attribute
+ * uses are extended in xmlSchemaBuildAttributeValidation(); thus this
+ * check is not needed.
*/
/*
- * 1.3 If it has an {attribute wildcard}, the complex type definition
- * must also have one, and the base type definition's {attribute
- * wildcard}'s {namespace constraint} must be a subset of the complex
- * type definition's {attribute wildcard}'s {namespace constraint},
- * as defined by Wildcard Subset (§3.10.6).
+ * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
+ * definition must also have one, and the base type definition's
+ * {attribute wildcard}'s {namespace constraint} must be a subset
+ * of the complex type definition's {attribute wildcard}'s {namespace
+ * constraint}, as defined by Wildcard Subset (§3.10.6)."
+ *
+ * NOTE (1.3) This is already checked in
+ * xmlSchemaBuildAttributeValidation; thus this check is not needed.
*
- * This is already checked in xmlSchemaBuildAttributeValidation; thus
- * this check is not needed.
+ * SPEC (1.4) "One of the following must be true:"
*/
-
+ if ((type->contentTypeDef != NULL) &&
+ (type->contentTypeDef == base->contentTypeDef)) {
+ /*
+ * SPEC (1.4.1) "The {content type} of the {base type definition}
+ * and the {content type} of the complex type definition itself
+ * must be the same simple type definition"
+ * PASS
+ */
+ } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
+ (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
+ /*
+ * SPEC (1.4.2) "The {content type} of both the {base type
+ * definition} and the complex type definition itself must
+ * be empty."
+ * PASS
+ */
+ } else {
+ /*
+ * SPEC (1.4.3) "All of the following must be true:"
+ */
+ if (type->subtypes == NULL) {
+ /*
+ * SPEC 1.4.3.1 The {content type} of the complex type
+ * definition itself must specify a particle.
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The content type must specify a particle", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ /*
+ * SPEC (1.4.3.2) "One of the following must be true:"
+ */
+ if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+ /*
+ * SPEC (1.4.3.2.1) "The {content type} of the {base type
+ * definition} must be empty.
+ * PASS
+ */
+ } else {
+ /*
+ * SPEC (1.4.3.2.2) "All of the following must be true:"
+ */
+ if ((type->contentType != base->contentType) ||
+ ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
+ (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
+ /*
+ * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
+ * or both must be element-only."
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The content type of both, the type and its base "
+ "type, must either 'mixed' or 'element-only'", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ /*
+ * FUTURE TODO SPEC (1.4.3.2.2.2) "The particle of the
+ * complex type definition must be a ·valid extension·
+ * of the {base type definition}'s particle, as defined
+ * in Particle Valid (Extension) (§3.9.6)."
+ *
+ * NOTE that we won't check "Particle Valid (Extension)",
+ * since it is ensured by the derivation process in
+ * xmlSchemaTypeFixup(). We need to implement this when heading
+ * for a construction API
+ */
+ }
+ /*
+ * TODO (1.5)
+ */
+ }
+ } else {
/*
- * 1.4 One of the following must be true:
- *
- * 1.4.1 The {content type} of the {base type definition} and the
- * {content type} of the complex type definition itself must be the same
- * simple type definition
+ * SPEC (2) "If the {base type definition} is a simple type definition,
+ * then all of the following must be true:"
*/
+ if (type->contentTypeDef != base) {
+ /*
+ * SPEC (2.1) "The {content type} must be the same simple type
+ * definition."
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The content type must be the simple base type", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
+ /*
+ * SPEC (2.2) "The {final} of the {base type definition} must not
+ * contain extension"
+ * NOTE that this is the same as (1.1).
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The 'final' of the base type definition "
+ "contains 'extension'", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ }
+ return (0);
+}
-
-
- } else {
+/**
+ * xmlSchemaCheckDerivationOKRestriction:
+ * @ctxt: the schema parser context
+ * @type: the complex type definition
+ *
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
+ *
+ * STATUS:
+ * missing:
+ * (5.4.2), (5.2.2.1)
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
+{
+ xmlSchemaTypePtr base;
+
+ /*
+ * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
+ * temporarily only.
+ */
+ base = type->baseType;
+ if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
+ /*
+ * SPEC (1) "The {base type definition} must be a complex type
+ * definition whose {final} does not contain restriction."
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The 'final' of the base type definition "
+ "contains 'restriction'", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ /*
+ * NOTE (3) and (4) are done in xmlSchemaBuildAttributeValidation().
+ *
+ * SPEC (5) "One of the following must be true:"
+ */
+ if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
/*
- * 2 If the {base type definition} is a simple type definition,
- * then all of the following must be true:
+ * SPEC (5.1) "The {base type definition} must be the
+ * ·ur-type definition·."
+ * PASS
*/
+ } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+ (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
/*
- * 2.1 The {content type} must be the same simple type definition.
+ * SPEC (5.2.1) "The {content type} of the complex type definition
+ * must be a simple type definition"
+ *
+ * SPEC (5.2.2) "One of the following must be true:"
*/
+ if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+ (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
+ /*
+ * SPEC (5.2.2.1) "The {content type} of the {base type
+ * definition} must be a simple type definition from which
+ * the {content type} is validly derived given the empty
+ * set as defined in Type Derivation OK (Simple) (§3.14.6)."
+ * URGENT TODO
+ */
+ } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+ (xmlSchemaIsParticleEmptiable(
+ (xmlSchemaParticlePtr) base->subtypes))) {
+ /*
+ * SPEC (5.2.2.2) "The {base type definition} must be mixed
+ * and have a particle which is ·emptiable· as defined in
+ * Particle Emptiable (§3.9.6)."
+ * PASS
+ */
+ } else {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The content type of the base type must be either "
+ "a simple type or 'mixed' and an emptiable particle", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
/*
- * 2.2 The {final} of the {base type definition} must not contain
- * extension
+ * SPEC (5.3.1) "The {content type} of the complex type itself must
+ * be empty"
*/
+ if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+ /*
+ * SPEC (5.3.2.1) "The {content type} of the {base type
+ * definition} must also be empty."
+ * PASS
+ */
+ } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
+ (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
+ xmlSchemaIsParticleEmptiable(
+ (xmlSchemaParticlePtr) base->subtypes)) {
+ /*
+ * SPEC (5.3.2.2) "The {content type} of the {base type
+ * definition} must be elementOnly or mixed and have a particle
+ * which is ·emptiable· as defined in Particle Emptiable (§3.9.6)."
+ * PASS
+ */
+ } else {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The content type of the base type must be either "
+ "empty or 'mixed' (or 'elements-only') and an emptiable "
+ "particle", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+ }
+ } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
+ ((type->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+ (base->contentType == XML_SCHEMA_CONTENT_MIXED))) {
+ /*
+ * SPEC (5.4.1.1) "The {content type} of the complex type definition
+ * itself must be element-only"
+ * SPEC (5.4.1.2) "The {content type} of the complex type definition
+ * itself and of the {base type definition} must be mixed"
+ */
+ /*
+ * SPEC (5.4.2) "The particle of the complex type definition itself
+ * must be a ·valid restriction· of the particle of the {content
+ * type} of the {base type definition} as defined in Particle Valid
+ * (Restriction) (§3.9.6).
+ * URGENT TODO
+ */
+ } else {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+ NULL, type, NULL,
+ "The type is not a valid restriction of its base type", NULL);
+ return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
}
+ return (0);
+}
+/**
+ * xmlSchemaCheckCTPropertiesCorrect:
+ * @ctxt: the schema parser context
+ * @type: the complex type definition
+ *
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaTypePtr type)
+{
+ int ret;
+ /*
+ * Complex Type Definition Properties Correct
+ */
+ ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
+ if (ret != 0)
+ return (ret);
+ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
+ ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
+ else
+ ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
+ return (ret);
}
+/**
+ * xmlSchemaCheckSRCCT:
+ * @ctxt: the schema parser context
+ * @type: the complex type definition
+ *
+ * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
+ * Schema Representation Constraint:
+ * Complex Type Definition Representation OK (src-ct)
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
static int
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaTypePtr type)
{
- xmlSchemaTypePtr base, content;
- int OK = 0;
+ xmlSchemaTypePtr base;
+ int ret = 0;
/*
* TODO: Adjust the error codes here, as I used
* XML_SCHEMAP_SRC_CT_1 only yet.
*/
- /*
- * Schema Representation Constraint:
- * Complex Type Definition Representation OK
- */
base = type->baseType;
- if (base == NULL) {
- xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, NULL, type, NULL,
- "Internal error: xmlSchemaCheckSRCCT, '%s', no base type",
- type->name);
- return (-1);
- }
-
- if (type->subtypes != NULL) {
- if (type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
- if IS_COMPLEX_TYPE(base) {
- /*
- * 1 If the <complexContent> alternative is chosen, the type definition
- * ·resolved· to by the ·actual value· of the base [attribute]
- * must be a complex type definition;
+ if (type->contentType != XML_SCHEMA_CONTENT_SIMPLE) {
+ /*
+ * 1 If the <complexContent> alternative is chosen, the type definition
+ * ·resolved· to by the ·actual value· of the base [attribute]
+ * must be a complex type definition;
+ */
+ if (! IS_COMPLEX_TYPE(base)) {
+ xmlChar *str = NULL;
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_CT_1,
+ NULL, type, type->node,
+ "If using <complexContent>, the base type is expected to be "
+ "a complex type. The base type '%s' is a simple type",
+ xmlSchemaFormatQName(&str, base->targetNamespace,
+ base->name));
+ FREE_AND_NULL(str)
+ return (XML_SCHEMAP_SRC_CT_1);
+ }
+ } else {
+ /*
+ * SPEC
+ * 2 If the <simpleContent> alternative is chosen, all of the
+ * following must be true:
+ * 2.1 The type definition ·resolved· to by the ·actual value· of the
+ * base [attribute] must be one of the following:
+ */
+ if (IS_SIMPLE_TYPE(base)) {
+ if ((type->flags &
+ XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) == 0) {
+ xmlChar *str = NULL;
+ /*
+ * 2.1.3 only if the <extension> alternative is also
+ * chosen, a simple type definition.
*/
+ /* TODO: Change error code to ..._SRC_CT_2_1_3. */
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_SRC_CT_1,
NULL, type, NULL,
- "The base type is not a complex type", NULL);
+ "If using <simpleContent> and <restriction>, the base "
+ "type must be a complex type. The base type '%s' is "
+ "a simple type",
+ xmlSchemaFormatQName(&str, base->targetNamespace,
+ base->name));
+ FREE_AND_NULL(str)
return (XML_SCHEMAP_SRC_CT_1);
- }
- } else if (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
-
- if IS_SIMPLE_TYPE(base) {
- if (type->flags &
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
- /*
- * 2.1.3 only if the <extension> alternative is also
- * chosen, a simple type definition.
- */
- /* TODO: Change error code to ..._SRC_CT_2_1_3. */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_CT_1,
+ }
+ } else {
+ /* Base type is a complex type. */
+ if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+ (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
+ /*
+ * 2.1.1 a complex type definition whose {content type} is a
+ * simple type definition;
+ * PASS
+ */
+ if (base->contentTypeDef == NULL) {
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
- "A complex type (simple content) cannot restrict "
- "an other simple type",
- NULL);
- return (XML_SCHEMAP_SRC_CT_1);
+ "Internal error: xmlSchemaCheckSRCCT, "
+ "'%s', base type has no content type",
+ type->name);
+ return (-1);
}
- OK = 1;
+ } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+ (type->flags &
+ XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) {
- } else { /* if IS_SIMPLE_TYPE(base) */
- if (base->contentType = XML_SCHEMA_CONTENT_MIXED) {
- /*
- * 2.1.2 only if the <restriction> alternative is also
- * chosen, a complex type definition whose {content type}
- * is mixed and a particle emptyable.
- */
- /*
- * FIXME TODO: Check for *empiable particle* is missing.
- */
- if ((type->flags &
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) == 0) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_CT_1,
- NULL, type, NULL,
- "A complex type (simple content) cannot "
- "extend an other complex type which has a "
- "content type of: 'mixed' and emptiable particle",
- NULL);
- return (XML_SCHEMAP_SRC_CT_1);
- }
- /*
- * NOTE: This will be fired as well, if the base type
- * is *'anyType'*.
- * NOTE: type->subtypes->subtypes will be the
- * <restriction> item.
- */
- if (type->subtypes->subtypes == NULL) {
- /* Yes, this is paranoid programming. */
- xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaCheckSRCCT, "
- "'%s', <simpleContent> has no <restriction>",
- type->name);
- return (-1);
- }
+ /*
+ * 2.1.2 only if the <restriction> alternative is also
+ * chosen, a complex type definition whose {content type}
+ * is mixed and a particle emptiable.
+ */
+ if (! xmlSchemaIsParticleEmptiable(
+ (xmlSchemaParticlePtr) base->subtypes)) {
+ ret = XML_SCHEMAP_SRC_CT_1;
+ } else if ((type->contentTypeDef == NULL) ||
+ (type->contentTypeDef->baseType == NULL)) {
+ xmlChar *str = NULL;
/*
* 2.2 If clause 2.1.2 above is satisfied, then there
* must be a <simpleType> among the [children] of
* <restriction>.
- */
- if (type->subtypes->subtypes->type !=
- XML_SCHEMA_TYPE_SIMPLE) {
- /* TODO: Change error code to ..._SRC_CT_2_2. */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_CT_1,
- NULL, type, NULL,
- "A <simpleType> is expected among the children "
- "of <restriction>", NULL);
- return (XML_SCHEMAP_SRC_CT_1);
- }
- OK = 1;
- } else { /* if (base->contentType = XML_SCHEMA_CONTENT_MIXED)*/
- /*
- * 2.1.1 a complex type definition whose {content type} is a
- * simple type definition;
- */
- if (base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_CT_1,
- NULL, type, NULL,
- "A complex type (simple content) cannot "
- "be derived from the complex type '%s'",
- base->name);
- return (XML_SCHEMAP_SRC_CT_1);
- }
- content = base->contentTypeDef;
- if (content == NULL) {
- xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaCheckSRCCT, "
- "'%s', base type has no content type",
- type->name);
- return (-1);
- }
- if (content->type != XML_SCHEMA_TYPE_SIMPLE) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_CT_1,
- NULL, type, NULL,
- "A complex type (simple content) cannot "
- "be derived from the complex type '%s'",
- base->name);
- return (XML_SCHEMAP_SRC_CT_1);
- }
+ */
+ /* TODO: Change error code to ..._SRC_CT_2_2. */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_CT_1,
+ NULL, type, NULL,
+ "A <simpleType> is expected among the children "
+ "of <restriction>, if <simpleContent> is used and "
+ "the base type '%s' is a complex type",
+ xmlSchemaFormatQName(&str, base->targetNamespace,
+ base->name));
+ FREE_AND_NULL(str)
+ return (XML_SCHEMAP_SRC_CT_1);
}
- }
- }
+ } else {
+ ret = XML_SCHEMAP_SRC_CT_1;
+ }
+ }
+ if (ret > 0) {
+ xmlChar *str = NULL;
+ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_CT_1,
+ NULL, type, NULL,
+ "If <simpleContent> and <restriction> is used, the "
+ "base type must be a simple type or a complex type with "
+ "mixed content and particle emptiable. The base type "
+ "'%s' is none of those",
+ xmlSchemaFormatQName(&str, base->targetNamespace,
+ base->name));
+ } else {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_SRC_CT_1,
+ NULL, type, NULL,
+ "If <simpleContent> and <extension> is used, the "
+ "base type must be a simple type. The base type '%s' "
+ "is a complex type",
+ xmlSchemaFormatQName(&str, base->targetNamespace,
+ base->name));
+ }
+ FREE_AND_NULL(str)
+ }
}
/*
- * TODO: 3 The corresponding complex type definition component must
+ * SPEC (3) "The corresponding complex type definition component must
* satisfy the conditions set out in Constraints on Complex Type
- * Definition Schema Components (§3.4.6);
- *
- * TODO: 4 If clause 2.2.1 or clause 2.2.2 in the correspondence specification
+ * Definition Schema Components (§3.4.6);"
+ * NOTE (3) will be done in xmlSchemaTypeFixup().
+ */
+ /*
+ * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
* above for {attribute wildcard} is satisfied, the intensional
* intersection must be expressible, as defined in Attribute Wildcard
* Intersection (§3.10.6).
+ * NOTE (4) is done in xmlSchemaBuildAttributeValidation().
*/
-
+ return (ret);
}
-#endif
-/**
- * xmlSchemaGroupDefFixup:
- * @typeDecl: the schema model group definition
- * @ctxt: the schema parser context
- *
- * Fixes model group definitions.
- */
+#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
+ xmlSchemaPCustomErrExt(pctxt, \
+ XML_SCHEMAP_INVALID_FACET_VALUE, \
+ NULL, (xmlSchemaTypePtr) fac1, fac1->node, \
+ "It is an error for both '%s' and '%s' to be specified on the "\
+ "same type definition", \
+ BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
+ BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
+
+#define FACET_RESTR_ERR(fac1, msg) \
+ xmlSchemaPCustomErr(pctxt, \
+ XML_SCHEMAP_INVALID_FACET_VALUE, \
+ NULL, (xmlSchemaTypePtr) fac1, fac1->node, \
+ msg, NULL);
+
+#define FACET_RESTR_FIXED_ERR(fac) \
+ xmlSchemaPCustomErr(pctxt, \
+ XML_SCHEMAP_INVALID_FACET_VALUE, \
+ NULL, (xmlSchemaTypePtr) fac, fac->node, \
+ "The base type's facet is 'fixed', thus the value must not " \
+ "differ", NULL);
+
static void
-xmlSchemaGroupDefFixup(xmlSchemaTypePtr group,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar * name ATTRIBUTE_UNUSED)
-{
- group->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- if ((group->ref != NULL) && (group->subtypes == NULL)) {
- xmlSchemaTypePtr groupDef;
- /*
- * Resolve the reference.
- */
- groupDef = xmlSchemaGetGroup(ctxt->schema, group->ref,
- group->refNs);
- if (groupDef == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, group, NULL,
- "ref", group->ref, group->refNs,
- XML_SCHEMA_TYPE_GROUP, NULL);
- return;
- }
- group->subtypes = groupDef;
- }
+xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaFacetPtr facet1,
+ xmlSchemaFacetPtr facet2,
+ int lessGreater,
+ int orEqual,
+ int ofBase)
+{
+ xmlChar *msg = NULL;
+
+ msg = xmlStrdup(BAD_CAST "'");
+ msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
+ msg = xmlStrcat(msg, BAD_CAST "' has to be");
+ if (lessGreater == 0)
+ msg = xmlStrcat(msg, BAD_CAST " equal to");
+ if (lessGreater == 1)
+ msg = xmlStrcat(msg, BAD_CAST " greater than");
+ else
+ msg = xmlStrcat(msg, BAD_CAST " less than");
+
+ if (orEqual)
+ msg = xmlStrcat(msg, BAD_CAST " or equal to");
+ msg = xmlStrcat(msg, BAD_CAST " '");
+ msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
+ if (ofBase)
+ msg = xmlStrcat(msg, BAD_CAST "' of the base type");
+ else
+ msg = xmlStrcat(msg, BAD_CAST "'");
+
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_INVALID_FACET_VALUE,
+ NULL, (xmlSchemaTypePtr) facet1, facet1->node,
+ (const char *) msg, NULL);
+
+ if (msg != NULL)
+ xmlFree(msg);
}
-#if 0 /* Enable when the content type will be computed. */
static int
-xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaTypePtr type)
+xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaTypePtr type)
{
- xmlSchemaTypePtr base, res = NULL;
+ xmlSchemaTypePtr base = type->baseType;
+ xmlSchemaFacetLinkPtr link, cur, last = NULL;
+ xmlSchemaFacetPtr facet, bfacet,
+ flength = NULL, ftotdig = NULL, ffracdig = NULL,
+ fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
+ fmininc = NULL, fmaxinc = NULL,
+ fminexc = NULL, fmaxexc = NULL,
+ bflength = NULL, bftotdig = NULL, bffracdig = NULL,
+ bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
+ bfmininc = NULL, bfmaxinc = NULL,
+ bfminexc = NULL, bfmaxexc = NULL;
+ int res, err = 0, fixedErr;
+ /*
+ * 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 ((type->facetSet == NULL) && (base->facetSet == NULL))
+ return (0);
- base = type->baseType;
- if (base == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "the complex type '%s' has no base type", type->name);
- return (-1);
- }
- if (IS_ANYTYPE(base) || (type->subtypes->type ==
- XML_SCHEMA_TYPE_COMPLEX_CONTENT)) {
- xmlSchemaTypePtr start;
+ last = type->facetSet;
+ if (last != NULL)
+ while (last->next != NULL)
+ last = last->next;
+
+ for (cur = type->facetSet; cur != NULL; cur = cur->next) {
+ facet = cur->facet;
+ switch (facet->type) {
+ case XML_SCHEMA_FACET_LENGTH:
+ flength = facet; break;
+ case XML_SCHEMA_FACET_MINLENGTH:
+ fminlen = facet; break;
+ case XML_SCHEMA_FACET_MININCLUSIVE:
+ fmininc = facet; break;
+ case XML_SCHEMA_FACET_MINEXCLUSIVE:
+ fminexc = facet; break;
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ fmaxlen = facet; break;
+ case XML_SCHEMA_FACET_MAXINCLUSIVE:
+ fmaxinc = facet; break;
+ case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+ fmaxexc = facet; break;
+ case XML_SCHEMA_FACET_TOTALDIGITS:
+ ftotdig = facet; break;
+ case XML_SCHEMA_FACET_FRACTIONDIGITS:
+ ffracdig = facet; break;
+ default:
+ break;
+ }
+ }
+ for (cur = base->facetSet; cur != NULL; cur = cur->next) {
+ facet = cur->facet;
+ switch (facet->type) {
+ case XML_SCHEMA_FACET_LENGTH:
+ bflength = facet; break;
+ case XML_SCHEMA_FACET_MINLENGTH:
+ bfminlen = facet; break;
+ case XML_SCHEMA_FACET_MININCLUSIVE:
+ bfmininc = facet; break;
+ case XML_SCHEMA_FACET_MINEXCLUSIVE:
+ bfminexc = facet; break;
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ bfmaxlen = facet; break;
+ case XML_SCHEMA_FACET_MAXINCLUSIVE:
+ bfmaxinc = facet; break;
+ case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+ bfmaxexc = facet; break;
+ case XML_SCHEMA_FACET_TOTALDIGITS:
+ bftotdig = facet; break;
+ case XML_SCHEMA_FACET_FRACTIONDIGITS:
+ bffracdig = facet; break;
+ default:
+ break;
+ }
+ }
+ err = 0;
+ /*
+ * length and minLength or maxLength (2.2) + (3.2)
+ */
+ if (flength && (fminlen || fmaxlen)) {
+ FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
+ "either of 'minLength' or 'maxLength' to be specified on "
+ "the same type definition")
+ }
+ /*
+ * Mutual exclusions in the same derivation step.
+ */
+ if ((fmaxinc) && (fmaxexc)) {
+ /*
+ * SCC "maxInclusive and maxExclusive"
+ */
+ FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
+ }
+ if ((fmininc) && (fminexc)) {
+ /*
+ * SCC "minInclusive and minExclusive"
+ */
+ FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
+ }
+
+ if (flength && bflength) {
/*
- * Effective 'mixed'.
+ * SCC "length valid restriction"
+ * The values have to be equal.
*/
- if (type->flags & XML_SCHEMAS_TYPE_MIXED)
- type->contentType = XML_SCHEMA_CONTENT_MIXED;
+ res = xmlSchemaCompareValues(flength->val, bflength->val);
+ if (res == -2)
+ goto internal_error;
/*
- * Effective content.
+ * TODO: Maby a bug in the spec.
*/
- if (IS_ANYTYPE(base))
- start = type;
- else
- start = type->subtypes;
-
- } else { /* if XML_SCHEMA_TYPE_COMPLEX_CONTENT */
- xmlSchemaTypePtr baseContentItem;
-
+ if (res != 0)
+ xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
+ if ((res != 0) && (bflength->fixed)) {
+ FACET_RESTR_FIXED_ERR(flength)
+ }
+
+ }
+ if (fminlen && bfminlen) {
/*
- * Complex type with simple content.
+ * SCC "minLength valid restriction"
+ * minLength >= BASE minLength
*/
- if IS_COMPLEX_TYPE(base) {
- if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
- /*
- * Summary: a complex type (simple content) can *restrict*
- * a complex type with the following content type:
- * 1. 'mixed' and an emptiable particle
- * 2. simple type
- */
- if (base->contentType == XML_SCHEMA_CONTENT_MIXED) {
- /*
- * 2 if the {content type} of the base type is mixed and a
- * particle which is ·emptiable·,
- * [...]
- * then starting from the simple type definition
- * corresponding to the <simpleType> among the [children]
- * of <restriction> (**which must be present**)
- *
- * FIXME TODO: Handle "emptiable particle".
- */
- res = type->subtypes->subtypes;
- if (res == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (restricting): <simpleContent> has no "
- "<restriction>",
- type->name);
- return (-1);
- }
-
- res->subtypes;
- if (res == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (restricting): <restriction> has no "
- "mandatory <simpleType>",
- type->name);
- return (-1);
- }
- } else {
- baseContentItem = base->contentTypeDef;
- if (baseContentItem == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (restricting), the base type has no "
- "content type", type->name);
- return (-1);
- }
- if IS_SIMPLE_TYPE(baseContentItem) {
+ res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1)
+ xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
+ if ((res != 0) && (bfminlen->fixed)) {
+ FACET_RESTR_FIXED_ERR(fminlen)
+ }
+ }
+ if (fmaxlen && bfmaxlen) {
+ /*
+ * SCC "maxLength valid restriction"
+ * maxLength <= BASE minLength
+ */
+ res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
+ if ((res != 0) && (bfmaxlen->fixed)) {
+ FACET_RESTR_FIXED_ERR(fmaxlen)
+ }
+ }
+ /*
+ * SCC "length and minLength or maxLength"
+ */
+ if (! flength)
+ flength = bflength;
+ if (flength) {
+ if (! fminlen)
+ flength = bflength;
+ if (fminlen) {
+ /* (1.1) length >= minLength */
+ res = xmlSchemaCompareValues(flength->val, fminlen->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1)
+ xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
+ }
+ if (! fmaxlen)
+ fmaxlen = bfmaxlen;
+ if (fmaxlen) {
+ /* (2.1) length <= maxLength */
+ res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
+ }
+ }
+ if (fmaxinc) {
+ /*
+ * "maxInclusive"
+ */
+ if (fmininc) {
+ /* SCC "maxInclusive >= minInclusive" */
+ res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
+ }
+ }
+ /*
+ * SCC "maxInclusive valid restriction"
+ */
+ if (bfmaxinc) {
+ /* maxInclusive <= BASE maxInclusive */
+ res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
+ if ((res != 0) && (bfmaxinc->fixed)) {
+ FACET_RESTR_FIXED_ERR(fmaxinc)
+ }
+ }
+ if (bfmaxexc) {
+ /* maxInclusive < BASE maxExclusive */
+ res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
+ }
+ }
+ if (bfmininc) {
+ /* maxInclusive >= BASE minInclusive */
+ res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
+ }
+ }
+ if (bfminexc) {
+ /* maxInclusive > BASE minExclusive */
+ res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
+ }
+ }
+ }
+ if (fmaxexc) {
+ /*
+ * "maxExclusive >= minExclusive"
+ */
+ if (fminexc) {
+ res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
+ }
+ }
+ /*
+ * "maxExclusive valid restriction"
+ */
+ if (bfmaxexc) {
+ /* maxExclusive <= BASE maxExclusive */
+ res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
+ }
+ if ((res != 0) && (bfmaxexc->fixed)) {
+ FACET_RESTR_FIXED_ERR(fmaxexc)
+ }
+ }
+ if (bfmaxinc) {
+ /* maxExclusive <= BASE maxInclusive */
+ res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
+ }
+ }
+ if (bfmininc) {
+ /* maxExclusive > BASE minInclusive */
+ res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
+ }
+ }
+ if (bfminexc) {
+ /* maxExclusive > BASE minExclusive */
+ res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
+ }
+ }
+ }
+ if (fminexc) {
+ /*
+ * "minExclusive < maxInclusive"
+ */
+ if (fmaxinc) {
+ res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
+ }
+ }
+ /*
+ * "minExclusive valid restriction"
+ */
+ if (bfminexc) {
+ /* minExclusive >= BASE minExclusive */
+ res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
+ }
+ if ((res != 0) && (bfminexc->fixed)) {
+ FACET_RESTR_FIXED_ERR(fminexc)
+ }
+ }
+ if (bfmaxinc) {
+ /* minExclusive <= BASE maxInclusive */
+ res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1) {
+ xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
+ }
+ }
+ if (bfmininc) {
+ /* minExclusive >= BASE minInclusive */
+ res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
+ }
+ }
+ if (bfmaxexc) {
+ /* minExclusive < BASE maxExclusive */
+ res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
+ }
+ }
+ }
+ if (fmininc) {
+ /*
+ * "minInclusive < maxExclusive"
+ */
+ if (fmaxexc) {
+ res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
+ }
+ }
+ /*
+ * "minExclusive valid restriction"
+ */
+ if (bfmininc) {
+ /* minInclusive >= BASE minInclusive */
+ res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
+ }
+ if ((res != 0) && (bfmininc->fixed)) {
+ FACET_RESTR_FIXED_ERR(fmininc)
+ }
+ }
+ if (bfmaxinc) {
+ /* minInclusive <= BASE maxInclusive */
+ res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == -1) {
+ xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
+ }
+ }
+ if (bfminexc) {
+ /* minInclusive > BASE minExclusive */
+ res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != 1)
+ xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
+ }
+ if (bfmaxexc) {
+ /* minInclusive < BASE maxExclusive */
+ res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
+ if (res == -2)
+ goto internal_error;
+ if (res != -1)
+ xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
+ }
+ }
+ if (ftotdig && bftotdig) {
+ /*
+ * SCC " totalDigits valid restriction"
+ * totalDigits <= BASE totalDigits
+ */
+ res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
+ -1, 1, 1);
+ if ((res != 0) && (bftotdig->fixed)) {
+ FACET_RESTR_FIXED_ERR(ftotdig)
+ }
+ }
+ if (ffracdig && bffracdig) {
+ /*
+ * SCC "fractionDigits valid restriction"
+ * fractionDigits <= BASE fractionDigits
+ */
+ res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
+ -1, 1, 1);
+ if ((res != 0) && (bffracdig->fixed)) {
+ FACET_RESTR_FIXED_ERR(ffracdig)
+ }
+ }
+ /*
+ * SCC "fractionDigits less than or equal to totalDigits"
+ */
+ if (! ftotdig)
+ ftotdig = bftotdig;
+ if (! ffracdig)
+ ffracdig = bffracdig;
+ if (ftotdig && ffracdig) {
+ res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
+ if (res == -2)
+ goto internal_error;
+ if (res == 1)
+ xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
+ -1, 1, 0);
+ }
+ /*
+ * *Enumerations* won' be added here, since only the first set
+ * of enumerations in the ancestor-or-self axis is used
+ * for validation, plus we need to use the base type of those
+ * enumerations for whitespace.
+ *
+ * *Patterns*: won't be add here, since they are ORed at
+ * type level and ANDed at ancestor level. This will
+ * happed during validation by walking the base axis
+ * of the type.
+ */
+ for (cur = base->facetSet; cur != NULL; cur = cur->next) {
+ bfacet = cur->facet;
+ /*
+ * Special handling of enumerations and patterns.
+ * TODO: hmm, they should not appear in the set, so remove this.
+ */
+ if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
+ (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
+ continue;
+ /*
+ * Search for a duplicate facet in the current type.
+ */
+ link = type->facetSet;
+ err = 0;
+ fixedErr = 0;
+ while (link != NULL) {
+ facet = link->facet;
+ if (facet->type == bfacet->type) {
+ switch (facet->type) {
+ case XML_SCHEMA_FACET_WHITESPACE:
/*
- * 1 If the base type is a complex type whose own
- * {content type} is a simple type and the <restriction>
- * alternative is chosen
+ * The whitespace must be stronger.
*/
- /* type->subtypes->subtypes will be the restriction item.*/
- res = type->subtypes->subtypes;
- if (res == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (restricting): <simpleType> has no "
- "<restriction>", type->name);
- return (-1);
+ if (facet->whitespace < bfacet->whitespace) {
+ FACET_RESTR_ERR(flength,
+ "The 'whitespace' value has to be equal to "
+ "or stronger than the 'whitespace' value of "
+ "the base type")
}
- /*
- * 1.1 the simple type definition corresponding to the
- * <simpleType> among the [children] of <restriction>if
- * there is one;
- */
- res = res->subtypes;
- if (res == NULL) {
- /*
- * 1.2 otherwise the {content type}
- * of the base type .
- */
- res = baseContentItem;
+ if ((bfacet->fixed) &&
+ (facet->whitespace != bfacet->whitespace)) {
+ FACET_RESTR_FIXED_ERR(facet)
}
- }
- }
- /*
- * SPECIAL TODO: If *restricting* the spec wants us to
- * create an *additional* simple type which restricts the
- * located simple type; we won't do this yet, and look how
- * far we get with it.
- */
- } else { /* if XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION */
- /*
- * Summary: a complex type (simple content) can *extend*
- * only a complex base with a simple type as content.
- */
- /*
- * 3 If the type definition ·resolved· to by the ·actual
- * value· of the base [attribute] is a complex type
- * definition (whose own {content type} *must be* a simple
- * type definition, see below) and the *<extension>*
- * alternative is chosen, then the {content type} of that
- * complex type definition;
- */
- res = base->contentTypeDef;
- if (res == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (extending), the base type has no content "
- "type", type->name);
- return (-1);
- }
- if (! IS_SIMPLE_TYPE(res)) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "CT '%s' (extending), the content type of the "
- "base is not a simple type", type->name);
- return (-1);
+ break;
+ default:
+ break;
}
- }
- } else /* if IS_COMPLEX_TYPE(base) */
- if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) {
- /*
- * 4 otherwise (the type definition ·resolved· to by the
- * ·actual value· of the base [attribute] is a simple type
- * definition and the <extension> alternative is chosen),
- * then that simple type definition.
- */
- res = base;
- }
- type->contentTypeDef = res;
- if (res == NULL) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_INTERNAL,
- NULL, type, NULL,
- "Internal error: xmlSchemaGetContentType, "
- "'%s', the content type could not be determined",
- type->name);
- return (-1);
+ /* Duplicate found. */
+ break;
+ }
+ link = link->next;
}
-
+ /*
+ * If no duplicate was found: add the base types's facet
+ * to the set.
+ */
+ if (link == NULL) {
+ link = (xmlSchemaFacetLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaFacetLink));
+ if (link == NULL) {
+ xmlSchemaPErrMemory(pctxt,
+ "deriving facets, creating a facet link", NULL);
+ return (-1);
+ }
+ link->facet = cur->facet;
+ link->next = NULL;
+ if (last == NULL)
+ type->facetSet = link;
+ else
+ last->next = link;
+ last = link;
+ }
+
}
-
+
+ return (0);
+internal_error:
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_INVALID_FACET_VALUE,
+ NULL, type, NULL,
+ "Internal error: xmlSchemaDeriveAndValidateFacets", NULL);
+ return (-1);
}
-#endif
/**
* xmlSchemaTypeFixup:
@@ -13587,540 +15100,500 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
* Fixes the content model of the type.
*/
static void
-xmlSchemaTypeFixup(xmlSchemaTypePtr item,
+xmlSchemaTypeFixup(xmlSchemaTypePtr type,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
- xmlSchemaTypePtr ctxtType;
-
- if (item == NULL)
+ if (type == NULL)
return;
- /*
- * Do not fixup built-in types.
- */
- if (item->type == XML_SCHEMA_TYPE_BASIC)
+ if ((type->type != XML_SCHEMA_TYPE_COMPLEX) &&
+ (type->type != XML_SCHEMA_TYPE_SIMPLE))
return;
- /*
- * Do not allow the following types to be typefixed, prior to
- * the corresponding simple/complex types.
- */
- if (ctxt->ctxtType == NULL) {
- switch (item->type) {
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
- case XML_SCHEMA_TYPE_UNION:
- case XML_SCHEMA_TYPE_RESTRICTION:
- case XML_SCHEMA_TYPE_EXTENSION:
+ if (! IS_NOT_TYPEFIXED(type))
+ return;
+ type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
+ if (name == NULL)
+ name = type->name;
+
+ if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
+ xmlSchemaTypePtr baseType;
+
+ /*
+ * Resolve & type-fix the base type.
+ */
+ baseType = type->baseType;
+ if (baseType == NULL) {
+ baseType = xmlSchemaGetType(ctxt->schema,
+ type->base, type->baseNs);
+ if (baseType == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, type->node,
+ "base", type->base, type->baseNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
return;
- default:
- break;
+ }
+ type->baseType = baseType;
}
- }
- if (name == NULL)
- name = item->name;
- if (item->contentType == XML_SCHEMA_CONTENT_UNKNOWN) {
- switch (item->type) {
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{
- if (item->subtypes != NULL) {
- if (item->subtypes->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN) {
- xmlSchemaTypeFixup(item->subtypes, ctxt,
- NULL);
- }
- item->contentType =
- XML_SCHEMA_CONTENT_SIMPLE;
- /* item->subtypes->contentType; */
- }
- break;
- }
- case XML_SCHEMA_TYPE_RESTRICTION:{
- xmlSchemaTypePtr base = NULL;
-
- ctxt->ctxtType->flags |=
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
- if (item->baseType != NULL)
- base = item->baseType;
- else if (item->base != NULL) {
- base =
- xmlSchemaGetType(ctxt->schema, item->base,
- item->baseNs);
- if (base == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, NULL,
- (xmlNodePtr) xmlSchemaGetPropNode(item->node, "base"),
- "base", item->base, item->baseNs,
- XML_SCHEMA_TYPE_BASIC, "type definition");
- } else if (base->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN) {
- xmlSchemaTypeFixup(base, ctxt, NULL);
- }
- }
- ctxt->ctxtType->baseType = base;
- if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX) {
- /*
- * ComplexType restriction.
- */
- /*
- * Content type.
- */
- if (item->subtypes == NULL)
- /* 1.1.1 */
- item->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((item->subtypes->subtypes == NULL) &&
- ((item->subtypes->type ==
- XML_SCHEMA_TYPE_ALL)
- || (item->subtypes->type ==
- XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- item->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((item->subtypes->type ==
- XML_SCHEMA_TYPE_CHOICE)
- && (item->subtypes->subtypes == NULL))
- /* 1.1.3 */
- item->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else {
- /* 1.2 and 2.X are applied at the other layer */
- item->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
- }
- } else {
- /*
- * SimpleType restriction.
- */
- /* TODO: Nothing? */
- }
- break;
- }
- case XML_SCHEMA_TYPE_EXTENSION:{
- xmlSchemaTypePtr base = NULL;
- xmlSchemaContentType explicitContentType;
-
+ if (IS_NOT_TYPEFIXED(baseType))
+ xmlSchemaTypeFixup(baseType, ctxt, NULL);
+ if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
+ /*
+ * Skip fixup if the base type is invalid.
+ * TODO: Generate a warning!
+ */
+ return;
+ }
+ /*
+ * This basically checks if the base type can be derived.
+ */
+ if (xmlSchemaCheckSRCCT(ctxt, type) != 0) {
+ type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
+ return;
+ }
+ /*
+ * Fixup the content type.
+ */
+ if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
+ /*
+ * Corresponds to <complexType><simpleContent>...
+ */
+ if ((IS_COMPLEX_TYPE(baseType)) &&
+ (baseType->contentTypeDef != NULL) &&
+ (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) {
+ /*
+ * SPEC (1) If <restriction> + base type is <complexType>,
+ * "whose own {content type} is a simple type..."
+ *
+ * NOTE (1.1) is handled during parsing of <restriction>.
+ *
+ * (1.2) "...otherwise (<restriction> has no <simpleType> among
+ * its [children]), the simple type definition which is the
+ * {content type} of the ... base type."
+ */
+ if (type->contentTypeDef->baseType == NULL) {
/*
- * An extension does exist on a complexType only.
+ * <simpleContent><restriction> has *no* <simpleType>
+ * child.
*/
- ctxt->ctxtType->flags |=
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
- if (item->recurse) {
- /* TODO: The word "recursive" should be changed to "circular" here. */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_UNKNOWN_BASE_TYPE,
- NULL, item, item->node,
- "This item is circular", NULL);
- return;
- }
- if (item->base != NULL) {
- base =
- xmlSchemaGetType(ctxt->schema, item->base,
- item->baseNs);
- if (base == NULL) {
- xmlSchemaPResCompAttrErr(ctxt,
- XML_SCHEMAP_SRC_RESOLVE,
- NULL, item, item->node,
- "base", item->base, item->baseNs,
- XML_SCHEMA_TYPE_BASIC, "type definition");
- } else if (base->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN) {
- item->recurse = 1;
- xmlSchemaTypeFixup(base, ctxt, NULL);
- item->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.
- */
- item->baseType = base;
- }
- if ((item->subtypes != NULL) &&
- (item->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN))
- xmlSchemaTypeFixup(item->subtypes, ctxt, NULL);
-
- explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
- if (item->subtypes == NULL)
- /* 1.1.1 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((item->subtypes->subtypes == NULL) &&
- ((item->subtypes->type ==
- XML_SCHEMA_TYPE_ALL)
- || (item->subtypes->type ==
- XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((item->subtypes->type ==
- XML_SCHEMA_TYPE_CHOICE)
- && (item->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 */
- item->contentType = base->contentType;
- } else if (base->contentType ==
- XML_SCHEMA_CONTENT_EMPTY) {
- /* 2.2 imbitable ! */
- item->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
- } else {
- /* 2.3 imbitable pareil ! */
- item->contentType =
- XML_SCHEMA_CONTENT_ELEMENTS;
- }
- }
- break;
- }
- case XML_SCHEMA_TYPE_COMPLEX:{
- ctxtType = ctxt->ctxtType;
- ctxt->ctxtType = item;
+ type->contentTypeDef->baseType =
+ baseType->contentTypeDef;
+ }
+ } else if ((IS_COMPLEX_TYPE(baseType)) &&
+ (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+ (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) {
+ /*
+ * SPEC (2) If <restriction> + base is a mixed <complexType> with
+ * an emptiable particle, then a simple type definition which
+ * restricts the <restriction>'s <simpleType> child.
+ */
+ if ((type->contentTypeDef == NULL) ||
+ (type->contentTypeDef->baseType == NULL)) {
/*
- * Start with an empty content-type type.
+ * TODO: Check if this ever happens.
*/
- if (item->subtypes == NULL)
- item->contentType = XML_SCHEMA_CONTENT_EMPTY;
-
- if ((item->subtypes == NULL) ||
- ((item->subtypes->type !=
- XML_SCHEMA_TYPE_SIMPLE_CONTENT) &&
- (item->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.
- */
- item->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
- item->flags |=
- XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
- /*
- * Assume that we inherit the content-type type
- * from 'anyType', which is 'mixed' and a particle
- * emptiable.
- */
- item->contentType = item->baseType->contentType;
- }
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_INTERNAL,
+ NULL, type, NULL,
+ "Internal error: xmlSchemaTypeFixup, "
+ "complex type '%s': the <simpleContent><restriction> "
+ "is missing a <simpleType> child, but was not catched "
+ "by xmlSchemaCheckSRCCT()", type->name);
+ }
+ } else if ((IS_COMPLEX_TYPE(baseType)) &&
+ (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)) {
+ /*
+ * SPEC (3) If <extension> + base is <complexType> with
+ * <simpleType> content, "...then the {content type} of that
+ * complex type definition"
+ */
+ if (baseType->contentTypeDef == NULL) {
+ /*
+ * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
+ * should have catched this already.
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_INTERNAL,
+ NULL, type, NULL,
+ "Internal error: xmlSchemaTypeFixup, "
+ "complex type '%s': the <extension>ed base type is "
+ "a complex type with no simple content type",
+ type->name);
+ }
+ type->contentTypeDef = baseType->contentTypeDef;
+ } else if ((IS_SIMPLE_TYPE(baseType)) &&
+ (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)) {
+ /*
+ * SPEC (4) <extension> + base is <simpleType>
+ * "... then that simple type definition"
+ */
+ type->contentTypeDef = baseType;
+ } else {
+ /*
+ * TODO: Check if this ever happens.
+ */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_INTERNAL,
+ NULL, type, NULL,
+ "Internal error: xmlSchemaTypeFixup, "
+ "complex type '%s' with <simpleContent>: unhandled "
+ "derivation case", type->name);
+ }
+ } else {
+ int dummySequence = 0;
+ xmlSchemaParticlePtr particle =
+ (xmlSchemaParticlePtr) type->subtypes;
+ /*
+ * Corresponds to <complexType><complexContent>...
+ *
+ * NOTE that the effective mixed was already set during parsing of
+ * <complexType> and <complexContent>; its flag value is
+ * XML_SCHEMAS_TYPE_MIXED.
+ *
+ * Compute the "effective content":
+ * (2.1.1) + (2.1.2) + (2.1.3)
+ */
+ if ((particle == NULL) ||
+ ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
+ ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
+ (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+ ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
+ (particle->minOccurs == 0))) &&
+ ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
+ if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
/*
- * Fixup the sub components.
+ * SPEC (2.1.4) "If the ·effective mixed· is true, then
+ * a particle whose properties are as follows:..."
+ *
+ * Empty sequence model group with
+ * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
+ * NOTE that we sill assign it the <complexType> node to
+ * somehow anchor it in the doc.
*/
- if ((item->subtypes != NULL) &&
- (item->subtypes->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN)) {
- xmlSchemaTypeFixup(item->subtypes, ctxt, NULL);
- }
- if (item->flags & XML_SCHEMAS_TYPE_MIXED) {
- item->contentType = XML_SCHEMA_CONTENT_MIXED;
- } else if (item->subtypes != NULL) {
+ if ((particle == NULL) ||
+ (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
+ /*
+ * Create the particle.
+ */
+ particle = xmlSchemaAddParticle(ctxt, ctxt->schema,
+ type->node, 1, 1);
+ if (particle == NULL)
+ return;
/*
- * Use the content-type type of the model groups
- * defined, if 'mixed' is not set. If 'mixed' is set
- * it will expand the content-type by allowing character
- * content to appear.
+ * Create the model group.
*/
- item->contentType =
- item->subtypes->contentType;
+ particle->children = (xmlSchemaTreeItemPtr)
+ xmlSchemaAddModelGroup(ctxt, ctxt->schema,
+ XML_SCHEMA_TYPE_SEQUENCE, NULL, type->node);
+ if (particle->children == NULL)
+ return;
+
+ type->subtypes = (xmlSchemaTypePtr) particle;
}
-
+ dummySequence = 1;
+ type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
+ } else {
/*
- * Some optimization for validation:
- * If there are no facets beside the "whitespace" facet,
- * then a value needs not to checked against against a
- * facet, thus no computed value is needed.
- * TODO URGENT: This is just a workaround, we need to
- * introduce the correct usage of contentType to store the
- * facets in!
+ * SPEC (2.1.5) "otherwise empty"
*/
- if ((item->baseType != NULL) &&
- (item->baseType->flags &
- XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
- item->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
- else {
- xmlSchemaFacetLinkPtr cur;
-
- for (cur = item->facetSet; cur != NULL;
- cur = cur->next) {
- if (cur->facet->type != XML_SCHEMA_FACET_WHITESPACE) {
- item->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
- break;
- }
- }
- }
-
- xmlSchemaBuildAttributeValidation(ctxt, item);
- xmlSchemaCheckDefaults(item, ctxt, item->name);
- ctxt->ctxtType = ctxtType;
- break;
- }
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT:{
- if (item->subtypes == NULL) {
- item->contentType = XML_SCHEMA_CONTENT_EMPTY;
- if (item->flags & XML_SCHEMAS_TYPE_MIXED)
- item->contentType =
- XML_SCHEMA_CONTENT_MIXED;
- } else {
- if (item->flags & XML_SCHEMAS_TYPE_MIXED) {
- item->contentType =
- XML_SCHEMA_CONTENT_MIXED;
- } else {
- xmlSchemaTypeFixup(item->subtypes, ctxt,
- NULL);
- if (item->subtypes != NULL)
- item->contentType =
- item->subtypes->contentType;
- }
- /*
- * Removed due to implementation of the build of attribute uses.
- */
- /*
- if (item->attributes == NULL)
- item->attributes =
- item->subtypes->attributes;
- */
- }
- break;
- }
- case XML_SCHEMA_TYPE_SIMPLE:
+ type->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ }
+ } else {
/*
- * Simple Type Definition Schema Component
- *
+ * SPEC (2.2) "otherwise the particle corresponding to the
+ * <all>, <choice>, <group> or <sequence> among the
+ * [children]."
*/
- ctxtType = ctxt->ctxtType;
- item->contentType = XML_SCHEMA_CONTENT_SIMPLE;
- if (item->subtypes->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN) {
- ctxt->ctxtType = item;
- xmlSchemaTypeFixup(item->subtypes, ctxt, NULL);
- }
- /* Fixup base type */
- if ((item->baseType != NULL) &&
- (item->baseType->contentType ==
- XML_SCHEMA_CONTENT_UNKNOWN)) {
- /* OPTIMIZE: Actually this one will never by hit, since
- * the base type is already type-fixed in <restriction>.
- */
- ctxt->ctxtType = item;
- xmlSchemaTypeFixup(item->baseType, ctxt, NULL);
+ type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
+ }
+ /*
+ * Compute the "content type".
+ */
+ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) {
+ /*
+ * SPEC (3.1) "If <restriction>..."
+ * (3.1.1) + (3.1.2) */
+ if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
+ if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+ type->contentType = XML_SCHEMA_CONTENT_MIXED;
}
- /* Base type:
- * 2 If the <list> or <union> alternative is chosen,
- * then the ·simple ur-type definition·.
+ } else {
+ /*
+ * SPEC (3.2) "If <extension>..."
*/
- if (item->subtypes->type ==
- XML_SCHEMA_TYPE_LIST) {
- item->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
- item->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
- } else if (item->subtypes->type ==
- XML_SCHEMA_TYPE_UNION) {
- item->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
- item->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
- } else if (item->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 (item->baseType != NULL) {
- if (item->baseType->flags &
- XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
- item->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
- else if (item->baseType->flags &
- XML_SCHEMAS_TYPE_VARIETY_LIST)
- item->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
- else if (item->baseType->flags &
- XML_SCHEMAS_TYPE_VARIETY_UNION)
- item->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+ if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+ /*
+ * SPEC (3.2.1)
+ */
+ type->contentType = baseType->contentType;
+ type->subtypes = baseType->subtypes;
+ /*
+ * NOTE that the effective mixed is ignored here.
+ */
+ } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+ /*
+ * SPEC (3.2.2)
+ */
+ if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+ type->contentType = XML_SCHEMA_CONTENT_MIXED;
+ } else {
+ /*
+ * SPEC (3.2.3)
+ */
+ if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+ type->contentType = XML_SCHEMA_CONTENT_MIXED;
+ /*
+ * "A model group whose {compositor} is sequence and whose
+ * {particles} are..."
+ */
+ if (! dummySequence) {
+ xmlSchemaTreeItemPtr effectiveContent =
+ (xmlSchemaTreeItemPtr) type->subtypes;
/*
- * 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.
+ * Create the particle.
*/
- if (item->baseType->facetSet != NULL) {
- last = item->facetSet;
- if (last != NULL)
- while (last->next != NULL)
- last = last->next;
- cur = item->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 ((item->facetSet != NULL) &&
- /* REMOVED: a check for
- * XML_SCHEMA_FACET_PATTERN was already
- * performed above.
-
- * (cur->facet->type !=
- * XML_SCHEMA_FACET_PATTERN) &&
- */
- (cur->facet->type !=
- XML_SCHEMA_FACET_ENUMERATION)) {
- facet = item->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;
- }
- /*
- * The facets are not copied but referenced
- * via the facet link.
- */
- facet->facet = cur->facet;
- facet->next = NULL;
- if (last == NULL)
- item->facetSet = facet;
- else
- last->next = facet;
- last = facet;
- }
- }
- }
+ particle = xmlSchemaAddParticle(ctxt, ctxt->schema,
+ type->node, 1, 1);
+ if (particle == NULL)
+ return;
/*
- * Some optimization for validation:
- * If there are no facets beside the "whitespace" facet,
- * then a value needs not to checked against against a
- * facet, thus no computed value is needed.
+ * Create the "sequence" model group.
*/
- if (item->baseType->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)
- item->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
- else {
- for (cur = item->facetSet; cur != NULL;
- cur = cur->next) {
- if (cur->facet->type != XML_SCHEMA_FACET_WHITESPACE) {
- item->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
- break;
- }
- }
- }
+ particle->children = (xmlSchemaTreeItemPtr)
+ xmlSchemaAddModelGroup(ctxt, ctxt->schema,
+ XML_SCHEMA_TYPE_SEQUENCE, NULL, type->node);
+ if (particle->children == NULL)
+ return;
+ type->subtypes = (xmlSchemaTypePtr) particle;
+ /*
+ * SPEC "the particle of the {content type} of
+ * the ... base ..."
+ * Create a duplicate of the base type's particle
+ * and assign its "term" to it.
+ */
+ particle->children->children =
+ (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(ctxt,
+ ctxt->schema, type->node,
+ ((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
+ ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
+ if (particle->children->children == NULL)
+ return;
+ particle = (xmlSchemaParticlePtr)
+ particle->children->children;
+ particle->children =
+ ((xmlSchemaParticlePtr) baseType->subtypes)->children;
+ /*
+ * SPEC "followed by the ·effective content·."
+ */
+ particle->next = effectiveContent;
+ } else {
+ /*
+ * This is the case when there is already an empty
+ * <sequence> with minOccurs==maxOccurs==1.
+ * Just add the base types's content type.
+ * NOTE that, although we miss to add an intermediate
+ * <sequence>, this should produce no difference to
+ * neither the regex compilation of the content model,
+ * nor to the complex type contraints.
+ */
+ particle->children->children =
+ (xmlSchemaTreeItemPtr) baseType->subtypes;
}
- }
+ }
+ }
+ }
+ /*
+ * Apply the complex type component constraints; this will not
+ * check attributes, since this is done in
+ * xmlSchemaBuildAttributeValidation().
+ */
+ if (xmlSchemaCheckCTComponent(ctxt, type) != 0)
+ return;
+ /*
+ * Inherit & check constraints for attributes.
+ */
+ xmlSchemaBuildAttributeValidation(ctxt, type);
+ } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
+ /*
+ * Simple Type Definition Schema Component
+ */
+ type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ /*
+ * Corresponds to <simpleType><list>...
+ * Resolve the itemType.
+ */
+ if ((type->subtypes == NULL) && (type->ref != NULL)) {
+ type->subtypes = xmlSchemaGetType(ctxt->schema,
+ type->ref, type->refNs);
+ if ((type->subtypes == NULL) ||
+ (! IS_SIMPLE_TYPE(type->subtypes))) {
+ type->subtypes = NULL;
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, type->node,
+ "itemType", type->ref, type->refNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
+ }
+ }
+ if (type->subtypes == NULL) {
/*
- * Check constraints.
+ * This one is really needed, so get out.
*/
- xmlSchemaCheckSRCSimpleType(ctxt, item);
- xmlSchemaCheckDefaults(item, ctxt, item->name);
- ctxt->ctxtType = ctxtType;
- break;
- case XML_SCHEMA_TYPE_SEQUENCE:
- case XML_SCHEMA_TYPE_ALL:
- case XML_SCHEMA_TYPE_CHOICE:
- item->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- break;
- case XML_SCHEMA_TYPE_GROUP:
+ return;
+ }
+ if (IS_NOT_TYPEFIXED(type->subtypes))
+ xmlSchemaTypeFixup(type->subtypes, ctxt, NULL);
+ /* Base type:
+ * 2 If the <list> or <union> alternative is chosen,
+ * then the ·simple ur-type definition·.
+ */
+ type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ /*
+ * Corresponds to <simpleType><union>...
+ * Resolve the member types.
+ */
+ xmlSchemaResolveUnionMemberTypes(ctxt, type);
+ if (type->memberTypes == NULL) {
/*
- * TODO: Handling was moved to xmlSchemaGroupDefFixup.
+ * This one is really needed, so get out.
*/
- break;
- case XML_SCHEMA_TYPE_LIST:
- xmlSchemaParseListRefFixup(item, ctxt);
- item->contentType = XML_SCHEMA_CONTENT_SIMPLE;
- break;
- case XML_SCHEMA_TYPE_UNION:
- xmlSchemaParseUnionRefCheck(item, ctxt);
- item->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_UR:
- case XML_SCHEMA_TYPE_ELEMENT:
- case XML_SCHEMA_TYPE_ATTRIBUTE:
- case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
- case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
- case XML_SCHEMA_TYPE_NOTATION:
- case XML_SCHEMA_FACET_MININCLUSIVE:
- case XML_SCHEMA_FACET_MINEXCLUSIVE:
- case XML_SCHEMA_FACET_MAXINCLUSIVE:
- case XML_SCHEMA_FACET_MAXEXCLUSIVE:
- case XML_SCHEMA_FACET_TOTALDIGITS:
- case XML_SCHEMA_FACET_FRACTIONDIGITS:
- case XML_SCHEMA_FACET_PATTERN:
- case XML_SCHEMA_FACET_ENUMERATION:
- case XML_SCHEMA_FACET_WHITESPACE:
- case XML_SCHEMA_FACET_LENGTH:
- case XML_SCHEMA_FACET_MAXLENGTH:
- case XML_SCHEMA_FACET_MINLENGTH:
- item->contentType = XML_SCHEMA_CONTENT_SIMPLE;
- if (item->subtypes != NULL)
- xmlSchemaTypeFixup(item->subtypes, ctxt, NULL);
- break;
- case XML_SCHEMA_TYPE_IDC_UNIQUE:
- case XML_SCHEMA_TYPE_IDC_KEY:
- case XML_SCHEMA_TYPE_IDC_KEYREF:
- break;
- }
+ return;
+ }
+ type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ } else {
+ xmlSchemaTypePtr baseType;
+ /*
+ * Corresponds to <simpleType><restriction>...
+ *
+ * Resolve the base type.
+ */
+ if ((type->baseType == NULL) && (type->base != NULL)) {
+ baseType = xmlSchemaGetType(ctxt->schema,
+ type->base, type->baseNs);
+
+ if (baseType == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, type, type->node,
+ "base", type->base, type->baseNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
+ }
+ type->baseType = baseType;
+ } else
+ baseType = type->baseType;
+
+ if (baseType == NULL)
+ return;
+
+ if (IS_NOT_TYPEFIXED(baseType))
+ xmlSchemaTypeFixup(baseType, ctxt, NULL);
+ /*
+ * Variety
+ * If the <restriction> alternative is chosen, then the
+ * {variety} of the {base type definition}.
+ */
+ if (baseType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
+ type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
+ else if (baseType->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+ /*
+ * Inherit the itemType.
+ */
+ type->subtypes = baseType->subtypes;
+ } else if (baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+ /*
+ * NOTE that we won't assign the memberTypes of the base,
+ * since this will make trouble when freeing them; we will
+ * use a lookup function to access them instead.
+ */
+ }
+
+ /*
+ * Some optimization for validation:
+ * If there are no facets beside the "whitespace" facet,
+ * then a value needs not to checked against against a
+ * facet, thus no computed value is needed.
+ */
+#if 0
+ if (baseType->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)
+ type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
+ else {
+ for (cur = type->facetSet; cur != NULL;
+ cur = cur->next) {
+ if (cur->facet->type != XML_SCHEMA_FACET_WHITESPACE) {
+ type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ /*
+ * Check constraints.
+ *
+ * TODO: Split this somehow, we need to know first if we can derive
+ * from the base type at all!
+ */
+ if (type->baseType != NULL) {
+ /*
+ * Schema Component Constraint: Simple Type Restriction
+ * (Facets)
+ * NOTE: Satisfaction of 1 and 2 arise from the fixup
+ * applied beforehand.
+ */
+ xmlSchemaCheckSRCSimpleType(ctxt, type);
+ xmlSchemaCheckFacetValues(type, ctxt);
+ xmlSchemaDeriveAndValidateFacets(ctxt, type);
+ }
}
+
#ifdef DEBUG_TYPE
- if (item->node != NULL) {
+ if (type->node != NULL) {
xmlGenericError(xmlGenericErrorContext,
"Type of %s : %s:%d :", name,
- item->node->doc->URL,
- xmlGetLineNo(item->node));
+ type->node->doc->URL,
+ xmlGetLineNo(type->node));
} else {
xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
}
- switch (item->contentType) {
- case XML_SCHEMA_CONTENT_SIMPLE:
- xmlGenericError(xmlGenericErrorContext, "simple\n");
- break;
- case XML_SCHEMA_CONTENT_ELEMENTS:
- xmlGenericError(xmlGenericErrorContext, "elements\n");
- break;
- case XML_SCHEMA_CONTENT_UNKNOWN:
- xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
- break;
- case XML_SCHEMA_CONTENT_EMPTY:
- xmlGenericError(xmlGenericErrorContext, "empty\n");
- break;
- 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;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "not registered !!!\n");
- break;
+ if ((IS_SIMPLE_TYPE(type)) || (IS_COMPLEX_TYPE(type))) {
+ switch (type->contentType) {
+ case XML_SCHEMA_CONTENT_SIMPLE:
+ xmlGenericError(xmlGenericErrorContext, "simple\n");
+ break;
+ case XML_SCHEMA_CONTENT_ELEMENTS:
+ xmlGenericError(xmlGenericErrorContext, "elements\n");
+ break;
+ case XML_SCHEMA_CONTENT_UNKNOWN:
+ xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
+ break;
+ case XML_SCHEMA_CONTENT_EMPTY:
+ xmlGenericError(xmlGenericErrorContext, "empty\n");
+ break;
+ case XML_SCHEMA_CONTENT_MIXED:
+ if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
+ type->subtypes))
+ xmlGenericError(xmlGenericErrorContext,
+ "mixed as emptiable particle\n");
+ else
+ 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;
+ default:
+ xmlGenericError(xmlGenericErrorContext,
+ "not registered !!!\n");
+ break;
+ }
}
#endif
}
@@ -14179,8 +15652,9 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
*/
/*
* This function is intended to deliver a compiled value
- * on the facet. In XML Schemas the type holding a facet,
- * cannot be a built-in type. Thus to ensure that other API
+ * on the facet. In this implementation of XML Schemata the
+ * type holding a facet, won't be a built-in type.
+ * Thus to ensure that other API
* calls (relaxng) do work, if the given type is a built-in
* type, we will assume that the given built-in type *is
* already* the base type.
@@ -14231,21 +15705,23 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
* of the facet.
*/
ret = xmlSchemaValidateSimpleTypeValue(vctxt, base,
- facet->value, 0, 1, 1, 0);
- facet->val = vctxt->value;
- vctxt->value = NULL;
+ facet->value, 0, 1, 1, 0);
if (ret > 0) {
/* error code */
if (ctxt != NULL) {
- xmlSchemaPErrExt(ctxt, facet->node,
- XML_SCHEMAP_INVALID_FACET,
- NULL, NULL, NULL,
- "Type definition '%s': The value '%s' of the "
- "facet '%s' is not valid.\n",
- name, facet->value,
- xmlSchemaFacetTypeToString(facet->type),
- NULL, NULL);
+ xmlChar *str = NULL;
+
+ xmlSchemaPCustomErrExt(ctxt,
+ XML_SCHEMAP_INVALID_FACET_VALUE,
+ NULL, (xmlSchemaTypePtr) facet, facet->node,
+ "The value '%s' of the facet does not validate "
+ "against the base type '%s'",
+ facet->value,
+ xmlSchemaFormatQName(&str,
+ base->targetNamespace, base->name), NULL);
+ FREE_AND_NULL(str)
}
+ /* xmlSchemaFacetTypeToString(facet->type), */
ret = -1;
} else if (ret < 0) {
xmlSchemaPErrExt(ctxt, facet->node,
@@ -14258,7 +15734,30 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
xmlSchemaFacetTypeToString(facet->type),
base->name, NULL, NULL);
ret = -1;
- }
+ } else {
+ if (vctxt->value != NULL) {
+ facet->val = vctxt->value;
+ vctxt->value = NULL;
+ } else {
+ xmlChar *str;
+ /*
+ * Ensure computed values even for type string.
+ * TODO OPTIMIZE MEMORY: The value will be hold twice,
+ * by the facet->value and by the computed value.
+ */
+ str = xmlStrdup(facet->value);
+ if (xmlSchemaPostCreateVal(vctxt, typeDecl,
+ BAD_CAST str, &(facet->val)) == -1) {
+ FREE_AND_NULL(str)
+ xmlSchemaPErr(ctxt, typeDecl->node,
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaCheckFacet, "
+ "post-creating a computed value.\n",
+ NULL, NULL);
+ /* Note that we don't return a failure yet.*/
+ }
+ }
+ }
if (reuseValCtxt == 0)
xmlSchemaFreeValidCtxt(vctxt);
break;
@@ -14288,14 +15787,11 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
if (tmp != 0) {
/* error code */
if (ctxt != NULL) {
- xmlSchemaPErrExt(ctxt, facet->node,
+ xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INVALID_FACET_VALUE,
- NULL, NULL, NULL,
- "Type definition '%s': The value '%s' of the "
- "facet '%s' is not valid.\n",
- name, facet->value,
- xmlSchemaFacetTypeToString(facet->type),
- NULL, NULL);
+ NULL, (xmlSchemaTypePtr) facet, facet->node,
+ "The value '%s' of the facet is not a valid "
+ "nonNegativeInteger", facet->value);
}
ret = -1;
}
@@ -14310,11 +15806,12 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
} else {
if (ctxt != NULL) {
- xmlSchemaPErr(ctxt, facet->node,
- XML_SCHEMAP_INVALID_WHITE_SPACE,
- "Type definition '%s': The value '%s' of the "
- "facet 'whiteSpace' is not valid.\n",
- name, facet->value);
+ /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_INVALID_FACET_VALUE,
+ NULL, (xmlSchemaTypePtr) facet, facet->node,
+ "The value '%s' of the facet is not a valid",
+ facet->value);
}
ret = -1;
}
@@ -14326,18 +15823,17 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
}
/**
- * xmlSchemaCheckDefaults:
+ * xmlSchemaCheckFacetValues:
* @typeDecl: the schema type definition
* @ctxt: the schema parser context
*
* Checks the default values types, especially for facets
*/
static void
-xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
- xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
+xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
+ xmlSchemaParserCtxtPtr ctxt)
{
- if (name == NULL)
- name = typeDecl->name;
+ const xmlChar *name = typeDecl->name;
/*
* NOTE: It is intended to use the facets list, instead
* of facetSet.
@@ -14366,80 +15862,58 @@ xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
/**
* xmlSchemaGetCircModelGrDefRef:
- * @ctxtGr: the searched model group
- * @list: the list of model groups to be processed
+ * @ctxtMGroup: the searched model group
+ * @selfMGroup: the second searched model group
+ * @particle: the first particle
*
* This one is intended to be used by
* xmlSchemaCheckGroupDefCircular only.
*
- * Returns the circular model group definition reference, otherwise NULL.
+ * Returns the particle with the circular model group definition reference,
+ * otherwise NULL.
*/
-static xmlSchemaTypePtr
-xmlSchemaGetCircModelGrDefRef(xmlSchemaTypePtr ctxtGrDef,
- xmlSchemaTypePtr gr)
-{
- xmlSchemaTypePtr circ = NULL;
- int marked;
- /*
- * We will search for an model group reference which
- * references the context model group definition.
- */
- while (gr != NULL) {
- if (((gr->type == XML_SCHEMA_TYPE_GROUP) ||
- (gr->type == XML_SCHEMA_TYPE_ALL) ||
- (gr->type == XML_SCHEMA_TYPE_SEQUENCE) ||
- (gr->type == XML_SCHEMA_TYPE_CHOICE)) &&
- (gr->subtypes != NULL)) {
- marked = 0;
- if ((gr->type == XML_SCHEMA_TYPE_GROUP) &&
- (gr->ref != NULL)) {
- if (gr->subtypes == ctxtGrDef)
- return (gr);
- else if (gr->subtypes->flags &
- XML_SCHEMAS_TYPE_MARKED) {
- gr = gr->next;
- continue;
- } else {
- /*
- * Mark to avoid infinite recursion on
- * circular references not yet examined.
- */
- gr->subtypes->flags |= XML_SCHEMAS_TYPE_MARKED;
- marked = 1;
- }
- if (gr->subtypes->subtypes != NULL)
- circ = xmlSchemaGetCircModelGrDefRef(ctxtGrDef,
- gr->subtypes->subtypes);
- /*
- * Unmark the visited model group definition.
- */
- if (marked)
- gr->subtypes->flags ^= XML_SCHEMAS_TYPE_MARKED;
- if (circ != NULL)
- return (circ);
- } else {
- circ = xmlSchemaGetCircModelGrDefRef(ctxtGrDef,
- (xmlSchemaTypePtr) gr->subtypes);
- if (circ != NULL)
- return (circ);
- }
-
+static xmlSchemaTreeItemPtr
+xmlSchemaGetCircModelGrDefRef(xmlSchemaTreeItemPtr ctxtMGroup,
+ xmlSchemaTreeItemPtr selfMGroup,
+ xmlSchemaTreeItemPtr particle)
+{
+ xmlSchemaTreeItemPtr circ = NULL;
+ xmlSchemaTreeItemPtr term;
+
+ while (particle != NULL) {
+ term = particle->children;
+ if ((term != NULL) &&
+ ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+ (term->type == XML_SCHEMA_TYPE_CHOICE) ||
+ (term->type == XML_SCHEMA_TYPE_ALL))) {
+ if (term == ctxtMGroup)
+ return (particle);
+ /*
+ * Avoid infinite recursion on circular references not yet
+ * examined.
+ */
+ if (term == selfMGroup)
+ return (NULL);
+ circ = xmlSchemaGetCircModelGrDefRef(ctxtMGroup, term,
+ term->children);
+ if (circ != NULL)
+ return (circ);
}
- gr = gr->next;
+ particle = particle->next;
}
return (NULL);
}
/**
* xmlSchemaCheckGroupDefCircular:
- * attrGr: the model group definition
+ * @item: the model group definition
* @ctxt: the parser context
* @name: the name
*
* Checks for circular references to model group definitions.
*/
static void
-xmlSchemaCheckGroupDefCircular(xmlSchemaTypePtr modelGrDef,
+xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
xmlSchemaParserCtxtPtr ctxt,
const xmlChar * name ATTRIBUTE_UNUSED)
{
@@ -14449,32 +15923,36 @@ xmlSchemaCheckGroupDefCircular(xmlSchemaTypePtr modelGrDef,
* of a group there must not be at any depth a particle whose {term}
* is the group itself.
*/
- /*
- * NOTE: "gr->subtypes" holds the referenced group.
- */
- if ((modelGrDef->type != XML_SCHEMA_TYPE_GROUP) ||
- ((modelGrDef->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) ||
- (modelGrDef->subtypes == NULL))
+ if ((item == NULL) ||
+ (item->type != XML_SCHEMA_TYPE_GROUP) ||
+ (item->children == NULL))
return;
- else {
- xmlSchemaTypePtr circ;
+ {
+ xmlSchemaTreeItemPtr circ;
- circ = xmlSchemaGetCircModelGrDefRef(modelGrDef, modelGrDef->subtypes);
+ circ = xmlSchemaGetCircModelGrDefRef(item->children, NULL,
+ item->children->children);
if (circ != NULL) {
+ xmlChar *str = NULL;
/*
- * TODO: Report the referenced attr group as QName.
+ * TODO: The error report is not adequate: this constraint
+ * is defined for model groups but not definitions, but since
+ * there cannot be any circular model groups without a model group
+ * definition (if not using a construction API), we check those
+ * defintions only.
*/
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_MG_PROPS_CORRECT_2,
- NULL, NULL, circ->node,
+ NULL, NULL, GET_NODE(circ),
"Circular reference to the model group definition '%s' "
- "defined", modelGrDef->name);
+ "defined", xmlSchemaFormatQName(&str,
+ item->targetNamespace, item->name));
+ FREE_AND_NULL(str)
/*
* NOTE: We will cut the reference to avoid further
- * confusion of the processor.
- * TODO: SPEC: Does the spec define how to process here?
+ * confusion of the processor. This is a fatal error.
*/
- circ->subtypes = NULL;
+ circ->children = NULL;
}
}
}
@@ -14845,6 +16323,50 @@ xmlSchemaCheckElemValConstr(xmlSchemaElementPtr decl,
}
}
+
+/**
+ * xmlSchemaMiscRefFixup:
+ * @item: an schema component
+ * @ctxt: a schema parser context
+ * @name: the internal name of the component
+ *
+ * Resolves references of misc. schema components.
+ */
+static void
+xmlSchemaMiscRefFixup(xmlSchemaTreeItemPtr item,
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ if (item->type == XML_SCHEMA_TYPE_PARTICLE) {
+ if ((item->children != NULL) &&
+ (item->children->type == XML_SCHEMA_EXTRA_QNAMEREF)) {
+ xmlSchemaQNameRefPtr ref = (xmlSchemaQNameRefPtr) item->children;
+ xmlSchemaTreeItemPtr refItem;
+ /*
+ * Resolve the reference.
+ */
+ item->children = NULL;
+ refItem = xmlSchemaGetNamedComponent(ctxt->schema,
+ ref->itemType, ref->name, ref->targetNamespace);
+ if (refItem == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
+ NULL, NULL, GET_NODE(item), "ref", ref->name,
+ ref->targetNamespace, ref->itemType, NULL);
+ } else {
+ if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
+ /*
+ * Assign the model group of the model group definition
+ * to the particle's "term".
+ */
+ item->children = refItem->children;
+ } else
+ item->children = refItem;
+ }
+ }
+ }
+}
+
+
/**
* xmlSchemaAttrFixup:
* @item: an schema attribute declaration/use.
@@ -15080,6 +16602,21 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
ctxt->schema = ret;
ctxt->ctxtType = NULL;
ctxt->parentItem = NULL;
+
+
+ if (ret->volatiles != NULL) {
+ xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) ret->volatiles;
+ int i;
+ xmlSchemaTreeItemPtr item;
+
+ for (i = 0; i < list->nbItems; i++) {
+ item = (xmlSchemaTreeItemPtr) list->items[i];
+ if (item->type == XML_SCHEMA_TYPE_PARTICLE)
+ xmlSchemaMiscRefFixup(item, ctxt, NULL);
+ /* xmlHashScan(ret->miscComps,
+ (xmlHashScanner) xmlSchemaMiscRefFixup, ctxt); */
+ }
+ }
/*
* Then fixup all attributes declarations
*/
@@ -15095,23 +16632,28 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
* Resolve identity-constraint keyRefs.
*/
xmlHashScan(ret->idcDef, (xmlHashScanner) xmlSchemaResolveIDCKeyRef, ctxt);
+ /*
+ * Check type defnitions for circular references.
+ */
+ xmlHashScan(ret->typeDecl, (xmlHashScanner)
+ xmlSchemaCheckTypeDefCircular, ctxt);
+ /*
+ * Check model groups defnitions for circular references.
+ */
+ xmlHashScan(ret->groupDecl, (xmlHashScanner)
+ xmlSchemaCheckGroupDefCircular, ctxt);
/*
* Check attribute groups for circular references.
*/
xmlHashScan(ret->attrgrpDecl, (xmlHashScanner)
xmlSchemaCheckAttributeGroupCircular, ctxt);
-
- /*
- * Then fixup all model group definitions.
- */
- xmlHashScan(ret->groupDecl, (xmlHashScanner) xmlSchemaGroupDefFixup, ctxt);
/*
* Then fix references of element declaration; apply constraints.
*/
xmlHashScanFull(ret->elemDecl,
- (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
+ (xmlHashScannerFull) xmlSchemaElementFixup, ctxt);
/*
* We will stop here if the schema was not valid to avoid internal errors
@@ -15126,23 +16668,13 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
* Then fixup all types properties
*/
xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
- /*
- * Check model groups defnitions for circular references.
- */
- xmlHashScan(ret->groupDecl, (xmlHashScanner)
- xmlSchemaCheckGroupDefCircular, ctxt);
/*
* Then build the content model for all complex types
*/
xmlHashScan(ret->typeDecl,
(xmlHashScanner) xmlSchemaBuildContentModel, ctxt);
-
- /*
- * Then check the defaults part of the type like facets values
- */
- /* OLD: xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults, ctxt); */
-
+
/*
* Validate the value constraint of attribute declarations/uses.
*/
@@ -15301,18 +16833,20 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
* by ·restriction· from it) the value of whiteSpace is fixed to
* collapse
*/
- if ((anc->type == XML_SCHEMA_TYPE_BASIC) &&
- (anc->builtInType == XML_SCHEMAS_STRING)) {
+ if ((anc->builtInType == XML_SCHEMAS_STRING) ||
+ (anc->builtInType == XML_SCHEMAS_NORMSTRING)) {
lin = type->facetSet;
do {
if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
return(lin->facet->whitespace);
- break;
}
lin = lin->next;
- } while (lin != NULL);
- break;
+ } while (lin != NULL);
+ if (anc->builtInType == XML_SCHEMAS_NORMSTRING)
+ return (XML_SCHEMAS_FACET_REPLACE);
+ else
+ return (XML_SCHEMAS_FACET_PRESERVE);
}
anc = anc->baseType;
} while (anc != anyST);
@@ -15345,12 +16879,15 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
{
int ret = 0;
xmlNodePtr node;
- xmlSchemaTypePtr biType; /* The build-in type. */
+ xmlSchemaTypePtr biType; /* The build-in type. */
xmlSchemaTypePtr tmpType;
xmlSchemaFacetLinkPtr facetLink;
int retFacet;
xmlSchemaFacetPtr facet;
unsigned long len = 0;
+ xmlSchemaWhitespaceValueType ws;
+
+ ws = (xmlSchemaWhitespaceValueType) xmlSchemaGetWhiteSpaceFacetValue(type);
#ifdef DEBUG_UNION_VALIDATION
printf("Facets of type: '%s'\n", (const char *) type->name);
@@ -15393,15 +16930,20 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
case XML_SCHEMA_FACET_MAXLENGTH:
if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
ret = xmlSchemaValidateListSimpleTypeFacet(facet,
- value, length, 0);
+ value, length, NULL);
len = length;
} else
- ret = xmlSchemaValidateLengthFacet(biType, facet,
- value, ctxt->value, &len);
+ ret = xmlSchemaValidateLengthFacetWhtsp(facet,
+ (xmlSchemaValType) biType->builtInType,
+ value, ctxt->value, &len, ws);
break;
default:
- ret = xmlSchemaValidateFacet(biType, facet, value,
- ctxt->value);
+ ret = xmlSchemaValidateFacetWhtsp(facet, ws,
+ biType->builtInType, value, ctxt->value, ws);
+ /*
+ * ret = xmlSchemaValidateFacet(biType, facet, value,
+ * ctxt->value);
+ */
}
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@@ -15416,35 +16958,58 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
facetLink = facetLink->next;
}
- if (ret >= 0) {
+
+ }
+
+ if (ret >= 0) {
+ xmlSchemaWhitespaceValueType fws;
+ int found = 0;
+ /*
+ * Process enumerations. Facet values are in the value space
+ * of the defining type's base type. This seems to be a bug in the
+ * XML Schema 1.0 spec. Use the whitespace type of the base type.
+ * Only the first set of enumerations in the ancestor-or-self axis
+ * is used for validation.
+ */
+ tmpType = type;
+ do {
/*
- * Process enumerations.
+ * Use the whitespace type of the base type.
*/
+ fws = (xmlSchemaWhitespaceValueType)
+ xmlSchemaGetWhiteSpaceFacetValue(tmpType->baseType);
retFacet = 0;
- facetLink = type->facetSet;
- while (facetLink != NULL) {
- if (facetLink->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
- retFacet = xmlSchemaValidateFacet(biType, facetLink->facet,
- value, ctxt->value);
- if (retFacet <= 0)
- break;
+ for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
+ if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
+ continue;
+ found = 1;
+ retFacet = xmlSchemaValidateFacetWhtsp(facet, fws,
+ biType->builtInType, value, ctxt->value, ws);
+ if (retFacet == 0)
+ break;
+ else if (retFacet < 0) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
+ "Internal error: xmlSchemaValidateFacetsInternal, "
+ "validating enumeration facet '%s' of type '%s'.\n",
+ facet->value, tmpType->name);
+ ret = -1;
+ break;
}
- facetLink = facetLink->next;
}
- if (retFacet > 0) {
- ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
- if (fireErrors)
- xmlSchemaVFacetErr(ctxt, ret, node,
- value, 0, type, NULL, NULL, NULL, NULL, NULL);
- } else if (retFacet < 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
- "Internal error: xmlSchemaValidateFacetsInternal, "
- "validating facet of type '%s'.\n",
- BAD_CAST "enumeration", NULL);
- ret = -1;
- }
- }
+ if (retFacet <= 0)
+ break;
+ tmpType = tmpType->baseType;
+ } while ((! found) && (tmpType != NULL) &&
+ (tmpType->type != XML_SCHEMA_TYPE_BASIC));
+ if (retFacet > 0) {
+ ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
+ if (fireErrors) {
+ xmlSchemaVFacetErr(ctxt, ret, node, value, 0, type, NULL,
+ NULL, NULL, NULL, NULL);
+ }
+ }
}
+
if (ret >= 0) {
/*
* Process patters. Pattern facets are ORed at type level
@@ -15474,7 +17039,7 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
facet = facetLink->facet;
}
if (retFacet != 0)
- break;
+ break;
tmpType = tmpType->baseType;
} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
if (retFacet > 0) {
@@ -15513,7 +17078,6 @@ static int xmlSchemaValidateElementByType(xmlSchemaValidCtxtPtr ctxt,
static void xmlSchemaBeginElement(xmlSchemaValidCtxtPtr vctxt);
static int xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt);
-#ifdef ELEM_INFO_ENABLED
/**
* xmlSchemaGetFreshElemInfo:
* @vctxt: the schema validation context
@@ -15582,8 +17146,6 @@ xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt,
return (info);
}
-#endif /* ELEM_INFO_ENABLED */
-
/**
* xmlSchemaFreeAttrStates:
@@ -15695,15 +17257,15 @@ xmlSchemaPostSchemaAssembleFixup(xmlSchemaParserCtxtPtr ctxt)
xmlSchemaAttrFixup((xmlSchemaAttributePtr) item, ctxt, NULL);
break;
case XML_SCHEMA_TYPE_ELEMENT:
- xmlSchemaRefFixupCallback((xmlSchemaElementPtr) item, ctxt,
+ xmlSchemaElementFixup((xmlSchemaElementPtr) item, ctxt,
NULL, NULL, NULL);
break;
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
xmlSchemaAttrGrpFixup((xmlSchemaAttributeGroupPtr) item,
ctxt, NULL);
break;
- case XML_SCHEMA_TYPE_GROUP:
- xmlSchemaGroupDefFixup(item, ctxt, NULL);
+ case XML_SCHEMA_TYPE_PARTICLE:
+ xmlSchemaMiscRefFixup((xmlSchemaTreeItemPtr) item, ctxt, NULL);
default:
break;
}
@@ -15713,9 +17275,15 @@ xmlSchemaPostSchemaAssembleFixup(xmlSchemaParserCtxtPtr ctxt)
*/
for (i = 0; i < nbItems; i++) {
item = items[i];
- switch (item->type) {
+ switch (item->type) {
+ case XML_SCHEMA_TYPE_COMPLEX:
+ case XML_SCHEMA_TYPE_SIMPLE:
+ xmlSchemaCheckTypeDefCircular(
+ (xmlSchemaTypePtr) item, ctxt, NULL);
+ break;
case XML_SCHEMA_TYPE_GROUP:
- xmlSchemaCheckGroupDefCircular(item, ctxt, NULL);
+ xmlSchemaCheckGroupDefCircular(
+ (xmlSchemaModelGroupDefPtr) item, ctxt, NULL);
break;
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
xmlSchemaCheckAttributeGroupCircular(
@@ -15726,9 +17294,7 @@ xmlSchemaPostSchemaAssembleFixup(xmlSchemaParserCtxtPtr ctxt)
}
}
/*
- * Fixup for all other item.
- * TODO: Hmm, not sure if starting from complex/simple types,
- * all subsequent items will be reached.
+ * Fixup for simple/complex types.
*/
for (i = 0; i < nbItems; i++) {
item = items[i];
@@ -15742,24 +17308,6 @@ xmlSchemaPostSchemaAssembleFixup(xmlSchemaParserCtxtPtr ctxt)
}
}
/*
- * Check facet values. Note that facets are
- * hold by simple type components only (and
- * by complex types in the current implementation).
- */
- /* OLD:
- for (i = 0; i < nbItems; i++) {
- item = items[i];
- switch (item->type) {
- case XML_SCHEMA_TYPE_SIMPLE:
- case XML_SCHEMA_TYPE_COMPLEX:
- xmlSchemaCheckDefaults(item, ctxt, NULL);
- break;
- default:
- break;
- }
- }
- */
- /*
* Build the content model for complex types.
*/
for (i = 0; i < nbItems; i++) {
@@ -15779,10 +17327,12 @@ xmlSchemaPostSchemaAssembleFixup(xmlSchemaParserCtxtPtr ctxt)
item = items[i];
switch (item->type) {
case XML_SCHEMA_TYPE_ATTRIBUTE:
- xmlSchemaCheckAttrValConstr((xmlSchemaAttributePtr) item, ctxt, NULL);
+ xmlSchemaCheckAttrValConstr((xmlSchemaAttributePtr) item,
+ ctxt, NULL);
break;
case XML_SCHEMA_TYPE_ELEMENT:
- xmlSchemaCheckElemValConstr((xmlSchemaElementPtr) item, ctxt, NULL);
+ xmlSchemaCheckElemValConstr((xmlSchemaElementPtr) item,
+ ctxt, NULL);
break;
default:
break;
@@ -16036,26 +17586,17 @@ xmlSchemaAssembleByXSIElem(xmlSchemaValidCtxtPtr vctxt,
static void
xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt,
const xmlChar * name ATTRIBUTE_UNUSED,
- xmlSchemaTypePtr type, xmlNodePtr node)
+ xmlSchemaBasicItemPtr item, xmlNodePtr node)
{
- xmlSchemaTypePtr oldtype = ctxt->type;
xmlNodePtr oldnode = ctxt->node;
-#ifdef DEBUG_CONTENT
- xmlGenericError(xmlGenericErrorContext,
- "xmlSchemaValidateCallback: %s, %s, %s\n",
- name, type->name, node->name);
-#endif
/*
* @type->type will be XML_SCHEMA_TYPE_ANY or XML_SCHEMA_TYPE_ELEMENT.
*/
- ctxt->type = type;
ctxt->node = node;
ctxt->cur = node->children;
-#ifdef ELEM_INFO_ENABLED
xmlSchemaBeginElement(ctxt);
-#endif
/*
* Assemble new schemata using xsi.
@@ -16077,43 +17618,32 @@ xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt,
* TODO: But a warning would be nice.
*/
}
- switch (type->type) {
+ switch (item->type) {
case XML_SCHEMA_TYPE_ELEMENT: {
- /*
- * NOTE: The build of the content model
- * (xmlSchemaBuildAContentModel) ensures that the element
- * declaration (and not a reference to it) will be given.
- */
- if (((xmlSchemaElementPtr) ctxt->type)->ref != NULL) {
- /*
- * This is paranoid coding ;-)... it should not
- * happen here any more.
- */
- xmlSchemaVCustomErr(ctxt,
- XML_SCHEMAV_INTERNAL,
- node, NULL,
- "Internal error: xmlSchemaValidateCallback, "
- "element declaration 'reference' encountered, "
- "but an element declaration was expected",
- NULL);
- goto leave;
- }
+#ifdef DEBUG_CONTENT
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlSchemaValidateCallback: %s, %s, %s\n",
+ name, ((xmlSchemaElementPtr) item)->name, node->name);
+#endif
xmlSchemaValidateElementByDeclaration(ctxt,
- (xmlSchemaElementPtr) type);
+ (xmlSchemaElementPtr) item);
break;
}
case XML_SCHEMA_TYPE_ANY:
- xmlSchemaValidateElementByWildcard(ctxt, type);
+#ifdef DEBUG_CONTENT
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlSchemaValidateCallback: %s, <any>, %s\n",
+ name, node->name);
+#endif
+ xmlSchemaValidateElementByWildcard(ctxt,
+ (xmlSchemaWildcardPtr) item);
break;
default:
break;
}
leave:
-#ifdef ELEM_INFO_ENABLED
xmlSchemaEndElement(ctxt);
-#endif
- ctxt->type = oldtype;
ctxt->node = oldnode;
}
@@ -16179,6 +17709,34 @@ xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
return (ret);
}
+static xmlSchemaTypePtr
+xmlSchemaGetSimpleContentType(xmlSchemaTypePtr complexType)
+{
+ xmlSchemaTypePtr ret;
+
+ if (complexType->type != XML_SCHEMA_TYPE_COMPLEX)
+ return (NULL);
+ if (complexType->contentTypeDef != NULL)
+ return (complexType->contentTypeDef);
+ /*
+ * TODO: This is only a workaround until the simple content
+ * type is computed for complex types with simple content.
+ */
+ ret = complexType->baseType;
+ while (ret != NULL) {
+ if (IS_SIMPLE_TYPE(ret))
+ return (ret);
+ if (ret->builtInType == XML_SCHEMAS_ANYTYPE)
+ return (NULL);
+ if ((ret->type == XML_SCHEMA_TYPE_COMPLEX) &&
+ (ret->contentTypeDef != NULL))
+ ret = ret->contentTypeDef;
+ else
+ ret = ret->baseType;
+ }
+ return (ret);
+}
+
/**
* xmlSchemaValidateSimpleTypeValue:
* @ctxt: a schema validation context
@@ -16289,18 +17847,20 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
}
if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
- xmlSchemaTypePtr base, anyType;
+ xmlSchemaTypePtr simpType, anyType;
anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
- base = type->baseType;
- while ((base != NULL) &&
- (base->type != XML_SCHEMA_TYPE_SIMPLE) &&
- (base->type != XML_SCHEMA_TYPE_BASIC) &&
- (base != anyType)) {
- base = base->baseType;
+ simpType = xmlSchemaGetSimpleContentType(type);
+ if (simpType == NULL) {
+ xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
+ "Internal error: xmlSchemaValidateSimpleTypeValue, "
+ "failed to obtain the simple content type of the complex "
+ "type '%s'\n",
+ type->name, NULL);
+ return (-1);
}
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, base, value, 1, 0, 1, 0);
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt, simpType, value, 1, 0, 1, 0);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
@@ -16309,15 +17869,14 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
} else if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) {
/*
* Check facets.
- */
- /*
- * This is somehow not nice, since if an error occurs
+ *
+ * TODO: This is somehow not nice, since if an error occurs
* the reported type will be the complex type; the spec
* wants a simple type to be created on the complex type
* if it has a simple content. For now we have to live with
* it.
- */
- ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ */
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@@ -16363,7 +17922,6 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
(type->builtInType == XML_SCHEMAS_STRING) &&
(ctxt->nodeInfo != NULL) &&
(ctxt->nodeInfo->flags & XML_SCHEMA_ELEM_INFO_VALUE_NEEDED)) {
-#ifdef IDC_VALUE_SUPPORT
xmlChar *valdup;
/*
* Create a precomputed string value for "string" as well if
@@ -16374,7 +17932,6 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
BAD_CAST valdup);
if ((valdup != NULL) && (ctxt->value == NULL))
xmlFree(valdup);
-#endif
}
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) {
/* 1.2.1 if {variety} is ·atomic· then the string must ·match·
@@ -16393,8 +17950,8 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
} else if ((applyFacets) && (type->facetSet != NULL)) {
/*
* Check facets.
- */
- ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ */
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@@ -16461,7 +18018,7 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
"validating list simple type '%s'\n",
type->name, NULL);
} else if ((ret == 0) && (applyFacets)) {
- ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, len, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@@ -16555,7 +18112,7 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
value = (const xmlChar *) normValue;
}
- ret = xmlSchemaValidateFacetsInternal(ctxt, type,
+ ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@@ -16810,8 +18367,6 @@ xmlSchemaHasElemOrCharContent(xmlNodePtr node)
* *
************************************************************************/
-#ifdef IDC_ENABLED
-
/**
* xmlSchemaAugmentIDC:
* @idcDef: the IDC definition
@@ -17192,7 +18747,6 @@ xmlSchemaAreValuesEqual(xmlSchemaValidCtxtPtr vctxt,
}
compareValue:
{
-#ifdef IDC_VALUE_SUPPORT
int ret;
int aws, bws;
@@ -17213,9 +18767,6 @@ compareValue:
return(-1);
} else
return(0);
-#else
- return (1);
-#endif
}
}
@@ -17345,8 +18896,6 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
sto->matcher->aidc->def->name, sto->sel->xpath);
#endif
-
-#ifdef IDC_XPATH_SUPPORT
if (nodeType == XML_ELEMENT_NODE)
res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
vctxt->nodeInfo->localName, vctxt->nodeInfo->namespaceName);
@@ -17354,9 +18903,6 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
vctxt->nodeInfo->localName, vctxt->nodeInfo->namespaceName);
-#else
- res = 0;
-#endif
if (res == -1) {
xmlSchemaVErr(vctxt, vctxt->node,
XML_SCHEMAV_INTERNAL,
@@ -17486,12 +19032,10 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
* Evaluate the state objects.
*/
while (sto != NULL) {
-#ifdef IDC_XPATH_SUPPORT
xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
- #if DEBUG_IDC
- xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
- sto->sel->xpath);
- #endif
+#if DEBUG_IDC
+ xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
+ sto->sel->xpath);
#endif
if (sto->nbHistory == 0)
goto deregister_check;
@@ -18036,7 +19580,7 @@ xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
xmlSchemaPSVIIDCNodePtr node, parNode = NULL; /* node-table entries. */
xmlSchemaPSVIIDCKeyPtr key, parKey; /* keys of in a key-sequence. */
xmlSchemaIDCAugPtr aidc;
- int i, j, k, ret = 0, oldNum, newDupls = 0;
+ int i, j, k, ret = 0, oldNum, newDupls;
int duplTop;
/*
@@ -18078,7 +19622,8 @@ start_binding:
aidc = vctxt->aidcs;
do {
if (aidc->def == bind->definition) {
- if (aidc->bubbleDepth >= vctxt->depth) {
+ if ((aidc->bubbleDepth == -1) ||
+ (aidc->bubbleDepth >= vctxt->depth)) {
bind = bind->next;
goto start_binding;
}
@@ -18102,6 +19647,7 @@ start_binding:
*/
oldNum = parBind->nbNodes; /* Skip newly added items. */
duplTop = oldNum + parBind->nbDupls;
+ newDupls = 0;
for (i = 0; i < bind->nbNodes; i++) {
node = bind->nodeTable[i];
@@ -18200,7 +19746,7 @@ start_binding:
*/
if (parBind->nodeTable == NULL) {
parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
- xmlMalloc(1 * sizeof(xmlSchemaPSVIIDCNodePtr));
+ xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
if (parBind->nodeTable == NULL) {
xmlSchemaVErrMemory(NULL,
"allocating IDC list of node-table items", NULL);
@@ -18208,7 +19754,7 @@ start_binding:
}
parBind->sizeNodes = 1;
} else if (duplTop >= parBind->sizeNodes) {
- parBind->sizeNodes++;
+ parBind->sizeNodes *= 2;
parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
sizeof(xmlSchemaPSVIIDCNodePtr));
@@ -18251,7 +19797,7 @@ start_binding:
lastParBind = parBind;
parBind = parBind->next;
}
- if (parBind == NULL) {
+ if ((parBind == NULL) && (bind->nbNodes != 0)) {
/*
* No binding for the IDC was found: create a new one and
* copy all node-tables.
@@ -18358,9 +19904,7 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
}
return (0);
}
-#endif /* IDC_ENABLED */
-#ifdef ELEM_INFO_ENABLED
/**
* xmlSchemaBeginElement:
* @vctxt: the WXS validation context
@@ -18396,7 +19940,6 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
vctxt->depth--;
return (0);
}
-#ifdef IDC_ENABLED
/*
* Evaluate the history of changes of active state objects.
*/
@@ -18416,13 +19959,11 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
* Validate IDC keyrefs.
*/
xmlSchemaCheckCVCIDCKeyRef(vctxt);
-#endif
/*
* Merge/free the IDC table.
*/
if (vctxt->nodeInfo->idcTable != NULL) {
-#ifdef IDC_ENABLED
#ifdef DEBUG_IDC
xmlSchemaDebugDumpIDCTable(stdout,
vctxt->nodeInfo->namespaceName,
@@ -18440,19 +19981,16 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
* requested for the PSVI.
*/
xmlSchemaIDCFreeIDCTable(vctxt->nodeInfo->idcTable);
-#endif
vctxt->nodeInfo->idcTable = NULL;
}
/*
* Cleanup IDC matchers.
*/
-#ifdef IDC_ENABLED
if (vctxt->nodeInfo->idcMatchers != NULL) {
xmlSchemaIDCFreeMatcherList(vctxt->nodeInfo->idcMatchers);
vctxt->nodeInfo->idcMatchers = NULL;
}
-#endif
/*
* Skip further processing if we are on the validation root.
@@ -18465,7 +20003,6 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
/*
* Reset the bubbleDepth if needed.
*/
-#ifdef IDC_ENABLED
if (vctxt->aidcs != NULL) {
xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
do {
@@ -18480,7 +20017,6 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
aidc = aidc->next;
} while (aidc != NULL);
}
-#endif
vctxt->depth--;
/*
* Clear the current elemInfo.
@@ -18495,8 +20031,6 @@ xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
return (0);
}
-#endif /* ELEM_INFO_ENABLED */
-
/**
* xmlSchemaValidateElementByDeclaration:
* @ctxt: a schema validation context
@@ -18547,10 +20081,8 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
/*
* Evaluate IDCs even if an error occured.
*/
-#ifdef IDC_ENABLED
if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
return (-1);
-#endif
return (ctxt->err);
}
/*
@@ -18564,10 +20096,8 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
/*
* Evaluate IDCs even if an error occured.
*/
-#ifdef IDC_ENABLED
if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
return (-1);
-#endif
return (ctxt->err);
}
@@ -18723,19 +20253,15 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
/*
* Evaluate IDCs even if an error occured.
*/
-#ifdef IDC_ENABLED
if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
return (-1);
-#endif
return (XML_SCHEMAV_CVC_TYPE_1);
}
/*
* Remember the actual-type definition.
*/
-#ifdef ELEM_INFO_ENABLED
ctxt->nodeInfo->typeDef = actualType;
-#endif
/*
* TODO: Since this should be already checked by the content model automaton,
@@ -18771,7 +20297,6 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
/*
* IDC: Register identity-constraint XPath matchers.
*/
-#ifdef IDC_ENABLED
if (elemDecl->idcs != NULL)
xmlSchemaIDCRegisterMatchers(ctxt, elemDecl);
/*
@@ -18779,7 +20304,6 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
*/
if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
return (-1);
-#endif
/*
* cvc-elt (3.3.4) : 5
* The appropriate case among the following must be true:
@@ -18871,12 +20395,10 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
* Consume the computed value for IDCs, ect. Note that default
* values are not supported yet.
*/
-#ifdef ELEM_INFO_ENABLED
if (ctxt->value != NULL) {
ctxt->nodeInfo->value = ctxt->value;
ctxt->value = NULL;
}
-#endif
ctxt->node = elem;
if (ret < 0) {
xmlSchemaVCustomErr(ctxt,
@@ -19046,10 +20568,9 @@ xmlSchemaValidateElementByWildcardInternal(xmlSchemaValidCtxtPtr ctxt,
/*
* Evaluate IDCs even if a validation error occured.
*/
-#ifdef IDC_ENABLED
if (xmlSchemaXPathEvaluate(ctxt,XML_ELEMENT_NODE) == -1)
return(-1);
-#endif
+
return (ctxt->err);
}
/*
@@ -19058,10 +20579,8 @@ xmlSchemaValidateElementByWildcardInternal(xmlSchemaValidCtxtPtr ctxt,
* definitely result in an IDC validation error if an IDC field
* resolves.
*/
-#ifdef IDC_ENABLED
if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
return(-1);
-#endif
}
if (node->children != NULL) {
child = node->children;
@@ -19078,10 +20597,10 @@ xmlSchemaValidateElementByWildcardInternal(xmlSchemaValidCtxtPtr ctxt,
"The namespace of the element is not allowed");
return (ctxt->err);
}
-#ifdef ELEM_INFO_ENABLED
+
ctxt->node = child;
xmlSchemaBeginElement(ctxt);
-#endif
+
/*
* Recurse over the children.
*/
@@ -19089,10 +20608,10 @@ xmlSchemaValidateElementByWildcardInternal(xmlSchemaValidCtxtPtr ctxt,
wild, child);
if (ret == -1)
return (-1);
-#ifdef ELEM_INFO_ENABLED
+
if (xmlSchemaEndElement(ctxt) == -1)
return (-1);
-#endif
+
if (ret != 0)
return (ret);
}
@@ -19111,9 +20630,10 @@ xmlSchemaValidateElementByWildcardInternal(xmlSchemaValidCtxtPtr ctxt,
*/
static int
xmlSchemaValidateElementByWildcard(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type)
+ xmlSchemaWildcardPtr wild)
{
- if ((type == NULL) || (type->type != XML_SCHEMA_TYPE_ANY) ||
+
+ if ((wild == NULL) || (wild->type != XML_SCHEMA_TYPE_ANY) ||
(ctxt->node == NULL)) {
xmlSchemaVCustomErr(ctxt,
XML_SCHEMAV_INTERNAL, ctxt->node, NULL,
@@ -19121,12 +20641,26 @@ xmlSchemaValidateElementByWildcard(xmlSchemaValidCtxtPtr ctxt,
"bad arguments", NULL);
return (-1);
}
+ if (wild->negNsSet != NULL) {
+ /*
+ * Workaround for negated namespaces.
+ */
+ if (ctxt->node->ns != NULL) {
+ if (xmlSchemaMatchesWildcardNs(wild, ctxt->node->ns->href) == 0) {
+ ctxt->flags |= XML_SCHEMA_VALID_INVALID_NEG_WILDCARD;
+ return (XML_SCHEMAV_ELEMENT_CONTENT);
+ }
+ } else if (xmlSchemaMatchesWildcardNs(wild, NULL) == 0) {
+ ctxt->flags |= XML_SCHEMA_VALID_INVALID_NEG_WILDCARD;
+ return (XML_SCHEMAV_ELEMENT_CONTENT);
+ }
+ }
return(xmlSchemaValidateElementByWildcardInternal(ctxt,
- type->attributeWildcard, ctxt->node));
+ wild, ctxt->node));
}
/**
- * xmlSchemaValidateAnyTypeContent:
+ * xmlSchemaValidateElementByAnyType:
* @ctxt: a schema validation context
* @node: the current element
*
@@ -19145,7 +20679,7 @@ xmlSchemaValidateElementByAnyType(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr oldtype;
xmlNodePtr top, cur;
xmlSchemaElementPtr decl;
- int skipContent, ret;
+ int skipContent, ret, insub = 0;
if ((type == NULL) || (ctxt->node == NULL))
return (-1);
@@ -19171,9 +20705,18 @@ xmlSchemaValidateElementByAnyType(xmlSchemaValidCtxtPtr ctxt,
decl = xmlHashLookup3(ctxt->schema->elemDecl,
cur->name, cur->ns->href, NULL);
else
- decl = xmlHashLookup3(ctxt->schema->elemDecl, cur->name, NULL, NULL);
- if (decl != NULL) {
- ctxt->node = cur;
+ decl = xmlHashLookup3(ctxt->schema->elemDecl, cur->name, NULL, NULL);
+ ctxt->node = cur;
+
+ if (insub) {
+ /*
+ * BEGIN element.
+ */
+ xmlSchemaBeginElement(ctxt);
+ } else
+ insub = 1;
+
+ if (decl != NULL) {
ret = xmlSchemaValidateElementByDeclaration(ctxt, decl);
ctxt->node = top;
if (ret < 0) {
@@ -19185,6 +20728,12 @@ xmlSchemaValidateElementByAnyType(xmlSchemaValidCtxtPtr ctxt,
} else if (ret > 0)
return (ret);
skipContent = 1;
+ } else {
+ /*
+ * IDCs.
+ */
+ if (xmlSchemaXPathEvaluate(ctxt,XML_ELEMENT_NODE) == -1)
+ return(-1);
}
}
/*
@@ -19196,10 +20745,16 @@ xmlSchemaValidateElementByAnyType(xmlSchemaValidCtxtPtr ctxt,
} else if ((cur != top) && (cur->next != NULL)) {
/* then siblings */
cur = cur->next;
- } else if (cur != top) {
+ } else if (cur != top) {
/* go up to parents->next if needed */
while (cur != top) {
- if (cur->parent != NULL)
+ if (cur->type == XML_ELEMENT_NODE) {
+ /*
+ * END element.
+ */
+ xmlSchemaEndElement(ctxt);
+ }
+ if (cur->parent != NULL)
cur = cur->parent;
if ((cur != top) && (cur->next != NULL)) {
cur = cur->next;
@@ -19297,41 +20852,57 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
*/
switch (type->contentType) {
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].
+ */
+ /*
+ * TODO: Is the entity stuff correct?
+ */
+ if (xmlSchemaHasElemOrCharContent(elem) == 1) {
+ xmlSchemaVComplexTypeErr(ctxt,
+ XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1,
+ elem, type,
+ "Character or element content is not allowed, "
+ "because the content type is empty");
+ }
+ break;
+ }
+ case XML_SCHEMA_CONTENT_MIXED:
/*
- * 1 If the {content type} is empty, then the element information
- * item has no character or element information item [children].
- */
- /*
- * TODO: Is the entity stuff correct?
+ * Some speedups for anyType or types derived directly from it.
*/
- if (xmlSchemaHasElemOrCharContent(elem) == 1) {
- xmlSchemaVComplexTypeErr(ctxt,
- XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1,
- elem, type,
- "Character or element content is not allowed, "
- "because the content type is empty");
- }
- break;
- }
- case XML_SCHEMA_CONTENT_MIXED:
- if ((type->subtypes == NULL) &&
- (type->baseType->builtInType == XML_SCHEMAS_ANYTYPE)) {
+ if (IS_ANYTYPE(type)) {
+ /*
+ * Corresponds to <element name="foo" [type="xsd:anyType"]/>.
+ */
+ ret = xmlSchemaValidateElementByAnyType(ctxt, type);
+ /* TODO: Handle -1. */
+ break;
+ }
+ if (IS_ANYTYPE(type->baseType) &&
+ (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) &&
+ (type->subtypes == type->baseType->subtypes)) {
/*
- * The type has 'anyType' as its base and no content model
- * is defined -> use 'anyType' as the type to validate
- * against.
+ * Corresponds to an <extension> of anyType.
*/
ret = xmlSchemaValidateElementByAnyType(ctxt, type->baseType);
/* TODO: Handle -1. */
break;
}
/* No break on purpose. */
- case XML_SCHEMA_CONTENT_ELEMENTS:
- {
+ case XML_SCHEMA_CONTENT_ELEMENTS: {
xmlRegExecCtxtPtr oldregexp = NULL;
xmlChar *values[10];
int terminal, nbval = 10, nbneg;
-
+ /*
+ * SPEC (2.4) If the {content type} is element-only or mixed,
+ * then the sequence of the element information item's
+ * element information item [children], if any, taken in
+ * order, is ·valid· with respect to the {content type}'s
+ * particle, as defined in Element Sequence Locally Valid
+ * (Particle) (§3.9.4).
+ */
/*
* Content model check initialization.
*/
@@ -19355,14 +20926,18 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
else
nsUri = NULL;
ret = xmlRegExecPushString2(ctxt->regexp,
- child->name, nsUri, child);
+ child->name, nsUri, child);
if (ctxt->err == XML_SCHEMAV_INTERNAL)
return (-1);
- /*
- * URGENT TODO: Could we anchor an error report
- * here to notify of invalid elements?
- * TODO: Perhaps it would be better to report
- * only the first erroneous element and then break.
+ if (ctxt->flags & XML_SCHEMA_VALID_INVALID_NEG_WILDCARD) {
+ ctxt->flags ^= XML_SCHEMA_VALID_INVALID_NEG_WILDCARD;
+ ret = -1;
+ }
+ /*
+ * URGENT TODO: Could we anchor an error report
+ * here to notify of invalid elements?
+ * TODO: Perhaps it would be better to report
+ * only the first erroneous element and then break.
*/
#ifdef DEBUG_AUTOMATA
if (ret < 0)
@@ -19418,33 +20993,31 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
if (type->contModel != NULL) {
if (ret == 0) {
xmlRegExecNextValues(ctxt->regexp, &nbval, &nbneg,
- &values[0], &terminal);
- if (nbval + nbneg != 0) {
- /*
- * If a next value still exists, I does not have to
- * mean that there's an element missing, since it
- * might be an optional element. So double check it.
- */
- ret = xmlRegExecPushString(ctxt->regexp,
- NULL, NULL);
- if (ret <= 0) {
- ret = 1;
- xmlSchemaVComplexTypeElemErr(ctxt,
- XML_SCHEMAV_ELEMENT_CONTENT,
- elem, type, "Missing child element(s)",
- nbval, nbneg, values);
- } else
- ret = 0;
+ &values[0], &terminal);
+ /*
+ * If a next value still exists, It does not have to
+ * mean that there's an element missing, since it
+ * might be an optional element. So double check it.
+ */
+ ret = xmlRegExecPushString(ctxt->regexp,
+ NULL, NULL);
+ if (ret <= 0) {
+ ret = 1;
+ xmlSchemaVComplexTypeElemErr(ctxt,
+ XML_SCHEMAV_ELEMENT_CONTENT,
+ elem, type, "Missing child element(s)",
+ nbval, nbneg, values);
+ } else
+ ret = 0;
#ifdef DEBUG_AUTOMATA
- xmlGenericError(xmlGenericErrorContext,
- "====> %s : %d\n", elem->name, ret);
+ xmlGenericError(xmlGenericErrorContext,
+ "====> %s : %d\n", elem->name, ret);
#endif
- }
#ifdef DEBUG_CONTENT
if (ret == 0)
xmlGenericError(xmlGenericErrorContext,
- "Element %s content check succeeded\n",
- elem->name);
+ "Element %s content check succeeded\n",
+ elem->name);
#endif
}
xmlRegFreeExecCtxt(ctxt->regexp);
@@ -19495,81 +21068,45 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
}
ctxt->node = elem;
ctxt->cur = elem->children;
- if (ret == 0) {
- /*
- * Validate the character content against a simple type.
- */
- /*
- * STREAM: Children are processed.
- */
- if (elem->children == NULL)
- value = NULL;
- else
- value = xmlNodeGetContent(elem);
- /*
- * URGENT TODO: Should facets for the simple type validation be
- * disabled, if the derivation of facets for complex types
- * is implemented?
- */
+ if (ret != 0) {
+ FREE_AND_NULL(value)
+ break;
+ }
+ /*
+ * Validate the character content against a simple type.
+ */
+ if (elem->children == NULL)
+ value = NULL;
+ else
+ value = xmlNodeGetContent(elem);
/*
* NOTE: This call won't check the correct types of the
* content nodes, since this should be done here.
*/
- ret = xmlSchemaValidateSimpleTypeValue(ctxt, type, value, 1, 1, 1, 0);
- if (ret > 0) {
- /*
- * NOTE: Although an error will be reported by
- * xmlSchemaValidateSimpleTypeValue, the spec wants
- * a specific complex type error to be reported
- * additionally.
- */
- xmlSchemaVComplexTypeErr(ctxt,
- XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
- elem, type,
- "The character content is not valid");
- ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
- } else if (ret < 0) {
- xmlSchemaVErr(ctxt, elem, XML_SCHEMAV_INTERNAL,
- "Internal error: xmlSchemaValidateComplexType, "
- "Element '%s': Error while validating character "
- "content against complex type '%s'.\n",
- elem->name, type->name);
- if (value != NULL)
- xmlFree(value);
- ctxt->type = oldtype;
- return (-1);
- }
- }
- if (ret == 0) {
- /*
- * Apply facets of the complexType. Be sure to pass the
- * built-in type to xmlSchemaValidateFacetsInternal.
- */
- /* URGENT 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.
- */
-
- ret = xmlSchemaValidateFacetsInternal(ctxt,
- type, value, 0, 1);
- if (ret > 0) {
- xmlSchemaVComplexTypeErr(ctxt,
- XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
- elem, type,
- "The character content is not valid");
- ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
- } else if (ret < 0) {
- xmlSchemaVErr(ctxt, elem, XML_SCHEMAV_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);
- ctxt->type = oldtype;
- return (-1);
- }
+ ret = xmlSchemaValidateSimpleTypeValue(ctxt,
+ type->contentTypeDef, value, 1, 1, 1, 0);
+ if (ret > 0) {
+ /*
+ * NOTE: Although an error will be reported by
+ * xmlSchemaValidateSimpleTypeValue, the spec wants
+ * a specific complex type error to be reported
+ * additionally.
+ */
+ xmlSchemaVComplexTypeErr(ctxt,
+ XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2,
+ elem, type,
+ "The character content is not valid");
+ ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
+ } else if (ret < 0) {
+ xmlSchemaVErr(ctxt, elem, XML_SCHEMAV_INTERNAL,
+ "Internal error: xmlSchemaValidateComplexType, "
+ "Element '%s': Error while validating character "
+ "content against complex type '%s'.\n",
+ elem->name, type->name);
+ if (value != NULL)
+ xmlFree(value);
+ ctxt->type = oldtype;
+ return (-1);
}
if (value != NULL)
xmlFree(value);
@@ -19660,13 +21197,14 @@ xmlSchemaValidateElementByType(xmlSchemaValidCtxtPtr ctxt,
static int
xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
+ xmlSchemaTypePtr type,
const xmlChar *value,
xmlSchemaValPtr *val)
{
xmlSchemaTypePtr prim;
if (val == NULL) {
- xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
+ xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"bad arguments", NULL, NULL);
@@ -19675,13 +21213,10 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
/*
* Only string or anySimpleType values are expected to be post-created.
*/
- prim = xmlSchemaGetPrimitiveType(vctxt->nodeInfo->typeDef);
+ prim = xmlSchemaGetPrimitiveType(type);
if ((prim->builtInType == XML_SCHEMAS_STRING) ||
(prim->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
{
-#if 0
- builtIn = xmlSchemaGetBuiltInTypeAncestor(vctxt->nodeInfo->typeDef);
-#endif
if (value == NULL)
/* TODO: Can this happen at all? */
*val = xmlSchemaNewStringValue(XML_SCHEMAS_STRING,
@@ -19689,7 +21224,7 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
else
*val = xmlSchemaNewStringValue(XML_SCHEMAS_STRING, value);
if ((*val) == NULL) {
- xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
+ xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"failed to create the value", NULL, NULL);
@@ -19697,7 +21232,7 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
}
return (0);
}
- xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
+ xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"the given type is not supported", NULL, NULL);
@@ -19771,7 +21306,8 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr vctxt,
/*
* Post-create the value.
*/
- if (xmlSchemaPostCreateVal(vctxt, value, &(vctxt->value)) == -1) {
+ if (xmlSchemaPostCreateVal(vctxt, vctxt->attrInfo->typeDef,
+ value, &(vctxt->value)) == -1) {
ret = -1;
goto exit;
}
@@ -19787,7 +21323,8 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr vctxt,
str = xmlStrdup(BAD_CAST "");
else
str = xmlStrdup(defValue);
- if (xmlSchemaPostCreateVal(vctxt, str, &defVal) == -1) {
+ if (xmlSchemaPostCreateVal(vctxt, vctxt->attrInfo->typeDef,
+ str, &defVal) == -1) {
ret = -1;
FREE_AND_NULL(str)
goto exit;
@@ -19979,15 +21516,12 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
tmp->decl = attrDecl;
tmp->value = defValue;
tmp->next = NULL;
-
- if (defAttrStates == NULL) {
- defAttrStates = tmp;
+ if (defAttrStatesTop == NULL)
defAttrStates = tmp;
- } else {
- defAttrStates->next = tmp;
- defAttrStatesTop = tmp;
- }
- }
+ else
+ defAttrStatesTop->next = tmp;
+ defAttrStatesTop = tmp;
+ }
}
attrUse = attrUse->next;
}
@@ -20128,8 +21662,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
ctxt->attrInfo->localName = curState->attr->name;
ctxt->nodeInfo = ctxt->attrInfo;
-
-#ifdef IDC_ENABLED
/*
* Evaluate IDCs.
*/
@@ -20140,7 +21672,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
goto fatal_exit;
}
-#endif
ret = xmlSchemaCheckAttrLocallyValid(ctxt, curState);
if (ret == -1)
goto fatal_exit;
@@ -20150,7 +21681,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
}
/* No break on purpose. */
case XML_SCHEMAS_ATTR_CHECKED:
-#ifdef IDC_ENABLED
if (ctxt->xpathStates != NULL) {
/*
* Evaluate IDCs.
@@ -20163,7 +21693,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
goto fatal_exit;
}
break;
-#endif
default:
break;
}
@@ -20240,8 +21769,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
attrDecl = curState->decl;
if (attrDecl->ref != NULL)
attrDecl = attrDecl->refDecl;
-
-#ifdef IDC_ENABLED
/*
* Evaluate IDCs on default attributes.
*/
@@ -20296,6 +21823,7 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
xmlChar *str = xmlStrdup(attrDecl->defValue);
if (xmlSchemaPostCreateVal(ctxt,
+ ctxt->attrInfo->typeDef,
str,
&(attrDecl->defVal)) == -1) {
FREE_AND_NULL(str)
@@ -20309,7 +21837,6 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
if (xmlSchemaXPathProcessHistory(ctxt, ctxt->depth +1) == -1)
goto fatal_exit;
}
-#endif
if (ctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
/*
@@ -20563,6 +22090,8 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
if (vctxt == NULL)
return;
+ vctxt->flags = 0;
+
vctxt->validationRoot = NULL;
if (vctxt->attr != NULL) {
xmlSchemaFreeAttributeStates(vctxt->attr);
@@ -20884,4 +22413,6 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
TODO return (0);
}
+#define bottom_xmlschemas
+#include "elfgcchack.h"
#endif /* LIBXML_SCHEMAS_ENABLED */