in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/Preprocessor.cs [542:815]
private void Preprocess(XmlSchema schema, string targetNamespace, ArrayList imports)
{
XmlSchema prevRootSchemaForRedefine = null;
if (schema.IsProcessing)
{
return;
}
schema.IsProcessing = true;
string tns = schema.TargetNamespace;
if (tns != null)
{
schema.TargetNamespace = tns = NameTable.Add(tns);
if (tns.Length == 0)
{
SendValidationEvent(ResXml.Sch_InvalidTargetNamespaceAttribute, schema);
}
else
{
ParseUri(tns, ResXml.Sch_InvalidNamespace, schema);
}
}
if (schema.Version != null)
{
XmlSchemaDatatype tokenDt = DatatypeImplementation.GetSimpleTypeFromTypeCode(XmlTypeCode.Token).Datatype;
object version;
Exception exception = tokenDt.TryParseValue(schema.Version, null, null, out version);
if (exception != null)
{
SendValidationEvent(ResXml.Sch_AttributeValueDataTypeDetailed, new string[] { "version", schema.Version, tokenDt.TypeCodeString, exception.Message }, exception, schema);
}
else
{
schema.Version = (string)version;
}
}
//Begin processing the schema after checking targetNamespace and verifying chameleon
Cleanup(schema);
for (int i = 0; i < schema.Includes.Count; ++i)
{
XmlSchemaExternal include = (XmlSchemaExternal)schema.Includes[i];
XmlSchema externalSchema = include.Schema;
SetParent(include, schema);
PreprocessAnnotation(include);
string loc = include.SchemaLocation;
if (loc != null)
{
ParseUri(loc, ResXml.Sch_InvalidSchemaLocation, include);
}
else if ((include.Compositor == Compositor.Include || include.Compositor == Compositor.Redefine) && externalSchema == null)
{
SendValidationEvent(ResXml.Sch_MissRequiredAttribute, "schemaLocation", include);
}
switch (include.Compositor)
{
case Compositor.Import:
XmlSchemaImport import = include as XmlSchemaImport;
string importNS = import.Namespace;
if (importNS == schema.TargetNamespace)
{
SendValidationEvent(ResXml.Sch_ImportTargetNamespace, include);
}
if (externalSchema != null)
{
if (importNS != externalSchema.TargetNamespace)
{
SendValidationEvent(ResXml.Sch_MismatchTargetNamespaceImport, importNS, externalSchema.TargetNamespace, import);
}
//SetParent(externalSchema, import);
prevRootSchemaForRedefine = _rootSchemaForRedefine;
_rootSchemaForRedefine = externalSchema; //Make the imported schema the root schema for redefines
Preprocess(externalSchema, importNS, imports);
_rootSchemaForRedefine = prevRootSchemaForRedefine; //Reset the root schema for redefines
}
else
{
if (importNS != null)
{
if (importNS.Length == 0)
{
SendValidationEvent(ResXml.Sch_InvalidNamespaceAttribute, importNS, include);
}
else
{
ParseUri(importNS, ResXml.Sch_InvalidNamespace, include);
}
}
}
break;
case Compositor.Include:
XmlSchema includedSchema = include.Schema;
if (includedSchema != null)
{
//SetParent(includedSchema, include);
goto default;
}
break;
case Compositor.Redefine:
if (externalSchema != null)
{
//SetParent(externalSchema, include);
CleanupRedefine(include);
goto default;
}
break;
default: //For include, redefine common case
if (externalSchema.TargetNamespace != null)
{
if (schema.TargetNamespace != externalSchema.TargetNamespace)
{ //namespaces for includes should be the same
SendValidationEvent(ResXml.Sch_MismatchTargetNamespaceInclude, externalSchema.TargetNamespace, schema.TargetNamespace, include);
}
}
else if (targetNamespace != null && targetNamespace.Length != 0)
{ //Chameleon redefine
externalSchema = GetChameleonSchema(targetNamespace, externalSchema);
include.Schema = externalSchema; //Reset the schema property to the cloned schema
}
Preprocess(externalSchema, schema.TargetNamespace, imports);
break;
}
}
//Begin processing the current schema passed to preprocess
//Build the namespaces that can be referenced in the current schema
_currentSchema = schema;
BuildRefNamespaces(schema);
ValidateIdAttribute(schema);
_targetNamespace = targetNamespace == null ? string.Empty : targetNamespace;
SetSchemaDefaults(schema);
_processedExternals.Clear();
XmlSchemaExternal external;
for (int i = 0; i < schema.Includes.Count; i++)
{
external = (XmlSchemaExternal)schema.Includes[i];
XmlSchema includedSchema = external.Schema;
if (includedSchema != null)
{
switch (external.Compositor)
{
case Compositor.Include:
if (_processedExternals[includedSchema] != null)
{
continue; //Already processed this included schema; TODO Need to look at other option than using HashTable
}
_processedExternals.Add(includedSchema, external);
CopyIncludedComponents(includedSchema, schema);
break;
case Compositor.Redefine:
if (_redefinedList == null)
{
_redefinedList = new ArrayList();
}
_redefinedList.Add(new RedefineEntry(external as XmlSchemaRedefine, _rootSchemaForRedefine));
if (_processedExternals[includedSchema] != null)
{
continue; //Already processed this included schema; TODO Need to look at other option than using HashTable
}
_processedExternals.Add(includedSchema, external);
CopyIncludedComponents(includedSchema, schema);
break;
case Compositor.Import:
if (includedSchema != _rootSchema)
{
XmlSchemaImport import = external as XmlSchemaImport;
string importNS = import.Namespace != null ? import.Namespace : string.Empty;
if (!imports.Contains(includedSchema))
{ //TODO Change ImportedSchemas to Hashtable
imports.Add(includedSchema);
}
if (!_rootSchema.ImportedNamespaces.Contains(importNS))
{
_rootSchema.ImportedNamespaces.Add(importNS);
}
}
break;
default:
Debug.Assert(false);
break;
}
}
else if (external.Compositor == Compositor.Redefine)
{
XmlSchemaRedefine redefine = external as XmlSchemaRedefine;
if (redefine.BaseUri == null)
{
for (int j = 0; j < redefine.Items.Count; ++j)
{
if (!(redefine.Items[j] is XmlSchemaAnnotation))
{
SendValidationEvent(ResXml.Sch_RedefineNoSchema, redefine);
break;
}
}
}
}
ValidateIdAttribute(external);
}
List<XmlSchemaObject> removeItemsList = new List<XmlSchemaObject>();
XmlSchemaObjectCollection schemaItems = schema.Items;
for (int i = 0; i < schemaItems.Count; ++i)
{
SetParent(schemaItems[i], schema);
XmlSchemaAttribute attribute = schemaItems[i] as XmlSchemaAttribute;
if (attribute != null)
{
PreprocessAttribute(attribute);
AddToTable(schema.Attributes, attribute.QualifiedName, attribute);
}
else if (schemaItems[i] is XmlSchemaAttributeGroup)
{
XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)schemaItems[i];
PreprocessAttributeGroup(attributeGroup);
AddToTable(schema.AttributeGroups, attributeGroup.QualifiedName, attributeGroup);
}
else if (schemaItems[i] is XmlSchemaComplexType)
{
XmlSchemaComplexType complexType = (XmlSchemaComplexType)schemaItems[i];
PreprocessComplexType(complexType, false);
AddToTable(schema.SchemaTypes, complexType.QualifiedName, complexType);
}
else if (schemaItems[i] is XmlSchemaSimpleType)
{
XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)schemaItems[i];
PreprocessSimpleType(simpleType, false);
AddToTable(schema.SchemaTypes, simpleType.QualifiedName, simpleType);
}
else if (schemaItems[i] is XmlSchemaElement)
{
XmlSchemaElement element = (XmlSchemaElement)schemaItems[i];
PreprocessElement(element);
AddToTable(schema.Elements, element.QualifiedName, element);
}
else if (schemaItems[i] is XmlSchemaGroup)
{
XmlSchemaGroup group = (XmlSchemaGroup)schemaItems[i];
PreprocessGroup(group);
AddToTable(schema.Groups, group.QualifiedName, group);
}
else if (schemaItems[i] is XmlSchemaNotation)
{
XmlSchemaNotation notation = (XmlSchemaNotation)schemaItems[i];
PreprocessNotation(notation);
AddToTable(schema.Notations, notation.QualifiedName, notation);
}
else if (schemaItems[i] is XmlSchemaAnnotation)
{
PreprocessAnnotation(schemaItems[i] as XmlSchemaAnnotation);
}
else
{
SendValidationEvent(ResXml.Sch_InvalidCollection, (XmlSchemaObject)schemaItems[i]);
removeItemsList.Add(schemaItems[i]);
}
}
for (int i = 0; i < removeItemsList.Count; ++i)
{
schema.Items.Remove(removeItemsList[i]);
}
}