XmlSchemas.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / Serialization / XmlSchemas.cs / 1 / XmlSchemas.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Serialization { 

    using System.Collections; 
    using System.Collections.Generic;
    using System.IO;
    using System;
    using System.Globalization; 
    using System.ComponentModel;
    using System.Xml.Serialization; 
    using System.Xml.Schema; 
    using System.Diagnostics;
    using System.Threading; 
    using System.Security.Permissions;
    using System.Security.Policy;
    using System.Security;
    using System.Net; 

    ///  
    ///  
    /// 
    ///    [To be supplied.] 
    /// 
    public class XmlSchemas : CollectionBase, IEnumerable {
        XmlSchemaSet schemaSet;
        Hashtable references; 
        SchemaObjectCache cache; // cached schema top-level items
        bool shareTypes; 
        Hashtable mergedSchemas; 
        internal Hashtable delayedSchemas = new Hashtable();
        bool isCompiled = false; 
        static XmlSchema xsd;
        static XmlSchema xml;

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public XmlSchema this[int index] {
            get { return (XmlSchema)List[index]; } 
            set { List[index] = value; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public XmlSchema this[string ns] {
            get { 
                IList values = (IList)SchemaSet.Schemas(ns);
                if (values.Count == 0)
                    return null;
                if (values.Count == 1) 
                    return (XmlSchema)values[0];
 
                throw new InvalidOperationException(Res.GetString(Res.XmlSchemaDuplicateNamespace, ns)); 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public IList GetSchemas(string ns) { 
            return (IList)SchemaSet.Schemas(ns); 
        }
 
        internal SchemaObjectCache Cache {
            get {
                if (cache == null)
                    cache = new SchemaObjectCache(); 
                return cache;
            } 
        } 

        internal Hashtable MergedSchemas { 
            get {
                if (mergedSchemas == null)
                    mergedSchemas = new Hashtable();
                return mergedSchemas; 
            }
        } 
 
        internal Hashtable References {
            get { 
                if (references == null)
                    references = new Hashtable();
                return references;
            } 
        }
 
        internal XmlSchemaSet SchemaSet { 
            get {
                if (schemaSet == null) { 
                    schemaSet = new XmlSchemaSet();
                    schemaSet.XmlResolver = null;
                    schemaSet.ValidationEventHandler += new ValidationEventHandler(IgnoreCompileErrors);
                } 
                return schemaSet;
            } 
        } 
        internal int Add(XmlSchema schema, bool delay) {
            if (delay) { 
                if (delayedSchemas[schema] == null)
                    delayedSchemas.Add(schema, schema);
                return -1;
            } 
            else {
                return Add(schema); 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public int Add(XmlSchema schema) {
            if (List.Contains(schema)) 
                return List.IndexOf(schema); 
            return List.Add(schema);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public int Add(XmlSchema schema, Uri baseUri) { 
            if (List.Contains(schema)) 
                return List.IndexOf(schema);
            if (baseUri != null) 
                schema.BaseUri = baseUri;
            return List.Add(schema);
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public void Add(XmlSchemas schemas) { 
            foreach (XmlSchema schema in schemas) {
                Add(schema);
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public void AddReference(XmlSchema schema) {
            References[schema] = schema;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public void Insert(int index, XmlSchema schema) { 
            List.Insert(index, schema);
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public int IndexOf(XmlSchema schema) {
            return List.IndexOf(schema); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public bool Contains(XmlSchema schema) { 
            return List.Contains(schema);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public bool Contains(string targetNamespace) { 
            return SchemaSet.Contains(targetNamespace); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public void Remove(XmlSchema schema) {
            List.Remove(schema); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public void CopyTo(XmlSchema[] array, int index) { 
            List.CopyTo(array, index);
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        protected override void OnInsert(int index, object value) {
            AddName((XmlSchema)value); 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void OnRemove(int index, object value) {
            RemoveName((XmlSchema)value);
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        protected override void OnClear() {
            schemaSet = null;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        protected override void OnSet(int index, object oldValue, object newValue) { 
            RemoveName((XmlSchema)oldValue);
            AddName((XmlSchema)newValue);
        }
 
        void AddName(XmlSchema schema) {
            if (isCompiled) throw new InvalidOperationException(Res.GetString(Res.XmlSchemaCompiled)); 
            if (SchemaSet.Contains(schema)) 
                SchemaSet.Reprocess(schema);
            else { 
                Prepare(schema);
                SchemaSet.Add(schema);
            }
        } 

        void Prepare(XmlSchema schema) { 
            // need to remove illegal  externals; 
            ArrayList removes = new ArrayList();
            string ns = schema.TargetNamespace; 
            foreach (XmlSchemaExternal external in schema.Includes) {
                if (external is XmlSchemaImport) {
                    if (ns == ((XmlSchemaImport)external).Namespace) {
                        removes.Add(external); 
                    }
                } 
            } 
            foreach(XmlSchemaObject o in removes) {
                schema.Includes.Remove(o); 
            }
        }

        void RemoveName(XmlSchema schema) { 
            SchemaSet.Remove(schema);
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public object Find(XmlQualifiedName name, Type type) {
            return Find(name, type, true); 
        }
        internal object Find(XmlQualifiedName name, Type type, bool checkCache) { 
            if (!IsCompiled) { 
                 foreach (XmlSchema schema in List) {
                    Preprocess(schema); 
                }
            }
            IList values = (IList)SchemaSet.Schemas(name.Namespace);
            if (values == null) return null; 

            foreach (XmlSchema schema in values) { 
                Preprocess(schema); 

                XmlSchemaObject ret = null; 
                if (typeof(XmlSchemaType).IsAssignableFrom(type)) {
                    ret = schema.SchemaTypes[name];
                    if (ret == null || !type.IsAssignableFrom(ret.GetType())) {
                        continue; 
                    }
                } 
                else if (type == typeof(XmlSchemaGroup)) { 
                    ret = schema.Groups[name];
                } 
                else if (type == typeof(XmlSchemaAttributeGroup)) {
                    ret = schema.AttributeGroups[name];
                }
                else if (type == typeof(XmlSchemaElement)) { 
                    ret = schema.Elements[name];
                } 
                else if (type == typeof(XmlSchemaAttribute)) { 
                    ret = schema.Attributes[name];
                } 
                else if (type == typeof(XmlSchemaNotation)) {
                    ret = schema.Notations[name];
                }
#if DEBUG 
            else {
                // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe 
                throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "XmlSchemas.Find: Invalid object type " + type.FullName)); 
            }
#endif 

                if (ret != null && shareTypes && checkCache && !IsReference(ret))
                    ret = Cache.AddItem(ret, name, this);
                if (ret != null) { 
                    return ret;
                } 
            } 
            return null;
        } 

        IEnumerator IEnumerable.GetEnumerator() {
            return new XmlSchemaEnumerator(this);
        } 

        internal static void Preprocess(XmlSchema schema) { 
            if (!schema.IsPreprocessed) { 
                try {
                    XmlNameTable nameTable = new System.Xml.NameTable(); 
                    Preprocessor prep = new Preprocessor(nameTable, new SchemaNames(nameTable), null);
                    prep.SchemaLocations = new Hashtable();
                    prep.Execute(schema, schema.TargetNamespace, false);
                } 
                catch(XmlSchemaException e) {
                    throw CreateValidationException(e, e.Message); 
                } 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static bool IsDataSet(XmlSchema schema) { 
            foreach (XmlSchemaObject o in schema.Items) { 
                if (o is XmlSchemaElement) {
                    XmlSchemaElement e = (XmlSchemaElement)o; 
                    if (e.UnhandledAttributes != null) {
                        foreach (XmlAttribute a in e.UnhandledAttributes) {
                            if (a.LocalName == "IsDataSet" && a.NamespaceURI == "urn:schemas-microsoft-com:xml-msdata") {
                                // currently the msdata:IsDataSet uses its own format for the boolean values 
                                if (a.Value == "True" || a.Value == "true" || a.Value == "1") return true;
                            } 
                        } 
                    }
                } 
            }
            return false;
        }
 
        void Merge(XmlSchema schema) {
            if (MergedSchemas[schema] != null) 
                return; 
            IList originals = (IList)SchemaSet.Schemas(schema.TargetNamespace);
            if (originals != null && originals.Count > 0) { 
                MergedSchemas.Add(schema, schema);
                Merge(originals, schema);
            }
            else { 
                Add(schema);
                MergedSchemas.Add(schema, schema); 
            } 
        }
 
        void AddImport(IList schemas, string ns) {
            foreach(XmlSchema s in schemas) {
                bool add = true;
                foreach (XmlSchemaExternal external in s.Includes) { 
                    if (external is XmlSchemaImport && ((XmlSchemaImport)external).Namespace == ns) {
                        add = false; 
                        break; 
                    }
                } 
                if (add) {
                    XmlSchemaImport import = new XmlSchemaImport();
                    import.Namespace = ns;
                    s.Includes.Add(import); 
                }
            } 
        } 

        void Merge(IList originals, XmlSchema schema) { 
            foreach (XmlSchema s in originals) {
                if (schema == s) {
                    return;
                } 
            }
 
            foreach (XmlSchemaExternal external in schema.Includes) { 
                if (external is XmlSchemaImport) {
                    external.SchemaLocation = null; 
                    if (external.Schema != null) {
                        Merge(external.Schema);
                    }
                    else { 
                        AddImport(originals, ((XmlSchemaImport)external).Namespace);
                    } 
                } 
                else {
                    if (external.Schema == null) { 
                        // we do not process includes or redefines by the schemaLocation
                        if (external.SchemaLocation != null) {
                            throw new InvalidOperationException(Res.GetString(Res.XmlSchemaIncludeLocation, this.GetType().Name, external.SchemaLocation));
                        } 
                    }
                    else { 
                        external.SchemaLocation = null; 
                        Merge(originals, external.Schema);
                    } 
                }
            }

            // bring all included items to the parent schema; 
            bool[] matchedItems = new bool[schema.Items.Count];
            int count = 0; 
            for (int i = 0; i < schema.Items.Count; i++) { 
                XmlSchemaObject o  = schema.Items[i];
                XmlSchemaObject dest = Find(o, originals); 
                if (dest != null) {
                    if (!Cache.Match(dest, o, shareTypes)) {
                        //
                        Debug.WriteLineIf(DiagnosticsSwitches.XmlSerialization.TraceVerbose, "XmlSerialization::Failed to Merge " + MergeFailedMessage(o, dest, schema.TargetNamespace) 
                            + "' Plase Compare hash:\r\n" + Cache.looks[dest] + "\r\n" + Cache.looks[o]);
                        throw new InvalidOperationException(MergeFailedMessage(o, dest, schema.TargetNamespace)); 
                    } 
                    matchedItems[i] = true;
                    count++; 
                }
            }
            if (count != schema.Items.Count) {
                XmlSchema destination = (XmlSchema)originals[0]; 
                for (int i = 0; i < schema.Items.Count; i++) {
                    if (!matchedItems[i]) { 
                        destination.Items.Add(schema.Items[i]); 
                    }
                } 
                destination.IsPreprocessed = false;
                Preprocess(destination);
            }
        } 

        static string ItemName(XmlSchemaObject o) { 
            if (o is XmlSchemaNotation) { 
                return ((XmlSchemaNotation)o).Name;
            } 
            else if (o is XmlSchemaGroup) {
                return ((XmlSchemaGroup)o).Name;
            }
            else if (o is XmlSchemaElement) { 
                return ((XmlSchemaElement)o).Name;
            } 
            else if (o is XmlSchemaType) { 
                return ((XmlSchemaType)o).Name;
            } 
            else if (o is XmlSchemaAttributeGroup) {
                return ((XmlSchemaAttributeGroup)o).Name;
            }
            else if (o is XmlSchemaAttribute) { 
                return ((XmlSchemaAttribute)o).Name;
            } 
            return null; 
        }
 
        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;
        }
 
        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 = XmlSchemas.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, null); 
            }
            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 = XmlSchemas.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 = XmlSchemas.GetParentName(o); 
                // Check content definition of schema type '{0}' from namespace '{1}'. {2}
                item = Res.GetString(Res.XmlSchemaContentDef, parentName.Name, parentName.Namespace, null); 
            } 
            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;
        }

        static string Dump(XmlSchemaObject o) { 
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true; 
            settings.Indent = true; 
            XmlSerializer s = new XmlSerializer(o.GetType());
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); 
            XmlWriter xmlWriter = XmlWriter.Create(sw, settings);
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("xs", XmlSchema.Namespace);
            s.Serialize(xmlWriter, o, ns); 
            return sw.ToString();
        } 
        static string MergeFailedMessage(XmlSchemaObject src, XmlSchemaObject dest, string ns) { 
            string err = Res.GetString(Res.XmlSerializableMergeItem, ns, GetSchemaItem(src, ns, null));
            err += "\r\n" + Dump(src); 
            err += "\r\n" + Dump(dest);
            return err;
        }
 
        internal XmlSchemaObject Find(XmlSchemaObject o, IList originals) {
            string name = ItemName(o); 
            if (name == null) 
                return null;
 
            Type type = o.GetType();

            foreach (XmlSchema s in originals) {
                foreach(XmlSchemaObject item in s.Items) { 
                    if (item.GetType() == type && name == ItemName(item)) {
                        return item; 
                    } 
                }
            } 
            return null;
        }

        ///  
        public bool IsCompiled {
            get { return isCompiled; } 
        } 

        ///  
        public void Compile(ValidationEventHandler handler, bool fullCompile) {
            if (isCompiled)
                return;
 
            foreach(XmlSchema s in delayedSchemas.Values)
                Merge(s); 
            delayedSchemas.Clear(); 

            if (fullCompile) { 
                schemaSet = new XmlSchemaSet();
                schemaSet.XmlResolver = null;
                schemaSet.ValidationEventHandler += handler;
 
                foreach (XmlSchema s in References.Values)
                    schemaSet.Add(s); 
                int schemaCount = schemaSet.Count; 

                foreach (XmlSchema s in List) { 
                    if (!SchemaSet.Contains(s)) {
                        schemaSet.Add(s);
                        schemaCount++;
                    } 
                }
 
                if (!SchemaSet.Contains(XmlSchema.Namespace)) { 
                    AddReference(XsdSchema);
                    schemaSet.Add(XsdSchema); 
                    schemaCount++;
                }

                if (!SchemaSet.Contains(XmlReservedNs.NsXml)) { 
                    AddReference(XmlSchema);
                    schemaSet.Add(XmlSchema); 
                    schemaCount++; 
                }
                schemaSet.Compile(); 
                schemaSet.ValidationEventHandler -= handler;
                isCompiled = schemaSet.IsCompiled && schemaCount == schemaSet.Count;
            }
            else { 
                try {
                    XmlNameTable nameTable = new System.Xml.NameTable(); 
                    Preprocessor prep = new Preprocessor(nameTable, new SchemaNames(nameTable), null); 
                    prep.XmlResolver = null;
                    prep.SchemaLocations = new Hashtable(); 
                    prep.ChameleonSchemas = new Hashtable();
                    foreach (XmlSchema schema in SchemaSet.Schemas()) {
                        prep.Execute(schema, schema.TargetNamespace, true);
                    } 
                }
                catch(XmlSchemaException e) { 
                    throw CreateValidationException(e, e.Message); 
                }
            } 
        }

        internal static Exception CreateValidationException(XmlSchemaException exception, string message) {
            XmlSchemaObject source = exception.SourceSchemaObject; 
            if (exception.LineNumber == 0 && exception.LinePosition == 0) {
                throw new InvalidOperationException(GetSchemaItem(source, null, message), exception); 
            } 
            else {
                string ns = null; 
                if (source != null) {
                    while (source.Parent != null) {
                        source = source.Parent;
                    } 
                    if (source is XmlSchema) {
                        ns = ((XmlSchema)source).TargetNamespace; 
                    } 
                }
                throw new InvalidOperationException(Res.GetString(Res.XmlSchemaSyntaxErrorDetails, ns, message, exception.LineNumber, exception.LinePosition), exception); 
            }
        }

        internal static void IgnoreCompileErrors(object sender, ValidationEventArgs args) { 
            return;
        } 
 
        internal static XmlSchema XsdSchema {
            get { 
                if (xsd == null) {
                    xsd = CreateFakeXsdSchema(XmlSchema.Namespace, "schema");
                }
                return xsd; 
            }
        } 
 
        internal static XmlSchema XmlSchema {
            get { 
                if (xml == null) {
                    xml = XmlSchema.Read(new StringReader(xmlSchema), null);
                }
                return xml; 
            }
        } 
 
        private static XmlSchema CreateFakeXsdSchema(string ns, string name) {
            /* Create fake xsd schema to fool the XmlSchema.Compiler 
                
                  
                    
                   
                
            */ 
            XmlSchema schema = new XmlSchema(); 
            schema.TargetNamespace = ns;
            XmlSchemaElement element = new XmlSchemaElement(); 
            element.Name = name;
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            element.SchemaType = type;
            schema.Items.Add(element); 
            return schema;
        } 
 
        internal void SetCache(SchemaObjectCache cache, bool shareTypes) {
            this.shareTypes = shareTypes; 
            this.cache = cache;
            if (shareTypes) {
                cache.GenerateSchemaGraph(this);
            } 
        }
 
        internal bool IsReference(XmlSchemaObject type) { 
            XmlSchemaObject parent = type;
            while (parent.Parent != null) { 
                parent = parent.Parent;
            }
            return References.Contains(parent);
        } 

        internal const string xmlSchema = @" 
 
 
  
  
   
    
     
   
   
  
 
  
 
  
  
   
 
"; 
    } 

    public class XmlSchemaEnumerator : IEnumerator, System.Collections.IEnumerator { 
        private XmlSchemas list;
        private int idx, end;

        public XmlSchemaEnumerator(XmlSchemas list) { 
            this.list = list;
            this.idx = -1; 
            this.end = list.Count - 1; 
        }
 
        public void Dispose() {
        }

        public bool MoveNext() { 
            if (this.idx >= this.end)
                return false; 
 
            this.idx++;
            return true; 
        }

        public XmlSchema Current {
            get { return this.list[this.idx]; } 
        }
 
        object System.Collections.IEnumerator.Current { 
            get { return this.list[this.idx]; }
        } 

        void System.Collections.IEnumerator.Reset() {
            this.idx = -1;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK