1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 namespace System.Xml.Schema
6 {
7     using System.IO;
8     using System.Collections;
9     using System.ComponentModel;
10     using System.Xml.Serialization;
11     using System.Threading;
12     using System.Diagnostics;
13     using System.Collections.Generic;
14 
15     /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema"]/*' />
16     /// <devdoc>
17     ///    <para>[To be supplied.]</para>
18     /// </devdoc>
19     [XmlRoot("schema", Namespace = XmlSchema.Namespace)]
20     public class XmlSchema : XmlSchemaObject
21     {
22         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Namespace"]/*' />
23         /// <devdoc>
24         ///    <para>[To be supplied.]</para>
25         /// </devdoc>
26         public const string Namespace = XmlReservedNs.NsXs;
27         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.InstanceNamespace"]/*' />
28         /// <devdoc>
29         ///    <para>[To be supplied.]</para>
30         /// </devdoc>
31         public const string InstanceNamespace = XmlReservedNs.NsXsi;
32 
33         private XmlSchemaForm _attributeFormDefault = XmlSchemaForm.None;
34         private XmlSchemaForm _elementFormDefault = XmlSchemaForm.None;
35         private XmlSchemaDerivationMethod _blockDefault = XmlSchemaDerivationMethod.None;
36         private XmlSchemaDerivationMethod _finalDefault = XmlSchemaDerivationMethod.None;
37         private string _targetNs;
38         private string _version;
39         private XmlSchemaObjectCollection _includes = new XmlSchemaObjectCollection();
40         private XmlSchemaObjectCollection _items = new XmlSchemaObjectCollection();
41         private string _id;
42         private XmlAttribute[] _moreAttributes;
43 
44         // compiled info
45         private bool _isCompiled = false;
46         private bool _isCompiledBySet = false;
47         private bool _isPreprocessed = false;
48         private bool _isRedefined = false;
49         private int _errorCount = 0;
50         private XmlSchemaObjectTable _attributes;
51         private XmlSchemaObjectTable _attributeGroups = new XmlSchemaObjectTable();
52         private XmlSchemaObjectTable _elements = new XmlSchemaObjectTable();
53         private XmlSchemaObjectTable _types = new XmlSchemaObjectTable();
54         private XmlSchemaObjectTable _groups = new XmlSchemaObjectTable();
55         private XmlSchemaObjectTable _notations = new XmlSchemaObjectTable();
56         private XmlSchemaObjectTable _identityConstraints = new XmlSchemaObjectTable();
57 
58         private static int s_globalIdCounter = -1;
59         private ArrayList _importedSchemas;
60         private ArrayList _importedNamespaces;
61 
62         private int _schemaId = -1; //Not added to a set
63         private Uri _baseUri;
64         private bool _isChameleon;
65         private Hashtable _ids = new Hashtable();
66         private XmlDocument _document;
67         private XmlNameTable _nameTable;
68 
69         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.XmlSchema"]/*' />
70         /// <devdoc>
71         ///    <para>[To be supplied.]</para>
72         /// </devdoc>
XmlSchema()73         public XmlSchema() { }
74 
75         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Read"]/*' />
76         /// <devdoc>
77         ///    <para>[To be supplied.]</para>
78         /// </devdoc>
Read(TextReader reader, ValidationEventHandler validationEventHandler)79         public static XmlSchema Read(TextReader reader, ValidationEventHandler validationEventHandler)
80         {
81             return Read(new XmlTextReader(reader), validationEventHandler);
82         }
83 
84         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Read1"]/*' />
85         /// <devdoc>
86         ///    <para>[To be supplied.]</para>
87         /// </devdoc>
Read(Stream stream, ValidationEventHandler validationEventHandler)88         public static XmlSchema Read(Stream stream, ValidationEventHandler validationEventHandler)
89         {
90             return Read(new XmlTextReader(stream), validationEventHandler);
91         }
92 
93         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Read2"]/*' />
94         /// <devdoc>
95         ///    <para>[To be supplied.]</para>
96         /// </devdoc>
Read(XmlReader reader, ValidationEventHandler validationEventHandler)97         public static XmlSchema Read(XmlReader reader, ValidationEventHandler validationEventHandler)
98         {
99             XmlNameTable nameTable = reader.NameTable;
100             Parser parser = new Parser(SchemaType.XSD, nameTable, new SchemaNames(nameTable), validationEventHandler);
101             try
102             {
103                 parser.Parse(reader, null);
104             }
105             catch (XmlSchemaException e)
106             {
107                 if (validationEventHandler != null)
108                 {
109                     validationEventHandler(null, new ValidationEventArgs(e));
110                 }
111                 else
112                 {
113                     throw;
114                 }
115                 return null;
116             }
117             return parser.XmlSchema;
118         }
119 
120         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write"]/*' />
121         /// <devdoc>
122         ///    <para>[To be supplied.]</para>
123         /// </devdoc>
Write(Stream stream)124         public void Write(Stream stream)
125         {
126             Write(stream, null);
127         }
128 
129         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write1"]/*' />
130         /// <devdoc>
131         ///    <para>[To be supplied.]</para>
132         /// </devdoc>
Write(Stream stream, XmlNamespaceManager namespaceManager)133         public void Write(Stream stream, XmlNamespaceManager namespaceManager)
134         {
135             XmlTextWriter xmlWriter = new XmlTextWriter(stream, null);
136             xmlWriter.Formatting = Formatting.Indented;
137             Write(xmlWriter, namespaceManager);
138         }
139 
140         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write2"]/*' />
141         /// <devdoc>
142         ///    <para>[To be supplied.]</para>
143         /// </devdoc>
Write(TextWriter writer)144         public void Write(TextWriter writer)
145         {
146             Write(writer, null);
147         }
148 
149         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write3"]/*' />
150         /// <devdoc>
151         ///    <para>[To be supplied.]</para>
152         /// </devdoc>
Write(TextWriter writer, XmlNamespaceManager namespaceManager)153         public void Write(TextWriter writer, XmlNamespaceManager namespaceManager)
154         {
155             XmlTextWriter xmlWriter = new XmlTextWriter(writer);
156             xmlWriter.Formatting = Formatting.Indented;
157             Write(xmlWriter, namespaceManager);
158         }
159 
160         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write4"]/*' />
161         /// <devdoc>
162         ///    <para>[To be supplied.]</para>
163         /// </devdoc>
Write(XmlWriter writer)164         public void Write(XmlWriter writer)
165         {
166             Write(writer, null);
167         }
168 
169         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Write5"]/*' />
170         /// <devdoc>
171         ///    <para>[To be supplied.]</para>
172         /// </devdoc>
Write(XmlWriter writer, XmlNamespaceManager namespaceManager)173         public void Write(XmlWriter writer, XmlNamespaceManager namespaceManager)
174         {
175             XmlSerializer serializer = new XmlSerializer(typeof(XmlSchema));
176             XmlSerializerNamespaces ns;
177 
178             if (namespaceManager != null)
179             {
180                 ns = new XmlSerializerNamespaces();
181                 bool ignoreXS = false;
182                 if (this.Namespaces != null)
183                 { //User may have set both nsManager and Namespaces property on the XmlSchema object
184                     ignoreXS = this.Namespaces.Namespaces.ContainsKey("xs") || this.Namespaces.Namespaces.ContainsValue(XmlReservedNs.NsXs);
185                 }
186                 if (!ignoreXS && namespaceManager.LookupPrefix(XmlReservedNs.NsXs) == null &&
187                     namespaceManager.LookupNamespace("xs") == null)
188                 {
189                     ns.Add("xs", XmlReservedNs.NsXs);
190                 }
191                 foreach (string prefix in namespaceManager)
192                 {
193                     if (prefix != "xml" && prefix != "xmlns")
194                     {
195                         ns.Add(prefix, namespaceManager.LookupNamespace(prefix));
196                     }
197                 }
198             }
199             else if (this.Namespaces != null && this.Namespaces.Count > 0)
200             {
201                 Dictionary<string, string> serializerNS = this.Namespaces.Namespaces;
202                 if (!serializerNS.ContainsKey("xs") && !serializerNS.ContainsValue(XmlReservedNs.NsXs))
203                 { //Prefix xs not defined AND schema namespace not already mapped to a prefix
204                     serializerNS.Add("xs", XmlReservedNs.NsXs);
205                 }
206                 ns = this.Namespaces;
207             }
208             else
209             {
210                 ns = new XmlSerializerNamespaces();
211                 ns.Add("xs", XmlSchema.Namespace);
212                 if (_targetNs != null && _targetNs.Length != 0)
213                 {
214                     ns.Add("tns", _targetNs);
215                 }
216             }
217             serializer.Serialize(writer, this, ns);
218         }
219 
220         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Compile"]/*' />
221         /// <devdoc>
222         ///    <para>[To be supplied.]</para>
223         /// </devdoc>
224         [Obsolete("Use System.Xml.Schema.XmlSchemaSet for schema compilation and validation. http://go.microsoft.com/fwlink/?linkid=14202")]
Compile(ValidationEventHandler validationEventHandler)225         public void Compile(ValidationEventHandler validationEventHandler)
226         {
227             SchemaInfo sInfo = new SchemaInfo();
228             sInfo.SchemaType = SchemaType.XSD;
229             CompileSchema(null, null, sInfo, null, validationEventHandler, NameTable, false);
230         }
231 
232         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Compileq"]/*' />
233         /// <devdoc>
234         ///    <para>[To be supplied.]</para>
235         /// </devdoc>
236         [Obsolete("Use System.Xml.Schema.XmlSchemaSet for schema compilation and validation. http://go.microsoft.com/fwlink/?linkid=14202")]
Compile(ValidationEventHandler validationEventHandler, XmlResolver resolver)237         public void Compile(ValidationEventHandler validationEventHandler, XmlResolver resolver)
238         {
239             SchemaInfo sInfo = new SchemaInfo();
240             sInfo.SchemaType = SchemaType.XSD;
241             CompileSchema(null, resolver, sInfo, null, validationEventHandler, NameTable, false);
242         }
243 
244 #pragma warning disable 618
CompileSchema(XmlSchemaCollection xsc, XmlResolver resolver, SchemaInfo schemaInfo, string ns, ValidationEventHandler validationEventHandler, XmlNameTable nameTable, bool CompileContentModel)245         internal bool CompileSchema(XmlSchemaCollection xsc, XmlResolver resolver, SchemaInfo schemaInfo, string ns, ValidationEventHandler validationEventHandler, XmlNameTable nameTable, bool CompileContentModel)
246         {
247             //Need to lock here to prevent multi-threading problems when same schema is added to set and compiled
248             lock (this)
249             {
250                 //Preprocessing
251                 SchemaCollectionPreprocessor prep = new SchemaCollectionPreprocessor(nameTable, null, validationEventHandler);
252                 prep.XmlResolver = resolver;
253                 if (!prep.Execute(this, ns, true, xsc))
254                 {
255                     return false;
256                 }
257 
258                 //Compilation
259                 SchemaCollectionCompiler compiler = new SchemaCollectionCompiler(nameTable, validationEventHandler);
260                 _isCompiled = compiler.Execute(this, schemaInfo, CompileContentModel);
261                 this.SetIsCompiled(_isCompiled);
262                 return _isCompiled;
263             }
264         }
265 #pragma warning restore 618
266 
CompileSchemaInSet(XmlNameTable nameTable, ValidationEventHandler eventHandler, XmlSchemaCompilationSettings compilationSettings)267         internal void CompileSchemaInSet(XmlNameTable nameTable, ValidationEventHandler eventHandler, XmlSchemaCompilationSettings compilationSettings)
268         {
269             Debug.Assert(_isPreprocessed);
270             Compiler setCompiler = new Compiler(nameTable, eventHandler, null, compilationSettings);
271             setCompiler.Prepare(this, true);
272             _isCompiledBySet = setCompiler.Compile();
273         }
274 
275         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.AttributeFormDefault"]/*' />
276         /// <devdoc>
277         ///    <para>[To be supplied.]</para>
278         /// </devdoc>
279         [XmlAttribute("attributeFormDefault"), DefaultValue(XmlSchemaForm.None)]
280         public XmlSchemaForm AttributeFormDefault
281         {
282             get { return _attributeFormDefault; }
283             set { _attributeFormDefault = value; }
284         }
285 
286         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.BlockDefault"]/*' />
287         /// <devdoc>
288         ///    <para>[To be supplied.]</para>
289         /// </devdoc>
290         [XmlAttribute("blockDefault"), DefaultValue(XmlSchemaDerivationMethod.None)]
291         public XmlSchemaDerivationMethod BlockDefault
292         {
293             get { return _blockDefault; }
294             set { _blockDefault = value; }
295         }
296 
297         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.FinalDefault"]/*' />
298         /// <devdoc>
299         ///    <para>[To be supplied.]</para>
300         /// </devdoc>
301         [XmlAttribute("finalDefault"), DefaultValue(XmlSchemaDerivationMethod.None)]
302         public XmlSchemaDerivationMethod FinalDefault
303         {
304             get { return _finalDefault; }
305             set { _finalDefault = value; }
306         }
307 
308         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.ElementFormDefault"]/*' />
309         /// <devdoc>
310         ///    <para>[To be supplied.]</para>
311         /// </devdoc>
312         [XmlAttribute("elementFormDefault"), DefaultValue(XmlSchemaForm.None)]
313         public XmlSchemaForm ElementFormDefault
314         {
315             get { return _elementFormDefault; }
316             set { _elementFormDefault = value; }
317         }
318 
319         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.TargetNamespace"]/*' />
320         /// <devdoc>
321         ///    <para>[To be supplied.]</para>
322         /// </devdoc>
323         [XmlAttribute("targetNamespace", DataType = "anyURI")]
324         public string TargetNamespace
325         {
326             get { return _targetNs; }
327             set { _targetNs = value; }
328         }
329 
330         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Version"]/*' />
331         /// <devdoc>
332         ///    <para>[To be supplied.]</para>
333         /// </devdoc>
334         [XmlAttribute("version", DataType = "token")]
335         public string Version
336         {
337             get { return _version; }
338             set { _version = value; }
339         }
340 
341         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Includes"]/*' />
342         /// <devdoc>
343         ///    <para>[To be supplied.]</para>
344         /// </devdoc>
345         [XmlElement("include", typeof(XmlSchemaInclude)),
346          XmlElement("import", typeof(XmlSchemaImport)),
347          XmlElement("redefine", typeof(XmlSchemaRedefine))]
348         public XmlSchemaObjectCollection Includes
349         {
350             get { return _includes; }
351         }
352 
353         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Items"]/*' />
354         /// <devdoc>
355         ///    <para>[To be supplied.]</para>
356         /// </devdoc>
357         [XmlElement("annotation", typeof(XmlSchemaAnnotation)),
358          XmlElement("attribute", typeof(XmlSchemaAttribute)),
359          XmlElement("attributeGroup", typeof(XmlSchemaAttributeGroup)),
360          XmlElement("complexType", typeof(XmlSchemaComplexType)),
361          XmlElement("simpleType", typeof(XmlSchemaSimpleType)),
362          XmlElement("element", typeof(XmlSchemaElement)),
363          XmlElement("group", typeof(XmlSchemaGroup)),
364          XmlElement("notation", typeof(XmlSchemaNotation))]
365         public XmlSchemaObjectCollection Items
366         {
367             get { return _items; }
368         }
369 
370         // Compiled info
371         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.IsCompiled"]/*' />
372         /// <devdoc>
373         ///    <para>[To be supplied.]</para>
374         /// </devdoc>
375         [XmlIgnore]
376         public bool IsCompiled
377         {
378             get
379             {
380                 return _isCompiled || _isCompiledBySet;
381             }
382         }
383 
384         [XmlIgnore]
385         internal bool IsCompiledBySet
386         {
387             get { return _isCompiledBySet; }
388             set { _isCompiledBySet = value; }
389         }
390 
391         [XmlIgnore]
392         internal bool IsPreprocessed
393         {
394             get { return _isPreprocessed; }
395             set { _isPreprocessed = value; }
396         }
397 
398         [XmlIgnore]
399         internal bool IsRedefined
400         {
401             get { return _isRedefined; }
402             set { _isRedefined = value; }
403         }
404 
405         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Attributes"]/*' />
406         /// <devdoc>
407         ///    <para>[To be supplied.]</para>
408         /// </devdoc>
409         [XmlIgnore]
410         public XmlSchemaObjectTable Attributes
411         {
412             get
413             {
414                 if (_attributes == null)
415                 {
416                     _attributes = new XmlSchemaObjectTable();
417                 }
418                 return _attributes;
419             }
420         }
421 
422         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.AttributeGroups"]/*' />
423         /// <devdoc>
424         ///    <para>[To be supplied.]</para>
425         /// </devdoc>
426         [XmlIgnore]
427         public XmlSchemaObjectTable AttributeGroups
428         {
429             get
430             {
431                 if (_attributeGroups == null)
432                 {
433                     _attributeGroups = new XmlSchemaObjectTable();
434                 }
435                 return _attributeGroups;
436             }
437         }
438 
439         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.SchemaTypes"]/*' />
440         /// <devdoc>
441         ///    <para>[To be supplied.]</para>
442         /// </devdoc>
443         [XmlIgnore]
444         public XmlSchemaObjectTable SchemaTypes
445         {
446             get
447             {
448                 if (_types == null)
449                 {
450                     _types = new XmlSchemaObjectTable();
451                 }
452                 return _types;
453             }
454         }
455 
456         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Elements"]/*' />
457         /// <devdoc>
458         ///    <para>[To be supplied.]</para>
459         /// </devdoc>
460         [XmlIgnore]
461         public XmlSchemaObjectTable Elements
462         {
463             get
464             {
465                 if (_elements == null)
466                 {
467                     _elements = new XmlSchemaObjectTable();
468                 }
469                 return _elements;
470             }
471         }
472 
473         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Id"]/*' />
474         /// <devdoc>
475         ///    <para>[To be supplied.]</para>
476         /// </devdoc>
477         [XmlAttribute("id", DataType = "ID")]
478         public string Id
479         {
480             get { return _id; }
481             set { _id = value; }
482         }
483 
484         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.UnhandledAttributes"]/*' />
485         /// <devdoc>
486         ///    <para>[To be supplied.]</para>
487         /// </devdoc>
488         [XmlAnyAttribute]
489         public XmlAttribute[] UnhandledAttributes
490         {
491             get { return _moreAttributes; }
492             set { _moreAttributes = value; }
493         }
494 
495         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Groups"]/*' />
496         /// <devdoc>
497         ///    <para>[To be supplied.]</para>
498         /// </devdoc>
499         [XmlIgnore]
500         public XmlSchemaObjectTable Groups
501         {
502             get { return _groups; }
503         }
504 
505         /// <include file='doc\XmlSchema.uex' path='docs/doc[@for="XmlSchema.Notations"]/*' />
506         /// <devdoc>
507         ///    <para>[To be supplied.]</para>
508         /// </devdoc>
509         [XmlIgnore]
510         public XmlSchemaObjectTable Notations
511         {
512             get { return _notations; }
513         }
514 
515         [XmlIgnore]
516         internal XmlSchemaObjectTable IdentityConstraints
517         {
518             get { return _identityConstraints; }
519         }
520 
521         [XmlIgnore]
522         internal Uri BaseUri
523         {
524             get { return _baseUri; }
525             set
526             {
527                 _baseUri = value;
528             }
529         }
530 
531         [XmlIgnore]
532         // Please be careful with this property. Since it lazy initialized and its value depends on a global state
533         //   if it gets called on multiple schemas in a different order the schemas will end up with different IDs
534         //   Unfortunately the IDs are used to sort the schemas in the schema set and thus changing the IDs might change
535         //   the order which would be a breaking change!!
536         // Simply put if you are planning to add or remove a call to this getter you need to be extra carefull
537         //   or better don't do it at all.
538         internal int SchemaId
539         {
540             get
541             {
542                 if (_schemaId == -1)
543                 {
544                     _schemaId = Interlocked.Increment(ref s_globalIdCounter);
545                 }
546                 return _schemaId;
547             }
548         }
549 
550         [XmlIgnore]
551         internal bool IsChameleon
552         {
553             get { return _isChameleon; }
554             set { _isChameleon = value; }
555         }
556 
557         [XmlIgnore]
558         internal Hashtable Ids
559         {
560             get { return _ids; }
561         }
562 
563         [XmlIgnore]
564         internal XmlDocument Document
565         {
566             get { if (_document == null) _document = new XmlDocument(); return _document; }
567         }
568 
569         [XmlIgnore]
570         internal int ErrorCount
571         {
572             get { return _errorCount; }
573             set { _errorCount = value; }
574         }
575 
Clone()576         internal new XmlSchema Clone()
577         {
578             XmlSchema that = new XmlSchema();
579             that._attributeFormDefault = _attributeFormDefault;
580             that._elementFormDefault = _elementFormDefault;
581             that._blockDefault = _blockDefault;
582             that._finalDefault = _finalDefault;
583             that._targetNs = _targetNs;
584             that._version = _version;
585             that._includes = _includes;
586 
587             that.Namespaces = this.Namespaces;
588             that._items = _items;
589             that.BaseUri = this.BaseUri;
590 
591             SchemaCollectionCompiler.Cleanup(that);
592             return that;
593         }
594 
DeepClone()595         internal XmlSchema DeepClone()
596         {
597             XmlSchema that = new XmlSchema();
598             that._attributeFormDefault = _attributeFormDefault;
599             that._elementFormDefault = _elementFormDefault;
600             that._blockDefault = _blockDefault;
601             that._finalDefault = _finalDefault;
602             that._targetNs = _targetNs;
603             that._version = _version;
604             that._isPreprocessed = _isPreprocessed;
605             //that.IsProcessing           = this.IsProcessing; //Not sure if this is needed
606 
607             //Clone its Items
608             for (int i = 0; i < _items.Count; ++i)
609             {
610                 XmlSchemaObject newItem;
611 
612                 XmlSchemaComplexType complexType;
613                 XmlSchemaElement element;
614                 XmlSchemaGroup group;
615 
616                 if ((complexType = _items[i] as XmlSchemaComplexType) != null)
617                 {
618                     newItem = complexType.Clone(this);
619                 }
620                 else if ((element = _items[i] as XmlSchemaElement) != null)
621                 {
622                     newItem = element.Clone(this);
623                 }
624                 else if ((group = _items[i] as XmlSchemaGroup) != null)
625                 {
626                     newItem = group.Clone(this);
627                 }
628                 else
629                 {
630                     newItem = _items[i].Clone();
631                 }
632                 that.Items.Add(newItem);
633             }
634 
635             //Clone Includes
636             for (int i = 0; i < _includes.Count; ++i)
637             {
638                 XmlSchemaExternal newInclude = (XmlSchemaExternal)_includes[i].Clone();
639                 that.Includes.Add(newInclude);
640             }
641             that.Namespaces = this.Namespaces;
642             //that.includes               = this.includes; //Need to verify this is OK for redefines
643             that.BaseUri = this.BaseUri;
644             return that;
645         }
646 
647         [XmlIgnore]
648         internal override string IdAttribute
649         {
650             get { return Id; }
651             set { Id = value; }
652         }
653 
SetIsCompiled(bool isCompiled)654         internal void SetIsCompiled(bool isCompiled)
655         {
656             _isCompiled = isCompiled;
657         }
658 
SetUnhandledAttributes(XmlAttribute[] moreAttributes)659         internal override void SetUnhandledAttributes(XmlAttribute[] moreAttributes)
660         {
661             _moreAttributes = moreAttributes;
662         }
AddAnnotation(XmlSchemaAnnotation annotation)663         internal override void AddAnnotation(XmlSchemaAnnotation annotation)
664         {
665             _items.Add(annotation);
666         }
667 
668         internal XmlNameTable NameTable
669         {
670             get { if (_nameTable == null) _nameTable = new System.Xml.NameTable(); return _nameTable; }
671         }
672 
673         internal ArrayList ImportedSchemas
674         {
675             get
676             {
677                 if (_importedSchemas == null)
678                 {
679                     _importedSchemas = new ArrayList();
680                 }
681                 return _importedSchemas;
682             }
683         }
684 
685         internal ArrayList ImportedNamespaces
686         {
687             get
688             {
689                 if (_importedNamespaces == null)
690                 {
691                     _importedNamespaces = new ArrayList();
692                 }
693                 return _importedNamespaces;
694             }
695         }
696 
GetExternalSchemasList(IList extList, XmlSchema schema)697         internal void GetExternalSchemasList(IList extList, XmlSchema schema)
698         {
699             Debug.Assert(extList != null && schema != null);
700             if (extList.Contains(schema))
701             {
702                 return;
703             }
704             extList.Add(schema);
705             for (int i = 0; i < schema.Includes.Count; ++i)
706             {
707                 XmlSchemaExternal ext = (XmlSchemaExternal)schema.Includes[i];
708                 if (ext.Schema != null)
709                 {
710                     GetExternalSchemasList(extList, ext.Schema);
711                 }
712             }
713         }
714 
715 #if TRUST_COMPILE_STATE
AddCompiledInfo(SchemaInfo schemaInfo)716         internal void AddCompiledInfo(SchemaInfo schemaInfo) {
717             XmlQualifiedName itemName;
718             foreach (XmlSchemaElement element in elements.Values) {
719                 itemName = element.QualifiedName;
720                 schemaInfo.TargetNamespaces[itemName.Namespace] = true;
721                 if (schemaInfo.ElementDecls[itemName] == null) {
722                     schemaInfo.ElementDecls.Add(itemName, element.ElementDecl);
723                 }
724             }
725             foreach (XmlSchemaAttribute attribute in attributes.Values) {
726                 itemName = attribute.QualifiedName;
727                 schemaInfo.TargetNamespaces[itemName.Namespace] = true;
728                 if (schemaInfo.ElementDecls[itemName] == null) {
729                     schemaInfo.AttributeDecls.Add(itemName, attribute.AttDef);
730                 }
731             }
732             foreach (XmlSchemaType type in types.Values) {
733                 itemName = type.QualifiedName;
734                 schemaInfo.TargetNamespaces[itemName.Namespace] = true;
735                 XmlSchemaComplexType complexType = type as XmlSchemaComplexType;
736                 if ((complexType == null || type != XmlSchemaComplexType.AnyType) && schemaInfo.ElementDeclsByType[itemName] == null) {
737                     schemaInfo.ElementDeclsByType.Add(itemName, type.ElementDecl);
738                 }
739             }
740             foreach (XmlSchemaNotation notation in notations.Values) {
741                 itemName = notation.QualifiedName;
742                 schemaInfo.TargetNamespaces[itemName.Namespace] = true;
743                 SchemaNotation no = new SchemaNotation(itemName);
744                 no.SystemLiteral = notation.System;
745                 no.Pubid = notation.Public;
746                 if (schemaInfo.Notations[itemName.Name] == null) {
747                     schemaInfo.Notations.Add(itemName.Name, no);
748                 }
749             }
750         }
751 #endif//TRUST_COMPILE_STATE
752     }
753 }
754