+ // AnyType derives from AnyType itself.\r
+ if (this == XmlSchemaComplexType.AnyType && BaseSchemaType == this)\r
+ return;\r
+\r
+ XmlSchemaType bst = b as XmlSchemaType;\r
+ if (b == this) // 1 and 2.1\r
+ return;\r
+ if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1\r
+ error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");\r
+ if (BaseSchemaType == b) // 2.2\r
+ return;\r
+ if (BaseSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1\r
+ error (h, "Derived type's base schema type is anyType.");\r
+ return;\r
+ }\r
+ // 2.3.2.1\r
+ XmlSchemaComplexType dbct = BaseSchemaType as XmlSchemaComplexType;\r
+ if (dbct != null) {\r
+ dbct.ValidateTypeDerivationOK (b, h, schema);\r
+ return;\r
+ }\r
+ // 2.3.2.2\r
+ XmlSchemaSimpleType dbst = BaseSchemaType as XmlSchemaSimpleType;\r
+ if (dbst != null) {\r
+ dbst.ValidateTypeDerivationOK (b, h, schema, true);\r
+ return;\r
+ }\r
+ }\r
+\r
+ // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)\r
+ internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,\r
+ ValidationEventHandler h, XmlSchema schema)\r
+ {\r
+ // 1.1\r
+ if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
+ error (h, "Derivation by extension is prohibited.");\r
+ // 1.2\r
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
+ XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;\r
+ XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;\r
+ if (da == null)\r
+ error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");\r
+ // TODO: How to evaluate "equal" type ...?\r
+ }\r
+ // 1.3 -> 3.10.6 Wildcard Subset.\r
+ if (AnyAttribute != null) {\r
+ if (baseComplexType.AnyAttribute == null)\r
+ error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");\r
+ else\r
+ baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);\r
+ }\r
+\r
+ // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).\r
+ // 1.4.2.1\r
+// if (contentTypeParticle == null)\r
+// error (h, "Extended complex type's content type must not be empty.");\r
+ // 1.4.2.2.1\r
+ if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {\r
+ // 1.4.2.2.2.1\r
+ if (this.GetContentType () != baseComplexType.GetContentType ())\r
+ error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");\r
+ // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)\r
+ else if (this.contentTypeParticle == null ||\r
+ !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {\r
+ XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;\r
+ if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))\r
+ error (h, "Invalid complex content extension was found.");\r
+ else {\r
+ // Identical sequence item should be checked, but\r
+ // I think it is naturally achieved as coded above.\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)\r
+ internal void ValidateSimpleBaseDerivationValidExtension (object baseType,\r
+ ValidationEventHandler h, XmlSchema schema)\r
+ {\r
+ XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;\r
+ if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
+ error (h, "Extension is prohibited by the base type.");\r
+\r
+ XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;\r
+ if (dt == null)\r
+ dt = st.Datatype;\r
+ if (dt != this.Datatype)\r
+ error (h, "To extend simple type, a complex type must have the same content type as the base type.");\r
+\r
+ /*\r
+ switch (resolvedContentType) {\r
+ case XmlSchemaContentType.Mixed:\r
+ case XmlSchemaContentType.TextOnly:\r
+ XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;\r
+ if ((st == null && Datatype != baseType) ||\r
+ (st != null && st.Datatype != Datatype))\r
+ goto case XmlSchemaContentType.ElementOnly;\r
+ if (st != null\r
+ && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
+ error (h, "Extension is prohibited by the base type.");\r
+ break;\r
+ case XmlSchemaContentType.ElementOnly:\r
+ case XmlSchemaContentType.Empty:\r
+ error (h, "To extend simple type, a complex type must have the same content type as the base type.");\r
+ break;\r
+ }\r
+ */\r
+ }\r
+\r
+ internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,\r
+ ValidationEventHandler h, XmlSchema schema)\r
+ {\r
+ // 1.\r
+ if (baseType == null) {\r
+ error (h, "Base schema type is not a complex type.");\r
+ return;\r
+ }\r
+ if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {\r
+ error (h, "Prohibited derivation by restriction by base schema type.");\r
+ return;\r
+ }\r
+\r
+ // 2.\r
+ foreach (DictionaryEntry entry in this.AttributeUses) {\r
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
+ XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;\r
+ if (baseAttr != null) {\r
+ // 2.1\r
+ // 2.1.1\r
+ if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)\r
+ error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
+ // 2.1.2\r
+ XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;\r
+ XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;\r
+ bool typeError = false;\r
+ if (attrSimpleType != null)\r
+ attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);\r
+ else if (attrSimpleType == null && baseAttrSimpleType != null)\r
+ typeError = true;\r
+ else {\r
+ Type t1 = attr.AttributeType.GetType ();\r
+ Type t2 = baseAttr.AttributeType.GetType ();\r
+ if (t1 != t2 && t1.IsSubclassOf (t2))\r
+ typeError = true;\r
+ }\r
+ if (typeError)\r
+ error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");\r
+ // 2.1.3\r
+ if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)\r
+ error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");\r
+ } else {\r
+ // 2.2\r
+ if (baseType.AttributeWildcard != null)\r
+ if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (\r
+ attr.QualifiedName.Namespace, schema) &&\r
+ !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))\r
+ error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
+ }\r
+ }\r
+ // I think 3. is considered in 2.\r
+ // 4.\r
+ if (this.AttributeWildcard != null) {\r
+ if (baseType.AttributeWildcard == null)\r
+ error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");\r
+ else\r
+ AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);\r
+ }\r
+\r
+ // 5.\r
+ if (contentTypeParticle == XmlSchemaParticle.Empty) {\r
+ // TODO: 5.1\r
+ // 5.2\r
+ if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&\r
+ !baseType.ContentTypeParticle.ValidateIsEmptiable ())\r
+ error (h, "Invalid content type derivation.");\r
+ } else {\r
+ // 5.3 => 3.9.6 Particle Valid (Restriction)\r
+ if (baseType.ContentTypeParticle != null) {\r
+ // 3.9.6 - 1 : same particle.\r
+ // 3.9.6 - 2 is covered by using ActualParticle.\r
+ if (!contentTypeParticle.ActualParticle.ParticleEquals (baseType.ContentTypeParticle.ActualParticle))\r
+ contentTypeParticle.ActualParticle.ValidateDerivationByRestriction (\r
+ baseType.ContentTypeParticle.ActualParticle, h, schema);\r
+ }\r
+ }\r
+ }\r
+\r
+#region Read\r
+ //<complexType\r
+ // abstract = boolean : false\r
+ // block = (#all | List of (extension | restriction)) \r
+ // final = (#all | List of (extension | restriction)) \r
+ // id = ID\r
+ // mixed = boolean : false\r
+ // name = NCName\r
+ // {any attributes with non-schema namespace . . .}>\r
+ // Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))\r
+ //</complexType>\r
+ internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)\r
+ {\r
+ XmlSchemaComplexType ctype = new XmlSchemaComplexType();\r
+ reader.MoveToElement();\r
+ Exception innerex;\r
+\r
+ if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
+ {\r
+ error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
+ reader.SkipToEnd();\r
+ return null;\r
+ }\r
+\r
+ ctype.LineNumber = reader.LineNumber;\r
+ ctype.LinePosition = reader.LinePosition;\r
+ ctype.SourceUri = reader.BaseURI;\r
+\r
+ while(reader.MoveToNextAttribute())\r
+ {\r
+ if(reader.Name == "abstract")\r
+ {\r
+ ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
+ if(innerex != null)\r
+ error(h,reader.Value + " is invalid value for abstract",innerex);\r
+ }\r
+ else if(reader.Name == "block")\r
+ {\r
+ ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",\r
+ XmlSchemaUtil.ComplexTypeBlockAllowed);\r
+ if(innerex != null)\r
+ warn(h,"some invalid values for block attribute were found",innerex);\r
+ }\r
+ else if(reader.Name == "final")\r
+ {\r
+ ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",\r
+ XmlSchemaUtil.FinalAllowed);\r
+ if(innerex != null)\r
+ warn(h,"some invalid values for final attribute were found",innerex);\r
+ }\r
+ else if(reader.Name == "id")\r
+ {\r
+ ctype.Id = reader.Value;\r
+ }\r
+ else if(reader.Name == "mixed")\r
+ {\r
+ ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
+ if(innerex != null)\r
+ error(h,reader.Value + " is invalid value for mixed",innerex);\r
+ }\r
+ else if(reader.Name == "name")\r
+ {\r
+ ctype.Name = reader.Value;\r
+ }\r
+ else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
+ {\r
+ error(h,reader.Name + " is not a valid attribute for complexType",null);\r
+ }\r
+ else\r
+ {\r
+ XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);\r
+ }\r
+ }\r
+ \r
+ reader.MoveToElement();\r
+ if(reader.IsEmptyElement)\r
+ return ctype;\r
+\r
+ //Content: 1. annotation?, \r
+ // 2. simpleContent | 2. complexContent | \r
+ // (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))\r
+ int level = 1;\r
+ while(reader.ReadNextElement())\r
+ {\r
+ if(reader.NodeType == XmlNodeType.EndElement)\r
+ {\r
+ if(reader.LocalName != xmlname)\r
+ error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
+ break;\r
+ }\r
+ if(level <= 1 && reader.LocalName == "annotation")\r
+ {\r
+ level = 2; //Only one annotation\r
+ XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
+ if(annotation != null)\r
+ ctype.Annotation = annotation;\r
+ continue;\r
+ }\r
+ if(level <=2)\r
+ {\r
+ if(reader.LocalName == "simpleContent")\r
+ {\r
+ level = 6;\r
+ XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);\r
+ if(simple != null)\r
+ ctype.ContentModel = simple;\r
+ continue;\r
+ }\r
+ if(reader.LocalName == "complexContent")\r
+ {\r
+ level = 6;\r
+ XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);\r
+ if(complex != null)\r
+ ctype.contentModel = complex;\r
+ continue;\r
+ }\r
+ }\r
+ if(level <= 3)\r
+ {\r
+ if(reader.LocalName == "group")\r
+ {\r
+ level = 4;\r
+ XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);\r
+ if(group != null)\r
+ ctype.particle = group;\r
+ continue;\r
+ }\r
+ if(reader.LocalName == "all")\r
+ {\r
+ level = 4;\r
+ XmlSchemaAll all = XmlSchemaAll.Read(reader,h);\r
+ if(all != null)\r
+ ctype.particle = all;\r
+ continue;\r
+ }\r
+ if(reader.LocalName == "choice")\r
+ {\r
+ level = 4;\r
+ XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);\r
+ if(choice != null)\r
+ ctype.particle = choice;\r
+ continue;\r
+ }\r
+ if(reader.LocalName == "sequence")\r
+ {\r
+ level = 4;\r
+ XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);\r
+ if(sequence != null)\r
+ ctype.particle = sequence;\r
+ continue;\r
+ }\r
+ }\r
+ if(level <= 4)\r
+ {\r
+ if(reader.LocalName == "attribute")\r
+ {\r
+ level = 4;\r
+ XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
+ if(attr != null)\r
+ ctype.Attributes.Add(attr);\r
+ continue;\r
+ }\r
+ if(reader.LocalName == "attributeGroup")\r
+ {\r
+ level = 4;\r
+ XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);\r
+ if(attr != null)\r
+ ctype.attributes.Add(attr);\r
+ continue;\r
+ }\r
+ }\r
+ if(level <= 5 && reader.LocalName == "anyAttribute")\r
+ {\r
+ level = 6;\r
+ XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);\r
+ if(anyattr != null)\r
+ ctype.AnyAttribute = anyattr;\r
+ continue;\r
+ }\r
+ reader.RaiseInvalidElementError();\r
+ }\r
+ return ctype;\r