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