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