private void CompileAttribute(XmlSchemaAttribute xa) {
if (xa.IsProcessing) {
SendValidationEvent(Res.Sch_AttributeCircularRef, xa);
return;
}
if (xa.AttDef != null) { //already compiled?
return;
}
xa.IsProcessing = true;
SchemaAttDef decl = null;
try {
if (!xa.RefName.IsEmpty) {
XmlSchemaAttribute a = (XmlSchemaAttribute)attributes[xa.RefName];
if (a == null) {
throw new XmlSchemaException(Res.Sch_UndeclaredAttribute, xa.RefName.ToString(), xa);
}
CompileAttribute(a);
if (a.AttDef == null) {
throw new XmlSchemaException(Res.Sch_RefInvalidAttribute, xa.RefName.ToString(), xa);
}
decl = a.AttDef.Clone();
XmlSchemaDatatype datatype = decl.Datatype;
if (datatype != null) {
if (a.FixedValue == null && a.DefaultValue == null) {
SetDefaultFixed(xa, decl);
}
else if (a.FixedValue != null) {
if (xa.DefaultValue != null) {
throw new XmlSchemaException(Res.Sch_FixedDefaultInRef, xa.RefName.ToString(), xa);
}
else if (xa.FixedValue != null ) {
object refFixedValue = datatype.ParseValue(xa.FixedValue, NameTable, new SchemaNamespaceManager(xa), true);
if ( !datatype.IsEqual(decl.DefaultValueTyped, refFixedValue)) {
throw new XmlSchemaException(Res.Sch_FixedInRef, xa.RefName.ToString(), xa);
}
}
}
}
xa.SetAttributeType(a.AttributeSchemaType);
}
else {
decl = new SchemaAttDef(xa.QualifiedName, xa.Prefix);
if (xa.SchemaType != null) {
CompileSimpleType(xa.SchemaType);
xa.SetAttributeType(xa.SchemaType);
decl.SchemaType = xa.SchemaType;
decl.Datatype = xa.SchemaType.Datatype;
}
else if (!xa.SchemaTypeName.IsEmpty) {
XmlSchemaSimpleType simpleType = GetSimpleType(xa.SchemaTypeName);
if (simpleType != null) {
xa.SetAttributeType(simpleType);
decl.Datatype = simpleType.Datatype;
decl.SchemaType = simpleType;
}
else {
throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, xa.SchemaTypeName.ToString(), xa);
}
}
else {
decl.SchemaType = DatatypeImplementation.AnySimpleType;
decl.Datatype = DatatypeImplementation.AnySimpleType.Datatype;
xa.SetAttributeType(DatatypeImplementation.AnySimpleType);
}
//} //Removed this here since the following should be done only if RefName is Empty
if (decl.Datatype != null) {
decl.Datatype.VerifySchemaValid(notations, xa);
}
SetDefaultFixed(xa, decl);
} //End of Else for !RefName.IsEmpty
decl.SchemaAttribute = xa; //So this is available for PSVI
xa.AttDef = decl;
}
catch (XmlSchemaException e) {
if (e.SourceSchemaObject == null) {
e.SetSource(xa);
}
SendValidationEvent(e);
xa.AttDef = SchemaAttDef.Empty;
}
finally {
xa.IsProcessing = false;
}
}