Add MIT license to System.XML.DLL
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaElement.cs
1 //\r
2 // System.Xml.Schema.XmlSchemaElement.cs\r
3 //\r
4 // Authors:\r
5 //      Dwivedi, Ajay kumar  Adwiv@Yahoo.com\r
6 //      Enomoto, Atsushi     ginga@kit.hi-ho.ne.jp\r
7 //\r
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;\r
30 using System.Collections;\r
31 using System.Xml;\r
32 using System.Xml.Serialization;\r
33 using System.ComponentModel;\r
34 \r
35 namespace System.Xml.Schema\r
36 {\r
37         /// <summary>\r
38         /// Summary description for XmlSchemaElement.\r
39         /// </summary>\r
40         public class XmlSchemaElement : XmlSchemaParticle\r
41         {\r
42                 private XmlSchemaDerivationMethod block;\r
43                 private XmlSchemaDerivationMethod blockResolved;\r
44                 private XmlSchemaObjectCollection constraints;\r
45                 private string defaultValue;\r
46                 private object elementType;\r
47                 private XmlSchemaDerivationMethod final;\r
48                 private XmlSchemaDerivationMethod finalResolved;\r
49                 private string fixedValue;\r
50                 private XmlSchemaForm form;\r
51                 private bool isAbstract;\r
52                 private bool isNillable;\r
53                 private string name;\r
54                 private XmlQualifiedName qName;\r
55                 private XmlQualifiedName refName;\r
56                 private XmlSchemaType schemaType;\r
57                 private XmlQualifiedName schemaTypeName;\r
58                 private XmlQualifiedName substitutionGroup;\r
59                 internal bool parentIsSchema = false;\r
60                 private string validatedDefaultValue;\r
61                 private string validatedFixedValue;\r
62                 private bool actualIsAbstract;\r
63                 private bool actualIsNillable;\r
64                 private XmlSchemaElement substitutionGroupElement;\r
65                 private ArrayList substitutingElements = new ArrayList ();\r
66                 private XmlSchemaElement referencedElement;\r
67 \r
68                 // Post compilation items. It should be added on all schema components.\r
69                 XmlSchema schema;\r
70 \r
71                 const string xmlname = "element";\r
72 \r
73                 public XmlSchemaElement()\r
74                 {\r
75                         block = XmlSchemaDerivationMethod.None;\r
76                         final = XmlSchemaDerivationMethod.None;\r
77                         constraints = new XmlSchemaObjectCollection();\r
78                         qName = XmlQualifiedName.Empty;\r
79                         refName = XmlQualifiedName.Empty;\r
80                         schemaTypeName = XmlQualifiedName.Empty;\r
81                         substitutionGroup = XmlQualifiedName.Empty;\r
82                 }\r
83 \r
84                 #region Attributes\r
85                 \r
86                 [DefaultValue(false)]\r
87                 [System.Xml.Serialization.XmlAttribute("abstract")]\r
88                 public bool IsAbstract \r
89                 {\r
90                         get{ return  isAbstract; }\r
91                         set{ isAbstract = value; }\r
92                 }\r
93 \r
94                 [DefaultValue(XmlSchemaDerivationMethod.None)]\r
95                 [System.Xml.Serialization.XmlAttribute("block")]\r
96                 public XmlSchemaDerivationMethod Block \r
97                 {\r
98                         get{ return  block; }\r
99                         set{ block = value; }\r
100                 }\r
101                 \r
102                 [DefaultValue(null)]\r
103                 [System.Xml.Serialization.XmlAttribute("default")]\r
104                 public string DefaultValue \r
105                 {\r
106                         get{ return  defaultValue; }\r
107                         set{ defaultValue = value; }\r
108                 }\r
109                 \r
110                 [DefaultValue(XmlSchemaDerivationMethod.None)]\r
111                 [System.Xml.Serialization.XmlAttribute("final")]\r
112                 public XmlSchemaDerivationMethod Final \r
113                 {\r
114                         get{ return  final; }\r
115                         set{ final = value; }\r
116                 }\r
117 \r
118                 [DefaultValue(null)]\r
119                 [System.Xml.Serialization.XmlAttribute("fixed")]\r
120                 public string FixedValue \r
121                 {\r
122                         get{ return  fixedValue; }\r
123                         set{ fixedValue = value; }\r
124                 }\r
125                 [DefaultValue(XmlSchemaForm.None)]\r
126                 [System.Xml.Serialization.XmlAttribute("form")]\r
127                 public XmlSchemaForm Form \r
128                 {\r
129                         get{ return  form; }\r
130                         set{ form = value; }\r
131                 }\r
132 \r
133                 [DefaultValue(null)]\r
134                 [System.Xml.Serialization.XmlAttribute("name")]\r
135                 public string Name \r
136                 {\r
137                         get{ return  name; }\r
138                         set{ name = value; }\r
139                 }\r
140 \r
141                 [DefaultValue(false)]\r
142                 [System.Xml.Serialization.XmlAttribute("nillable")]\r
143                 public bool IsNillable \r
144                 {\r
145                         get{ return  isNillable; }\r
146                         set{ isNillable = value; }\r
147                 }\r
148 \r
149                 [System.Xml.Serialization.XmlAttribute("ref")]\r
150                 public XmlQualifiedName RefName \r
151                 {\r
152                         get{ return  refName; }\r
153                         set{ refName = value;}\r
154                 }\r
155 \r
156                 [System.Xml.Serialization.XmlAttribute("substitutionGroup")]\r
157                 public XmlQualifiedName SubstitutionGroup\r
158                 {\r
159                         get{ return  substitutionGroup; }\r
160                         set{ substitutionGroup = value; }\r
161                 }\r
162                 \r
163                 [System.Xml.Serialization.XmlAttribute("type")]\r
164                 public XmlQualifiedName SchemaTypeName \r
165                 {\r
166                         get{ return  schemaTypeName; }\r
167                         set{ schemaTypeName = value; }\r
168                 }\r
169                 #endregion\r
170 \r
171                 #region Elements\r
172 \r
173                 [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
174                 [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
175                 public XmlSchemaType SchemaType \r
176                 {\r
177                         get{ return  schemaType; }\r
178                         set{ schemaType = value; }\r
179                 }\r
180 \r
181                 [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]\r
182                 [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]\r
183                 [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]\r
184                 public XmlSchemaObjectCollection Constraints \r
185                 {\r
186                         get{ return constraints; }\r
187                 }\r
188                 #endregion\r
189 \r
190                 #region Post Compilation Schema Info\r
191                 [XmlIgnore]\r
192                 public XmlQualifiedName QualifiedName \r
193                 {\r
194                         get{ return qName; }\r
195                 }\r
196 \r
197                 [XmlIgnore]\r
198                 public object ElementType \r
199                 {\r
200                         get {\r
201                                 if (referencedElement != null)\r
202                                         return referencedElement.ElementType;\r
203                                 else\r
204                                         return elementType;\r
205                         }\r
206                 }\r
207 \r
208                 [XmlIgnore]\r
209                 public XmlSchemaDerivationMethod BlockResolved \r
210                 {\r
211                         get{\r
212                                 if (referencedElement != null)\r
213                                         return referencedElement.BlockResolved;\r
214                                 else\r
215                                         return blockResolved;\r
216                         }\r
217                 }\r
218                 \r
219                 [XmlIgnore]\r
220                 public XmlSchemaDerivationMethod FinalResolved \r
221                 {\r
222                         get{\r
223                                 if (referencedElement != null)\r
224                                         return referencedElement.FinalResolved;\r
225                                 else\r
226                                         return finalResolved;\r
227                         }\r
228                 }\r
229 \r
230                 internal bool ActualIsNillable {\r
231                         get {\r
232                                 if (referencedElement != null)\r
233                                         return referencedElement.ActualIsNillable;\r
234                                 else\r
235                                         return actualIsNillable;\r
236                         }\r
237                 }\r
238                 \r
239                 internal bool ActualIsAbstract {\r
240                         get {\r
241                                 if (referencedElement != null)\r
242                                         return referencedElement.ActualIsAbstract;\r
243                                 else\r
244                                         return actualIsAbstract;\r
245                         }\r
246                 }\r
247                 \r
248                 // Post compilation default value (normalized)\r
249                 internal string ValidatedDefaultValue {\r
250                         get{\r
251                                 if (referencedElement != null)\r
252                                         return referencedElement.ValidatedDefaultValue;\r
253                                 else\r
254                                         return validatedDefaultValue;\r
255                         }\r
256                 }\r
257 \r
258                 // Post compilation fixed value (normalized)\r
259                 internal string ValidatedFixedValue {\r
260                         get{\r
261                                 if (referencedElement != null)\r
262                                         return referencedElement.ValidatedFixedValue;\r
263                                 else\r
264                                         return validatedFixedValue;\r
265                         }\r
266                 }\r
267 \r
268                 internal ArrayList SubstitutingElements {\r
269                         get {\r
270                                 if (referencedElement != null)\r
271                                         return referencedElement.SubstitutingElements;\r
272                                 else\r
273                                         return this.substitutingElements;\r
274                         }\r
275                 }\r
276 \r
277                 internal XmlSchemaElement SubstitutionGroupElement {\r
278                         get {\r
279                                 if (referencedElement != null)\r
280                                         return referencedElement.SubstitutionGroupElement;\r
281                                 else\r
282                                         return substitutionGroupElement;\r
283                         }\r
284                 }\r
285 \r
286                 #endregion\r
287 \r
288                 private XmlSchemaParticle substChoice;\r
289 \r
290                 /// <remarks>\r
291                 /// a) If Element has parent as schema:\r
292                 ///             1. name must be present and of type NCName.\r
293                 ///             2. ref must be absent\r
294                 ///             3. form must be absent\r
295                 ///             4. minOccurs must be absent\r
296                 ///             5. maxOccurs must be absent\r
297                 ///     b) If Element has parent is not schema and ref is absent\r
298                 ///             1. name must be present and of type NCName.\r
299                 ///             2. if form equals qualified or form is absent and schema's formdefault is qualifed,\r
300                 ///                targetNamespace is schema's targetnamespace else empty.\r
301                 ///             3. type and either <simpleType> or <complexType> are mutually exclusive\r
302                 ///             4. default and fixed must not both be present.\r
303                 ///             5. substitutiongroup must be absent\r
304                 ///             6. final must be absent\r
305                 ///             7. abstract must be absent\r
306                 ///     c) if the parent is not schema and ref is set\r
307                 ///             1. name must not be present\r
308                 ///             2. all of <simpleType>,<complexType>,  <key>, <keyref>, <unique>, nillable, \r
309                 ///                default, fixed, form, block and type,  must be absent.\r
310                 ///         3. substitutiongroup is prohibited\r
311                 ///             4. final is prohibited\r
312                 ///             5. abstract is prohibited\r
313                 ///             6. default and fixed must not both be present.(Actually both are absent)\r
314                 /// </remarks>  \r
315                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
316                 {\r
317                         // If this is already compiled this time, simply skip.\r
318                         if (this.IsComplied (schema.CompilationId))\r
319                                 return 0;\r
320                         this.schema = schema;\r
321 \r
322                         if(this.defaultValue != null && this.fixedValue != null)\r
323                                 error(h,"both default and fixed can't be present");\r
324 \r
325                         if(parentIsSchema || isRedefineChild)\r
326                         {\r
327                                 if(this.refName != null && !RefName.IsEmpty)\r
328                                         error(h,"ref must be absent");\r
329 \r
330                                 if(this.name == null)   //b1\r
331                                         error(h,"Required attribute name must be present");\r
332                                 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2\r
333                                         error(h,"attribute name must be NCName");\r
334                                 else\r
335                                         this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);\r
336 \r
337                                 if(form != XmlSchemaForm.None)\r
338                                         error(h,"form must be absent");\r
339                                 if(MinOccursString != null)\r
340                                         error(h,"minOccurs must be absent");\r
341                                 if(MaxOccursString != null)\r
342                                         error(h,"maxOccurs must be absent");\r
343 \r
344                                 XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);\r
345                                 if(final == XmlSchemaDerivationMethod.All)\r
346                                         finalResolved = allfinal;\r
347                                 else if(final == XmlSchemaDerivationMethod.None)\r
348                                         finalResolved = XmlSchemaDerivationMethod.Empty;\r
349                                 else \r
350                                 {\r
351 //                                      if((final & ~allfinal) != 0)\r
352                                         if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)\r
353                                                 error (h,"some values for final are invalid in this context");\r
354                                         finalResolved = final & allfinal;\r
355                                 }\r
356 \r
357                                 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)\r
358                                 {\r
359                                         error(h,"both schemaType and content can't be present");\r
360                                 }\r
361 \r
362                                 //Even if both are present, read both of them.\r
363                                 if(schemaType != null)\r
364                                 {\r
365                                         if(schemaType is XmlSchemaSimpleType)\r
366                                         {\r
367                                                 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);\r
368                                         }\r
369                                         else if(schemaType is XmlSchemaComplexType)\r
370                                         {\r
371                                                 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);\r
372                                         }\r
373                                         else\r
374                                                 error(h,"only simpletype or complextype is allowed");\r
375                                 }\r
376                                 if(schemaTypeName != null && !schemaTypeName.IsEmpty)\r
377                                 {\r
378                                         if(!XmlSchemaUtil.CheckQName(SchemaTypeName))\r
379                                                 error(h,"SchemaTypeName must be an XmlQualifiedName");\r
380                                 }\r
381                                 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)\r
382                                 {\r
383                                         if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))\r
384                                                 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");\r
385                                 }\r
386 \r
387                                 foreach(XmlSchemaObject obj in constraints)\r
388                                 {\r
389                                         if(obj is XmlSchemaUnique)\r
390                                                 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);\r
391                                         else if(obj is XmlSchemaKey)\r
392                                                 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);\r
393                                         else if(obj is XmlSchemaKeyref)\r
394                                                 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);\r
395                                 }\r
396                         }\r
397                         else\r
398                         {\r
399                                 if(substitutionGroup != null && !substitutionGroup.IsEmpty)\r
400                                         error(h,"substitutionGroup must be absent");\r
401                                 if(final != XmlSchemaDerivationMethod.None)\r
402                                         error(h,"final must be absent");\r
403 \r
404                                 CompileOccurence (h, schema);\r
405 \r
406                                 if(refName == null || RefName.IsEmpty)\r
407                                 {\r
408                                         string targetNamespace = String.Empty;\r
409 \r
410                                         if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))\r
411                                                 targetNamespace = schema.TargetNamespace;\r
412 \r
413                                         if(this.name == null)   //b1\r
414                                                 error(h,"Required attribute name must be present");\r
415                                         else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2\r
416                                                 error(h,"attribute name must be NCName");\r
417                                         else\r
418                                                 this.qName = new XmlQualifiedName(this.name, targetNamespace);\r
419                                 \r
420                                         if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)\r
421                                         {\r
422                                                 error(h,"both schemaType and content can't be present");\r
423                                         }\r
424 \r
425                                         //Even if both are present, read both of them.\r
426                                         if(schemaType != null)\r
427                                         {\r
428                                                 if(schemaType is XmlSchemaSimpleType)\r
429                                                 {\r
430                                                         errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);\r
431                                                 }\r
432                                                 else if(schemaType is XmlSchemaComplexType)\r
433                                                 {\r
434                                                         errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);\r
435                                                 }\r
436                                                 else\r
437                                                         error(h,"only simpletype or complextype is allowed");\r
438                                         }\r
439                                         if(schemaTypeName != null && !schemaTypeName.IsEmpty)\r
440                                         {\r
441                                                 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))\r
442                                                         error(h,"SchemaTypeName must be an XmlQualifiedName");\r
443                                         }\r
444                                         if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)\r
445                                         {\r
446                                                 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))\r
447                                                         error(h,"SubstitutionGroup must be a valid XmlQualifiedName");\r
448                                         }\r
449 \r
450                                         foreach(XmlSchemaObject obj in constraints)\r
451                                         {\r
452                                                 if(obj is XmlSchemaUnique)\r
453                                                         errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);\r
454                                                 else if(obj is XmlSchemaKey)\r
455                                                         errorCount += ((XmlSchemaKey)obj).Compile(h,schema);\r
456                                                 else if(obj is XmlSchemaKeyref)\r
457                                                         errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);\r
458                                         }\r
459                                 }\r
460                                 else\r
461                                 {\r
462                                         if(!XmlSchemaUtil.CheckQName(RefName))\r
463                                                 error(h,"RefName must be a XmlQualifiedName");\r
464 \r
465                                         if(name != null)\r
466                                                 error(h,"name must not be present when ref is present");\r
467                                         if(Constraints.Count != 0)\r
468                                                 error(h,"key, keyref and unique must be absent");\r
469                                         if(isNillable)\r
470                                                 error(h,"nillable must be absent");\r
471                                         if(defaultValue != null)\r
472                                                 error(h,"default must be absent");\r
473                                         if(fixedValue != null)\r
474                                                 error(h,"fixed must be null");\r
475                                         if(form != XmlSchemaForm.None)\r
476                                                 error(h,"form must be absent");\r
477                                         if(block != XmlSchemaDerivationMethod.None)\r
478                                                 error(h,"block must be absent");\r
479                                         if(schemaTypeName != null && !schemaTypeName.IsEmpty)\r
480                                                 error(h,"type must be absent");\r
481                                         if(SchemaType != null)\r
482                                                 error(h,"simpleType or complexType must be absent");\r
483 \r
484                                         qName = RefName;\r
485                                 }\r
486                         }\r
487 \r
488                         switch (block) {\r
489                         case XmlSchemaDerivationMethod.All:\r
490                                 blockResolved = XmlSchemaDerivationMethod.All;\r
491                                 break;\r
492                         case XmlSchemaDerivationMethod.None:\r
493                                 blockResolved = XmlSchemaDerivationMethod.Empty;\r
494                                 break;\r
495                         default:\r
496                                 if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)\r
497                                         error (h,"Some of the values for block are invalid in this context");\r
498                                 blockResolved = block;\r
499                                 break;\r
500                         }\r
501 \r
502                         if (Constraints != null) {\r
503                                 XmlSchemaObjectTable table = new XmlSchemaObjectTable ();\r
504                                 foreach (XmlSchemaIdentityConstraint c in Constraints) {\r
505                                         XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);\r
506                                 }\r
507                         }\r
508 \r
509                         XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
510 \r
511                         this.CompilationId = schema.CompilationId;\r
512                         return errorCount;\r
513                 }\r
514 \r
515                 [MonoTODO ("Return clone in case when it returns itself")]\r
516                 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)\r
517                 {\r
518                         if (OptimizedParticle != null)\r
519                                 return OptimizedParticle;\r
520                         if (RefName != null && RefName != XmlQualifiedName.Empty) {\r
521                                 referencedElement = schema.Elements [RefName] as XmlSchemaElement;\r
522                         }\r
523 \r
524 //                      if (this.referencedElement != null)\r
525 //                              OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);\r
526 //                      else \r
527                         if (ValidatedMaxOccurs == 0)\r
528                                 OptimizedParticle = XmlSchemaParticle.Empty;\r
529                         // Substitution Group\r
530                         else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {\r
531                                 XmlSchemaChoice choice = new XmlSchemaChoice ();\r
532                                 choice.MinOccurs = MinOccurs;\r
533                                 choice.MaxOccurs = MaxOccurs;\r
534                                 substChoice = choice;\r
535                                 choice.Compile (null, schema); // compute Validated Min/Max Occurs.\r
536                                 XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;\r
537                                 item.MinOccurs = 1;\r
538                                 item.MaxOccurs = 1;\r
539                                 item.substitutionGroupElement = null;\r
540                                 item.substitutingElements = null;\r
541                                 for (int i = 0; i < SubstitutingElements.Count; i++) {\r
542                                         XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;\r
543 //                                      choice.Items.Add (se);\r
544 //                                      choice.CompiledItems.Add (se);\r
545                                         this.AddSubstElementRecursively (choice.Items, se);\r
546                                         this.AddSubstElementRecursively (choice.CompiledItems, se);\r
547                                 }\r
548                                 if (!choice.Items.Contains (item)) {\r
549                                         choice.Items.Add (item);\r
550                                         choice.CompiledItems.Add (item);\r
551                                 }\r
552                                 OptimizedParticle = choice;\r
553                         }\r
554                         else\r
555                                 OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;\r
556                         return OptimizedParticle;\r
557                 }\r
558 \r
559                 private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)\r
560                 {\r
561                         if (el.SubstitutingElements != null)\r
562                                 for (int i = 0; i < el.SubstitutingElements.Count; i++)\r
563                                         this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);\r
564                         if (!col.Contains (el))\r
565                                 col.Add (el);\r
566                 }\r
567 \r
568                 internal void FillSubstitutionElementInfo ()\r
569                 {\r
570                         if (this.substitutionGroupElement != null)\r
571                                 return;\r
572 \r
573                         if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
574                                 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;\r
575                                 this.substitutionGroupElement = substElem;\r
576                                 if (substElem != null)\r
577                                         substElem.substitutingElements.Add (this);\r
578                         }\r
579                 }\r
580 \r
581                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
582                 {\r
583                         if (IsValidated (schema.CompilationId))\r
584                                 return errorCount;\r
585 \r
586                         // See XML Schema Structures 3.6 for the complete description.\r
587 \r
588                         // Element Declaration Properties Correct\r
589                         // 1. = 3.3.1 (modulo 5.3)\r
590 \r
591                         // 3.3.1:\r
592                         // {annotation} is as is.\r
593                         // {name}, {target namespace}, {scope}, {disallowed substitution},\r
594                         // {substitution group exclusions} (handled the same as 'disallowed substitution')\r
595                         // and {identity-constraint-definitions} are Compile()d.\r
596                         // {value constraint} is going to be filled in step 2.\r
597 \r
598                         // actual {nillable}, {abstract} \r
599                         this.actualIsNillable = IsNillable;\r
600                         this.actualIsAbstract = IsAbstract;\r
601 \r
602                         // Before determining element type, we need to validate substituting element\r
603                         if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
604                                 XmlSchemaElement substElem = substitutionGroupElement;\r
605                                 if (substElem != null)\r
606                                         substElem.Validate (h, schema);\r
607                         }\r
608 \r
609                         // {type} from here\r
610                         XmlSchemaDatatype datatype = null;\r
611                         if (schemaType != null)\r
612                                 elementType = schemaType;\r
613                         else if (SchemaTypeName != XmlQualifiedName.Empty) {\r
614                                 XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;\r
615                                 // If el is null, then it is missing sub components .\r
616                                 if (type != null) {\r
617                                         type.Validate (h, schema);\r
618                                         elementType = type;\r
619                                 }\r
620                                 else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
621                                         elementType = XmlSchemaComplexType.AnyType;
622                                 else if (XmlSchemaUtil.IsBuiltInDatatypeName (SchemaTypeName)) {\r
623                                         datatype = XmlSchemaDatatype.FromName (SchemaTypeName);\r
624                                         if (datatype == null)\r
625                                                 error (h, "Invalid schema datatype was specified.");\r
626                                         else\r
627                                                 elementType = datatype;\r
628                                 }\r
629                                 // otherwise, it might be missing sub components.\r
630                                 else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))\r
631                                         error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");\r
632                         }\r
633                         else if (RefName != XmlQualifiedName.Empty)\r
634                         {\r
635                                 XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;\r
636                                 // If el is null, then it is missing sub components .\r
637                                 if (refElem != null) {\r
638                                         this.referencedElement = refElem;\r
639                                         errorCount += refElem.Validate (h, schema);\r
640                                 }\r
641                                 // otherwise, it might be missing sub components.\r
642                                 else if (!schema.IsNamespaceAbsent (RefName.Namespace))\r
643                                         error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");\r
644                         }\r
645                         \r
646                         // Otherwise if there are substitution group, then the type of the substitution group element.\r
647                         if (referencedElement == null) {\r
648                                 if (elementType == null && this.substitutionGroupElement != null)\r
649                                         elementType = substitutionGroupElement.ElementType;\r
650                                 // Otherwise, the -ur type- definition.\r
651                                 if (elementType == null)\r
652                                         elementType = XmlSchemaComplexType.AnyType;\r
653                         }\r
654 \r
655                         XmlSchemaType xsType = elementType as XmlSchemaType;\r
656                         if (xsType != null) {\r
657                                 errorCount += xsType.Validate (h, schema);\r
658                                 datatype = xsType.Datatype;\r
659                         }\r
660                         // basic {type} is now filled, except for derivation by {substitution group}.\r
661 \r
662                         // {substitution group affiliation}\r
663                         // 3. subsitution group's type derivation check.\r
664                         if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
665                                 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;\r
666                                 // If el is null, then it is missing sub components .\r
667                                 if (substElem != null) {\r
668                                         XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;\r
669                                         if (substSchemaType != null) {\r
670                                                 // 3.3.6 Properties Correct 3.\r
671                                                 if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)\r
672                                                         error (h, "Substituted element blocks substitution.");\r
673                                                 if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)\r
674                                                         error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");\r
675                                         }\r
676                                         XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;\r
677                                         if (xsComplexType != null)\r
678                                                 xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);\r
679                                         else {\r
680                                                 XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;\r
681                                                 if (xsSimpleType != null)\r
682                                                         xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);\r
683                                         }\r
684 \r
685                                 }\r
686                                 // otherwise, it might be missing sub components.\r
687                                 else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))\r
688                                         error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");\r
689                         }\r
690 \r
691                         // 2. ElementDefaultValid\r
692                         // 4. ID with {value constraint} is prohibited.\r
693                         if (defaultValue != null || fixedValue != null) {\r
694                                 ValidateElementDefaultValidImmediate (h, schema);\r
695                                 if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.\r
696                                         datatype.TokenizedType == XmlTokenizedType.ID)\r
697                                         error (h, "Element type is ID, which does not allows default or fixed values.");\r
698                         }\r
699 \r
700                         // Identity constraints (3.11.3 / 3.11.6)\r
701                         foreach (XmlSchemaIdentityConstraint ident in Constraints)\r
702                                 ident.Validate (h, schema);\r
703 \r
704                         ValidationId = schema.ValidationId;\r
705                         return errorCount;\r
706                 }\r
707 \r
708                 internal override bool ParticleEquals (XmlSchemaParticle other)\r
709                 {\r
710                         XmlSchemaElement element = other as XmlSchemaElement;\r
711                         if (element == null)\r
712                                 return false;\r
713                         if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||\r
714                                 this.ValidatedMinOccurs != element.ValidatedMinOccurs)\r
715                                 return false;\r
716                         if (this.QualifiedName != element.QualifiedName ||\r
717                                 this.ElementType != element.ElementType ||\r
718                                 this.Constraints.Count != element.Constraints.Count)\r
719                                 return false;\r
720                         for (int i = 0; i < this.Constraints.Count; i++) {\r
721                                 XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;\r
722                                 XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;\r
723                                 if (c1.QualifiedName != c2.QualifiedName ||\r
724                                         c1.Selector.XPath != c2.Selector.XPath ||\r
725                                         c1.Fields.Count != c2.Fields.Count)\r
726                                         return false;\r
727                                 for (int f = 0; f < c1.Fields.Count; f++) {\r
728                                         XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;\r
729                                         XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;\r
730                                         if (f1.XPath != f2.XPath)\r
731                                                 return false;\r
732                                 }\r
733                         }\r
734                         if (this.BlockResolved != element.BlockResolved ||\r
735                                 this.FinalResolved != element.FinalResolved ||\r
736                                 this.ValidatedDefaultValue != element.ValidatedDefaultValue ||\r
737                                 this.ValidatedFixedValue != element.ValidatedFixedValue)\r
738                                 return false;\r
739                         return true;\r
740                 }\r
741 \r
742                 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
743                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
744                 {\r
745                         // element - NameAndTypeOK\r
746                         XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;\r
747                         if (baseElement != null) {\r
748                                 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);\r
749                         }\r
750 \r
751                         // any - NSCompat\r
752                         XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;\r
753                         if (baseAny != null) {\r
754                                 // NSCompat\r
755                                 if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))\r
756                                         return false;\r
757                                 return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);\r
758                         }\r
759 \r
760 //*\r
761                         // choice - RecurseAsIfGroup\r
762                         XmlSchemaGroupBase gb = null;\r
763                         if (baseParticle is XmlSchemaSequence)\r
764                                 gb = new XmlSchemaSequence ();\r
765                         else if (baseParticle is XmlSchemaChoice)\r
766                                 gb = new XmlSchemaChoice ();\r
767                         else if (baseParticle is XmlSchemaAll)\r
768                                 gb = new XmlSchemaAll ();\r
769 \r
770                         if (gb != null) {\r
771                                 gb.Items.Add (this);\r
772                                 gb.Compile (h, schema);\r
773                                 gb.Validate (h, schema);\r
774                                 // It looks weird, but here we never think about \r
775                                 // _pointlessness_ of this groupbase particle.\r
776                                 return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);\r
777                         }\r
778 //*/\r
779                         return true;\r
780                 }\r
781 \r
782                 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,\r
783                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
784                 {\r
785                         // 1.\r
786                         if (this.QualifiedName != baseElement.QualifiedName) {\r
787                                 if (raiseError)\r
788                                         error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");\r
789                                 return false;\r
790                         }\r
791                         // 2.\r
792                         if (this.isNillable && !baseElement.isNillable) {\r
793                                 if (raiseError)\r
794                                         error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");\r
795                                 return false;\r
796                         }\r
797                         // 3.\r
798                         if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))\r
799                                 return false;\r
800                         // 4.\r
801                         if (baseElement.ValidatedFixedValue != null &&\r
802                                 baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {\r
803                                 if (raiseError)\r
804                                         error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");\r
805                                 return false;\r
806                         }\r
807                         // 5. TODO: What is "identity constraints subset" ???\r
808 \r
809                         // 6. \r
810                         if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {\r
811                                 if (raiseError)\r
812                                         error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");\r
813                                 return false;\r
814                         }\r
815                         // 7.\r
816                         if (baseElement.ElementType != null) {\r
817                                 XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;\r
818                                 if (derivedCType != null) {\r
819                                         // FIXME: W3C REC says that it is Type Derivation OK to be check, but\r
820                                         // in fact it should be DerivationValid (Restriction, Complex).\r
821                                         derivedCType.ValidateDerivationValidRestriction (\r
822                                                 baseElement.ElementType as XmlSchemaComplexType, h, schema);\r
823                                         derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);\r
824                                 } else {\r
825                                         XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;\r
826                                         if (derivedSType != null)\r
827                                                 derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);\r
828                                         else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {\r
829                                                 if (raiseError)\r
830                                                         error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");\r
831                                                 return false;\r
832                                         }\r
833                                 }\r
834                         }\r
835                         return true;\r
836                 }\r
837 \r
838                 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)\r
839                 {\r
840                         XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;\r
841                         if (ct == null || ct.Particle == null)\r
842                                 return;\r
843                         ct.Particle.CheckRecursion (depth + 1, h, schema);\r
844                 }\r
845 \r
846                 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,\r
847                         ValidationEventHandler h, XmlSchema schema)\r
848                 {\r
849                         if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))\r
850                                 error (h, "Ambiguous element label was detected: " + this.QualifiedName);\r
851                         else {\r
852                                 foreach (XmlSchemaAny any in nsNames) {\r
853                                         if (any.ValidatedMaxOccurs == 0)\r
854                                                 continue;\r
855                                         if (any.HasValueAny ||\r
856                                                 any.HasValueLocal && this.QualifiedName.Namespace == "" ||\r
857                                                 any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||\r
858                                                 any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {\r
859                                                 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);\r
860                                                 break;\r
861                                         } else if (!any.HasValueOther) {\r
862                                                 bool bad = false;\r
863                                                 foreach (string ns in any.ResolvedNamespaces) {\r
864                                                         if (ns == this.QualifiedName.Namespace) {\r
865                                                                 bad = true;\r
866                                                                 break;\r
867                                                         }\r
868                                                 }\r
869                                                 if (bad) {\r
870                                                         error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);\r
871                                                         break;\r
872                                                 }\r
873                                         } else {\r
874                                                 if (any.TargetNamespace.Length == 0 ||\r
875                                                         any.TargetNamespace != this.QualifiedName.Namespace)\r
876                                                         error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);\r
877                                         }\r
878                                 }\r
879                                 qnames.Add (this.QualifiedName, this);\r
880                         }\r
881                 }\r
882 \r
883                 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
884                         ValidationEventHandler h, XmlSchema schema)\r
885                 {\r
886                         XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;\r
887                         if (labeled == null)\r
888                                 labels.Add (this.QualifiedName, this);\r
889                         else if (labeled.ElementType != this.ElementType)\r
890                                 error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);\r
891                 }\r
892 \r
893 \r
894                 // 3.3.6 Element Default Valid (Immediate)\r
895                 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)\r
896                 {\r
897                         // This presumes that ElementType is already filled.\r
898 \r
899                         XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;\r
900                         XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;\r
901                         if (simpleType != null)\r
902                                 datatype = simpleType.Datatype;\r
903 \r
904                         if (datatype == null) {\r
905                                 XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;\r
906                                 switch (complexType.ContentType) {\r
907                                 case XmlSchemaContentType.Empty:\r
908                                 case XmlSchemaContentType.ElementOnly:\r
909                                         error (h, "Element content type must be simple type or mixed.");\r
910                                         break;\r
911                                 }\r
912                                 datatype = XmlSchemaSimpleType.AnySimpleType;\r
913                         }\r
914 \r
915                         XmlNamespaceManager nsmgr = null;\r
916                         if (datatype.TokenizedType == XmlTokenizedType.QName) {\r
917                                 if (this.Namespaces != null)\r
918                                         foreach (XmlQualifiedName qname in Namespaces.ToArray ())\r
919                                                 nsmgr.AddNamespace (qname.Name, qname.Namespace);\r
920                         }\r
921 \r
922                         try {\r
923                                 if (defaultValue != null) {\r
924                                         validatedDefaultValue = datatype.Normalize (defaultValue);\r
925                                         datatype.ParseValue (validatedDefaultValue, null, nsmgr);\r
926                                 }\r
927                         } catch (Exception ex) {\r
928                                 // FIXME: This is not a good way to handle exception, but\r
929                                 // I think there is no remedy for such Framework specification.\r
930                                 error (h, "The Element's default value is invalid with respect to its type definition.", ex);\r
931                         }\r
932                         try {\r
933                                 if (fixedValue != null) {\r
934                                         validatedFixedValue = datatype.Normalize (fixedValue);\r
935                                         datatype.ParseValue (validatedFixedValue, null, nsmgr);\r
936                                 }\r
937                         } catch (Exception ex) {\r
938                                 // FIXME: This is not a good way to handle exception.\r
939                                 error (h, "The Element's fixed value is invalid with its type definition.", ex);\r
940                         }\r
941                 }\r
942 \r
943                 //<element\r
944                 //  abstract = boolean : false\r
945                 //  block = (#all | List of (extension | restriction | substitution)) \r
946                 //  default = string\r
947                 //  final = (#all | List of (extension | restriction)) \r
948                 //  fixed = string\r
949                 //  form = (qualified | unqualified)\r
950                 //  id = ID\r
951                 //  maxOccurs = (nonNegativeInteger | unbounded)  : 1\r
952                 //  minOccurs = nonNegativeInteger : 1\r
953                 //  name = NCName\r
954                 //  nillable = boolean : false\r
955                 //  ref = QName\r
956                 //  substitutionGroup = QName\r
957                 //  type = QName\r
958                 //  {any attributes with non-schema namespace . . .}>\r
959                 //  Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))\r
960                 //</element>\r
961 \r
962                 internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)\r
963                 {\r
964                         XmlSchemaElement element = new XmlSchemaElement();\r
965                         Exception innerex;\r
966                         reader.MoveToElement();\r
967 \r
968                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
969                         {\r
970                                 error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);\r
971                                 reader.Skip();\r
972                                 return null;\r
973                         }\r
974 \r
975                         element.LineNumber = reader.LineNumber;\r
976                         element.LinePosition = reader.LinePosition;\r
977                         element.SourceUri = reader.BaseURI;\r
978 \r
979                         while(reader.MoveToNextAttribute())\r
980                         {\r
981                                 if(reader.Name == "abstract")\r
982                                 {\r
983                                         element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
984                                         if(innerex != null)\r
985                                                 error(h,reader.Value + " is invalid value for abstract",innerex);\r
986                                 }\r
987                                 else if(reader.Name == "block")\r
988                                 {\r
989                                         element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",\r
990                                                 XmlSchemaUtil.ElementBlockAllowed);\r
991                                         if(innerex != null)\r
992                                                 error (h,"some invalid values for block attribute were found",innerex);\r
993                                 }\r
994                                 else if(reader.Name == "default")\r
995                                 {\r
996                                         element.defaultValue = reader.Value;\r
997                                 }\r
998                                 else if(reader.Name == "final")\r
999                                 {\r
1000                                         element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",\r
1001                                                 XmlSchemaUtil.FinalAllowed);\r
1002                                         if(innerex != null)\r
1003                                                 error (h,"some invalid values for final attribute were found",innerex);\r
1004                                 }\r
1005                                 else if(reader.Name == "fixed")\r
1006                                 {\r
1007                                         element.fixedValue = reader.Value;\r
1008                                 }\r
1009                                 else if(reader.Name == "form")\r
1010                                 {\r
1011                                         element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);\r
1012                                         if(innerex != null)\r
1013                                                 error(h,reader.Value + " is an invalid value for form attribute",innerex);\r
1014                                 }\r
1015                                 else if(reader.Name == "id")\r
1016                                 {\r
1017                                         element.Id = reader.Value;\r
1018                                 }\r
1019                                 else if(reader.Name == "maxOccurs")\r
1020                                 {\r
1021                                         try\r
1022                                         {\r
1023                                                 element.MaxOccursString = reader.Value;\r
1024                                         }\r
1025                                         catch(Exception e)\r
1026                                         {\r
1027                                                 error(h,reader.Value + " is an invalid value for maxOccurs",e);\r
1028                                         }\r
1029                                 }\r
1030                                 else if(reader.Name == "minOccurs")\r
1031                                 {\r
1032                                         try\r
1033                                         {\r
1034                                                 element.MinOccursString = reader.Value;\r
1035                                         }\r
1036                                         catch(Exception e)\r
1037                                         {\r
1038                                                 error(h,reader.Value + " is an invalid value for minOccurs",e);\r
1039                                         }\r
1040                                 }\r
1041                                 else if(reader.Name == "name")\r
1042                                 {\r
1043                                         element.Name = reader.Value;\r
1044                                 }\r
1045                                 else if(reader.Name == "nillable")\r
1046                                 {\r
1047                                         element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
1048                                         if(innerex != null)\r
1049                                                 error(h,reader.Value + "is not a valid value for nillable",innerex);\r
1050                                 }\r
1051                                 else if(reader.Name == "ref")\r
1052                                 {\r
1053                                         element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
1054                                         if(innerex != null)\r
1055                                                 error(h, reader.Value + " is not a valid value for ref attribute",innerex);\r
1056                                 }\r
1057                                 else if(reader.Name == "substitutionGroup")\r
1058                                 {\r
1059                                         element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
1060                                         if(innerex != null)\r
1061                                                 error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);\r
1062                                 }\r
1063                                 else if(reader.Name == "type")\r
1064                                 {\r
1065                                         element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
1066                                         if(innerex != null)\r
1067                                                 error(h, reader.Value + " is not a valid value for type attribute",innerex);\r
1068                                 }\r
1069                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
1070                                 {\r
1071                                         error(h,reader.Name + " is not a valid attribute for element",null);\r
1072                                 }\r
1073                                 else\r
1074                                 {\r
1075                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,element);\r
1076                                 }\r
1077                         }\r
1078                         \r
1079                         reader.MoveToElement();\r
1080                         if(reader.IsEmptyElement)\r
1081                                 return element;\r
1082 \r
1083                         //  Content: annotation?, \r
1084                         //                      (simpleType | complexType)?, \r
1085                         //                      (unique | key | keyref)*\r
1086                         int level = 1;\r
1087                         while(reader.ReadNextElement())\r
1088                         {\r
1089                                 if(reader.NodeType == XmlNodeType.EndElement)\r
1090                                 {\r
1091                                         if(reader.LocalName != xmlname)\r
1092                                                 error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);\r
1093                                         break;\r
1094                                 }\r
1095                                 if(level <= 1 && reader.LocalName == "annotation")\r
1096                                 {\r
1097                                         level = 2; //Only one annotation\r
1098                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
1099                                         if(annotation != null)\r
1100                                                 element.Annotation = annotation;\r
1101                                         continue;\r
1102                                 }\r
1103                                 if(level <= 2)\r
1104                                 {\r
1105                                         if(reader.LocalName == "simpleType")\r
1106                                         {\r
1107                                                 level = 3;\r
1108                                                 XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);\r
1109                                                 if(simple != null)\r
1110                                                         element.SchemaType = simple;\r
1111                                                 continue;\r
1112                                         }\r
1113                                         if(reader.LocalName == "complexType")\r
1114                                         {\r
1115                                                 level = 3;\r
1116                                                 XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);\r
1117                                                 if(complex != null)\r
1118                                                 {\r
1119                                                         element.SchemaType = complex;\r
1120                                                 }\r
1121                                                 continue;\r
1122                                         }\r
1123                                 }\r
1124                                 if(level <= 3)\r
1125                                 {\r
1126                                         if(reader.LocalName == "unique")\r
1127                                         {\r
1128                                                 level = 3;\r
1129                                                 XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);\r
1130                                                 if(unique != null)\r
1131                                                         element.constraints.Add(unique);\r
1132                                                 continue;\r
1133                                         }\r
1134                                         else if(reader.LocalName == "key")\r
1135                                         {\r
1136                                                 level = 3;\r
1137                                                 XmlSchemaKey key = XmlSchemaKey.Read(reader,h);\r
1138                                                 if(key != null)\r
1139                                                         element.constraints.Add(key);\r
1140                                                 continue;\r
1141                                         }\r
1142                                         else if(reader.LocalName == "keyref")\r
1143                                         {\r
1144                                                 level = 3;\r
1145                                                 XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);\r
1146                                                 if(keyref != null)\r
1147                                                         element.constraints.Add(keyref);\r
1148                                                 continue;\r
1149                                         }\r
1150                                 }\r
1151                                 reader.RaiseInvalidElementError();\r
1152                         }\r
1153                         return element;\r
1154                 }\r
1155         }\r
1156 }\r