private void CompileLocalAttributes(XmlSchemaComplexType baseType, XmlSchemaComplexType derivedType, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlSchemaDerivationMethod derivedBy) {
XmlSchemaAnyAttribute baseAttributeWildcard = baseType != null ? baseType.AttributeWildcard : null;
foreach (XmlSchemaObject obj in attributes) {
if (obj is XmlSchemaAttribute) {
XmlSchemaAttribute attribute = (XmlSchemaAttribute)obj;
if (attribute.Use != XmlSchemaUse.Prohibited) {
CompileAttribute(attribute);
}
if (attribute.Use != XmlSchemaUse.Prohibited ||
(attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
}
else {
SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
}
}
else {
SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
}
}
else { // is XmlSchemaAttributeGroupRef
XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)this.schema.AttributeGroups[attributeGroupRef.RefName];
if (attributeGroup != null) {
CompileAttributeGroup(attributeGroup);
foreach (XmlSchemaAttribute attribute in attributeGroup.AttributeUses.Values) {
if (attribute.Use != XmlSchemaUse.Prohibited ||
(attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
}
else {
SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attributeGroupRef);
}
}
else {
SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
}
}
anyAttribute = CompileAnyAttributeIntersection(anyAttribute, attributeGroup.AttributeWildcard);
}
else {
SendValidationEvent(Res.Sch_UndefAttributeGroupRef, attributeGroupRef.RefName.ToString(), attributeGroupRef);
}
}
}
// check derivation rules
if (baseType != null) {
if (derivedBy == XmlSchemaDerivationMethod.Extension) {
derivedType.SetAttributeWildcard(CompileAnyAttributeUnion(anyAttribute, baseAttributeWildcard));
foreach(XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
if (attribute != null) {
Debug.Assert(attribute.Use != XmlSchemaUse.Prohibited);
if (attribute.AttributeSchemaType != attributeBase.AttributeSchemaType || attributeBase.Use == XmlSchemaUse.Prohibited) {
SendValidationEvent(Res.Sch_InvalidAttributeExtension, attribute);
}
}
else {
derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
}
}
}
else { // derivedBy == XmlSchemaDerivationMethod.Restriction
// Schema Component Constraint: Derivation Valid (Restriction, Complex)
if ((anyAttribute != null) && (baseAttributeWildcard == null || !XmlSchemaAnyAttribute.IsSubset(anyAttribute, baseAttributeWildcard))) {
SendValidationEvent(Res.Sch_InvalidAnyAttributeRestriction, derivedType);
}
else {
derivedType.SetAttributeWildcard(anyAttribute); //complete wildcard
}
// Add form the base
foreach(XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
if (attribute == null) {
derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
}
else {
if (attributeBase.Use == XmlSchemaUse.Prohibited && attribute.Use != XmlSchemaUse.Prohibited) {
#if DEBUG
string position = string.Empty;
if (derivedType.SourceUri != null) {
position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
}
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
#endif
SendValidationEvent(Res.Sch_AttributeRestrictionProhibited, attribute);
}
else if (attribute.Use == XmlSchemaUse.Prohibited) {
continue;
}
else if (attributeBase.AttributeSchemaType == null || attribute.AttributeSchemaType == null || !XmlSchemaType.IsDerivedFrom(attribute.AttributeSchemaType, attributeBase.AttributeSchemaType, XmlSchemaDerivationMethod.Empty)) {
SendValidationEvent(Res.Sch_AttributeRestrictionInvalid, attribute);
}
}
}
// Check additional ones are valid restriction of base's wildcard
foreach(XmlSchemaAttribute attribute in derivedType.AttributeUses.Values) {
XmlSchemaAttribute attributeBase = (XmlSchemaAttribute)baseType.AttributeUses[attribute.QualifiedName];
if (attributeBase != null) {
continue;
}
if (baseAttributeWildcard == null || !baseAttributeWildcard.Allows(attribute.QualifiedName)) {
#if DEBUG
string position = string.Empty;
if (derivedType.SourceUri != null) {
position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
}
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
#endif
SendValidationEvent(Res.Sch_AttributeRestrictionInvalidFromWildcard, attribute);
}
}
}
}
else {
derivedType.SetAttributeWildcard(anyAttribute);
}
}