//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ namespace System.Web.Services.Description { using System; using System.Collections; using System.Collections.Specialized; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; internal class SchemaCompiler { static StringCollection warnings; internal static StringCollection Warnings { get { if (warnings == null) warnings = new StringCollection(); return warnings; } } internal static StringCollection Compile(XmlSchemas schemas) { AddImports(schemas); Warnings.Clear(); schemas.Compile(new ValidationEventHandler(ValidationCallbackWithErrorCode), true); return Warnings; } static void AddImport(XmlSchema schema, string ns) { if (schema.TargetNamespace == ns) return; foreach (XmlSchemaExternal ex in schema.Includes) { XmlSchemaImport import = ex as XmlSchemaImport; if (import != null && import.Namespace == ns) { return; } } XmlSchemaImport newImport = new XmlSchemaImport(); newImport.Namespace = ns; schema.Includes.Add(newImport); } static void AddImports(XmlSchemas schemas) { foreach (XmlSchema schema in schemas) { AddImport(schema, Soap.Encoding); AddImport(schema, ServiceDescription.Namespace); } } internal static string WarningDetails(XmlSchemaException exception, string message) { string details; XmlSchemaObject source = exception.SourceSchemaObject; if (exception.LineNumber == 0 && exception.LinePosition == 0) { details = GetSchemaItem(source, null, message); } else { string ns = null; if (source != null) { while (source.Parent != null) { source = source.Parent; } if (source is XmlSchema) { ns = ((XmlSchema)source).TargetNamespace; } } details = Res.GetString(Res.SchemaSyntaxErrorDetails, ns, message, exception.LineNumber, exception.LinePosition); } return details; } static string GetSchemaItem(XmlSchemaObject o, string ns, string details) { if (o == null) { return null; } while (o.Parent != null && !(o.Parent is XmlSchema)) { o = o.Parent; } if (ns == null || ns.Length == 0) { XmlSchemaObject tmp = o; while (tmp.Parent != null) { tmp = tmp.Parent; } if (tmp is XmlSchema) { ns = ((XmlSchema)tmp).TargetNamespace; } } string item = null; if (o is XmlSchemaNotation) { item = Res.GetString(Res.XmlSchemaNamedItem, ns, "notation", ((XmlSchemaNotation)o).Name, details); } else if (o is XmlSchemaGroup) { item = Res.GetString(Res.XmlSchemaNamedItem, ns, "group", ((XmlSchemaGroup)o).Name, details); } else if (o is XmlSchemaElement) { XmlSchemaElement e = ((XmlSchemaElement)o); if (e.Name == null || e.Name.Length == 0) { XmlQualifiedName parentName = GetParentName(o); // Element reference '{0}' declared in schema type '{1}' from namespace '{2}' item = Res.GetString(Res.XmlSchemaElementReference, e.RefName.ToString(), parentName.Name, parentName.Namespace); } else { item = Res.GetString(Res.XmlSchemaNamedItem, ns, "element", e.Name, details); } } else if (o is XmlSchemaType) { item = Res.GetString(Res.XmlSchemaNamedItem, ns, o.GetType() == typeof(XmlSchemaSimpleType) ? "simpleType" : "complexType", ((XmlSchemaType)o).Name, details); } else if (o is XmlSchemaAttributeGroup) { item = Res.GetString(Res.XmlSchemaNamedItem, ns, "attributeGroup", ((XmlSchemaAttributeGroup)o).Name, details); } else if (o is XmlSchemaAttribute) { XmlSchemaAttribute a = ((XmlSchemaAttribute)o); if (a.Name == null || a.Name.Length == 0) { XmlQualifiedName parentName = GetParentName(o); // Attribure reference '{0}' declared in schema type '{1}' from namespace '{2}' return Res.GetString(Res.XmlSchemaAttributeReference, a.RefName.ToString(), parentName.Name, parentName.Namespace); } else { item = Res.GetString(Res.XmlSchemaNamedItem, ns, "attribute", a.Name, details); } } else if (o is XmlSchemaContent) { XmlQualifiedName parentName = GetParentName(o); // Check content definition of schema type '{0}' from namespace '{1}'. {2} item = Res.GetString(Res.XmlSchemaContentDef, parentName.Name, parentName.Namespace, details); } else if (o is XmlSchemaExternal) { string itemType = o is XmlSchemaImport ? "import" : o is XmlSchemaInclude ? "include" : o is XmlSchemaRedefine ? "redefine" : o.GetType().Name; item = Res.GetString(Res.XmlSchemaItem, ns, itemType, details); } else if (o is XmlSchema) { item = Res.GetString(Res.XmlSchema, ns, details); } else { item = Res.GetString(Res.XmlSchemaNamedItem, ns, o.GetType().Name, null, details); } return item; } internal static XmlQualifiedName GetParentName(XmlSchemaObject item) { while (item.Parent != null) { if (item.Parent is XmlSchemaType) { XmlSchemaType type = (XmlSchemaType)item.Parent; if (type.Name != null && type.Name.Length != 0) { return type.QualifiedName; } } item = item.Parent; } return XmlQualifiedName.Empty; } private static void ValidationCallbackWithErrorCode (object sender, ValidationEventArgs args) { Warnings.Add(Res.GetString(args.Severity == XmlSeverityType.Error ? Res.SchemaValidationError : Res.SchemaValidationWarning, WarningDetails(args.Exception, args.Message))); } } }