private void LoadExternals(XmlSchema schema, XmlSchemaCollection xsc) {
if (schema.IsProcessing) {
return;
}
schema.IsProcessing = true;
foreach(XmlSchemaExternal include in schema.Includes) {
Uri includeLocation = null;
//CASE 1: If the Schema object of the include has been set
if (include.Schema != null) {
// already loaded
if (include is XmlSchemaImport && ((XmlSchemaImport)include).Namespace == XmlReservedNs.NsXml) {
buildinIncluded = true;
}
else {
includeLocation = include.BaseUri;
if (includeLocation != null && schemaLocations[includeLocation] == null) {
schemaLocations.Add(includeLocation, includeLocation);
}
LoadExternals(include.Schema, xsc);
}
continue;
}
//CASE 2: If the include has been already added to the schema collection directly
if (xsc != null && include is XmlSchemaImport) { //Added for SchemaCollection compatibility
XmlSchemaImport import = (XmlSchemaImport)include;
string importNS = import.Namespace != null ? import.Namespace : string.Empty;
include.Schema = xsc[importNS]; //Fetch it from the collection
if (include.Schema != null) {
include.Schema = include.Schema.Clone();
if (include.Schema.BaseUri != null && schemaLocations[include.Schema.BaseUri] == null) {
schemaLocations.Add(include.Schema.BaseUri, include.Schema.BaseUri);
}
//To avoid re-including components that were already included through a different path
Uri subUri = null;
foreach (XmlSchemaExternal subInc in include.Schema.Includes) {
if (subInc is XmlSchemaImport) {
XmlSchemaImport subImp = (XmlSchemaImport)subInc;
subUri = subImp.BaseUri != null ? subImp.BaseUri : (subImp.Schema != null && subImp.Schema.BaseUri != null ? subImp.Schema.BaseUri : null);
if (subUri != null) {
if(schemaLocations[subUri] != null) {
subImp.Schema = null; //So that the components are not included again
}
else { //if its not there already, add it
schemaLocations.Add(subUri, subUri); //The schema for that location is available
}
}
}
}
continue;
}
}
//CASE 3: If the imported namespace is the XML namespace, load built-in schema
if (include is XmlSchemaImport && ((XmlSchemaImport)include).Namespace == XmlReservedNs.NsXml) {
if (!buildinIncluded) {
buildinIncluded = true;
include.Schema = Preprocessor.GetBuildInSchema();
}
continue;
}
//CASE4: Parse schema from the provided location
string schemaLocation = include.SchemaLocation;
if (schemaLocation == null) {
continue;
}
Uri ruri = ResolveSchemaLocationUri(schema, schemaLocation);
if (ruri != null && schemaLocations[ruri] == null) {
Stream stream = GetSchemaEntity(ruri);
if (stream != null) {
include.BaseUri = ruri;
schemaLocations.Add(ruri, ruri);
XmlTextReader reader = new XmlTextReader(ruri.ToString(), stream, NameTable);
reader.XmlResolver = xmlResolver;
try {
Parser parser = new Parser(SchemaType.XSD, NameTable, SchemaNames, EventHandler);
parser.Parse(reader, null);
while(reader.Read());// wellformness check
include.Schema = parser.XmlSchema;
LoadExternals(include.Schema, xsc);
}
catch(XmlSchemaException e) {
SendValidationEventNoThrow(new XmlSchemaException(Res.Sch_CannotLoadSchema, new string[] {schemaLocation, e.Message}, e.SourceUri, e.LineNumber, e.LinePosition), XmlSeverityType.Error);
}
catch(Exception) {
SendValidationEvent(Res.Sch_InvalidIncludeLocation, include, XmlSeverityType.Warning);
}
finally {
reader.Close();
}
}
else {
SendValidationEvent(Res.Sch_InvalidIncludeLocation, include, XmlSeverityType.Warning);
}
}
}
schema.IsProcessing = false;
}