diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2004-06-08 17:52:16 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2004-06-08 17:52:16 +0000 |
commit | 50355f00411e8e8ba5c547c674470b2cdf2e8da3 (patch) | |
tree | 03e25023370e66c704de292229f0627c383ce897 /xmlschemas.c | |
parent | 8304d87d0d4ba6d087f7ec4166bbe716375a402a (diff) | |
download | libxml2-50355f00411e8e8ba5c547c674470b2cdf2e8da3.tar.gz |
applied another patch from Kasimier Buchcik for Schema Component
* xmlschemas.c include/libxml/xmlerror.h: applied another patch
from Kasimier Buchcik for Schema Component Constraints
* test/schemas/* result/schemas/*: added the regression tests
Daniel
Diffstat (limited to 'xmlschemas.c')
-rw-r--r-- | xmlschemas.c | 290 |
1 files changed, 240 insertions, 50 deletions
diff --git a/xmlschemas.c b/xmlschemas.c index e810e9ab..30dba1f7 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -5360,6 +5360,16 @@ xmlSchemaBuildAttributeUsesOwned(xmlSchemaParserCtxtPtr ctxt, return (0); } +/** + * xmlSchemaCloneWildcardNsConstraints: + * @ctxt: the schema parser context + * @dest: the destination wildcard + * @source: the source wildcard + * + * Clones the namespace constraints of source + * and assignes them to dest. + * Returns -1 on internal error, 0 otherwise. + */ static int xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr *dest, @@ -5396,6 +5406,17 @@ xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, return(0); } +/** + * xmlSchemaUnionWildcards: + * @ctxt: the schema parser context + * @completeWild: the first wildcard + * @curWild: the second wildcard + * + * Unions the namespace constraints of the given wildcards. + * @completeWild will hold the resulting union. + * Returns a positive error code on failure, -1 in case of an + * internal error, 0 otherwise. + */ static int xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr completeWild, @@ -5444,7 +5465,7 @@ xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, /* * 2 If either O1 or O2 is any, then any must be the value */ - if ((completeWild->any != curWild->any) && (completeWild->any)) { + if (completeWild->any != curWild->any) { if (completeWild->any == 0) { completeWild->any = 1; if (completeWild->nsSet != NULL) { @@ -5456,6 +5477,7 @@ xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, completeWild->negNsSet = NULL; } } + return (0); } /* * 3 If both O1 and O2 are sets of (namespace names or ·absent·), @@ -5498,6 +5520,8 @@ xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, (curWild->negNsSet != NULL) && (completeWild->negNsSet->value != curWild->negNsSet->value)) { completeWild->negNsSet->value = NULL; + + return(0); } /* * 5. @@ -5568,7 +5592,7 @@ xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, "The union of the wilcard is not expressible\n", NULL, NULL); - return(0); + return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); } else if ((!nsFound) && (!absentFound)) { /* * 5.4 If the set S does not include either the negated namespace @@ -5642,6 +5666,17 @@ xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, } +/** + * xmlSchemaIntersectWildcards: + * @ctxt: the schema parser context + * @completeWild: the first wildcard + * @curWild: the second wildcard + * + * Intersects the namespace constraints of the given wildcards. + * @completeWild will hold the resulting intersection. + * Returns a positive error code on failure, -1 in case of an + * internal error, 0 otherwise. + */ static int xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr completeWild, @@ -5794,7 +5829,7 @@ xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, "The intersection of the wilcard is not expressible\n", NULL, NULL); - return(0); + return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); } /* * 6 If the one is a negation of a namespace name and the other @@ -5809,11 +5844,96 @@ xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, return(0); } +/** + * xmlSchemaIsWildcardNsConstraintSubset: + * @ctxt: the schema parser context + * @wildA: the first wildcard + * @wildB: the second wildcard + * + * Returns 1 if the namespace constraint of @wildA is an intensional + * subset of @wildB, 0 otherwise. + */ +static int +xmlSchemaIsWildcardNsConstraintSubset( + xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, + xmlSchemaWildcardPtr wildA, + xmlSchemaWildcardPtr wildB) +{ -static xmlSchemaWildcardPtr -xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, - xmlSchemaAttributePtr attrs, - xmlSchemaWildcardPtr completeWild) + /* + * Schema Component Constraint: Wildcard Subset + */ + /* + * 1 super must be any. + */ + if (wildB->any) + return (1); + /* + * 2.1 sub must be a pair of not and a namespace name or ·absent·. + * 2.2 super must be a pair of not and the same value. + */ + if ((wildA->negNsSet != NULL) && + (wildB->negNsSet != NULL) && + (wildA->negNsSet->value == wildA->negNsSet->value)) + return (1); + /* + * 3.1 sub must be a set whose members are either namespace names or ·absent·. + */ + if (wildA->nsSet != NULL) { + /* + * 3.2.1 super must be the same set or a superset thereof. + */ + if (wildB->nsSet != NULL) { + xmlSchemaWildcardNsPtr cur, curB; + int found = 0; + + cur = wildA->nsSet; + while (cur != NULL) { + found = 0; + curB = wildB->nsSet; + while (curB != NULL) { + if (cur->value == curB->value) { + found = 1; + break; + } + curB = curB->next; + } + if (!found) + return (0); + cur = cur->next; + } + if (found) + return (1); + } else if (wildB->negNsSet != NULL) { + xmlSchemaWildcardNsPtr cur; + /* + * 3.2.2 super must be a pair of not and a namespace name or + * ·absent· and that value must not be in sub's set. + */ + cur = wildA->nsSet; + while (cur != NULL) { + if (cur->value == wildB->negNsSet->value) + return (0); + cur = cur->next; + } + return (1); + } + } + return (0); +} + +/** + * xmlSchemaBuildCompleteAttributeWildcard: + * @ctxt: the schema parser context + * @attrs: the attribute list + * @completeWild: the resulting complete wildcard + * + * Returns -1 in case of an internal error, 0 otherwise. + */ +static int +xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, + xmlSchemaAttributePtr attrs, + xmlSchemaWildcardPtr *completeWild) { while (attrs != NULL) { if (attrs->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { @@ -5822,44 +5942,39 @@ xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, group = (xmlSchemaAttributeGroupPtr) attrs; if ((group->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { if (group->attributes != NULL) { - if (group->attributeWildcard != NULL) - xmlSchemaBuildCompleteAttributeWildcard(ctxt, - group->attributes, group->attributeWildcard); - else - group->attributeWildcard = - xmlSchemaBuildCompleteAttributeWildcard(ctxt, - group->attributes, group->attributeWildcard); + if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, + group->attributes, &group->attributeWildcard) == -1) + return (-1); } group->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; } if (group->attributeWildcard != NULL) { - if (completeWild == NULL) { + if (*completeWild == NULL) { /* * Copy the first encountered wildcard as context, except for the annotation. */ - completeWild = xmlSchemaAddWildcard(ctxt); - completeWild->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; - if (!xmlSchemaCloneWildcardNsConstraints(ctxt, - &completeWild, group->attributeWildcard)) - return(NULL); - completeWild->processContents = group->attributeWildcard->processContents; + *completeWild = xmlSchemaAddWildcard(ctxt); + (*completeWild)->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; + 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. */ - completeWild->node = group->attributeWildcard->node; - return(completeWild); - } - if (xmlSchemaIntersectWildcards(ctxt, completeWild, group->attributeWildcard) == -1) { - xmlSchemaFreeWildcard(completeWild); - return(NULL); + (*completeWild)->node = group->attributeWildcard->node; + + } else if (xmlSchemaIntersectWildcards(ctxt, *completeWild, group->attributeWildcard) == -1) { + xmlSchemaFreeWildcard(*completeWild); + return (-1); } } } attrs = attrs->next; } - return (completeWild); + return (0); } /** @@ -5911,7 +6026,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr xmlSchemaAttributeLinkPtr cur, base, tmp, id = NULL, prev = NULL, uses = NULL, lastUse = NULL, lastBaseUse = NULL; xmlSchemaAttributePtr attrs; - int baseIsAnyType = 0; + int baseIsAnyType = 0; /* * Complex Type Definition with complex content Schema Component. @@ -5927,6 +6042,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr } if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) || (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) { + /* * Inherit the attribute uses of the base type. */ @@ -5966,11 +6082,16 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr attrs = type->subtypes->subtypes->attributes; /* * Handle attribute wildcards. - */ - type->attributeWildcard = - xmlSchemaBuildCompleteAttributeWildcard(ctxt, - attrs, - type->subtypes->subtypes->attributeWildcard); + */ + type->attributeWildcard = type->subtypes->subtypes->attributeWildcard; + + if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, + attrs, &type->attributeWildcard) == -1) { + if ((type->attributeWildcard != NULL) && + (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) + type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; + return (-1); + } if ((type->attributeWildcard != NULL) && (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; @@ -5992,6 +6113,65 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr type->attributeWildcard = baseType->attributeWildcard; } } + if (!baseIsAnyType) { + if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) { + if (type->attributeWildcard != NULL) { + /* + * Derivation Valid (Restriction, Complex) + * 4.1 The {base type definition} must also have one. + */ + if (baseType->attributeWildcard == NULL) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, + "The derived type \"%s\" has an attribute wildcard, " + "but the base type \"%s\" does not have one.\n", + type->name, baseType->name); + return (1); + } else if (xmlSchemaIsWildcardNsConstraintSubset(ctxt, + type->attributeWildcard, baseType->attributeWildcard) == 0) { + /* 4.2 */ + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, + "The wildcard in the derived type \"%s\" is not a valid " + "subset of the one in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + /* 4.3 Unless the {base type definition} is the ·ur-type + * definition·, the complex type definition's {attribute + * wildcard}'s {process contents} must be identical to or + * stronger than the {base type definition}'s {attribute + * wildcard}'s {process contents}, where strict is stronger + * than lax is stronger than skip. + */ + if (type->attributeWildcard->processContents < + baseType->attributeWildcard->processContents) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, + "The process contents of the wildcard in the " + "derived type \"%s\" is weaker than " + "that in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + } + } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { + /* + * Derivation Valid (Extension) + * At this point the type and the base have both, either + * no wildcard or a wildcard. + */ + if ((baseType->attributeWildcard != NULL) && + (baseType->attributeWildcard != type->attributeWildcard)) { + /* 1.3 */ + if (xmlSchemaIsWildcardNsConstraintSubset(ctxt, + baseType->attributeWildcard, type->attributeWildcard) == 0) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_COS_CT_EXTENDS_1_3, + "The wildcard in the derived type \"%s\" is not a valid " + "superset of the one in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + } + } + } } else { /* * Although the complexType is implicitely derived by "restriction" @@ -5999,9 +6179,18 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr */ baseType = NULL; attrs = type->attributes; - if (attrs != NULL) - type->attributeWildcard = - xmlSchemaBuildCompleteAttributeWildcard(ctxt, attrs, type->attributeWildcard); + if (attrs != NULL) { + if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, + attrs, &type->attributeWildcard) == -1) { + if ((type->attributeWildcard != NULL) && + (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) + type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; + return (-1); + } + if ((type->attributeWildcard != NULL) && + ((type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD) == 0)) + type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; + } } /* * Gather attribute uses defined by this type. @@ -6089,6 +6278,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr } /* * TODO: derivation-ok-restriction 2.1.2 ({type definition} must be validly derived) + * TODO: derivation-ok-restriction 2.1.3 */ break; } @@ -6152,13 +6342,13 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr type->attributeUses = uses; } else lastBaseUse->next = uses; - } + } } else { /* - * Derive implicitely from the ur-type. - */ + * Derive implicitely from the ur-type. + */ type->attributeUses = uses; -} + } /* * 3.4.6 -> Complex Type Definition Properties Correct */ @@ -6169,10 +6359,10 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr /* * 4. Two distinct attribute declarations in the {attribute uses} must * not have identical {name}s and {target namespace}s. - * + * * Note that this was already done for "restriction" and types derived from * the ur-type. - */ + */ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { tmp = cur->next; while (tmp != NULL) { @@ -6184,11 +6374,11 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_4, "ct-props-correct.4: Duplicate attribute use with the name \"%s\" specified\n", xmlSchemaGetOnymousAttrName(cur->attr), NULL); - break; - } + break; + } tmp = tmp->next; - } - } + } + } /* * 5. Two distinct attribute declarations in the {attribute uses} must * not have {type definition}s which are or are derived from ID. @@ -6205,7 +6395,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr "\"%s\" and \"%s\" have types which derived from ID\n", xmlSchemaGetOnymousAttrName(id->attr), xmlSchemaGetOnymousAttrName(cur->attr)); - } + } id = cur; } /* @@ -6220,7 +6410,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr else prev->next = cur->next; cur = cur->next; - xmlFree(tmp); + xmlFree(tmp); } else { prev = cur; cur = cur->next; @@ -8431,7 +8621,7 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche printf("found\n"); #endif found = 1; - ctxt->cur = (xmlNodePtr) attr; + ctxt->cur = (xmlNodePtr) attr; if (attrDecl->subtypes == NULL) { curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED; |