Added "Particle correct 2" to parsing of model groups. Added handling
* xmlschemas.c: Added "Particle correct 2" to parsing of model groups.
Added handling substitution groups inside <choice> and <sequence>;
for <all> this is not supported yet. Changed circular checks for
model groups definitions. "memberTypes" are processed at different
levels now: component resolution first, construction later; this
goes hand in hand with a global change to handle component
resolution in a distinct phase. Fixed invalid default values for
elements to mark the schema as invalid; this just resulted in an
error report previously, but the schema was handled as valid.
Separated the assignment of the model groups to referencing
model group definition references (i.e. particles); this was
needed to perform the circularity check for model group definitions.
Added "Element Declaration Properties Correct (e-props-correct)"
constraints. Separated component resolution for simple/complex
types.
* include/libxml/schemasInternals.h: Added a flag for substitution
group heads.
diff --git a/xmlschemas.c b/xmlschemas.c
index cb13635..7d45996 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -154,6 +154,10 @@
(item->type == XML_SCHEMA_TYPE_CHOICE) || \
(item->type == XML_SCHEMA_TYPE_ALL))
+#define ELEM_TYPE(item) item->subtypes
+
+#define SUBST_GROUP_AFF(item) item->refDecl
+
#if 0
#define WXS_GET_NEXT(item) xmlSchemaGetNextComponent((xmlSchemaBasicItemPtr) item)
#endif
@@ -240,6 +244,7 @@
const xmlChar **localImports; /* list of locally imported namespaces */
int sizeLocalImports;
int nbLocalImports;
+ xmlHashTablePtr substGroups;
};
@@ -353,6 +358,7 @@
xmlNodePtr node;
};
+#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
/**
* xmlSchemaModelGroupDef:
*
@@ -369,6 +375,7 @@
const xmlChar *name;
const xmlChar *targetNamespace;
xmlNodePtr node;
+ int flags;
};
typedef struct _xmlSchemaIDC xmlSchemaIDC;
@@ -629,6 +636,18 @@
const xmlChar *targetNamespace;
};
+/**
+ * xmlSchemaSubstGroup:
+ *
+ *
+ */
+typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
+typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
+struct _xmlSchemaSubstGroup {
+ xmlSchemaElementPtr head;
+ xmlSchemaItemListPtr members;
+};
+
/************************************************************************
* *
* Some predeclarations *
@@ -672,8 +691,6 @@
xmlSchemaTypePtr type,
const xmlChar *value,
xmlSchemaValPtr *val);
-static xmlSchemaTypePtr
-xmlSchemaGetSimpleContentType(xmlSchemaTypePtr complexType);
static int
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
static xmlSchemaTreeItemPtr
@@ -2789,6 +2806,146 @@
return (ret);
}
+static xmlSchemaItemListPtr
+xmlSchemaNewItemList(void)
+{
+ xmlSchemaItemListPtr ret;
+
+ ret = xmlMalloc(sizeof(xmlSchemaItemList));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "allocating an item list structure", NULL);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaItemList));
+ return (ret);
+}
+
+/**
+ * xmlSchemaAddElementSubstitutionMember:
+ * @pctxt: a schema parser context
+ * @head: the head of the substitution group
+ * @member: the new member of the substitution group
+ *
+ * Allocate a new annotation structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static int
+xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaElementPtr head,
+ xmlSchemaElementPtr member)
+{
+ xmlSchemaSubstGroupPtr substGroup;
+
+ if (pctxt == NULL)
+ return (-1);
+
+ if (pctxt->substGroups == NULL) {
+ pctxt->substGroups = xmlHashCreateDict(10, pctxt->dict);
+ if (pctxt->substGroups == NULL)
+ return (-1);
+ }
+ substGroup = xmlHashLookup2(pctxt->substGroups, head->name,
+ head->targetNamespace);
+ if (substGroup == NULL) {
+ int res;
+
+ substGroup = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
+ if (substGroup == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "xmlSchemaAddElementSubstitution, allocating a substitution "
+ "group container",
+ NULL);
+ return (-1);
+ }
+ substGroup->members = xmlSchemaNewItemList();
+ if (substGroup->members == NULL) {
+ xmlFree(substGroup);
+ return (-1);
+ }
+ substGroup->head = head;
+
+ res = xmlHashAddEntry2(pctxt->substGroups,
+ head->name, head->targetNamespace, substGroup);
+ if (res != 0) {
+ xmlFree(substGroup->members);
+ xmlFree(substGroup);
+ xmlSchemaPErr(pctxt, member->node,
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaAddElementSubstitution, "
+ "failed to add a new substitution group container for "
+ "'%s'.\n", head->name, NULL);
+ return (-1);
+ }
+ }
+ if (substGroup->members->items == NULL) {
+ substGroup->members->items = (void **) xmlMalloc(
+ 5 * sizeof(xmlSchemaElementPtr));
+ if (substGroup->members->items == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "allocating list of substitution group members", NULL);
+ return (-1);
+ }
+ substGroup->members->sizeItems = 5;
+ } else if (substGroup->members->sizeItems <=
+ substGroup->members->nbItems) {
+ substGroup->members->sizeItems *= 2;
+ substGroup->members->items = (void **) xmlRealloc(
+ substGroup->members->items,
+ substGroup->members->sizeItems * sizeof(xmlSchemaElementPtr));
+ if (substGroup->members->items == NULL) {
+ xmlSchemaPErrMemory(NULL,
+ "re-allocating list of substitution group members", NULL);
+ substGroup->members->sizeItems = 0;
+ return (-1);
+ }
+ }
+ ((xmlSchemaElementPtr *) substGroup->members->items)
+ [substGroup->members->nbItems++] = (void *) member;
+ return (0);
+}
+
+/**
+ * xmlSchemaGetElementSubstitutionGroup:
+ * @pctxt: a schema parser context
+ * @head: the head of the substitution group
+ * @member: the new member of the substitution group
+ *
+ * Allocate a new annotation structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlSchemaSubstGroupPtr
+xmlSchemaGetElementSubstitutionGroup(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaElementPtr head)
+{
+ if (pctxt == NULL)
+ return (NULL);
+
+ if (pctxt->substGroups == NULL)
+ return (NULL);
+
+ return ((xmlSchemaSubstGroupPtr) xmlHashLookup2(pctxt->substGroups,
+ head->name, head->targetNamespace));
+}
+
+/**
+ * xmlSchemaFreeItemList:
+ * @annot: a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaFreeItemList(xmlSchemaItemListPtr list)
+{
+ if (list == NULL)
+ return;
+ if (list->items != NULL)
+ xmlFree(list->items);
+ xmlFree(list);
+}
+
/**
* xmlSchemaFreeAnnot:
* @annot: a schema type structure
@@ -2970,6 +3127,22 @@
xmlFree(item);
}
+/**
+ * xmlSchemaFreeQNameRef:
+ * @item: a QName reference structure
+ *
+ * Deallocatea a QName reference structure.
+ */
+static void
+xmlSchemaFreeSubstGroup(xmlSchemaSubstGroupPtr item)
+{
+ if (item == NULL)
+ return;
+ if (item->members != NULL)
+ xmlSchemaFreeItemList(item->members);
+ xmlFree(item);
+}
+
static int
xmlSchemaAddVolatile(xmlSchemaPtr schema,
xmlSchemaBasicItemPtr item)
@@ -2977,14 +3150,12 @@
xmlSchemaItemListPtr list;
if (schema->volatiles == NULL) {
- schema->volatiles = (void *) xmlMalloc(sizeof(xmlSchemaItemList));
+ schema->volatiles = (void *) xmlSchemaNewItemList();
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) {
@@ -3258,9 +3429,7 @@
}
}
}
- if (list->items != NULL)
- xmlFree(list->items);
- xmlFree(list);
+ xmlSchemaFreeItemList(list);
}
}
/**
@@ -7527,23 +7696,9 @@
(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
(!xmlStrEqual(attr->name, BAD_CAST "form")))
{
- if (xmlStrEqual(attr->name, BAD_CAST "substitutionGroup")) {
- /*
- * 3.3.6 : 3 If there is a non-·absent· {substitution
- * group affiliation}, then {scope} must be global.
- * TODO: This one is redundant, since the S4S does
- * prohibit this attribute on local declarations already;
- * so why an explicit error code? Weird spec.
- * TODO: Think about hanling this equal to the other attributes.
- */
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_E_PROPS_CORRECT_3,
- NULL, (xmlSchemaTypePtr) decl, attr);
- } else {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, (xmlSchemaTypePtr) decl, attr);
- }
+ xmlSchemaPIllegalAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, (xmlSchemaTypePtr) decl, attr);
}
} else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
@@ -7582,7 +7737,10 @@
*/
attr = xmlSchemaGetPropNode(node, "final");
if (attr == NULL) {
- decl->flags |= XML_SCHEMAS_ELEM_FINAL_ABSENT;
+ if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
+ decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
+ if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
+ decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
} else {
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
@@ -7670,7 +7828,7 @@
"The attribute 'type' and the <complexType> child are "
"mutually exclusive", NULL);
} else
- decl->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0);
+ ELEM_TYPE(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
child = child->next;
} else if (IS_SCHEMA(child, "simpleType")) {
/*
@@ -7685,7 +7843,7 @@
"The attribute 'type' and the <simpleType> child are "
"mutually exclusive", NULL);
} else
- decl->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+ ELEM_TYPE(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
child = child->next;
}
while ((IS_SCHEMA(child, "unique")) ||
@@ -7769,6 +7927,11 @@
* Mark the simple type as being of variety "union".
*/
type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+ /*
+ * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
+ * then the ·simple ur-type definition·."
+ */
+ type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
/*
* Check for illegal attributes.
*/
@@ -7934,6 +8097,11 @@
* Mark the type as being of variety "list".
*/
type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+ /*
+ * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
+ * then the ·simple ur-type definition·."
+ */
+ type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
/*
* Check for illegal attributes.
*/
@@ -9484,7 +9652,7 @@
xmlNodePtr child = NULL;
xmlAttrPtr attr;
const xmlChar *oldcontainer, *container;
- int min, max;
+ int min = 0, max = 0;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -9504,7 +9672,8 @@
min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
"(nonNegativeInteger | unbounded)");
- }
+ }
+ xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
/*
* Create a particle
*/
@@ -9641,9 +9810,12 @@
}
}
ctxt->container = oldcontainer;
- if (withParticle)
- return ((xmlSchemaTreeItemPtr) particle);
- else
+ if (withParticle) {
+ if ((min == 0) && (max == 0))
+ return (NULL);
+ else
+ return ((xmlSchemaTreeItemPtr) particle);
+ } else
return ((xmlSchemaTreeItemPtr) item);
}
@@ -10818,6 +10990,9 @@
}
if (ctxt->localImports != NULL)
xmlFree((xmlChar *) ctxt->localImports);
+ if (ctxt->substGroups != NULL)
+ xmlHashFree(ctxt->substGroups,
+ (xmlHashDeallocator) xmlSchemaFreeSubstGroup);
xmlDictFree(ctxt->dict);
xmlFree(ctxt);
}
@@ -10828,6 +11003,139 @@
* *
************************************************************************/
+
+static void
+xmlSchemaWalkSubstGroups(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaSubstGroupPtr substGroup,
+ xmlAutomataStatePtr startState,
+ xmlAutomataStatePtr endState)
+{
+ xmlSchemaElementPtr member;
+ xmlSchemaSubstGroupPtr sg;
+ int i;
+
+ for (i = 0; i < substGroup->members->nbItems; i++) {
+ member = (xmlSchemaElementPtr) substGroup->members->items[i];
+ if ((member->flags & XML_SCHEMAS_ELEM_ABSTRACT) == 0) {
+ xmlAutomataNewEpsilon(pctxt->am,
+ xmlAutomataNewTransition2(pctxt->am,
+ startState, NULL,
+ member->name, member->targetNamespace, member),
+ endState);
+ }
+ if (member->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
+ sg = xmlSchemaGetElementSubstitutionGroup(pctxt, member);
+ if (sg != NULL)
+ xmlSchemaWalkSubstGroups(pctxt, sg, startState, endState);
+ }
+ }
+}
+
+static void
+xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaParticlePtr particle,
+ xmlSchemaSubstGroupPtr substGroup)
+{
+ xmlAutomataStatePtr start;
+ xmlSchemaElementPtr elemDecl;
+ xmlAutomataStatePtr end;
+
+ elemDecl = (xmlSchemaElementPtr) particle->children;
+ /*
+ * Wrap the substitution group with a CHOICE.
+ */
+ start = pctxt->state;
+ end = xmlAutomataNewState(pctxt->am);
+
+ if (particle->maxOccurs == 1) {
+ /*
+ * NOTE that we put the declaration in, even if it's abstract,
+ */
+ xmlAutomataNewEpsilon(pctxt->am,
+ xmlAutomataNewTransition2(pctxt->am,
+ start, NULL,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl),
+ end);
+ xmlSchemaWalkSubstGroups(pctxt, substGroup, start, end);
+ } else {
+ int counter;
+ xmlAutomataStatePtr hop;
+ int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+ UNBOUNDED : particle->maxOccurs - 1;
+ int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
+
+ counter =
+ xmlAutomataNewCounter(pctxt->am, minOccurs,
+ maxOccurs);
+ hop = xmlAutomataNewState(pctxt->am);
+
+ xmlAutomataNewEpsilon(pctxt->am,
+ xmlAutomataNewTransition2(pctxt->am,
+ start, NULL,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl),
+ hop);
+
+ xmlSchemaWalkSubstGroups(pctxt, substGroup, start, hop);
+
+ xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
+ xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+ }
+ if (particle->minOccurs == 0)
+ xmlAutomataNewEpsilon(pctxt->am, start, end);
+ pctxt->state = end;
+}
+
+static void
+xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaParticlePtr particle)
+{
+ xmlSchemaSubstGroupPtr substGroup;
+
+ substGroup = xmlSchemaGetElementSubstitutionGroup(ctxt,
+ (xmlSchemaElementPtr) particle->children);
+ if (substGroup != NULL) {
+ /*
+ * Substitution groups.
+ */
+ xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, substGroup);
+ } else {
+ xmlSchemaElementPtr elemDecl;
+ xmlAutomataStatePtr start;
+
+ elemDecl = (xmlSchemaElementPtr) particle->children;
+
+ if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
+ return;
+ if (particle->maxOccurs == 1) {
+ start = ctxt->state;
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl);
+ } else if ((particle->maxOccurs >= UNBOUNDED) && (particle->minOccurs < 2)) {
+ /* Special case. */
+ start = ctxt->state;
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl);
+ xmlAutomataNewEpsilon(ctxt->am, ctxt->state, start);
+ } else {
+ int counter;
+ int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+ UNBOUNDED : particle->maxOccurs - 1;
+ int minOccurs = particle->minOccurs < 1 ?
+ 0 : particle->minOccurs - 1;
+
+ start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
+ counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
+ ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl);
+ xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
+ ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
+ NULL, counter);
+ }
+ if (particle->minOccurs == 0)
+ xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
+ }
+}
+
/**
* xmlSchemaBuildAContentModel:
* @ctxt: the schema parser context
@@ -10954,94 +11262,9 @@
ctxt->state = end;
break;
}
- case XML_SCHEMA_TYPE_ELEMENT:{
- xmlAutomataStatePtr oldstate;
- xmlSchemaElementPtr elemDecl;
-
- elemDecl = (xmlSchemaElementPtr) particle->children;
-
- oldstate = ctxt->state;
-
- if (particle->maxOccurs >= UNBOUNDED) {
- if (particle->minOccurs > 1) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
- counter = xmlAutomataNewCounter(ctxt->am,
- particle->minOccurs - 1, UNBOUNDED);
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
- ctxt->state, NULL,
- elemDecl->name,
- elemDecl->targetNamespace,
- (xmlSchemaTypePtr) elemDecl);
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state =
- xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
- counter);
-
- } else {
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
- ctxt->state, NULL,
- elemDecl->name,
- elemDecl->targetNamespace,
- (xmlSchemaTypePtr) elemDecl);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
- oldstate);
- if (particle->minOccurs == 0) {
- /* basically an elem* */
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
- }
- }
- } else if ((particle->maxOccurs > 1) || (particle->minOccurs > 1)) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
- counter = xmlAutomataNewCounter(ctxt->am,
- particle->minOccurs - 1,
- particle->maxOccurs - 1);
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- ctxt->state,
- NULL,
- elemDecl->name,
- elemDecl->targetNamespace,
- (xmlSchemaTypePtr) elemDecl);
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
- NULL, counter);
- if (particle->minOccurs == 0) {
- /* basically an elem? */
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
- }
-
- } else {
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- ctxt->state,
- NULL,
- elemDecl->name,
- elemDecl->targetNamespace,
- (xmlSchemaTypePtr) elemDecl);
- if (particle->minOccurs == 0) {
- /* basically an elem? */
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
- }
- }
- break;
- }
+ case XML_SCHEMA_TYPE_ELEMENT:
+ xmlSchemaBuildContentModelForElement(ctxt, particle);
+ break;
case XML_SCHEMA_TYPE_SEQUENCE:{
xmlSchemaTreeItemPtr sub;
@@ -11329,63 +11552,71 @@
* term.
*/
static void
-xmlSchemaElementFixup(xmlSchemaElementPtr elem,
+xmlSchemaElementFixup(xmlSchemaElementPtr elemDecl,
xmlSchemaParserCtxtPtr ctxt,
const xmlChar * name ATTRIBUTE_UNUSED,
const xmlChar * context ATTRIBUTE_UNUSED,
const xmlChar * namespace ATTRIBUTE_UNUSED)
{
- if ((ctxt == NULL) || (elem == NULL) ||
- ((elem != NULL) && (elem->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
+ if ((ctxt == NULL) || (elemDecl == NULL) ||
+ ((elemDecl != NULL) && (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
return;
- elem->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
+ elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
- if ((elem->subtypes == NULL) && (elem->namedType != NULL)) {
+ if ((elemDecl->subtypes == NULL) && (elemDecl->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);
+ type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
+ elemDecl->namedTypeNs);
if (type == NULL) {
xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- NULL, (xmlSchemaTypePtr) elem, elem->node,
- "type", elem->namedType, elem->namedTypeNs,
+ NULL, (xmlSchemaTypePtr) elemDecl, elemDecl->node,
+ "type", elemDecl->namedType, elemDecl->namedTypeNs,
XML_SCHEMA_TYPE_BASIC, "type definition");
} else
- elem->subtypes = type;
+ elemDecl->subtypes = type;
}
- if (elem->substGroup != NULL) {
+ if (elemDecl->substGroup != NULL) {
xmlSchemaElementPtr substHead;
/*
* FIXME TODO: Do we need a new field in _xmlSchemaElement for
* substitutionGroup?
*/
- substHead = xmlSchemaGetElem(ctxt->schema, elem->substGroup,
- elem->substGroupNs);
+ substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
+ elemDecl->substGroupNs);
if (substHead == NULL) {
xmlSchemaPResCompAttrErr(ctxt,
XML_SCHEMAP_SRC_RESOLVE,
- NULL, (xmlSchemaTypePtr) elem, NULL,
- "substitutionGroup", elem->substGroup, elem->substGroupNs,
- XML_SCHEMA_TYPE_ELEMENT, NULL);
+ NULL, (xmlSchemaTypePtr) elemDecl, NULL,
+ "substitutionGroup", elemDecl->substGroup,
+ elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
} else {
xmlSchemaElementFixup(substHead, ctxt, NULL, NULL, NULL);
+ if ((substHead->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
+ substHead->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
+ /*
+ * Set the "substitution group affiliation".
+ * NOTE that now we use the "refDecl" field for this.
+ */
+ elemDecl->refDecl = substHead;
/*
* (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 (elemDecl->subtypes == NULL)
+ elemDecl->subtypes = substHead->subtypes;
+ xmlSchemaAddElementSubstitutionMember(ctxt, substHead, elemDecl);
}
}
- if ((elem->subtypes == NULL) && (elem->namedType == NULL) &&
- (elem->substGroup == NULL))
- elem->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+ if ((elemDecl->subtypes == NULL) && (elemDecl->namedType == NULL) &&
+ (elemDecl->substGroup == NULL))
+ elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
}
/**
@@ -11393,7 +11624,10 @@
* @ctxt: the schema parser context
* @type: the schema simple type definition
*
- * Checks and builds the memberTypes of the union simple type.
+ * Checks and builds the "member type definitions" property of the union
+ * simple type. This handles part (1), part (2) is done in
+ * xmlSchemaFinishMemberTypeDefinitionsProperty()
+ *
* Returns -1 in case of an internal error, 0 otherwise.
*/
static int
@@ -11401,14 +11635,15 @@
xmlSchemaTypePtr type)
{
- xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
+ xmlSchemaTypeLinkPtr link, lastLink, newLink;
xmlSchemaTypePtr memberType;
- /* 1 If the <union> alternative is chosen, then [Definition:]
+ /*
+ * SPEC (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.
+ * <simpleType>s among the [children] of <union>, if any."
*/
/*
* Resolve references.
@@ -11437,10 +11672,7 @@
link = link->next;
xmlFree(newLink);
} else {
- link->type = memberType;
- if (IS_NOT_TYPEFIXED(memberType))
- xmlSchemaTypeFixup(memberType, ctxt, NULL);
-
+ link->type = memberType;
lastLink = link;
link = link->next;
}
@@ -11455,8 +11687,6 @@
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)
@@ -11466,43 +11696,6 @@
lastLink = link;
memberType = memberType->next;
}
- /*
- * The actual value is then formed by replacing any union type
- * definition in the ·explicit members· with the members of their
- * {member type definitions}, in order.
- */
- link = type->memberTypes;
- while (link != NULL) {
- /* TODO: type-fixup it. */
- if (link->type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
- subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
- if (subLink != NULL) {
- link->type = subLink->type;
- if (subLink->next != NULL) {
- lastLink = link->next;
- subLink = subLink->next;
- prevLink = link;
- while (subLink != NULL) {
- newLink = (xmlSchemaTypeLinkPtr)
- xmlMalloc(sizeof(xmlSchemaTypeLink));
- if (newLink == NULL) {
- xmlSchemaPErrMemory(ctxt, "allocating a type link",
- NULL);
- return (-1);
- }
- newLink->type = memberType;
- prevLink->next = newLink;
- prevLink = newLink;
- newLink->next = lastLink;
-
- subLink = subLink->next;
- }
- }
- }
- }
- link = link->next;
- }
-
return (0);
}
@@ -13081,15 +13274,7 @@
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,
@@ -13097,6 +13282,12 @@
"The definition is circular", NULL);
return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
}
+ if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
+ /*
+ * Avoid inifinite recursion on circular types not yet checked.
+ */
+ return (0);
+ }
ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
ancestor->baseType);
@@ -13105,7 +13296,7 @@
}
/**
- * xmlSchemaCheckGroupDefCircular:
+ * xmlSchemaCheckTypeDefCircular:
* @item: the complex/simple type definition
* @ctxt: the parser context
* @name: the name
@@ -13126,6 +13317,68 @@
}
/**
+ * xmlSchemaResolveTypeDefs:
+ * @item: the complex/simple type definition
+ * @ctxt: the parser context
+ * @name: the name
+ *
+ * Checks for circular type definitions.
+ */
+static void
+xmlSchemaResolveTypeDefs(xmlSchemaTypePtr typeDef,
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ if (typeDef == NULL)
+ return;
+
+ if (IS_SIMPLE_TYPE(typeDef)) {
+ if (typeDef->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ /*
+ * Resolve the memberTypes.
+ */
+ xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
+ return;
+ } else if (typeDef->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
+ /*
+ * Resolve the itemType.
+ */
+ if ((typeDef->subtypes == NULL) && (typeDef->ref != NULL)) {
+ typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
+ typeDef->ref, typeDef->refNs);
+ if ((typeDef->subtypes == NULL) ||
+ (! IS_SIMPLE_TYPE(typeDef->subtypes))) {
+ typeDef->subtypes = NULL;
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, typeDef, typeDef->node,
+ "itemType", typeDef->ref, typeDef->refNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
+ }
+ }
+ return;
+ }
+ }
+ /*
+ * Resolve the base type.
+ */
+ if (typeDef->baseType == NULL) {
+ typeDef->baseType = xmlSchemaGetType(ctxt->schema,
+ typeDef->base, typeDef->baseNs);
+ if (typeDef->baseType == NULL) {
+ xmlSchemaPResCompAttrErr(ctxt,
+ XML_SCHEMAP_SRC_RESOLVE,
+ NULL, typeDef, typeDef->node,
+ "base", typeDef->base, typeDef->baseNs,
+ XML_SCHEMA_TYPE_SIMPLE, NULL);
+ return;
+ }
+ }
+}
+
+
+
+/**
* xmlSchemaCheckSTPropsCorrect:
* @ctxt: the schema parser context
* @type: the simple type definition
@@ -13978,6 +14231,7 @@
*/
vctxt->node = node;
vctxt->cur = NULL;
+ /* ret = xmlSchemaCheckCVCSimpleType(vctxt, elemDecl->value, typeDef, 0); */
if (IS_SIMPLE_TYPE(type))
ret = xmlSchemaValidateSimpleTypeValue(vctxt, type, value,
1, 1, 1, 0);
@@ -13986,8 +14240,11 @@
value, 1, 1, 1, 0);
else
return (ret);
-
- /* ret = xmlSchemaCheckCVCSimpleType(vctxt, elemDecl->value, typeDef, 0); */
+ if (ret != 0) {
+ pctxt->err = vctxt->err;
+ pctxt->nberrors++;
+ }
+
if (ret < 0) {
xmlSchemaPErr(pctxt, node,
/* NOTNICE: error code: This function will be used during
@@ -13998,7 +14255,8 @@
"while validating a value constaint value.\n",
NULL, NULL);
- }
+ }
+
return (ret);
}
@@ -14109,24 +14367,24 @@
(type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)) ||
((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
(type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)))
- return (0);
+ return (1);
} else {
/*
* SPEC (2.1) "B and D must be the same type definition."
*/
- return (1);
+ return (0);
}
/*
* SPEC (2.2) "B must be D's {base type definition}."
*/
if (type->baseType == baseType)
- return (1);
+ return (0);
/*
* SPEC (2.3.1) "D's {base type definition} must not be the ·ur-type
* definition·."
*/
if (IS_ANYTYPE(type->baseType))
- return (0);
+ return (1);
if (IS_COMPLEX_TYPE(type->baseType)) {
/*
@@ -15269,6 +15527,53 @@
return (-1);
}
+static int
+xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaTypePtr type)
+{
+ xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
+ /*
+ * The actual value is then formed by replacing any union type
+ * definition in the ·explicit members· with the members of their
+ * {member type definitions}, in order.
+ */
+ link = type->memberTypes;
+ while (link != NULL) {
+
+ if (IS_NOT_TYPEFIXED(link->type))
+ xmlSchemaTypeFixup(link->type, pctxt, NULL);
+
+ if (link->type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
+ subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
+ if (subLink != NULL) {
+ link->type = subLink->type;
+ if (subLink->next != NULL) {
+ lastLink = link->next;
+ subLink = subLink->next;
+ prevLink = link;
+ while (subLink != NULL) {
+ newLink = (xmlSchemaTypeLinkPtr)
+ xmlMalloc(sizeof(xmlSchemaTypeLink));
+ if (newLink == NULL) {
+ xmlSchemaPErrMemory(pctxt, "allocating a type link",
+ NULL);
+ return (-1);
+ }
+ newLink->type = subLink->type;
+ prevLink->next = newLink;
+ prevLink = newLink;
+ newLink->next = lastLink;
+
+ subLink = subLink->next;
+ }
+ }
+ }
+ }
+ link = link->next;
+ }
+ return (0);
+}
+
/**
* xmlSchemaTypeFixup:
* @typeDecl: the schema type definition
@@ -15290,27 +15595,22 @@
type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
if (name == NULL)
name = type->name;
+
+ if (type->baseType == NULL) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_INTERNAL,
+ NULL, type, NULL,
+ "Internal error: xmlSchemaTypeFixup, "
+ "baseType is missing on '%s'", type->name);
+ return;
+ }
if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
- xmlSchemaTypePtr baseType;
+ xmlSchemaTypePtr baseType = type->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;
- }
- type->baseType = baseType;
- }
+ * Type-fix the base type.
+ */
if (IS_NOT_TYPEFIXED(baseType))
xmlSchemaTypeFixup(baseType, ctxt, NULL);
if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
@@ -15597,21 +15897,7 @@
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) {
/*
* This one is really needed, so get out.
@@ -15619,50 +15905,24 @@
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);
+ xmlSchemaTypeFixup(type->subtypes, ctxt, NULL);
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
/*
* Corresponds to <simpleType><union>...
- * Resolve the member types.
- */
- xmlSchemaResolveUnionMemberTypes(ctxt, type);
+ */
if (type->memberTypes == NULL) {
/*
* This one is really needed, so get out.
*/
return;
}
- type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+ if (xmlSchemaFinishMemberTypeDefinitionsProperty(ctxt, type) == -1)
+ return;
} else {
- xmlSchemaTypePtr baseType;
+ xmlSchemaTypePtr baseType = type->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);
/*
@@ -16050,33 +16310,47 @@
* otherwise NULL.
*/
static xmlSchemaTreeItemPtr
-xmlSchemaGetCircModelGrDefRef(xmlSchemaTreeItemPtr ctxtMGroup,
- xmlSchemaTreeItemPtr selfMGroup,
+xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
xmlSchemaTreeItemPtr particle)
{
xmlSchemaTreeItemPtr circ = NULL;
xmlSchemaTreeItemPtr term;
+ xmlSchemaModelGroupDefPtr gdef;
- while (particle != NULL) {
+ for (; particle != NULL; particle = particle->next) {
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);
+ if (term == NULL)
+ continue;
+ switch (term->type) {
+ case XML_SCHEMA_TYPE_GROUP:
+ gdef = (xmlSchemaModelGroupDefPtr) term;
+ if (gdef == groupDef)
+ return (particle);
+ /*
+ * Mark this model group definition to avoid infinite
+ * recursion on circular references not yet examined.
+ */
+ if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
+ continue;
+ if (gdef->children != NULL) {
+ gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
+ circ = xmlSchemaGetCircModelGrDefRef(groupDef,
+ gdef->children->children);
+ gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
+ if (circ != NULL)
+ return (circ);
+ }
+ break;
+ case XML_SCHEMA_TYPE_SEQUENCE:
+ case XML_SCHEMA_TYPE_CHOICE:
+ case XML_SCHEMA_TYPE_ALL:
+ circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
+ if (circ != NULL)
+ return (circ);
+ break;
+ default:
+ break;
}
- particle = particle->next;
}
return (NULL);
}
@@ -16088,11 +16362,12 @@
* @name: the name
*
* Checks for circular references to model group definitions.
+ * Additionally it
*/
static void
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar * name ATTRIBUTE_UNUSED)
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name ATTRIBUTE_UNUSED)
{
/*
* Schema Component Constraint: Model Group Correct
@@ -16107,8 +16382,7 @@
{
xmlSchemaTreeItemPtr circ;
- circ = xmlSchemaGetCircModelGrDefRef(item->children, NULL,
- item->children->children);
+ circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
if (circ != NULL) {
xmlChar *str = NULL;
/*
@@ -16134,6 +16408,28 @@
}
}
+/**
+ * xmlSchemaGroupDefTermFixup:
+ * @item: the particle with a model group definition as term
+ * @ctxt: the parser context
+ * @name: the name
+ *
+ * Checks for circular references to model group definitions.
+ * Additionally it
+ */
+static void
+xmlSchemaGroupDefTermFixup(xmlSchemaParticlePtr item,
+ xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ if ((item == NULL) ||
+ (item->type != XML_SCHEMA_TYPE_PARTICLE) ||
+ (item->children == NULL) ||
+ (item->children->type != XML_SCHEMA_TYPE_GROUP) ||
+ (item->children->children == NULL))
+ return;
+ item->children = item->children->children;
+}
/**
* xmlSchemaGetCircAttrGrRef:
@@ -16384,56 +16680,172 @@
}
}
-#if 0 /* Not used yet. */
+/**
+ * xmlSchemaCheckElemPropsCorrect:
+ * @ctxt: a schema parser context
+ * @decl: the element declaration
+ * @name: the name of the attribute
+ *
+ * Schema Component Constraint:
+ * Element Declaration Properties Correct (e-props-correct)
+ *
+ * STATUS:
+ * missing: (6)
+ */
static int
-xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaElementPtr edecl)
+xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaElementPtr elemDecl)
{
+ int ret = 0;
+ xmlSchemaTypePtr typeDef = ELEM_TYPE(elemDecl);
/*
- * TODO: 1 The values of the properties of an element declaration must be as
- * described in the property tableau in The Element Declaration Schema
- * Component (§3.3.1), modulo the impact of Missing Sub-components (§5.3).
- */
+ * SPEC (1) "The values of the properties of an element declaration
+ * must be as described in the property tableau in The Element
+ * Declaration Schema Component (§3.3.1), modulo the impact of Missing
+ * Sub-components (§5.3)."
+ */
+ if (SUBST_GROUP_AFF(elemDecl) != NULL) {
+ xmlSchemaElementPtr substGrAff = SUBST_GROUP_AFF(elemDecl);
+ /*
+ * SPEC (3) "If there is a non-·absent· {substitution group
+ * affiliation}, then {scope} must be global."
+ */
+ if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_E_PROPS_CORRECT_3,
+ NULL, (xmlSchemaTypePtr) elemDecl, elemDecl->node,
+ "Only global element declarations can have a "
+ "substitution group affiliation", NULL);
+ ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
+ }
+ /*
+ * SPEC (4) "If there is a {substitution group affiliation},
+ * the {type definition}
+ * of the element declaration must be validly derived from the {type
+ * definition} of the {substitution group affiliation}, given the value
+ * of the {substitution group exclusions} of the {substitution group
+ * affiliation}, as defined in Type Derivation OK (Complex) (§3.4.6)
+ * (if the {type definition} is complex) or as defined in
+ * Type Derivation OK (Simple) (§3.14.6) (if the {type definition} is
+ * simple)."
+ *
+ * NOTE: {substitution group exclusions} means the values of the
+ * attribute "final".
+ */
+ if (typeDef != ELEM_TYPE(SUBST_GROUP_AFF(elemDecl))) {
+ int set = 0;
+
+ if (substGrAff->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
+ set |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
+ if (substGrAff->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
+ set |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
+
+ if (xmlSchemaCheckCOSDerivedOK(pctxt->schema, typeDef,
+ ELEM_TYPE(substGrAff), set) != 0) {
+ xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
+
+ ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
+ xmlSchemaPCustomErrExt(pctxt,
+ XML_SCHEMAP_E_PROPS_CORRECT_4,
+ NULL, (xmlSchemaTypePtr) elemDecl, elemDecl->node,
+ "The type definition '%s' is not validly derived from "
+ "the type definition '%s' of the element declaration "
+ "'%s' (the substitution group affiliation)",
+ xmlSchemaGetComponentQName(&strA, typeDef),
+ xmlSchemaGetComponentQName(&strB, ELEM_TYPE(substGrAff)),
+ xmlSchemaGetComponentQName(&strC, substGrAff));
+ FREE_AND_NULL(strA)
+ FREE_AND_NULL(strB)
+ FREE_AND_NULL(strC)
+ }
+ }
+ }
/*
- * 2 If there is a {value constraint}, the canonical lexical
- * representation of its value must be ·valid· with respect to the {type
- * definition} as defined in Element Default Valid (Immediate) (§3.3.6).
- *
- * NOTE: This is done in xmlSchemaCheckElemValConstr.
- */
- /*
- * 3 If there is a non-·absent· {substitution group affiliation},
- * then {scope} must be global.
- *
- * NOTE: This is done in xmlSchemaParseElement.
- * TODO: Move it to this layer here.
- */
- /*
- * TODO: 4 If there is a {substitution group affiliation}, the {type definition}
- * of the element declaration must be validly derived from the {type
- * definition} of the {substitution group affiliation}, given the value
- * of the {substitution group exclusions} of the {substitution group
- * affiliation}, as defined in Type Derivation OK (Complex) (§3.4.6)
- * (if the {type definition} is complex) or as defined in
- * Type Derivation OK (Simple) (§3.14.6) (if the {type definition} is
- * simple).
- */
- /*
- * TODO: 5 If the {type definition} or {type definition}'s {content type}
+ * SPEC (5) "If the {type definition} or {type definition}'s
+ * {content type}
* is or is derived from ID then there must not be a {value constraint}.
* Note: The use of ID as a type definition for elements goes beyond
- * XML 1.0, and should be avoided if backwards compatibility is desired
+ * XML 1.0, and should be avoided if backwards compatibility is desired"
*/
+ if ((elemDecl->value != NULL) &&
+ ((IS_SIMPLE_TYPE(typeDef) &&
+ xmlSchemaIsDerivedFromBuiltInType(pctxt,
+ ELEM_TYPE(elemDecl), XML_SCHEMAS_ID)) ||
+ (IS_COMPLEX_TYPE(typeDef) &&
+ HAS_SIMPLE_CONTENT(typeDef) &&
+ xmlSchemaIsDerivedFromBuiltInType(pctxt,
+ typeDef->contentTypeDef, XML_SCHEMAS_ID)))) {
+
+ ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_E_PROPS_CORRECT_5,
+ NULL, (xmlSchemaTypePtr) elemDecl, elemDecl->node,
+ "The type definition (or type definition's content type) is or "
+ "is derived from ID; value constraints are not allowed in "
+ "conjunction with such a type definition", NULL);
+ } else if (elemDecl->value != NULL) {
+ int vcret;
+ xmlNodePtr node = NULL;
+
+ /*
+ * SPEC (2) "If there is a {value constraint}, the canonical lexical
+ * representation of its value must be ·valid· with respect to the
+ * {type definition} as defined in Element Default Valid (Immediate)
+ * (§3.3.6)."
+ */
+ if (typeDef == NULL) {
+ xmlSchemaPErr(pctxt, elemDecl->node,
+ XML_SCHEMAP_INTERNAL,
+ "Internal error: xmlSchemaCheckElemPropsCorrect, "
+ "type is missing... skipping validation of "
+ "the value constraint", NULL, NULL);
+ return (-1);
+ }
+ /*
+ * Ensure there's a validation context.
+ */
+ if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
+ return (-1);
+ if (elemDecl->node != NULL) {
+ if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
+ node = (xmlNodePtr) xmlHasProp(elemDecl->node,
+ BAD_CAST "fixed");
+ else
+ node = (xmlNodePtr) xmlHasProp(elemDecl->node,
+ BAD_CAST "default");
+ }
+ pctxt->vctxt->node = node;
+ pctxt->vctxt->cur = NULL;
+ vcret = xmlSchemaCheckCOSValidDefault(pctxt, pctxt->vctxt, typeDef,
+ elemDecl->value, node);
+ if (vcret == 0) {
+ /*
+ * Consume the computed value.
+ */
+ elemDecl->defVal = pctxt->vctxt->value;
+ pctxt->vctxt->value = NULL;
+ } else if (vcret < 0) {
+ xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INTERNAL,
+ NULL, NULL, node,
+ "Internal error: xmlSchemaElemCheckValConstr, "
+ "failed to validate the value constraint of the "
+ "element declaration '%s'",
+ elemDecl->name);
+ ret = vcret;
+ } else
+ ret = vcret;
+ }
+
/*
- * TODO: 6 Circular substitution groups are disallowed. That is, it must not
- * be possible to return to an element declaration by repeatedly following
- * the {substitution group affiliation} property.
+ * TODO: SPEC (6) "Circular substitution groups are disallowed.
+ * That is, it must not be possible to return to an element declaration
+ * by repeatedly following the {substitution group affiliation} property."
*/
+ return (ret);
}
-#endif
/**
- * xmlSchemaCheckElemValConstr:
+ * xmlSchemaCheckElementDeclComponent
* @item: an schema element declaration/particle
* @ctxt: a schema parser context
* @name: the name of the attribute
@@ -16443,64 +16855,15 @@
* Fixes finish doing the computations on the element declarations.
*/
static void
-xmlSchemaCheckElemValConstr(xmlSchemaElementPtr decl,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar * name ATTRIBUTE_UNUSED)
-{
- if (decl->value != NULL) {
- int ret;
- xmlNodePtr node = NULL;
- xmlSchemaTypePtr type;
-
- /*
- * 2 If there is a {value constraint}, the canonical lexical
- * representation of its value must be ·valid· with respect to the {type
- * definition} as defined in Element Default Valid (Immediate) (§3.3.6).
- */
- if (decl->subtypes == NULL) {
- xmlSchemaPErr(ctxt, decl->node,
- XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaCheckElemValConstr, "
- "type is missing... skipping validation of "
- "the value constraint", NULL, NULL);
- return;
- }
- /*
- * Ensure there's a validation context.
- */
- if (xmlSchemaCreateVCtxtOnPCtxt(ctxt) == -1)
- return;
-
- type = decl->subtypes;
-
- if (decl->node != NULL) {
- if (decl->flags & XML_SCHEMAS_ELEM_FIXED)
- node = (xmlNodePtr) xmlHasProp(decl->node, BAD_CAST "fixed");
- else
- node = (xmlNodePtr) xmlHasProp(decl->node, BAD_CAST "default");
- }
- ctxt->vctxt->node = node;
- ctxt->vctxt->cur = NULL;
- ret = xmlSchemaCheckCOSValidDefault(ctxt, ctxt->vctxt, type, decl->value,
- node);
- if (ret == 0) {
- /*
- * Consume the computed value.
- */
- decl->defVal = ctxt->vctxt->value;
- ctxt->vctxt->value = NULL;
- } else if (ret < 0) {
- xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
- NULL, NULL, node,
- "Internal error: xmlSchemaElemCheckValConstr, "
- "failed to validate the value constraint of the "
- "element declaration '%s'",
- decl->name);
- }
- }
+xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
+ xmlSchemaParserCtxtPtr ctxt,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ if (elemDecl == NULL)
+ return;
+ xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl);
}
-
/**
* xmlSchemaMiscRefFixup:
* @item: an schema component
@@ -16532,10 +16895,13 @@
} else {
if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
/*
- * Assign the model group of the model group definition
- * to the particle's "term".
+ * NOTE that we will assign the model group definition
+ * itself to the "term" of the particle. This will ease
+ * the check for circular model group definitions. After
+ * that the "term" will be assigned the model group of the
+ * model group definition.
*/
- item->children = refItem->children;
+ item->children = refItem;
} else
item->children = refItem;
}
@@ -16780,6 +17146,13 @@
ctxt->ctxtType = NULL;
ctxt->parentItem = NULL;
+ /*
+ * Resolve base types of simple/complex types.
+ */
+ xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaResolveTypeDefs, ctxt);
+
+ if (ctxt->nberrors != 0)
+ goto exit;
if (ret->volatiles != NULL) {
xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) ret->volatiles;
@@ -16790,21 +17163,17 @@
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
*/
xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt);
-
/*
* Then fixup all attributes group declarations
*/
xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup,
ctxt);
-
/*
* Resolve identity-constraint keyRefs.
*/
@@ -16819,19 +17188,31 @@
*/
xmlHashScan(ret->groupDecl, (xmlHashScanner)
xmlSchemaCheckGroupDefCircular, ctxt);
+ /*
+ * Set the "term" of particles pointing to model group definitions
+ * to the contained model group.
+ */
+ if (ret->volatiles != NULL) {
+ xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) ret->volatiles;
+ int i;
+ xmlSchemaParticlePtr item;
+ for (i = 0; i < list->nbItems; i++) {
+ item = (xmlSchemaParticlePtr) list->items[i];
+ if (item->type == XML_SCHEMA_TYPE_PARTICLE)
+ xmlSchemaGroupDefTermFixup(item, ctxt, NULL);
+ }
+ }
/*
* Check attribute groups for circular references.
*/
xmlHashScan(ret->attrgrpDecl, (xmlHashScanner)
- xmlSchemaCheckAttributeGroupCircular, ctxt);
-
+ xmlSchemaCheckAttributeGroupCircular, ctxt);
/*
* Then fix references of element declaration; apply constraints.
*/
xmlHashScanFull(ret->elemDecl,
(xmlHashScannerFull) xmlSchemaElementFixup, ctxt);
-
/*
* We will stop here if the schema was not valid to avoid internal errors
* on missing sub-components. This is not conforming to the spec, since it
@@ -16845,22 +17226,19 @@
* Then fixup all types properties
*/
xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
-
/*
* Then build the content model for all complex types
*/
xmlHashScan(ret->typeDecl,
- (xmlHashScanner) xmlSchemaBuildContentModel, ctxt);
-
+ (xmlHashScanner) xmlSchemaBuildContentModel, ctxt);
/*
* Validate the value constraint of attribute declarations/uses.
*/
xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaCheckAttrValConstr, ctxt);
-
/*
* Validate the value constraint of element declarations.
*/
- xmlHashScan(ret->elemDecl, (xmlHashScanner) xmlSchemaCheckElemValConstr, ctxt);
+ xmlHashScan(ret->elemDecl, (xmlHashScanner) xmlSchemaCheckElementDeclComponent, ctxt);
exit:
if (ctxt->nberrors != 0) {
@@ -17430,6 +17808,10 @@
for (i = 0; i < nbItems; i++) {
item = items[i];
switch (item->type) {
+ case XML_SCHEMA_TYPE_COMPLEX:
+ case XML_SCHEMA_TYPE_SIMPLE:
+ xmlSchemaResolveTypeDefs(item, ctxt, NULL);
+ break;
case XML_SCHEMA_TYPE_ATTRIBUTE:
xmlSchemaAttrFixup((xmlSchemaAttributePtr) item, ctxt, NULL);
break;
@@ -17471,6 +17853,20 @@
}
}
/*
+ * Set the "term" of particles pointing to model group definitions
+ * to the contained model group.
+ */
+ for (i = 0; i < nbItems; i++) {
+ item = items[i];
+ if ((item->type == XML_SCHEMA_TYPE_PARTICLE) &&
+ (((xmlSchemaParticlePtr) item)->children != NULL) &&
+ (((xmlSchemaParticlePtr) item)->children->type ==
+ XML_SCHEMA_TYPE_GROUP)) {
+ xmlSchemaGroupDefTermFixup((xmlSchemaParticlePtr) item,
+ ctxt, NULL);
+ }
+ }
+ /*
* Fixup for simple/complex types.
*/
for (i = 0; i < nbItems; i++) {
@@ -17508,7 +17904,7 @@
ctxt, NULL);
break;
case XML_SCHEMA_TYPE_ELEMENT:
- xmlSchemaCheckElemValConstr((xmlSchemaElementPtr) item,
+ xmlSchemaCheckElementDeclComponent((xmlSchemaElementPtr) item,
ctxt, NULL);
break;
default:
@@ -17886,34 +18282,6 @@
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
@@ -18023,50 +18391,7 @@
} while (cur != NULL);
}
- if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
- xmlSchemaTypePtr simpType, anyType;
-
- anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
-
- 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, simpType, value, 1, 0, 1, 0);
- if (ret < 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating complex type '%s'\n",
- type->name, NULL);
- } else if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) {
- /*
- * Check facets.
- *
- * 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,
- value, 0, fireErrors);
- if (ret < 0) {
- xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
- "Internal error: xmlSchemaValidateSimpleTypeValue, "
- "validating facets of complex type '%s'\n",
- type->name, NULL);
- } else if (ret > 0) {
- ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
- if (fireErrors)
- xmlSchemaVSimpleTypeErr(ctxt, ret, node, value, type);
- }
- }
- } else if (type->type == XML_SCHEMA_TYPE_BASIC) {
+ if (type->type == XML_SCHEMA_TYPE_BASIC) {
if (ctxt->value != NULL) {
xmlSchemaFreeValue(ctxt->value);
@@ -20348,7 +20673,7 @@
xmlFree(attrValue);
}
- type = elemDecl->subtypes;
+ type = ELEM_TYPE(elemDecl);
actualType = type;
/*
@@ -20435,8 +20760,8 @@
(type->flags & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
- if (! xmlSchemaCheckCOSDerivedOK(ctxt->schema, localType,
- type, set)) {
+ if (xmlSchemaCheckCOSDerivedOK(ctxt->schema, localType,
+ type, set) != 0) {
xmlChar *strA = NULL, *strB = NULL;
xmlSchemaVCustomErrExt(ctxt,
@@ -20448,8 +20773,8 @@
localType->targetNamespace,
localType->name),
xmlSchemaFormatQName(&strB,
- elemDecl->subtypes->targetNamespace,
- elemDecl->subtypes->name), NULL);
+ ELEM_TYPE(elemDecl)->targetNamespace,
+ ELEM_TYPE(elemDecl)->name), NULL);
FREE_AND_NULL(strA)
FREE_AND_NULL(strB)
}
@@ -20545,7 +20870,7 @@
* NOTE: 'local' above means types aquired by xsi:type.
*/
ret = 0;
- if (actualType != elemDecl->subtypes) {
+ if (actualType != ELEM_TYPE(elemDecl)) {
xmlSchemaCreatePCtxtOnVCtxt(ctxt);
ret = xmlSchemaCheckCOSValidDefault(ctxt->pctxt, ctxt, actualType,
elemDecl->value, NULL);
@@ -20571,7 +20896,7 @@
* done above.
*/
if (ret == 0) {
- if (actualType != elemDecl->subtypes)
+ if (actualType != ELEM_TYPE(elemDecl))
ret = xmlSchemaValidateElementByType(ctxt, actualType, 0, 0);
else
ret = xmlSchemaValidateElementByType(ctxt, actualType, 0, 1);