2 // System.Xml.Schema.XmlSchemaElement.cs
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
6 // Enomoto, Atsushi ginga@kit.hi-ho.ne.jp
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
30 using System.Collections;
32 using System.Xml.Serialization;
33 using System.ComponentModel;
35 namespace System.Xml.Schema
38 /// Summary description for XmlSchemaElement.
40 public class XmlSchemaElement : XmlSchemaParticle
42 private XmlSchemaDerivationMethod block;
43 private XmlSchemaObjectCollection constraints;
44 private string defaultValue;
45 private object elementType;
47 private XmlSchemaType elementSchemaType;
49 private XmlSchemaDerivationMethod final;
50 private string fixedValue;
51 private XmlSchemaForm form;
52 private bool isAbstract;
53 private bool isNillable;
55 private XmlQualifiedName refName;
56 private XmlSchemaType schemaType;
57 private XmlQualifiedName schemaTypeName;
58 private XmlQualifiedName substitutionGroup;
60 // Post compilation items.
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;
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;
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
120 set{ block = value; }
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
136 set{ final = value; }
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
155 [System.Xml.Serialization.XmlAttribute("name")]
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; }
194 [XmlElement("simpleType",typeof(XmlSchemaSimpleType))]
195 [XmlElement("complexType",typeof(XmlSchemaComplexType))]
196 public XmlSchemaType SchemaType
198 get{ return schemaType; }
199 set{ schemaType = value; }
202 [XmlElement("unique",typeof(XmlSchemaUnique))]
203 [XmlElement("key",typeof(XmlSchemaKey))]
204 [XmlElement("keyref",typeof(XmlSchemaKeyref))]
205 public XmlSchemaObjectCollection Constraints
207 get{ return constraints; }
211 #region Post Compilation Schema Info
213 public XmlQualifiedName QualifiedName
222 public object ElementType
225 if (referencedElement != null)
226 return referencedElement.ElementType;
234 public XmlSchemaType ElementSchemaType
237 if (referencedElement != null)
238 return referencedElement.ElementSchemaType;
240 return elementSchemaType;
246 public XmlSchemaDerivationMethod BlockResolved
249 if (referencedElement != null)
250 return referencedElement.BlockResolved;
252 return blockResolved;
257 public XmlSchemaDerivationMethod FinalResolved
260 if (referencedElement != null)
261 return referencedElement.FinalResolved;
263 return finalResolved;
267 internal bool ActualIsNillable {
269 if (referencedElement != null)
270 return referencedElement.ActualIsNillable;
272 return actualIsNillable;
276 internal bool ActualIsAbstract {
278 if (referencedElement != null)
279 return referencedElement.ActualIsAbstract;
281 return actualIsAbstract;
285 // Post compilation default value (normalized)
286 internal string ValidatedDefaultValue {
288 if (referencedElement != null)
289 return referencedElement.ValidatedDefaultValue;
291 return validatedDefaultValue;
295 // Post compilation fixed value (normalized)
296 internal string ValidatedFixedValue {
298 if (referencedElement != null)
299 return referencedElement.ValidatedFixedValue;
301 return validatedFixedValue;
305 internal ArrayList SubstitutingElements {
307 if (referencedElement != null)
308 return referencedElement.SubstitutingElements;
310 return this.substitutingElements;
314 internal XmlSchemaElement SubstitutionGroupElement {
316 if (referencedElement != null)
317 return referencedElement.SubstitutionGroupElement;
319 return substitutionGroupElement;
325 internal override void SetParent (XmlSchemaObject parent)
327 base.SetParent (parent);
328 if (SchemaType != null)
329 SchemaType.SetParent (this);
330 foreach (XmlSchemaObject obj in Constraints)
331 obj.SetParent (this);
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)
359 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
361 // If this is already compiled this time, simply skip.
362 if (CompilationId == schema.CompilationId)
364 InitPostCompileInformations ();
365 this.schema = schema;
367 if(this.defaultValue != null && this.fixedValue != null)
368 error(h,"both default and fixed can't be present");
370 if(parentIsSchema || isRedefineChild)
372 if(this.refName != null && !RefName.IsEmpty)
373 error(h,"ref must be absent");
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");
380 this.qName = new XmlQualifiedName (this.name, AncestorSchema.TargetNamespace);
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");
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;
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;
402 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
404 error(h,"both schemaType and content can't be present");
407 //Even if both are present, read both of them.
408 if(schemaType != null)
410 if(schemaType is XmlSchemaSimpleType)
412 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
414 else if(schemaType is XmlSchemaComplexType)
416 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
419 error(h,"only simpletype or complextype is allowed");
421 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
423 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
424 error(h,"SchemaTypeName must be an XmlQualifiedName");
426 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
428 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
429 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
432 foreach(XmlSchemaObject obj in constraints)
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);
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");
449 CompileOccurence (h, schema);
451 if(refName == null || RefName.IsEmpty)
453 string targetNamespace = String.Empty;
455 if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && AncestorSchema.ElementFormDefault == XmlSchemaForm.Qualified))
456 targetNamespace = AncestorSchema.TargetNamespace;
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");
463 this.qName = new XmlQualifiedName(this.name, targetNamespace);
465 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
467 error(h,"both schemaType and content can't be present");
470 //Even if both are present, read both of them.
471 if(schemaType != null)
473 if(schemaType is XmlSchemaSimpleType)
475 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
477 else if(schemaType is XmlSchemaComplexType)
479 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
482 error(h,"only simpletype or complextype is allowed");
484 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
486 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
487 error(h,"SchemaTypeName must be an XmlQualifiedName");
489 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
491 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
492 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
495 foreach(XmlSchemaObject obj in constraints)
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);
507 if(!XmlSchemaUtil.CheckQName(RefName))
508 error(h,"RefName must be a XmlQualifiedName");
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");
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");
534 case XmlSchemaDerivationMethod.All:
535 blockResolved = XmlSchemaDerivationMethod.All;
537 case XmlSchemaDerivationMethod.None:
538 blockResolved = XmlSchemaDerivationMethod.Empty;
541 if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
542 error (h,"Some of the values for block are invalid in this context");
543 blockResolved = block;
547 if (Constraints != null) {
548 XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
549 foreach (XmlSchemaIdentityConstraint c in Constraints) {
550 XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
554 XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
556 this.CompilationId = schema.CompilationId;
560 // FIXME: Return clone in case when it returns itself
561 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
563 if (OptimizedParticle != null)
564 return OptimizedParticle;
565 if (RefName != null && RefName != XmlQualifiedName.Empty) {
566 referencedElement = schema.FindElement (RefName);
569 // if (this.referencedElement != null)
570 // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
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;
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);
593 if (!choice.Items.Contains (item)) {
594 choice.Items.Add (item);
595 choice.CompiledItems.Add (item);
597 OptimizedParticle = choice;
600 OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;
601 return OptimizedParticle;
604 private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)
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))
613 internal void FillSubstitutionElementInfo ()
615 if (this.substitutionGroupElement != null)
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);
626 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
628 if (IsValidated (schema.CompilationId))
631 // See XML Schema Structures 3.6 for the complete description.
633 // Element Declaration Properties Correct
634 // 1. = 3.3.1 (modulo 5.3)
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.
643 // actual {nillable}, {abstract}
644 this.actualIsNillable = IsNillable;
645 this.actualIsAbstract = IsAbstract;
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);
655 XmlSchemaDatatype datatype = null;
656 if (schemaType != null)
657 elementType = schemaType;
658 else if (SchemaTypeName != XmlQualifiedName.Empty) {
659 XmlSchemaType type = schema.FindSchemaType (SchemaTypeName);
661 type.Validate (h, schema);
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.");
671 elementType = datatype;
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.");
677 else if (RefName != XmlQualifiedName.Empty)
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);
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.");
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;
699 XmlSchemaType xsType = elementType as XmlSchemaType;
700 if (xsType != null) {
701 errorCount += xsType.Validate (h, schema);
702 datatype = xsType.Datatype;
704 // basic {type} is now filled, except for derivation by {substitution group}.
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 + ".");
720 XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
721 if (xsComplexType != null)
722 xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
724 XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
725 if (xsSimpleType != null)
726 xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
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.");
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.");
744 // Identity constraints (3.11.3 / 3.11.6)
745 foreach (XmlSchemaIdentityConstraint ident in Constraints)
746 ident.Validate (h, schema);
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);
758 ValidationId = schema.ValidationId;
762 internal override bool ParticleEquals (XmlSchemaParticle other)
764 XmlSchemaElement element = other as XmlSchemaElement;
767 if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||
768 this.ValidatedMinOccurs != element.ValidatedMinOccurs)
770 if (this.QualifiedName != element.QualifiedName ||
771 this.ElementType != element.ElementType ||
772 this.Constraints.Count != element.Constraints.Count)
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)
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)
788 if (this.BlockResolved != element.BlockResolved ||
789 this.FinalResolved != element.FinalResolved ||
790 this.ValidatedDefaultValue != element.ValidatedDefaultValue ||
791 this.ValidatedFixedValue != element.ValidatedFixedValue)
796 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
797 ValidationEventHandler h, XmlSchema schema, bool raiseError)
799 // element - NameAndTypeOK
800 XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
801 if (baseElement != null) {
802 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);
806 XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
807 if (baseAny != null) {
809 if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))
811 return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);
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 ();
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);
836 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
837 ValidationEventHandler h, XmlSchema schema, bool raiseError)
840 if (this.QualifiedName != baseElement.QualifiedName) {
842 error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
846 if (this.isNillable && !baseElement.isNillable) {
848 error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
852 if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))
855 if (baseElement.ValidatedFixedValue != null &&
856 baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {
858 error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
861 // 5. TODO: What is "identity constraints subset" ???
864 if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {
866 error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
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);
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) {
884 error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
892 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
894 XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
895 if (ct == null || ct.Particle == null)
897 ct.Particle.CheckRecursion (depth + 1, h, schema);
900 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
901 ValidationEventHandler h, XmlSchema schema)
903 if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
904 error (h, "Ambiguous element label was detected: " + this.QualifiedName);
906 foreach (XmlSchemaAny any in nsNames) {
907 if (any.ValidatedMaxOccurs == 0)
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);
915 } else if (!any.HasValueOther) {
917 foreach (string ns in any.ResolvedNamespaces) {
918 if (ns == this.QualifiedName.Namespace) {
924 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
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));
932 qnames.Add (this.QualifiedName, this);
936 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
937 ValidationEventHandler h, XmlSchema schema)
939 XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
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);
947 // 3.3.6 Element Default Valid (Immediate)
948 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
950 // This presumes that ElementType is already filled.
952 XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
953 XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
954 if (simpleType != null)
955 datatype = simpleType.Datatype;
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.");
965 datatype = XmlSchemaSimpleType.AnySimpleType;
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);
976 if (defaultValue != null) {
977 validatedDefaultValue = datatype.Normalize (defaultValue);
978 datatype.ParseValue (validatedDefaultValue, null, nsmgr);
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);
986 if (fixedValue != null) {
987 validatedFixedValue = datatype.Normalize (fixedValue);
988 datatype.ParseValue (validatedFixedValue, null, nsmgr);
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);
997 // abstract = boolean : false
998 // block = (#all | List of (extension | restriction | substitution))
1000 // final = (#all | List of (extension | restriction))
1002 // form = (qualified | unqualified)
1004 // maxOccurs = (nonNegativeInteger | unbounded) : 1
1005 // minOccurs = nonNegativeInteger : 1
1007 // nillable = boolean : false
1009 // substitutionGroup = QName
1011 // {any attributes with non-schema namespace . . .}>
1012 // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
1015 internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
1017 XmlSchemaElement element = new XmlSchemaElement();
1019 reader.MoveToElement();
1021 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1023 error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
1028 element.LineNumber = reader.LineNumber;
1029 element.LinePosition = reader.LinePosition;
1030 element.SourceUri = reader.BaseURI;
1032 while(reader.MoveToNextAttribute())
1034 if(reader.Name == "abstract")
1036 element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1038 error(h,reader.Value + " is invalid value for abstract",innerex);
1040 else if(reader.Name == "block")
1042 element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1043 XmlSchemaUtil.ElementBlockAllowed);
1045 error (h,"some invalid values for block attribute were found",innerex);
1047 else if(reader.Name == "default")
1049 element.defaultValue = reader.Value;
1051 else if(reader.Name == "final")
1053 element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1054 XmlSchemaUtil.FinalAllowed);
1056 error (h,"some invalid values for final attribute were found",innerex);
1058 else if(reader.Name == "fixed")
1060 element.fixedValue = reader.Value;
1062 else if(reader.Name == "form")
1064 element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
1066 error(h,reader.Value + " is an invalid value for form attribute",innerex);
1068 else if(reader.Name == "id")
1070 element.Id = reader.Value;
1072 else if(reader.Name == "maxOccurs")
1076 element.MaxOccursString = reader.Value;
1080 error(h,reader.Value + " is an invalid value for maxOccurs",e);
1083 else if(reader.Name == "minOccurs")
1087 element.MinOccursString = reader.Value;
1091 error(h,reader.Value + " is an invalid value for minOccurs",e);
1094 else if(reader.Name == "name")
1096 element.Name = reader.Value;
1098 else if(reader.Name == "nillable")
1100 element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1102 error(h,reader.Value + "is not a valid value for nillable",innerex);
1104 else if(reader.Name == "ref")
1106 element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1108 error(h, reader.Value + " is not a valid value for ref attribute",innerex);
1110 else if(reader.Name == "substitutionGroup")
1112 element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1114 error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
1116 else if(reader.Name == "type")
1118 element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
1120 error(h, reader.Value + " is not a valid value for type attribute",innerex);
1122 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1124 error(h,reader.Name + " is not a valid attribute for element",null);
1128 XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
1132 reader.MoveToElement();
1133 if(reader.IsEmptyElement)
1136 // Content: annotation?,
1137 // (simpleType | complexType)?,
1138 // (unique | key | keyref)*
1140 while(reader.ReadNextElement())
1142 if(reader.NodeType == XmlNodeType.EndElement)
1144 if(reader.LocalName != xmlname)
1145 error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
1148 if(level <= 1 && reader.LocalName == "annotation")
1150 level = 2; //Only one annotation
1151 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1152 if(annotation != null)
1153 element.Annotation = annotation;
1158 if(reader.LocalName == "simpleType")
1161 XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
1163 element.SchemaType = simple;
1166 if(reader.LocalName == "complexType")
1169 XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
1172 element.SchemaType = complex;
1179 if(reader.LocalName == "unique")
1182 XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
1184 element.constraints.Add(unique);
1187 else if(reader.LocalName == "key")
1190 XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
1192 element.constraints.Add(key);
1195 else if(reader.LocalName == "keyref")
1198 XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
1200 element.constraints.Add(keyref);
1204 reader.RaiseInvalidElementError();