(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaElement.cs
blob9ccb00f4a0d65383513c47985897194b9cdb8751
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 //
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.
29 using System;
30 using System.Collections;
31 using System.Xml;
32 using System.Xml.Serialization;
33 using System.ComponentModel;
35 namespace System.Xml.Schema
37 /// <summary>
38 /// Summary description for XmlSchemaElement.
39 /// </summary>
40 public class XmlSchemaElement : XmlSchemaParticle
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;
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;
75 const string xmlname = "element";
77 public XmlSchemaElement()
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 ();
88 private void InitPostCompileInformations ()
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;
105 #region Attributes
107 [DefaultValue(false)]
108 [System.Xml.Serialization.XmlAttribute("abstract")]
109 public bool IsAbstract
111 get{ return isAbstract; }
112 set{ isAbstract = value; }
115 [DefaultValue(XmlSchemaDerivationMethod.None)]
116 [System.Xml.Serialization.XmlAttribute("block")]
117 public XmlSchemaDerivationMethod Block
119 get{ return block; }
120 set{ block = value; }
123 [DefaultValue(null)]
124 [System.Xml.Serialization.XmlAttribute("default")]
125 public string DefaultValue
127 get{ return defaultValue; }
128 set{ defaultValue = value; }
131 [DefaultValue(XmlSchemaDerivationMethod.None)]
132 [System.Xml.Serialization.XmlAttribute("final")]
133 public XmlSchemaDerivationMethod Final
135 get{ return final; }
136 set{ final = value; }
139 [DefaultValue(null)]
140 [System.Xml.Serialization.XmlAttribute("fixed")]
141 public string FixedValue
143 get{ return fixedValue; }
144 set{ fixedValue = value; }
146 [DefaultValue(XmlSchemaForm.None)]
147 [System.Xml.Serialization.XmlAttribute("form")]
148 public XmlSchemaForm Form
150 get{ return form; }
151 set{ form = value; }
154 [DefaultValue(null)]
155 [System.Xml.Serialization.XmlAttribute("name")]
156 public string Name
158 get{ return name; }
159 set{ name = value; }
162 [DefaultValue(false)]
163 [System.Xml.Serialization.XmlAttribute("nillable")]
164 public bool IsNillable
166 get{ return isNillable; }
167 set{ isNillable = value; }
170 [System.Xml.Serialization.XmlAttribute("ref")]
171 public XmlQualifiedName RefName
173 get{ return refName; }
174 set{ refName = value;}
177 [System.Xml.Serialization.XmlAttribute("substitutionGroup")]
178 public XmlQualifiedName SubstitutionGroup
180 get{ return substitutionGroup; }
181 set{ substitutionGroup = value; }
184 [System.Xml.Serialization.XmlAttribute("type")]
185 public XmlQualifiedName SchemaTypeName
187 get{ return schemaTypeName; }
188 set{ schemaTypeName = value; }
190 #endregion
192 #region Elements
194 [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
195 [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
196 public XmlSchemaType SchemaType
198 get{ return schemaType; }
199 set{ schemaType = value; }
202 [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]
203 [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]
204 [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]
205 public XmlSchemaObjectCollection Constraints
207 get{ return constraints; }
209 #endregion
211 #region Post Compilation Schema Info
212 [XmlIgnore]
213 public XmlQualifiedName QualifiedName
215 get{ return qName; }
218 [XmlIgnore]
219 #if NET_2_0
220 [Obsolete]
221 #endif
222 public object ElementType
224 get {
225 if (referencedElement != null)
226 return referencedElement.ElementType;
227 else
228 return elementType;
232 #if NET_2_0
233 [XmlIgnore]
234 public XmlSchemaType ElementSchemaType
236 get {
237 if (referencedElement != null)
238 return referencedElement.ElementSchemaType;
239 else
240 return elementSchemaType;
243 #endif
245 [XmlIgnore]
246 public XmlSchemaDerivationMethod BlockResolved
248 get{
249 if (referencedElement != null)
250 return referencedElement.BlockResolved;
251 else
252 return blockResolved;
256 [XmlIgnore]
257 public XmlSchemaDerivationMethod FinalResolved
259 get{
260 if (referencedElement != null)
261 return referencedElement.FinalResolved;
262 else
263 return finalResolved;
267 internal bool ActualIsNillable {
268 get {
269 if (referencedElement != null)
270 return referencedElement.ActualIsNillable;
271 else
272 return actualIsNillable;
276 internal bool ActualIsAbstract {
277 get {
278 if (referencedElement != null)
279 return referencedElement.ActualIsAbstract;
280 else
281 return actualIsAbstract;
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;
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;
305 internal ArrayList SubstitutingElements {
306 get {
307 if (referencedElement != null)
308 return referencedElement.SubstitutingElements;
309 else
310 return this.substitutingElements;
314 internal XmlSchemaElement SubstitutionGroupElement {
315 get {
316 if (referencedElement != null)
317 return referencedElement.SubstitutionGroupElement;
318 else
319 return substitutionGroupElement;
323 #endregion
325 /// <remarks>
326 /// a) If Element has parent as schema:
327 /// 1. name must be present and of type NCName.
328 /// 2. ref must be absent
329 /// 3. form must be absent
330 /// 4. minOccurs must be absent
331 /// 5. maxOccurs must be absent
332 /// b) If Element has parent is not schema and ref is absent
333 /// 1. name must be present and of type NCName.
334 /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
335 /// targetNamespace is schema's targetnamespace else empty.
336 /// 3. type and either <simpleType> or <complexType> are mutually exclusive
337 /// 4. default and fixed must not both be present.
338 /// 5. substitutiongroup must be absent
339 /// 6. final must be absent
340 /// 7. abstract must be absent
341 /// c) if the parent is not schema and ref is set
342 /// 1. name must not be present
343 /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
344 /// default, fixed, form, block and type, must be absent.
345 /// 3. substitutiongroup is prohibited
346 /// 4. final is prohibited
347 /// 5. abstract is prohibited
348 /// 6. default and fixed must not both be present.(Actually both are absent)
349 /// </remarks>
350 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
352 // If this is already compiled this time, simply skip.
353 if (this.IsComplied (schema.CompilationId))
354 return 0;
355 InitPostCompileInformations ();
356 this.schema = schema;
358 if(this.defaultValue != null && this.fixedValue != null)
359 error(h,"both default and fixed can't be present");
361 if(parentIsSchema || isRedefineChild)
363 if(this.refName != null && !RefName.IsEmpty)
364 error(h,"ref must be absent");
366 if(this.name == null) //b1
367 error(h,"Required attribute name must be present");
368 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
369 error(h,"attribute name must be NCName");
370 else
371 this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);
373 if(form != XmlSchemaForm.None)
374 error(h,"form must be absent");
375 if(MinOccursString != null)
376 error(h,"minOccurs must be absent");
377 if(MaxOccursString != null)
378 error(h,"maxOccurs must be absent");
380 XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
381 if(final == XmlSchemaDerivationMethod.All)
382 finalResolved = allfinal;
383 else if(final == XmlSchemaDerivationMethod.None)
384 finalResolved = XmlSchemaDerivationMethod.Empty;
385 else
387 // if((final & ~allfinal) != 0)
388 if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)
389 error (h,"some values for final are invalid in this context");
390 finalResolved = final & allfinal;
393 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
395 error(h,"both schemaType and content can't be present");
398 //Even if both are present, read both of them.
399 if(schemaType != null)
401 if(schemaType is XmlSchemaSimpleType)
403 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
405 else if(schemaType is XmlSchemaComplexType)
407 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
409 else
410 error(h,"only simpletype or complextype is allowed");
412 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
414 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
415 error(h,"SchemaTypeName must be an XmlQualifiedName");
417 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
419 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
420 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
423 foreach(XmlSchemaObject obj in constraints)
425 if(obj is XmlSchemaUnique)
426 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
427 else if(obj is XmlSchemaKey)
428 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
429 else if(obj is XmlSchemaKeyref)
430 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
433 else
435 if(substitutionGroup != null && !substitutionGroup.IsEmpty)
436 error(h,"substitutionGroup must be absent");
437 if(final != XmlSchemaDerivationMethod.None)
438 error(h,"final must be absent");
440 CompileOccurence (h, schema);
442 if(refName == null || RefName.IsEmpty)
444 string targetNamespace = String.Empty;
446 if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))
447 targetNamespace = schema.TargetNamespace;
449 if(this.name == null) //b1
450 error(h,"Required attribute name must be present");
451 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
452 error(h,"attribute name must be NCName");
453 else
454 this.qName = new XmlQualifiedName(this.name, targetNamespace);
456 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
458 error(h,"both schemaType and content can't be present");
461 //Even if both are present, read both of them.
462 if(schemaType != null)
464 if(schemaType is XmlSchemaSimpleType)
466 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
468 else if(schemaType is XmlSchemaComplexType)
470 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
472 else
473 error(h,"only simpletype or complextype is allowed");
475 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
477 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
478 error(h,"SchemaTypeName must be an XmlQualifiedName");
480 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
482 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
483 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
486 foreach(XmlSchemaObject obj in constraints)
488 if(obj is XmlSchemaUnique)
489 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
490 else if(obj is XmlSchemaKey)
491 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
492 else if(obj is XmlSchemaKeyref)
493 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
496 else
498 if(!XmlSchemaUtil.CheckQName(RefName))
499 error(h,"RefName must be a XmlQualifiedName");
501 if(name != null)
502 error(h,"name must not be present when ref is present");
503 if(Constraints.Count != 0)
504 error(h,"key, keyref and unique must be absent");
505 if(isNillable)
506 error(h,"nillable must be absent");
507 if(defaultValue != null)
508 error(h,"default must be absent");
509 if(fixedValue != null)
510 error(h,"fixed must be null");
511 if(form != XmlSchemaForm.None)
512 error(h,"form must be absent");
513 if(block != XmlSchemaDerivationMethod.None)
514 error(h,"block must be absent");
515 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
516 error(h,"type must be absent");
517 if(SchemaType != null)
518 error(h,"simpleType or complexType must be absent");
520 qName = RefName;
524 switch (block) {
525 case XmlSchemaDerivationMethod.All:
526 blockResolved = XmlSchemaDerivationMethod.All;
527 break;
528 case XmlSchemaDerivationMethod.None:
529 blockResolved = XmlSchemaDerivationMethod.Empty;
530 break;
531 default:
532 if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
533 error (h,"Some of the values for block are invalid in this context");
534 blockResolved = block;
535 break;
538 if (Constraints != null) {
539 XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
540 foreach (XmlSchemaIdentityConstraint c in Constraints) {
541 XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
545 XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
547 this.CompilationId = schema.CompilationId;
548 return errorCount;
551 [MonoTODO ("Return clone in case when it returns itself")]
552 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
554 if (OptimizedParticle != null)
555 return OptimizedParticle;
556 if (RefName != null && RefName != XmlQualifiedName.Empty) {
557 referencedElement = schema.Elements [RefName] as XmlSchemaElement;
560 // if (this.referencedElement != null)
561 // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
562 // else
563 if (ValidatedMaxOccurs == 0)
564 OptimizedParticle = XmlSchemaParticle.Empty;
565 // Substitution Group
566 else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {
567 XmlSchemaChoice choice = new XmlSchemaChoice ();
568 choice.MinOccurs = MinOccurs;
569 choice.MaxOccurs = MaxOccurs;
570 substChoice = choice;
571 choice.Compile (null, schema); // compute Validated Min/Max Occurs.
572 XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;
573 item.MinOccurs = 1;
574 item.MaxOccurs = 1;
575 item.substitutionGroupElement = null;
576 item.substitutingElements = null;
577 for (int i = 0; i < SubstitutingElements.Count; i++) {
578 XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;
579 // choice.Items.Add (se);
580 // choice.CompiledItems.Add (se);
581 this.AddSubstElementRecursively (choice.Items, se);
582 this.AddSubstElementRecursively (choice.CompiledItems, se);
584 if (!choice.Items.Contains (item)) {
585 choice.Items.Add (item);
586 choice.CompiledItems.Add (item);
588 OptimizedParticle = choice;
590 else
591 OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;
592 return OptimizedParticle;
595 private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)
597 if (el.SubstitutingElements != null)
598 for (int i = 0; i < el.SubstitutingElements.Count; i++)
599 this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);
600 if (!col.Contains (el))
601 col.Add (el);
604 internal void FillSubstitutionElementInfo ()
606 if (this.substitutionGroupElement != null)
607 return;
609 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
610 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
611 this.substitutionGroupElement = substElem;
612 if (substElem != null)
613 substElem.substitutingElements.Add (this);
617 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
619 if (IsValidated (schema.CompilationId))
620 return errorCount;
622 // See XML Schema Structures 3.6 for the complete description.
624 // Element Declaration Properties Correct
625 // 1. = 3.3.1 (modulo 5.3)
627 // 3.3.1:
628 // {annotation} is as is.
629 // {name}, {target namespace}, {scope}, {disallowed substitution},
630 // {substitution group exclusions} (handled the same as 'disallowed substitution')
631 // and {identity-constraint-definitions} are Compile()d.
632 // {value constraint} is going to be filled in step 2.
634 // actual {nillable}, {abstract}
635 this.actualIsNillable = IsNillable;
636 this.actualIsAbstract = IsAbstract;
638 // Before determining element type, we need to validate substituting element
639 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
640 XmlSchemaElement substElem = substitutionGroupElement;
641 if (substElem != null)
642 substElem.Validate (h, schema);
645 // {type} from here
646 XmlSchemaDatatype datatype = null;
647 if (schemaType != null)
648 elementType = schemaType;
649 else if (SchemaTypeName != XmlQualifiedName.Empty) {
650 XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
651 if (type != null) {
652 type.Validate (h, schema);
653 elementType = type;
655 else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
656 elementType = XmlSchemaComplexType.AnyType;
657 else if (XmlSchemaUtil.IsBuiltInDatatypeName (SchemaTypeName)) {
658 datatype = XmlSchemaDatatype.FromName (SchemaTypeName);
659 if (datatype == null)
660 error (h, "Invalid schema datatype was specified.");
661 else
662 elementType = datatype;
664 // otherwise, it might be missing sub components.
665 else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))
666 error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");
668 else if (RefName != XmlQualifiedName.Empty)
670 XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;
671 // If el is null, then it is missing sub components .
672 if (refElem != null) {
673 this.referencedElement = refElem;
674 errorCount += refElem.Validate (h, schema);
676 // otherwise, it might be missing sub components.
677 else if (!schema.IsNamespaceAbsent (RefName.Namespace))
678 error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");
681 // Otherwise if there are substitution group, then the type of the substitution group element.
682 if (referencedElement == null) {
683 if (elementType == null && this.substitutionGroupElement != null)
684 elementType = substitutionGroupElement.ElementType;
685 // Otherwise, the -ur type- definition.
686 if (elementType == null)
687 elementType = XmlSchemaComplexType.AnyType;
690 XmlSchemaType xsType = elementType as XmlSchemaType;
691 if (xsType != null) {
692 errorCount += xsType.Validate (h, schema);
693 datatype = xsType.Datatype;
695 // basic {type} is now filled, except for derivation by {substitution group}.
697 // {substitution group affiliation}
698 // 3. subsitution group's type derivation check.
699 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
700 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
701 // If el is null, then it is missing sub components .
702 if (substElem != null) {
703 XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;
704 if (substSchemaType != null) {
705 // 3.3.6 Properties Correct 3.
706 if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)
707 error (h, "Substituted element blocks substitution.");
708 if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)
709 error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");
711 XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
712 if (xsComplexType != null)
713 xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
714 else {
715 XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
716 if (xsSimpleType != null)
717 xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
721 // otherwise, it might be missing sub components.
722 else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))
723 error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");
726 // 2. ElementDefaultValid
727 // 4. ID with {value constraint} is prohibited.
728 if (defaultValue != null || fixedValue != null) {
729 ValidateElementDefaultValidImmediate (h, schema);
730 if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.
731 datatype.TokenizedType == XmlTokenizedType.ID)
732 error (h, "Element type is ID, which does not allows default or fixed values.");
735 // Identity constraints (3.11.3 / 3.11.6)
736 foreach (XmlSchemaIdentityConstraint ident in Constraints)
737 ident.Validate (h, schema);
739 #if NET_2_0
740 elementSchemaType = elementType as XmlSchemaType;
741 if (elementSchemaType == null && elementType != null)
742 elementSchemaType = XmlSchemaType.GetBuiltInType (((XmlSchemaDatatype) elementType).TypeCode);
743 #endif
745 ValidationId = schema.ValidationId;
746 return errorCount;
749 internal override bool ParticleEquals (XmlSchemaParticle other)
751 XmlSchemaElement element = other as XmlSchemaElement;
752 if (element == null)
753 return false;
754 if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||
755 this.ValidatedMinOccurs != element.ValidatedMinOccurs)
756 return false;
757 if (this.QualifiedName != element.QualifiedName ||
758 this.ElementType != element.ElementType ||
759 this.Constraints.Count != element.Constraints.Count)
760 return false;
761 for (int i = 0; i < this.Constraints.Count; i++) {
762 XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;
763 XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;
764 if (c1.QualifiedName != c2.QualifiedName ||
765 c1.Selector.XPath != c2.Selector.XPath ||
766 c1.Fields.Count != c2.Fields.Count)
767 return false;
768 for (int f = 0; f < c1.Fields.Count; f++) {
769 XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;
770 XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;
771 if (f1.XPath != f2.XPath)
772 return false;
775 if (this.BlockResolved != element.BlockResolved ||
776 this.FinalResolved != element.FinalResolved ||
777 this.ValidatedDefaultValue != element.ValidatedDefaultValue ||
778 this.ValidatedFixedValue != element.ValidatedFixedValue)
779 return false;
780 return true;
783 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
784 ValidationEventHandler h, XmlSchema schema, bool raiseError)
786 // element - NameAndTypeOK
787 XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
788 if (baseElement != null) {
789 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);
792 // any - NSCompat
793 XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
794 if (baseAny != null) {
795 // NSCompat
796 if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))
797 return false;
798 return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);
802 // choice - RecurseAsIfGroup
803 XmlSchemaGroupBase gb = null;
804 if (baseParticle is XmlSchemaSequence)
805 gb = new XmlSchemaSequence ();
806 else if (baseParticle is XmlSchemaChoice)
807 gb = new XmlSchemaChoice ();
808 else if (baseParticle is XmlSchemaAll)
809 gb = new XmlSchemaAll ();
811 if (gb != null) {
812 gb.Items.Add (this);
813 gb.Compile (h, schema);
814 gb.Validate (h, schema);
815 // It looks weird, but here we never think about
816 // _pointlessness_ of this groupbase particle.
817 return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);
819 //*/
820 return true;
823 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
824 ValidationEventHandler h, XmlSchema schema, bool raiseError)
826 // 1.
827 if (this.QualifiedName != baseElement.QualifiedName) {
828 if (raiseError)
829 error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
830 return false;
832 // 2.
833 if (this.isNillable && !baseElement.isNillable) {
834 if (raiseError)
835 error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
836 return false;
838 // 3.
839 if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))
840 return false;
841 // 4.
842 if (baseElement.ValidatedFixedValue != null &&
843 baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {
844 if (raiseError)
845 error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
846 return false;
848 // 5. TODO: What is "identity constraints subset" ???
850 // 6.
851 if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {
852 if (raiseError)
853 error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
854 return false;
856 // 7.
857 if (baseElement.ElementType != null) {
858 XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;
859 if (derivedCType != null) {
860 // FIXME: W3C REC says that it is Type Derivation OK to be check, but
861 // in fact it should be DerivationValid (Restriction, Complex).
862 derivedCType.ValidateDerivationValidRestriction (
863 baseElement.ElementType as XmlSchemaComplexType, h, schema);
864 derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);
865 } else {
866 XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;
867 if (derivedSType != null)
868 derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);
869 else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {
870 if (raiseError)
871 error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
872 return false;
876 return true;
879 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
881 XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
882 if (ct == null || ct.Particle == null)
883 return;
884 ct.Particle.CheckRecursion (depth + 1, h, schema);
887 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
888 ValidationEventHandler h, XmlSchema schema)
890 if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
891 error (h, "Ambiguous element label was detected: " + this.QualifiedName);
892 else {
893 foreach (XmlSchemaAny any in nsNames) {
894 if (any.ValidatedMaxOccurs == 0)
895 continue;
896 if (any.HasValueAny ||
897 any.HasValueLocal && this.QualifiedName.Namespace == "" ||
898 any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||
899 any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {
900 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
901 break;
902 } else if (!any.HasValueOther) {
903 bool bad = false;
904 foreach (string ns in any.ResolvedNamespaces) {
905 if (ns == this.QualifiedName.Namespace) {
906 bad = true;
907 break;
910 if (bad) {
911 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
912 break;
914 } else {
915 if (any.TargetNamespace.Length == 0 ||
916 any.TargetNamespace != this.QualifiedName.Namespace)
917 error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);
920 qnames.Add (this.QualifiedName, this);
924 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
925 ValidationEventHandler h, XmlSchema schema)
927 XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
928 if (labeled == null)
929 labels.Add (this.QualifiedName, this);
930 else if (labeled.ElementType != this.ElementType)
931 error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);
935 // 3.3.6 Element Default Valid (Immediate)
936 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
938 // This presumes that ElementType is already filled.
940 XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
941 XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
942 if (simpleType != null)
943 datatype = simpleType.Datatype;
945 if (datatype == null) {
946 XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;
947 switch (complexType.ContentType) {
948 case XmlSchemaContentType.Empty:
949 case XmlSchemaContentType.ElementOnly:
950 error (h, "Element content type must be simple type or mixed.");
951 break;
953 datatype = XmlSchemaSimpleType.AnySimpleType;
956 XmlNamespaceManager nsmgr = null;
957 if (datatype.TokenizedType == XmlTokenizedType.QName) {
958 if (this.Namespaces != null)
959 foreach (XmlQualifiedName qname in Namespaces.ToArray ())
960 nsmgr.AddNamespace (qname.Name, qname.Namespace);
963 try {
964 if (defaultValue != null) {
965 validatedDefaultValue = datatype.Normalize (defaultValue);
966 datatype.ParseValue (validatedDefaultValue, null, nsmgr);
968 } catch (Exception ex) {
969 // FIXME: This is not a good way to handle exception, but
970 // I think there is no remedy for such Framework specification.
971 error (h, "The Element's default value is invalid with respect to its type definition.", ex);
973 try {
974 if (fixedValue != null) {
975 validatedFixedValue = datatype.Normalize (fixedValue);
976 datatype.ParseValue (validatedFixedValue, null, nsmgr);
978 } catch (Exception ex) {
979 // FIXME: This is not a good way to handle exception.
980 error (h, "The Element's fixed value is invalid with its type definition.", ex);
984 //<element
985 // abstract = boolean : false
986 // block = (#all | List of (extension | restriction | substitution))
987 // default = string
988 // final = (#all | List of (extension | restriction))
989 // fixed = string
990 // form = (qualified | unqualified)
991 // id = ID
992 // maxOccurs = (nonNegativeInteger | unbounded) : 1
993 // minOccurs = nonNegativeInteger : 1
994 // name = NCName
995 // nillable = boolean : false
996 // ref = QName
997 // substitutionGroup = QName
998 // type = QName
999 // {any attributes with non-schema namespace . . .}>
1000 // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
1001 //</element>
1003 internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
1005 XmlSchemaElement element = new XmlSchemaElement();
1006 Exception innerex;
1007 reader.MoveToElement();
1009 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1011 error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
1012 reader.Skip();
1013 return null;
1016 element.LineNumber = reader.LineNumber;
1017 element.LinePosition = reader.LinePosition;
1018 element.SourceUri = reader.BaseURI;
1020 while(reader.MoveToNextAttribute())
1022 if(reader.Name == "abstract")
1024 element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1025 if(innerex != null)
1026 error(h,reader.Value + " is invalid value for abstract",innerex);
1028 else if(reader.Name == "block")
1030 element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1031 XmlSchemaUtil.ElementBlockAllowed);
1032 if(innerex != null)
1033 error (h,"some invalid values for block attribute were found",innerex);
1035 else if(reader.Name == "default")
1037 element.defaultValue = reader.Value;
1039 else if(reader.Name == "final")
1041 element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1042 XmlSchemaUtil.FinalAllowed);
1043 if(innerex != null)
1044 error (h,"some invalid values for final attribute were found",innerex);
1046 else if(reader.Name == "fixed")
1048 element.fixedValue = reader.Value;
1050 else if(reader.Name == "form")
1052 element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
1053 if(innerex != null)
1054 error(h,reader.Value + " is an invalid value for form attribute",innerex);
1056 else if(reader.Name == "id")
1058 element.Id = reader.Value;
1060 else if(reader.Name == "maxOccurs")
1064 element.MaxOccursString = reader.Value;
1066 catch(Exception e)
1068 error(h,reader.Value + " is an invalid value for maxOccurs",e);
1071 else if(reader.Name == "minOccurs")
1075 element.MinOccursString = reader.Value;
1077 catch(Exception e)
1079 error(h,reader.Value + " is an invalid value for minOccurs",e);
1082 else if(reader.Name == "name")
1084 element.Name = reader.Value;
1086 else if(reader.Name == "nillable")
1088 element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1089 if(innerex != null)
1090 error(h,reader.Value + "is not a valid value for nillable",innerex);
1092 else if(reader.Name == "ref")
1094 element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1095 if(innerex != null)
1096 error(h, reader.Value + " is not a valid value for ref attribute",innerex);
1098 else if(reader.Name == "substitutionGroup")
1100 element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1101 if(innerex != null)
1102 error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
1104 else if(reader.Name == "type")
1106 element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1107 if(innerex != null)
1108 error(h, reader.Value + " is not a valid value for type attribute",innerex);
1110 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1112 error(h,reader.Name + " is not a valid attribute for element",null);
1114 else
1116 XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
1120 reader.MoveToElement();
1121 if(reader.IsEmptyElement)
1122 return element;
1124 // Content: annotation?,
1125 // (simpleType | complexType)?,
1126 // (unique | key | keyref)*
1127 int level = 1;
1128 while(reader.ReadNextElement())
1130 if(reader.NodeType == XmlNodeType.EndElement)
1132 if(reader.LocalName != xmlname)
1133 error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
1134 break;
1136 if(level <= 1 && reader.LocalName == "annotation")
1138 level = 2; //Only one annotation
1139 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1140 if(annotation != null)
1141 element.Annotation = annotation;
1142 continue;
1144 if(level <= 2)
1146 if(reader.LocalName == "simpleType")
1148 level = 3;
1149 XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
1150 if(simple != null)
1151 element.SchemaType = simple;
1152 continue;
1154 if(reader.LocalName == "complexType")
1156 level = 3;
1157 XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
1158 if(complex != null)
1160 element.SchemaType = complex;
1162 continue;
1165 if(level <= 3)
1167 if(reader.LocalName == "unique")
1169 level = 3;
1170 XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
1171 if(unique != null)
1172 element.constraints.Add(unique);
1173 continue;
1175 else if(reader.LocalName == "key")
1177 level = 3;
1178 XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
1179 if(key != null)
1180 element.constraints.Add(key);
1181 continue;
1183 else if(reader.LocalName == "keyref")
1185 level = 3;
1186 XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
1187 if(keyref != null)
1188 element.constraints.Add(keyref);
1189 continue;
1192 reader.RaiseInvalidElementError();
1194 return element;