2003-07-19 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchema.cs
1 //\r
2 // System.Xml.Schema.XmlSchema.cs\r
3 //\r
4 // Author:\r
5 //      Dwivedi, Ajay kumar  Adwiv@Yahoo.com\r
6 //      Atsushi Enomoto  ginga@kit.hi-ho.ne.jp\r
7 //\r
8 using System;\r
9 using System.Collections;\r
10 using System.Xml;\r
11 using System.IO;\r
12 using System.Xml.Serialization;\r
13 using System.ComponentModel;\r
14 \r
15 namespace System.Xml.Schema\r
16 {\r
17         /// <summary>\r
18         /// Summary description for XmlSchema.\r
19         /// </summary>\r
20         [XmlRoot("schema",Namespace=XmlSchema.Namespace)]\r
21         public class XmlSchema : XmlSchemaObject\r
22         {\r
23                 //public constants\r
24                 public const string Namespace = "http://www.w3.org/2001/XMLSchema";\r
25                 public const string InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";\r
26 \r
27                 //private fields\r
28                 private XmlSchemaForm attributeFormDefault ;\r
29                 private XmlSchemaObjectTable attributeGroups ;\r
30                 private XmlSchemaObjectTable attributes ;\r
31                 private XmlSchemaDerivationMethod blockDefault ;\r
32                 private XmlSchemaForm elementFormDefault ;\r
33                 private XmlSchemaObjectTable elements ;\r
34                 private XmlSchemaDerivationMethod finalDefault ;\r
35                 private XmlSchemaObjectTable groups ;\r
36                 private string id ;\r
37                 private XmlSchemaObjectCollection includes ;\r
38                 private XmlSchemaObjectCollection items ;\r
39                 private XmlSchemaObjectTable notations ;\r
40                 private XmlSchemaObjectTable schemaTypes ;\r
41                 private string targetNamespace ;\r
42                 private XmlAttribute[] unhandledAttributes ;\r
43                 private string version;\r
44                 private string language;\r
45 \r
46                 // post schema compilation infoset\r
47                 private Hashtable idCollection;\r
48 \r
49                 // Compiler specific things\r
50                 private static string xmlname = "schema";\r
51 \r
52                 public XmlSchema()\r
53                 {\r
54                         attributeFormDefault= XmlSchemaForm.None;\r
55                         blockDefault            = XmlSchemaDerivationMethod.None;\r
56                         elementFormDefault      = XmlSchemaForm.None;\r
57                         finalDefault            = XmlSchemaDerivationMethod.None;\r
58                         includes                        = new XmlSchemaObjectCollection();\r
59                         isCompiled                      = false;\r
60                         items                           = new XmlSchemaObjectCollection();\r
61                         attributeGroups         = new XmlSchemaObjectTable();\r
62                         attributes                      = new XmlSchemaObjectTable();\r
63                         elements                        = new XmlSchemaObjectTable();\r
64                         groups                          = new XmlSchemaObjectTable();\r
65                         notations                       = new XmlSchemaObjectTable();\r
66                         schemaTypes                     = new XmlSchemaObjectTable();\r
67                         idCollection                    = new Hashtable ();\r
68 \r
69                 }\r
70 \r
71                 #region Properties\r
72 \r
73                 [DefaultValue(XmlSchemaForm.None)]\r
74                 [System.Xml.Serialization.XmlAttribute("attributeFormDefault")]\r
75                 public XmlSchemaForm AttributeFormDefault\r
76                 {\r
77                         get{ return attributeFormDefault; }\r
78                         set{ this.attributeFormDefault = value;}\r
79                 }\r
80 \r
81                 [DefaultValue(XmlSchemaDerivationMethod.None)]\r
82                 [System.Xml.Serialization.XmlAttribute("blockDefault")]\r
83                 public XmlSchemaDerivationMethod BlockDefault\r
84                 {\r
85                         get{ return blockDefault;}\r
86                         set{ blockDefault = value;}\r
87                 }\r
88 \r
89                 [DefaultValue(XmlSchemaDerivationMethod.None)]\r
90                 [System.Xml.Serialization.XmlAttribute("finalDefault")]\r
91                 public XmlSchemaDerivationMethod FinalDefault\r
92                 {\r
93                         get{ return finalDefault;}\r
94                         set{ finalDefault = value;}\r
95                 }\r
96 \r
97                 [DefaultValue(XmlSchemaForm.None)]\r
98                 [System.Xml.Serialization.XmlAttribute("elementFormDefault")]\r
99                 public XmlSchemaForm ElementFormDefault\r
100                 {\r
101                         get{ return elementFormDefault;}\r
102                         set{ elementFormDefault = value;}\r
103                 }\r
104 \r
105                 [System.Xml.Serialization.XmlAttribute("targetNamespace")]\r
106                 public string TargetNamespace\r
107                 {\r
108                         get{ return targetNamespace;}\r
109                         set{ targetNamespace = value;}\r
110                 }\r
111 \r
112                 [System.Xml.Serialization.XmlAttribute("version")]\r
113                 public string Version\r
114                 {\r
115                         get{ return version;}\r
116                         set{ version = value;}\r
117                 }\r
118 \r
119                 [XmlElement("include",typeof(XmlSchemaInclude),Namespace="http://www.w3.org/2001/XMLSchema")]\r
120                 [XmlElement("import",typeof(XmlSchemaImport),Namespace="http://www.w3.org/2001/XMLSchema")]\r
121                 [XmlElement("redefine",typeof(XmlSchemaRedefine),Namespace="http://www.w3.org/2001/XMLSchema")]\r
122                 public XmlSchemaObjectCollection Includes\r
123                 {\r
124                         get{ return includes;}\r
125                 }\r
126 \r
127                 [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
128                 [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
129                 [XmlElement("group",typeof(XmlSchemaGroup),Namespace="http://www.w3.org/2001/XMLSchema")]\r
130                         //Only Schema's attributeGroup has type XmlSchemaAttributeGroup.\r
131                         //Others (complextype, restrictions etc) must have XmlSchemaAttributeGroupRef\r
132                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroup),Namespace="http://www.w3.org/2001/XMLSchema")]\r
133                 [XmlElement("element",typeof(XmlSchemaElement),Namespace="http://www.w3.org/2001/XMLSchema")]\r
134                 [XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace="http://www.w3.org/2001/XMLSchema")]\r
135                 [XmlElement("notation",typeof(XmlSchemaNotation),Namespace="http://www.w3.org/2001/XMLSchema")]\r
136                 [XmlElement("annotation",typeof(XmlSchemaAnnotation),Namespace="http://www.w3.org/2001/XMLSchema")]\r
137                 public XmlSchemaObjectCollection Items\r
138                 {\r
139                         get{ return items;}\r
140                 }\r
141 \r
142                 [XmlIgnore]\r
143                 public bool IsCompiled\r
144                 {\r
145                         get{ return isCompiled;}\r
146                 }\r
147 \r
148                 [XmlIgnore]\r
149                 public XmlSchemaObjectTable Attributes\r
150                 {\r
151                         get{ return attributes;}\r
152                 }\r
153 \r
154                 [XmlIgnore]\r
155                 public XmlSchemaObjectTable AttributeGroups\r
156                 {\r
157                         get{ return attributeGroups; }\r
158                 }\r
159 \r
160                 [XmlIgnore]\r
161                 public XmlSchemaObjectTable SchemaTypes\r
162                 {\r
163                         get{ return schemaTypes; }\r
164                 }\r
165 \r
166                 [XmlIgnore]\r
167                 public XmlSchemaObjectTable Elements\r
168                 {\r
169                         get{ return elements;}\r
170                 }\r
171 \r
172                 [System.Xml.Serialization.XmlAttribute("id")]\r
173                 public string Id\r
174                 {\r
175                         get{ return id;}\r
176                         set{ id = value;}\r
177                 }\r
178 \r
179                 [XmlAnyAttribute]\r
180                 public XmlAttribute[] UnhandledAttributes\r
181                 {\r
182                         get\r
183                         {\r
184                                 if(unhandledAttributeList != null)\r
185                                 {\r
186                                         unhandledAttributes = (XmlAttribute[]) unhandledAttributeList.ToArray(typeof(XmlAttribute));\r
187                                         unhandledAttributeList = null;\r
188                                 }\r
189                                 return unhandledAttributes;\r
190                         }\r
191                         set\r
192                         {\r
193                                 unhandledAttributes = value;\r
194                                 unhandledAttributeList = null;\r
195                         }\r
196                 }\r
197 \r
198                 [XmlIgnore]\r
199                 public XmlSchemaObjectTable Groups\r
200                 {\r
201                         get{ return groups;}\r
202                 }\r
203 \r
204                 [XmlIgnore]\r
205                 public XmlSchemaObjectTable Notations\r
206                 {\r
207                         get{ return notations;}\r
208                 }\r
209 \r
210                 // New attribute defined in W3C schema element\r
211                 [System.Xml.Serialization.XmlAttribute("xml:lang")]\r
212                 public string Language\r
213                 {\r
214                         get{ return  language; }\r
215                         set{ language = value; }\r
216                 }\r
217 \r
218                 internal Hashtable IDCollection\r
219                 {\r
220                         get { return idCollection; }\r
221                 }\r
222 \r
223                 /*\r
224                 internal XmlSchemaForm ElementFormDefaultCompiled\r
225                 {\r
226                         get { return elementFormDefaultCompiled; }\r
227                 }\r
228 \r
229                 internal XmlSchemaForm AttributeFormDefaultCompiled\r
230                 {\r
231                         get { return attributeFormDefaultCompiled; }\r
232                 }\r
233 \r
234                 internal XmlSchemaDerivationMethod BlockDefaultCompiled\r
235                 {\r
236                         get { return blockDefaultCompiled; }\r
237                 }\r
238 \r
239                 internal XmlSchemaDerivationMethod FinalDefaultCompiled\r
240                 {\r
241                         get { return finalDefaultCompiled; }\r
242                 }\r
243                 */\r
244 \r
245                 #endregion\r
246 \r
247                 #region Compile\r
248 \r
249                 // Methods\r
250                 /// <summary>\r
251                 /// This compile method does two things:\r
252                 /// 1. It compiles and fills the PSVI dataset\r
253                 /// 2. Validates the schema by calling Validate method.\r
254                 /// Every XmlSchemaObject has a Compile Method which gets called.\r
255                 /// </summary>\r
256                 /// <remarks>\r
257                 ///             1. blockDefault must be one of #all | List of (extension | restriction | substitution)\r
258                 ///             2. finalDefault must be one of (#all | List of (extension | restriction| union| list))\r
259                 ///             3. id must be of type ID\r
260                 ///             4. targetNamespace should be any uri\r
261                 ///             5. version should be a normalizedString\r
262                 ///             6. xml:lang should be a language\r
263                 /// </remarks>\r
264                 [MonoTODO]\r
265                 public void Compile(ValidationEventHandler handler)\r
266                 {\r
267                         CompilationId = Guid.NewGuid ();\r
268 \r
269                         //1. Union and List are not allowed in block default\r
270                         if(BlockDefault != XmlSchemaDerivationMethod.All)\r
271                         {\r
272                                 if((BlockDefault & XmlSchemaDerivationMethod.List)!=0 )\r
273                                         error(handler, "list is not allowed in blockDefault attribute");\r
274                                 if((BlockDefault & XmlSchemaDerivationMethod.Union)!=0 )\r
275                                         error(handler, "union is not allowed in blockDefault attribute");\r
276                         }\r
277 \r
278                         //2. Substitution is not allowed in finaldefault.\r
279                         if(FinalDefault != XmlSchemaDerivationMethod.All)\r
280                         {\r
281                                 if((FinalDefault & XmlSchemaDerivationMethod.Substitution)!=0 )\r
282                                         error(handler, "substitution is not allowed in finalDefault attribute");\r
283                         }\r
284 \r
285                         //3. id must be of type ID\r
286                         XmlSchemaUtil.CompileID(Id, this, this.IDCollection, handler);\r
287 \r
288                         //4. targetNamespace should be of type anyURI or absent\r
289                         if(TargetNamespace != null)\r
290                         {\r
291                                 if(!XmlSchemaUtil.CheckAnyUri(TargetNamespace))\r
292                                         error(handler, TargetNamespace+" is not a valid value for targetNamespace attribute of schema");\r
293                         }\r
294 \r
295                         //5. version should be of type normalizedString\r
296                         if(!XmlSchemaUtil.CheckNormalizedString(Version))\r
297                                 error(handler, Version + "is not a valid value for version attribute of schema");\r
298 \r
299                         //6. xml:lang must be a language\r
300                         if(!XmlSchemaUtil.CheckLanguage(Language))\r
301                                 error(handler, Language + " is not a valid language");\r
302 \r
303                         // Compile the content of this schema\r
304                         foreach(XmlSchemaObject obj in Includes)\r
305                         {\r
306                                 if(obj is XmlSchemaExternal)\r
307                                 {\r
308                                         //FIXME: Kuch to karo! (Do Something ;)\r
309                                 }\r
310                                 else\r
311                                 {\r
312                                         error(handler,"Object of Type "+obj.GetType().Name+" is not valid in Includes Property of XmlSchema");\r
313                                 }\r
314                         }\r
315                         // It is hack, but types are required before element/attributes.\r
316                         foreach (XmlSchemaObject obj in Items)\r
317                         {\r
318                                 if(obj is XmlSchemaComplexType)\r
319                                 {\r
320                                         XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;\r
321                                         ctype.istoplevel = true;\r
322                                         int numerr = ctype.Compile(handler, this);\r
323                                         errorCount += numerr;\r
324                                         if(numerr == 0)\r
325                                         {\r
326                                                 schemaTypes.Add(ctype.QualifiedName, ctype);\r
327                                         }\r
328                                 }\r
329                                 else if(obj is XmlSchemaSimpleType)\r
330                                 {\r
331                                         XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;\r
332                                         stype.islocal = false; //This simple type is toplevel\r
333                                         int numerr = stype.Compile(handler, this);\r
334                                         errorCount += numerr;\r
335                                         if(numerr == 0)\r
336                                         {\r
337                                                 SchemaTypes.Add(stype.QualifiedName, stype);\r
338                                         }\r
339                                 }\r
340                         }\r
341 \r
342                         foreach(XmlSchemaObject obj in Items)\r
343                         {\r
344                                 if(obj is XmlSchemaAnnotation)\r
345                                 {\r
346                                         int numerr = ((XmlSchemaAnnotation)obj).Compile(handler, this);\r
347                                         errorCount += numerr;\r
348                                         if( numerr == 0)\r
349                                         {\r
350                                                 //FIXME: What PSVI set do we add this to?\r
351                                         }\r
352                                 }\r
353                                 else if(obj is XmlSchemaAttribute)\r
354                                 {\r
355                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
356                                         attr.parentIsSchema = true;\r
357                                         int numerr = attr.Compile(handler, this);\r
358                                         errorCount += numerr;\r
359                                         if(numerr == 0)\r
360                                         {\r
361                                                 Attributes.Add(attr.QualifiedName, attr);\r
362                                         }\r
363                                 }\r
364                                 else if(obj is XmlSchemaAttributeGroup)\r
365                                 {\r
366                                         XmlSchemaAttributeGroup attrgrp = (XmlSchemaAttributeGroup) obj;\r
367                                         int numerr = attrgrp.Compile(handler, this);\r
368                                         errorCount += numerr;\r
369                                         if(numerr == 0)\r
370                                         {\r
371                                                 AttributeGroups.Add(attrgrp.QualifiedName, attrgrp);\r
372                                         }\r
373                                 }\r
374                                 else if(obj is XmlSchemaComplexType)\r
375                                 {\r
376                                         // Do nothing here.\r
377                                 }\r
378                                 else if(obj is XmlSchemaSimpleType)\r
379                                 {\r
380                                         // Do nothing here.\r
381                                 }\r
382                                 else if(obj is XmlSchemaElement)\r
383                                 {\r
384                                         XmlSchemaElement elem = (XmlSchemaElement) obj;\r
385                                         elem.parentIsSchema = true;\r
386                                         int numerr = elem.Compile(handler, this);\r
387                                         errorCount += numerr;\r
388                                         if(numerr == 0)\r
389                                         {\r
390                                                 Elements.Add(elem.QualifiedName,elem);\r
391                                         }\r
392                                 }\r
393                                 else if(obj is XmlSchemaGroup)\r
394                                 {\r
395                                         XmlSchemaGroup grp = (XmlSchemaGroup) obj;\r
396                                         int numerr = grp.Compile(handler, this);\r
397                                         errorCount += numerr;\r
398                                         if(numerr == 0)\r
399                                         {\r
400                                                 Groups.Add(grp.QualifiedName,grp);\r
401                                         }\r
402                                 }\r
403                                 else if(obj is XmlSchemaNotation)\r
404                                 {\r
405                                         XmlSchemaNotation ntn = (XmlSchemaNotation) obj;\r
406                                         int numerr = ntn.Compile(handler, this);\r
407                                         errorCount += numerr;\r
408                                         if(numerr == 0)\r
409                                         {\r
410                                                 Notations.Add(ntn.QualifiedName, ntn);\r
411                                         }\r
412                                 }\r
413                                 else\r
414                                 {\r
415                                         ValidationHandler.RaiseValidationError(handler,this,\r
416                                                 "Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema");\r
417                                 }\r
418                         }\r
419                         Validate(handler);\r
420                 }\r
421 \r
422                 #endregion\r
423 \r
424                 [MonoTODO]\r
425                 private void Validate(ValidationEventHandler handler)\r
426                 {\r
427                         foreach(XmlSchemaAttribute attr in Attributes.Values)\r
428                         {\r
429                                 attr.Validate(handler, this);\r
430                         }\r
431                         foreach(XmlSchemaAttributeGroup attrgrp in AttributeGroups.Values)\r
432                         {\r
433                                 attrgrp.Validate(handler);\r
434                         }\r
435                         foreach(XmlSchemaType type in SchemaTypes.Values)\r
436                         {\r
437                                 if(type is XmlSchemaComplexType)\r
438                                 {\r
439                                         ((XmlSchemaComplexType)type).Validate(handler);\r
440                                 }\r
441                                 else\r
442                                         ((XmlSchemaSimpleType)type).Validate(handler, this);\r
443                         }\r
444                         foreach(XmlSchemaElement elem in Elements.Values)\r
445                         {\r
446                                 elem.Validate(handler);\r
447                         }\r
448                         foreach(XmlSchemaGroup grp in Groups.Values)\r
449                         {\r
450                                 grp.Validate(handler);\r
451                         }\r
452                         foreach(XmlSchemaNotation ntn in Notations.Values)\r
453                         {\r
454                                 ntn.Validate(handler);\r
455                         }\r
456                 }\r
457 \r
458 \r
459                 #region Read\r
460 \r
461                 public static XmlSchema Read(TextReader reader, ValidationEventHandler validationEventHandler)\r
462                 {\r
463                         return Read(new XmlTextReader(reader),validationEventHandler);\r
464                 }\r
465                 public static XmlSchema Read(Stream stream, ValidationEventHandler validationEventHandler)\r
466                 {\r
467                         return Read(new XmlTextReader(stream),validationEventHandler);\r
468                 }\r
469 \r
470                 public static XmlSchema Read(XmlReader rdr, ValidationEventHandler validationEventHandler)\r
471                 {\r
472                         //XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));\r
473                         //return (XmlSchema) xser.Deserialize(reader);\r
474                         XmlSchemaReader reader = new XmlSchemaReader(rdr, validationEventHandler);\r
475 \r
476                         while(reader.ReadNextElement())\r
477                         {\r
478                                 switch(reader.NodeType)\r
479                                 {\r
480                                         case XmlNodeType.Element:\r
481                                                 if(reader.LocalName == "schema")\r
482                                                 {\r
483                                                         XmlSchema schema = new XmlSchema();\r
484 \r
485                                                         schema.LineNumber = reader.LineNumber;\r
486                                                         schema.LinePosition = reader.LinePosition;\r
487                                                         schema.SourceUri = reader.BaseURI;\r
488 \r
489                                                         ReadAttributes(schema, reader, validationEventHandler);\r
490                                                         //IsEmptyElement does not behave properly if reader is\r
491                                                         //positioned at an attribute.\r
492                                                         reader.MoveToElement();\r
493                                                         if(!reader.IsEmptyElement)\r
494                                                         {\r
495                                                                 ReadContent(schema, reader, validationEventHandler);\r
496                                                         }\r
497                                                         return schema;\r
498                                                 }\r
499                                                 else\r
500                                                 {\r
501                                                         //Schema can't be generated. Throw an exception\r
502                                                         throw new XmlSchemaException("The root element must be schema", null);\r
503                                                 }\r
504                                         default:\r
505                                                 error(validationEventHandler, "This should never happen. XmlSchema.Read 1 ",null);\r
506                                                 break;\r
507                                 }\r
508                         }\r
509                         throw new XmlSchemaException("The top level schema must have namespace "+XmlSchema.Namespace, null);\r
510                 }\r
511 \r
512                 private static void ReadAttributes(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)\r
513                 {\r
514                         Exception ex;\r
515 \r
516                         reader.MoveToElement();\r
517                         while(reader.MoveToNextAttribute())\r
518                         {\r
519                                 switch(reader.Name)\r
520                                 {\r
521                                         case "attributeFormDefault" :\r
522                                                 schema.attributeFormDefault = XmlSchemaUtil.ReadFormAttribute(reader,out ex);\r
523                                                 if(ex != null)\r
524                                                         error(h, reader.Value + " is not a valid value for attributeFormDefault.", ex);\r
525                                                 break;\r
526                                         case "blockDefault" :\r
527                                                 schema.blockDefault = XmlSchemaUtil.ReadDerivationAttribute(reader,out ex, "blockDefault");\r
528                                                 if(ex != null)\r
529                                                         warn(h, ex.Message, ex);\r
530                                                 break;\r
531                                         case "elementFormDefault":\r
532                                                 schema.elementFormDefault = XmlSchemaUtil.ReadFormAttribute(reader, out ex);\r
533                                                 if(ex != null)\r
534                                                         error(h, reader.Value + " is not a valid value for elementFormDefault.", ex);\r
535                                                 break;\r
536                                         case "finalDefault":\r
537                                                 schema.finalDefault = XmlSchemaUtil.ReadDerivationAttribute(reader, out ex, "finalDefault");\r
538                                                 if(ex != null)\r
539                                                         warn(h, ex.Message , ex);\r
540                                                 break;\r
541                                         case "id":\r
542                                                 schema.id = reader.Value;\r
543                                                 break;\r
544                                         case "targetNamespace":\r
545                                                 schema.targetNamespace = reader.Value;\r
546                                                 break;\r
547                                         case "version":\r
548                                                 schema.version = reader.Value;\r
549                                                 break;\r
550                                         case "xml:lang":\r
551                                                 schema.language = reader.Value;\r
552                                                 break;\r
553                                         default:\r
554                                                 if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
555                                                         error(h, reader.Name + " attribute is not allowed in schema element",null);\r
556                                                 else\r
557                                                 {\r
558                                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,schema);\r
559                                                 }\r
560                                                 break;\r
561                                 }\r
562                         }\r
563                 }\r
564 \r
565                 private static void ReadContent(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)\r
566                 {\r
567                         reader.MoveToElement();\r
568                         if(reader.LocalName != "schema" && reader.NamespaceURI != XmlSchema.Namespace && reader.NodeType != XmlNodeType.Element)\r
569                                 error(h, "UNREACHABLE CODE REACHED: Method: Schema.ReadContent, " + reader.LocalName + ", " + reader.NamespaceURI,null);\r
570 \r
571                         //(include | import | redefine | annotation)*,\r
572                         //((simpleType | complexType | group | attributeGroup | element | attribute | notation | annotation)*\r
573                         int level = 1;\r
574                         while(reader.ReadNextElement())\r
575                         {\r
576                                 if(reader.NodeType == XmlNodeType.EndElement)\r
577                                 {\r
578                                         if(reader.LocalName != xmlname)\r
579                                                 error(h,"Should not happen :2: XmlSchema.Read, name="+reader.Name,null);\r
580                                         break;\r
581                                 }\r
582                                 if(level <= 1)\r
583                                 {\r
584                                         if(reader.LocalName == "include")\r
585                                         {\r
586                                                 XmlSchemaInclude include = XmlSchemaInclude.Read(reader,h);\r
587                                                 if(include != null)\r
588                                                         schema.includes.Add(include);\r
589                                                 continue;\r
590                                         }\r
591                                         if(reader.LocalName == "import")\r
592                                         {\r
593                                                 XmlSchemaImport import = XmlSchemaImport.Read(reader,h);\r
594                                                 if(import != null)\r
595                                                         schema.includes.Add(import);\r
596                                                 continue;\r
597                                         }\r
598                                         if(reader.LocalName == "redefine")\r
599                                         {\r
600                                                 XmlSchemaRedefine redefine = XmlSchemaRedefine.Read(reader,h);\r
601                                                 if(redefine != null)\r
602                                                         schema.includes.Add(redefine);\r
603                                                 continue;\r
604                                         }\r
605                                         if(reader.LocalName == "annotation")\r
606                                         {\r
607                                                 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
608                                                 if(annotation != null)\r
609                                                         schema.items.Add(annotation);\r
610                                                 continue;\r
611                                         }\r
612                                 }\r
613                                 if(level <=2)\r
614                                 {\r
615                                         level = 2;\r
616                                         if(reader.LocalName == "simpleType")\r
617                                         {\r
618                                                 XmlSchemaSimpleType stype = XmlSchemaSimpleType.Read(reader,h);\r
619                                                 if(stype != null)\r
620                                                         schema.items.Add(stype);\r
621                                                 continue;\r
622                                         }\r
623                                         if(reader.LocalName == "complexType")\r
624                                         {\r
625                                                 XmlSchemaComplexType ctype = XmlSchemaComplexType.Read(reader,h);\r
626                                                 if(ctype != null)\r
627                                                         schema.items.Add(ctype);\r
628                                                 continue;\r
629                                         }\r
630                                         if(reader.LocalName == "group")\r
631                                         {\r
632                                                 XmlSchemaGroup group = XmlSchemaGroup.Read(reader,h);\r
633                                                 if(group != null)\r
634                                                         schema.items.Add(group);\r
635                                                 continue;\r
636                                         }\r
637                                         if(reader.LocalName == "attributeGroup")\r
638                                         {\r
639                                                 XmlSchemaAttributeGroup attributeGroup = XmlSchemaAttributeGroup.Read(reader,h);\r
640                                                 if(attributeGroup != null)\r
641                                                         schema.items.Add(attributeGroup);\r
642                                                 continue;\r
643                                         }\r
644                                         if(reader.LocalName == "element")\r
645                                         {\r
646                                                 XmlSchemaElement element = XmlSchemaElement.Read(reader,h);\r
647                                                 if(element != null)\r
648                                                         schema.items.Add(element);\r
649                                                 continue;\r
650                                         }\r
651                                         if(reader.LocalName == "attribute")\r
652                                         {\r
653                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
654                                                 if(attr != null)\r
655                                                         schema.items.Add(attr);\r
656                                                 continue;\r
657                                         }\r
658                                         if(reader.LocalName == "notation")\r
659                                         {\r
660                                                 XmlSchemaNotation notation = XmlSchemaNotation.Read(reader,h);\r
661                                                 if(notation != null)\r
662                                                         schema.items.Add(notation);\r
663                                                 continue;\r
664                                         }\r
665                                         if(reader.LocalName == "annotation")\r
666                                         {\r
667                                                 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
668                                                 if(annotation != null)\r
669                                                         schema.items.Add(annotation);\r
670                                                 continue;\r
671                                         }\r
672                                 }\r
673                                 reader.RaiseInvalidElementError();\r
674                         }\r
675                 }\r
676                 #endregion\r
677 \r
678                 #region write\r
679 \r
680                 public void Write(System.IO.Stream stream)\r
681                 {\r
682                         Write(stream,null);\r
683                 }\r
684                 public void Write(System.IO.TextWriter writer)\r
685                 {\r
686                         Write(writer,null);\r
687                 }\r
688                 public void Write(System.Xml.XmlWriter writer)\r
689                 {\r
690                         Write(writer,null);\r
691                 }\r
692                 public void Write(System.IO.Stream stream, System.Xml.XmlNamespaceManager namespaceManager)\r
693                 {\r
694                         Write(new XmlTextWriter(stream,null),namespaceManager);\r
695                 }\r
696                 public void Write(System.IO.TextWriter writer, System.Xml.XmlNamespaceManager namespaceManager)\r
697                 {\r
698                         XmlTextWriter xwriter = new XmlTextWriter(writer);\r
699                         xwriter.Formatting = Formatting.Indented;\r
700                         Write(xwriter,namespaceManager);\r
701                 }\r
702                 public void Write(System.Xml.XmlWriter writer, System.Xml.XmlNamespaceManager namespaceManager)\r
703                 {\r
704                         if(Namespaces == null)\r
705                         {\r
706                                 Namespaces = new XmlSerializerNamespaces();\r
707                         }\r
708                         //Add the xml schema namespace.\r
709                         if(Namespaces.Count == 0)\r
710                         {\r
711                                 Namespaces.Add("xs", XmlSchema.Namespace);\r
712                                 if (TargetNamespace != null && TargetNamespace != String.Empty)\r
713                                         Namespaces.Add("tns", TargetNamespace);\r
714                         }\r
715                         if(namespaceManager != null)\r
716                         {\r
717                                 foreach(string name in namespaceManager)\r
718                                 {\r
719                                         //xml and xmlns namespaced are added by default in namespaceManager.\r
720                                         //So we should ignore them\r
721                                         if(name!="xml" && name != "xmlns")\r
722                                                 Namespaces.Add(name,namespaceManager.LookupNamespace(name));\r
723                                 }\r
724                         }\r
725 \r
726                         XmlSerializer xser = new XmlSerializer(typeof(XmlSchema));\r
727                         xser.Serialize(writer,this,Namespaces);\r
728                         writer.Flush();\r
729                 }\r
730                 #endregion\r
731         }\r
732 }\r