private void CheckParticleDerivation(XmlSchemaComplexType complexType) {
XmlSchemaComplexType baseType = complexType.BaseXmlSchemaType as XmlSchemaComplexType;
restrictionErrorMsg = null;
if (baseType != null && baseType != XmlSchemaComplexType.AnyType && complexType.DerivedBy == XmlSchemaDerivationMethod.Restriction) {
XmlSchemaParticle derivedParticle = CannonicalizePointlessRoot(complexType.ContentTypeParticle);
XmlSchemaParticle baseParticle = CannonicalizePointlessRoot(baseType.ContentTypeParticle);
if (!IsValidRestriction(derivedParticle, baseParticle)) {
#if DEBUG
if(complexType.ContentTypeParticle != null && baseType.ContentTypeParticle != null) {
string position = string.Empty;
if (complexType.SourceUri != null) {
position = " in " + complexType.SourceUri + "(" + complexType.LineNumber + ", " + complexType.LinePosition + ")";
}
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType content restriction" + position);
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpContentModel(baseType.ContentTypeParticle));
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpContentModel(complexType.ContentTypeParticle));
}
#endif
if (restrictionErrorMsg != null) {
SendValidationEvent(Res.Sch_InvalidParticleRestrictionDetailed, restrictionErrorMsg, complexType);
}
else {
SendValidationEvent(Res.Sch_InvalidParticleRestriction, complexType);
}
}
}
else if (baseType == XmlSchemaComplexType.AnyType) { //The complex type itself is not explicitly derived by restriction but it could have local elements which have anonymous types that are derived by restriction
foreach(XmlSchemaElement localElement in complexType.LocalElements.Values) {
if (localElement.IsLocalTypeDerivationChecked) { //Element already checked
continue;
}
XmlSchemaComplexType localComplexType = localElement.ElementSchemaType as XmlSchemaComplexType;
if (localComplexType != null && localElement.SchemaTypeName == XmlQualifiedName.Empty && localElement.RefName == XmlQualifiedName.Empty) { //Only local elements
localElement.IsLocalTypeDerivationChecked = true; //Not clearing this flag after recursion to make sure this check is not repeated for multiple references of the same local element (through group refs)
CheckParticleDerivation(localComplexType);
}
}
}
}