in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/SchemaCollectionCompiler.cs [2258:2425]
private void CompileElement(XmlSchemaElement xe)
{
if (xe.IsProcessing)
{
SendValidationEvent(ResXml.Sch_ElementCircularRef, xe);
return;
}
if (xe.ElementDecl != null)
{
return;
}
xe.IsProcessing = true;
SchemaElementDecl decl = null;
try
{
if (!xe.RefName.IsEmpty)
{
XmlSchemaElement e = (XmlSchemaElement)_schema.Elements[xe.RefName];
if (e == null)
{
throw new XmlSchemaException(ResXml.Sch_UndeclaredElement, xe.RefName.ToString(), xe);
}
CompileElement(e);
if (e.ElementDecl == null)
{
throw new XmlSchemaException(ResXml.Sch_RefInvalidElement, xe.RefName.ToString(), xe);
}
xe.SetElementType(e.ElementSchemaType);
decl = e.ElementDecl.Clone();
}
else
{
if (xe.SchemaType != null)
{
xe.SetElementType(xe.SchemaType);
}
else if (!xe.SchemaTypeName.IsEmpty)
{
xe.SetElementType(GetAnySchemaType(xe.SchemaTypeName));
if (xe.ElementSchemaType == null)
{
throw new XmlSchemaException(ResXml.Sch_UndeclaredType, xe.SchemaTypeName.ToString(), xe);
}
}
else if (!xe.SubstitutionGroup.IsEmpty)
{
XmlSchemaElement examplar = (XmlSchemaElement)_schema.Elements[xe.SubstitutionGroup];
if (examplar == null)
{
throw new XmlSchemaException(ResXml.Sch_UndeclaredEquivClass, xe.SubstitutionGroup.Name.ToString(), xe);
}
if (examplar.IsProcessing)
{ //Circular subst group; already detected by now
return;
}
CompileElement(examplar);
if (examplar.ElementDecl == null)
{ //If head is invalid, fall back to AnyType
xe.SetElementType(XmlSchemaComplexType.AnyType);
decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
}
else
{
xe.SetElementType(examplar.ElementSchemaType);
decl = examplar.ElementDecl.Clone();
}
}
else
{
xe.SetElementType(XmlSchemaComplexType.AnyType);
decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
}
if (decl == null)
{
Debug.Assert(xe.ElementSchemaType != null);
if (xe.ElementSchemaType is XmlSchemaComplexType)
{
XmlSchemaComplexType complexType = (XmlSchemaComplexType)xe.ElementSchemaType;
CompileComplexType(complexType);
if (complexType.ElementDecl != null)
{
decl = complexType.ElementDecl.Clone();
// decl.LocalElements = complexType.LocalElementDecls;
}
}
else if (xe.ElementSchemaType is XmlSchemaSimpleType)
{
XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)xe.ElementSchemaType;
CompileSimpleType(simpleType);
if (simpleType.ElementDecl != null)
{
decl = simpleType.ElementDecl.Clone();
}
}
}
decl.Name = xe.QualifiedName;
decl.IsAbstract = xe.IsAbstract;
XmlSchemaComplexType ct = xe.ElementSchemaType as XmlSchemaComplexType;
if (ct != null)
{
decl.IsAbstract |= ct.IsAbstract;
}
decl.IsNillable = xe.IsNillable;
decl.Block |= xe.BlockResolved;
}
if (decl.Datatype != null)
{
decl.Datatype.VerifySchemaValid(_schema.Notations, xe);
}
if (xe.DefaultValue != null || xe.FixedValue != null)
{
if (decl.ContentValidator != null)
{
if (decl.ContentValidator.ContentType == XmlSchemaContentType.TextOnly)
{
if (xe.DefaultValue != null)
{
decl.Presence = SchemaDeclBase.Use.Default;
decl.DefaultValueRaw = xe.DefaultValue;
}
else
{
decl.Presence = SchemaDeclBase.Use.Fixed;
decl.DefaultValueRaw = xe.FixedValue;
}
if (decl.Datatype != null)
{
decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xe), true);
}
}
else if (decl.ContentValidator.ContentType != XmlSchemaContentType.Mixed || !decl.ContentValidator.IsEmptiable)
{
throw new XmlSchemaException(ResXml.Sch_ElementCannotHaveValue, xe);
}
}
}
if (xe.HasConstraints)
{
XmlSchemaObjectCollection constraints = xe.Constraints;
CompiledIdentityConstraint[] compiledConstraints = new CompiledIdentityConstraint[constraints.Count];
int idx = 0;
for (int i = 0; i < constraints.Count; ++i)
{
XmlSchemaIdentityConstraint constraint = (XmlSchemaIdentityConstraint)constraints[i];
CompileIdentityConstraint(constraint);
compiledConstraints[idx++] = constraint.CompiledConstraint;
}
decl.Constraints = compiledConstraints;
}
decl.SchemaElement = xe; //So this is available for PSVI
xe.ElementDecl = decl;
}
catch (XmlSchemaException e)
{
if (e.SourceSchemaObject == null)
{
e.SetSource(xe);
}
SendValidationEvent(e);
xe.ElementDecl = SchemaElementDecl.Empty;
}
finally
{
xe.IsProcessing = false;
}
}