2 // System.Xml.Schema.XmlSchemaElement.cs
\r
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
\r
6 // Enomoto, Atsushi ginga@kit.hi-ho.ne.jp
\r
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;
\r
32 using System.Xml.Serialization;
\r
33 using System.ComponentModel;
\r
35 namespace System.Xml.Schema
\r
38 /// Summary description for XmlSchemaElement.
\r
40 public class XmlSchemaElement : XmlSchemaParticle
\r
42 private XmlSchemaDerivationMethod block;
\r
43 private XmlSchemaObjectCollection constraints;
\r
44 private string defaultValue;
\r
45 private object elementType;
\r
47 private XmlSchemaType elementSchemaType;
\r
49 private XmlSchemaDerivationMethod final;
\r
50 private string fixedValue;
\r
51 private XmlSchemaForm form;
\r
52 private bool isAbstract;
\r
53 private bool isNillable;
\r
54 private string name;
\r
55 private XmlQualifiedName refName;
\r
56 private XmlSchemaType schemaType;
\r
57 private XmlQualifiedName schemaTypeName;
\r
58 private XmlQualifiedName substitutionGroup;
\r
60 // Post compilation items.
\r
62 internal bool parentIsSchema = false;
\r
63 private XmlQualifiedName qName;
\r
64 private XmlSchemaDerivationMethod blockResolved;
\r
65 private XmlSchemaDerivationMethod finalResolved;
\r
66 // private XmlSchemaParticle substChoice;
\r
67 private XmlSchemaElement referencedElement;
\r
68 private ArrayList substitutingElements = new ArrayList ();
\r
69 private XmlSchemaElement substitutionGroupElement;
\r
70 private bool actualIsAbstract;
\r
71 private bool actualIsNillable;
\r
72 private string validatedDefaultValue;
\r
73 private string validatedFixedValue;
\r
75 const string xmlname = "element";
\r
77 public XmlSchemaElement()
\r
79 block = XmlSchemaDerivationMethod.None;
\r
80 final = XmlSchemaDerivationMethod.None;
\r
81 constraints = new XmlSchemaObjectCollection();
\r
82 refName = XmlQualifiedName.Empty;
\r
83 schemaTypeName = XmlQualifiedName.Empty;
\r
84 substitutionGroup = XmlQualifiedName.Empty;
\r
85 InitPostCompileInformations ();
\r
88 private void InitPostCompileInformations ()
\r
90 qName = XmlQualifiedName.Empty;
\r
92 // parentIsSchema = false; ... it is set in Schema's Compile()
\r
93 blockResolved = XmlSchemaDerivationMethod.None;
\r
94 finalResolved = XmlSchemaDerivationMethod.None;
\r
95 // substChoice = null;
\r
96 referencedElement = null;
\r
97 substitutingElements.Clear ();
\r
98 substitutionGroupElement = null;
\r
99 actualIsAbstract = false;
\r
100 actualIsNillable = false;
\r
101 validatedDefaultValue = null;
\r
102 validatedFixedValue = null;
\r
107 [DefaultValue(false)]
\r
108 [System.Xml.Serialization.XmlAttribute("abstract")]
\r
109 public bool IsAbstract
\r
111 get{ return isAbstract; }
\r
112 set{ isAbstract = value; }
\r
115 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
116 [System.Xml.Serialization.XmlAttribute("block")]
\r
117 public XmlSchemaDerivationMethod Block
\r
119 get{ return block; }
\r
120 set{ block = value; }
\r
123 [DefaultValue(null)]
\r
124 [System.Xml.Serialization.XmlAttribute("default")]
\r
125 public string DefaultValue
\r
127 get{ return defaultValue; }
\r
128 set{ defaultValue = value; }
\r
131 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
132 [System.Xml.Serialization.XmlAttribute("final")]
\r
133 public XmlSchemaDerivationMethod Final
\r
135 get{ return final; }
\r
136 set{ final = value; }
\r
139 [DefaultValue(null)]
\r
140 [System.Xml.Serialization.XmlAttribute("fixed")]
\r
141 public string FixedValue
\r
143 get{ return fixedValue; }
\r
144 set{ fixedValue = value; }
\r
146 [DefaultValue(XmlSchemaForm.None)]
\r
147 [System.Xml.Serialization.XmlAttribute("form")]
\r
148 public XmlSchemaForm Form
\r
150 get{ return form; }
\r
151 set{ form = value; }
\r
155 [System.Xml.Serialization.XmlAttribute("name")]
\r
156 public string Name
\r
158 get{ return name; }
\r
159 set{ name = value; }
\r
162 [DefaultValue(false)]
\r
163 [System.Xml.Serialization.XmlAttribute("nillable")]
\r
164 public bool IsNillable
\r
166 get{ return isNillable; }
\r
167 set{ isNillable = value; }
\r
170 [System.Xml.Serialization.XmlAttribute("ref")]
\r
171 public XmlQualifiedName RefName
\r
173 get{ return refName; }
\r
174 set{ refName = value;}
\r
177 [System.Xml.Serialization.XmlAttribute("substitutionGroup")]
\r
178 public XmlQualifiedName SubstitutionGroup
\r
180 get{ return substitutionGroup; }
\r
181 set{ substitutionGroup = value; }
\r
184 [System.Xml.Serialization.XmlAttribute("type")]
\r
185 public XmlQualifiedName SchemaTypeName
\r
187 get{ return schemaTypeName; }
\r
188 set{ schemaTypeName = value; }
\r
194 [XmlElement("simpleType",typeof(XmlSchemaSimpleType))]
\r
195 [XmlElement("complexType",typeof(XmlSchemaComplexType))]
\r
196 public XmlSchemaType SchemaType
\r
198 get{ return schemaType; }
\r
199 set{ schemaType = value; }
\r
202 [XmlElement("unique",typeof(XmlSchemaUnique))]
\r
203 [XmlElement("key",typeof(XmlSchemaKey))]
\r
204 [XmlElement("keyref",typeof(XmlSchemaKeyref))]
\r
205 public XmlSchemaObjectCollection Constraints
\r
207 get{ return constraints; }
\r
211 #region Post Compilation Schema Info
\r
213 public XmlQualifiedName QualifiedName
\r
215 get{ return qName; }
\r
222 public object ElementType
\r
225 if (referencedElement != null)
\r
226 return referencedElement.ElementType;
\r
228 return elementType;
\r
234 public XmlSchemaType ElementSchemaType
\r
237 if (referencedElement != null)
\r
238 return referencedElement.ElementSchemaType;
\r
240 return elementSchemaType;
\r
246 public XmlSchemaDerivationMethod BlockResolved
\r
249 if (referencedElement != null)
\r
250 return referencedElement.BlockResolved;
\r
252 return blockResolved;
\r
257 public XmlSchemaDerivationMethod FinalResolved
\r
260 if (referencedElement != null)
\r
261 return referencedElement.FinalResolved;
\r
263 return finalResolved;
\r
267 internal bool ActualIsNillable {
\r
269 if (referencedElement != null)
\r
270 return referencedElement.ActualIsNillable;
\r
272 return actualIsNillable;
\r
276 internal bool ActualIsAbstract {
\r
278 if (referencedElement != null)
\r
279 return referencedElement.ActualIsAbstract;
\r
281 return actualIsAbstract;
\r
285 // Post compilation default value (normalized)
\r
286 internal string ValidatedDefaultValue {
\r
288 if (referencedElement != null)
\r
289 return referencedElement.ValidatedDefaultValue;
\r
291 return validatedDefaultValue;
\r
295 // Post compilation fixed value (normalized)
\r
296 internal string ValidatedFixedValue {
\r
298 if (referencedElement != null)
\r
299 return referencedElement.ValidatedFixedValue;
\r
301 return validatedFixedValue;
\r
305 internal ArrayList SubstitutingElements {
\r
307 if (referencedElement != null)
\r
308 return referencedElement.SubstitutingElements;
\r
310 return this.substitutingElements;
\r
314 internal XmlSchemaElement SubstitutionGroupElement {
\r
316 if (referencedElement != null)
\r
317 return referencedElement.SubstitutionGroupElement;
\r
319 return substitutionGroupElement;
\r
326 /// a) If Element has parent as schema:
\r
327 /// 1. name must be present and of type NCName.
\r
328 /// 2. ref must be absent
\r
329 /// 3. form must be absent
\r
330 /// 4. minOccurs must be absent
\r
331 /// 5. maxOccurs must be absent
\r
332 /// b) If Element has parent is not schema and ref is absent
\r
333 /// 1. name must be present and of type NCName.
\r
334 /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
\r
335 /// targetNamespace is schema's targetnamespace else empty.
\r
336 /// 3. type and either <simpleType> or <complexType> are mutually exclusive
\r
337 /// 4. default and fixed must not both be present.
\r
338 /// 5. substitutiongroup must be absent
\r
339 /// 6. final must be absent
\r
340 /// 7. abstract must be absent
\r
341 /// c) if the parent is not schema and ref is set
\r
342 /// 1. name must not be present
\r
343 /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
\r
344 /// default, fixed, form, block and type, must be absent.
\r
345 /// 3. substitutiongroup is prohibited
\r
346 /// 4. final is prohibited
\r
347 /// 5. abstract is prohibited
\r
348 /// 6. default and fixed must not both be present.(Actually both are absent)
\r
350 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
\r
352 // If this is already compiled this time, simply skip.
\r
353 if (CompilationId == schema.CompilationId)
\r
355 InitPostCompileInformations ();
\r
356 this.schema = schema;
\r
358 if (SchemaType != null)
\r
359 SchemaType.Parent = this;
\r
360 foreach (XmlSchemaObject obj in Constraints)
\r
364 if(this.defaultValue != null && this.fixedValue != null)
\r
365 error(h,"both default and fixed can't be present");
\r
367 if(parentIsSchema || isRedefineChild)
\r
369 if(this.refName != null && !RefName.IsEmpty)
\r
370 error(h,"ref must be absent");
\r
372 if(this.name == null) //b1
\r
373 error(h,"Required attribute name must be present");
\r
374 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
\r
375 error(h,"attribute name must be NCName");
\r
377 this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);
\r
379 if(form != XmlSchemaForm.None)
\r
380 error(h,"form must be absent");
\r
381 if(MinOccursString != null)
\r
382 error(h,"minOccurs must be absent");
\r
383 if(MaxOccursString != null)
\r
384 error(h,"maxOccurs must be absent");
\r
386 XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
\r
387 if(final == XmlSchemaDerivationMethod.All)
\r
388 finalResolved = allfinal;
\r
389 else if(final == XmlSchemaDerivationMethod.None)
\r
390 finalResolved = XmlSchemaDerivationMethod.Empty;
\r
393 // if((final & ~allfinal) != 0)
\r
394 if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)
\r
395 error (h,"some values for final are invalid in this context");
\r
396 finalResolved = final & allfinal;
\r
399 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
401 error(h,"both schemaType and content can't be present");
\r
404 //Even if both are present, read both of them.
\r
405 if(schemaType != null)
\r
407 if(schemaType is XmlSchemaSimpleType)
\r
409 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
\r
411 else if(schemaType is XmlSchemaComplexType)
\r
413 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
\r
416 error(h,"only simpletype or complextype is allowed");
\r
418 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
420 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
\r
421 error(h,"SchemaTypeName must be an XmlQualifiedName");
\r
423 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
\r
425 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
\r
426 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
\r
429 foreach(XmlSchemaObject obj in constraints)
\r
431 if(obj is XmlSchemaUnique)
\r
432 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
\r
433 else if(obj is XmlSchemaKey)
\r
434 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
\r
435 else if(obj is XmlSchemaKeyref)
\r
436 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
\r
441 if(substitutionGroup != null && !substitutionGroup.IsEmpty)
\r
442 error(h,"substitutionGroup must be absent");
\r
443 if(final != XmlSchemaDerivationMethod.None)
\r
444 error(h,"final must be absent");
\r
446 CompileOccurence (h, schema);
\r
448 if(refName == null || RefName.IsEmpty)
\r
450 string targetNamespace = String.Empty;
\r
452 if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))
\r
453 targetNamespace = schema.TargetNamespace;
\r
455 if(this.name == null) //b1
\r
456 error(h,"Required attribute name must be present");
\r
457 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
\r
458 error(h,"attribute name must be NCName");
\r
460 this.qName = new XmlQualifiedName(this.name, targetNamespace);
\r
462 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
464 error(h,"both schemaType and content can't be present");
\r
467 //Even if both are present, read both of them.
\r
468 if(schemaType != null)
\r
470 if(schemaType is XmlSchemaSimpleType)
\r
472 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
\r
474 else if(schemaType is XmlSchemaComplexType)
\r
476 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
\r
479 error(h,"only simpletype or complextype is allowed");
\r
481 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
483 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
\r
484 error(h,"SchemaTypeName must be an XmlQualifiedName");
\r
486 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
\r
488 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
\r
489 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
\r
492 foreach(XmlSchemaObject obj in constraints)
\r
494 if(obj is XmlSchemaUnique)
\r
495 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
\r
496 else if(obj is XmlSchemaKey)
\r
497 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
\r
498 else if(obj is XmlSchemaKeyref)
\r
499 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
\r
504 if(!XmlSchemaUtil.CheckQName(RefName))
\r
505 error(h,"RefName must be a XmlQualifiedName");
\r
508 error(h,"name must not be present when ref is present");
\r
509 if(Constraints.Count != 0)
\r
510 error(h,"key, keyref and unique must be absent");
\r
512 error(h,"nillable must be absent");
\r
513 if(defaultValue != null)
\r
514 error(h,"default must be absent");
\r
515 if(fixedValue != null)
\r
516 error(h,"fixed must be null");
\r
517 if(form != XmlSchemaForm.None)
\r
518 error(h,"form must be absent");
\r
519 if(block != XmlSchemaDerivationMethod.None)
\r
520 error(h,"block must be absent");
\r
521 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
522 error(h,"type must be absent");
\r
523 if(SchemaType != null)
\r
524 error(h,"simpleType or complexType must be absent");
\r
531 case XmlSchemaDerivationMethod.All:
\r
532 blockResolved = XmlSchemaDerivationMethod.All;
\r
534 case XmlSchemaDerivationMethod.None:
\r
535 blockResolved = XmlSchemaDerivationMethod.Empty;
\r
538 if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
\r
539 error (h,"Some of the values for block are invalid in this context");
\r
540 blockResolved = block;
\r
544 if (Constraints != null) {
\r
545 XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
\r
546 foreach (XmlSchemaIdentityConstraint c in Constraints) {
\r
547 XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
\r
551 XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
\r
553 this.CompilationId = schema.CompilationId;
\r
557 [MonoTODO ("Return clone in case when it returns itself")]
\r
558 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
\r
560 if (OptimizedParticle != null)
\r
561 return OptimizedParticle;
\r
562 if (RefName != null && RefName != XmlQualifiedName.Empty) {
\r
563 referencedElement = schema.Elements [RefName] as XmlSchemaElement;
\r
566 // if (this.referencedElement != null)
\r
567 // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
\r
569 if (ValidatedMaxOccurs == 0)
\r
570 OptimizedParticle = XmlSchemaParticle.Empty;
\r
571 // Substitution Group
\r
572 else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {
\r
573 XmlSchemaChoice choice = new XmlSchemaChoice ();
\r
574 choice.MinOccurs = MinOccurs;
\r
575 choice.MaxOccurs = MaxOccurs;
\r
576 // substChoice = choice;
\r
577 choice.Compile (null, schema); // compute Validated Min/Max Occurs.
\r
578 XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;
\r
579 item.MinOccurs = 1;
\r
580 item.MaxOccurs = 1;
\r
581 item.substitutionGroupElement = null;
\r
582 item.substitutingElements = null;
\r
583 for (int i = 0; i < SubstitutingElements.Count; i++) {
\r
584 XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;
\r
585 // choice.Items.Add (se);
\r
586 // choice.CompiledItems.Add (se);
\r
587 this.AddSubstElementRecursively (choice.Items, se);
\r
588 this.AddSubstElementRecursively (choice.CompiledItems, se);
\r
590 if (!choice.Items.Contains (item)) {
\r
591 choice.Items.Add (item);
\r
592 choice.CompiledItems.Add (item);
\r
594 OptimizedParticle = choice;
\r
597 OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;
\r
598 return OptimizedParticle;
\r
601 private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)
\r
603 if (el.SubstitutingElements != null)
\r
604 for (int i = 0; i < el.SubstitutingElements.Count; i++)
\r
605 this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);
\r
606 if (!col.Contains (el))
\r
610 internal void FillSubstitutionElementInfo ()
\r
612 if (this.substitutionGroupElement != null)
\r
615 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
616 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
\r
617 this.substitutionGroupElement = substElem;
\r
618 if (substElem != null)
\r
619 substElem.substitutingElements.Add (this);
\r
623 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
\r
625 if (IsValidated (schema.CompilationId))
\r
628 // See XML Schema Structures 3.6 for the complete description.
\r
630 // Element Declaration Properties Correct
\r
631 // 1. = 3.3.1 (modulo 5.3)
\r
634 // {annotation} is as is.
\r
635 // {name}, {target namespace}, {scope}, {disallowed substitution},
\r
636 // {substitution group exclusions} (handled the same as 'disallowed substitution')
\r
637 // and {identity-constraint-definitions} are Compile()d.
\r
638 // {value constraint} is going to be filled in step 2.
\r
640 // actual {nillable}, {abstract}
\r
641 this.actualIsNillable = IsNillable;
\r
642 this.actualIsAbstract = IsAbstract;
\r
644 // Before determining element type, we need to validate substituting element
\r
645 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
646 XmlSchemaElement substElem = substitutionGroupElement;
\r
647 if (substElem != null)
\r
648 substElem.Validate (h, schema);
\r
651 // {type} from here
\r
652 XmlSchemaDatatype datatype = null;
\r
653 if (schemaType != null)
\r
654 elementType = schemaType;
\r
655 else if (SchemaTypeName != XmlQualifiedName.Empty) {
\r
656 XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
\r
657 if (type != null) {
\r
658 type.Validate (h, schema);
\r
659 elementType = type;
\r
661 else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
\r
662 elementType = XmlSchemaComplexType.AnyType;
663 else if (XmlSchemaUtil.IsBuiltInDatatypeName (SchemaTypeName)) {
\r
664 datatype = XmlSchemaDatatype.FromName (SchemaTypeName);
\r
665 if (datatype == null)
\r
666 error (h, "Invalid schema datatype was specified.");
\r
668 elementType = datatype;
\r
670 // otherwise, it might be missing sub components.
\r
671 else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))
\r
672 error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");
\r
674 else if (RefName != XmlQualifiedName.Empty)
\r
676 XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;
\r
677 // If el is null, then it is missing sub components .
\r
678 if (refElem != null) {
\r
679 this.referencedElement = refElem;
\r
680 errorCount += refElem.Validate (h, schema);
\r
682 // otherwise, it might be missing sub components.
\r
683 else if (!schema.IsNamespaceAbsent (RefName.Namespace))
\r
684 error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");
\r
687 // Otherwise if there are substitution group, then the type of the substitution group element.
\r
688 if (referencedElement == null) {
\r
689 if (elementType == null && this.substitutionGroupElement != null)
\r
690 elementType = substitutionGroupElement.ElementType;
\r
691 // Otherwise, the -ur type- definition.
\r
692 if (elementType == null)
\r
693 elementType = XmlSchemaComplexType.AnyType;
\r
696 XmlSchemaType xsType = elementType as XmlSchemaType;
\r
697 if (xsType != null) {
\r
698 errorCount += xsType.Validate (h, schema);
\r
699 datatype = xsType.Datatype;
\r
701 // basic {type} is now filled, except for derivation by {substitution group}.
\r
703 // {substitution group affiliation}
\r
704 // 3. subsitution group's type derivation check.
\r
705 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
706 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
\r
707 // If el is null, then it is missing sub components .
\r
708 if (substElem != null) {
\r
709 XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;
\r
710 if (substSchemaType != null) {
\r
711 // 3.3.6 Properties Correct 3.
\r
712 if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)
\r
713 error (h, "Substituted element blocks substitution.");
\r
714 if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)
\r
715 error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");
\r
717 XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
\r
718 if (xsComplexType != null)
\r
719 xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
\r
721 XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
\r
722 if (xsSimpleType != null)
\r
723 xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
\r
727 // otherwise, it might be missing sub components.
\r
728 else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))
\r
729 error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");
\r
732 // 2. ElementDefaultValid
\r
733 // 4. ID with {value constraint} is prohibited.
\r
734 if (defaultValue != null || fixedValue != null) {
\r
735 ValidateElementDefaultValidImmediate (h, schema);
\r
736 if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.
\r
737 datatype.TokenizedType == XmlTokenizedType.ID)
\r
738 error (h, "Element type is ID, which does not allows default or fixed values.");
\r
741 // Identity constraints (3.11.3 / 3.11.6)
\r
742 foreach (XmlSchemaIdentityConstraint ident in Constraints)
\r
743 ident.Validate (h, schema);
\r
746 if (elementType != null) {
\r
747 elementSchemaType = elementType as XmlSchemaType;
\r
748 if (elementType == XmlSchemaSimpleType.AnySimpleType)
\r
749 elementSchemaType = XmlSchemaSimpleType.XsAnySimpleType;
\r
750 if (elementSchemaType == null)
\r
751 elementSchemaType = XmlSchemaType.GetBuiltInSimpleType (SchemaTypeName);
\r
755 ValidationId = schema.ValidationId;
\r
759 internal override bool ParticleEquals (XmlSchemaParticle other)
\r
761 XmlSchemaElement element = other as XmlSchemaElement;
\r
762 if (element == null)
\r
764 if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||
\r
765 this.ValidatedMinOccurs != element.ValidatedMinOccurs)
\r
767 if (this.QualifiedName != element.QualifiedName ||
\r
768 this.ElementType != element.ElementType ||
\r
769 this.Constraints.Count != element.Constraints.Count)
\r
771 for (int i = 0; i < this.Constraints.Count; i++) {
\r
772 XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;
\r
773 XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;
\r
774 if (c1.QualifiedName != c2.QualifiedName ||
\r
775 c1.Selector.XPath != c2.Selector.XPath ||
\r
776 c1.Fields.Count != c2.Fields.Count)
\r
778 for (int f = 0; f < c1.Fields.Count; f++) {
\r
779 XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;
\r
780 XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;
\r
781 if (f1.XPath != f2.XPath)
\r
785 if (this.BlockResolved != element.BlockResolved ||
\r
786 this.FinalResolved != element.FinalResolved ||
\r
787 this.ValidatedDefaultValue != element.ValidatedDefaultValue ||
\r
788 this.ValidatedFixedValue != element.ValidatedFixedValue)
\r
793 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
\r
794 ValidationEventHandler h, XmlSchema schema, bool raiseError)
\r
796 // element - NameAndTypeOK
\r
797 XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
\r
798 if (baseElement != null) {
\r
799 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);
\r
803 XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
\r
804 if (baseAny != null) {
\r
806 if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))
\r
808 return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);
\r
812 // choice - RecurseAsIfGroup
\r
813 XmlSchemaGroupBase gb = null;
\r
814 if (baseParticle is XmlSchemaSequence)
\r
815 gb = new XmlSchemaSequence ();
\r
816 else if (baseParticle is XmlSchemaChoice)
\r
817 gb = new XmlSchemaChoice ();
\r
818 else if (baseParticle is XmlSchemaAll)
\r
819 gb = new XmlSchemaAll ();
\r
822 gb.Items.Add (this);
\r
823 gb.Compile (h, schema);
\r
824 gb.Validate (h, schema);
\r
825 // It looks weird, but here we never think about
\r
826 // _pointlessness_ of this groupbase particle.
\r
827 return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);
\r
833 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
\r
834 ValidationEventHandler h, XmlSchema schema, bool raiseError)
\r
837 if (this.QualifiedName != baseElement.QualifiedName) {
\r
839 error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
\r
843 if (this.isNillable && !baseElement.isNillable) {
\r
845 error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
\r
849 if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))
\r
852 if (baseElement.ValidatedFixedValue != null &&
\r
853 baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {
\r
855 error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
\r
858 // 5. TODO: What is "identity constraints subset" ???
\r
861 if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {
\r
863 error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
\r
867 if (baseElement.ElementType != null) {
\r
868 XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;
\r
869 if (derivedCType != null) {
\r
870 // FIXME: W3C REC says that it is Type Derivation OK to be check, but
\r
871 // in fact it should be DerivationValid (Restriction, Complex).
\r
872 derivedCType.ValidateDerivationValidRestriction (
\r
873 baseElement.ElementType as XmlSchemaComplexType, h, schema);
\r
874 derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);
\r
876 XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;
\r
877 if (derivedSType != null)
\r
878 derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);
\r
879 else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {
\r
881 error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
\r
889 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
\r
891 XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
\r
892 if (ct == null || ct.Particle == null)
\r
894 ct.Particle.CheckRecursion (depth + 1, h, schema);
\r
897 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
\r
898 ValidationEventHandler h, XmlSchema schema)
\r
900 if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
\r
901 error (h, "Ambiguous element label was detected: " + this.QualifiedName);
\r
903 foreach (XmlSchemaAny any in nsNames) {
\r
904 if (any.ValidatedMaxOccurs == 0)
\r
906 if (any.HasValueAny ||
\r
907 any.HasValueLocal && this.QualifiedName.Namespace == "" ||
\r
908 any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||
\r
909 any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {
\r
910 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
\r
912 } else if (!any.HasValueOther) {
\r
914 foreach (string ns in any.ResolvedNamespaces) {
\r
915 if (ns == this.QualifiedName.Namespace) {
\r
921 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
\r
925 if (any.TargetNamespace != this.QualifiedName.Namespace)
\r
926 error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);
\r
929 qnames.Add (this.QualifiedName, this);
\r
933 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
\r
934 ValidationEventHandler h, XmlSchema schema)
\r
936 XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
\r
937 if (labeled == null)
\r
938 labels.Add (this.QualifiedName, this);
\r
939 else if (labeled.ElementType != this.ElementType)
\r
940 error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);
\r
944 // 3.3.6 Element Default Valid (Immediate)
\r
945 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
\r
947 // This presumes that ElementType is already filled.
\r
949 XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
\r
950 XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
\r
951 if (simpleType != null)
\r
952 datatype = simpleType.Datatype;
\r
954 if (datatype == null) {
\r
955 XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;
\r
956 switch (complexType.ContentType) {
\r
957 case XmlSchemaContentType.Empty:
\r
958 case XmlSchemaContentType.ElementOnly:
\r
959 error (h, "Element content type must be simple type or mixed.");
\r
962 datatype = XmlSchemaSimpleType.AnySimpleType;
\r
965 XmlNamespaceManager nsmgr = null;
\r
966 if (datatype.TokenizedType == XmlTokenizedType.QName) {
\r
967 if (this.Namespaces != null)
\r
968 foreach (XmlQualifiedName qname in Namespaces.ToArray ())
\r
969 nsmgr.AddNamespace (qname.Name, qname.Namespace);
\r
973 if (defaultValue != null) {
\r
974 validatedDefaultValue = datatype.Normalize (defaultValue);
\r
975 datatype.ParseValue (validatedDefaultValue, null, nsmgr);
\r
977 } catch (Exception ex) {
\r
978 // FIXME: This is not a good way to handle exception, but
\r
979 // I think there is no remedy for such Framework specification.
\r
980 error (h, "The Element's default value is invalid with respect to its type definition.", ex);
\r
983 if (fixedValue != null) {
\r
984 validatedFixedValue = datatype.Normalize (fixedValue);
\r
985 datatype.ParseValue (validatedFixedValue, null, nsmgr);
\r
987 } catch (Exception ex) {
\r
988 // FIXME: This is not a good way to handle exception.
\r
989 error (h, "The Element's fixed value is invalid with its type definition.", ex);
\r
994 // abstract = boolean : false
\r
995 // block = (#all | List of (extension | restriction | substitution))
\r
996 // default = string
\r
997 // final = (#all | List of (extension | restriction))
\r
999 // form = (qualified | unqualified)
\r
1001 // maxOccurs = (nonNegativeInteger | unbounded) : 1
\r
1002 // minOccurs = nonNegativeInteger : 1
\r
1004 // nillable = boolean : false
\r
1006 // substitutionGroup = QName
\r
1008 // {any attributes with non-schema namespace . . .}>
\r
1009 // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
\r
1012 internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
\r
1014 XmlSchemaElement element = new XmlSchemaElement();
\r
1015 Exception innerex;
\r
1016 reader.MoveToElement();
\r
1018 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
\r
1020 error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
\r
1025 element.LineNumber = reader.LineNumber;
\r
1026 element.LinePosition = reader.LinePosition;
\r
1027 element.SourceUri = reader.BaseURI;
\r
1029 while(reader.MoveToNextAttribute())
\r
1031 if(reader.Name == "abstract")
\r
1033 element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
\r
1034 if(innerex != null)
\r
1035 error(h,reader.Value + " is invalid value for abstract",innerex);
\r
1037 else if(reader.Name == "block")
\r
1039 element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
\r
1040 XmlSchemaUtil.ElementBlockAllowed);
\r
1041 if(innerex != null)
\r
1042 error (h,"some invalid values for block attribute were found",innerex);
\r
1044 else if(reader.Name == "default")
\r
1046 element.defaultValue = reader.Value;
\r
1048 else if(reader.Name == "final")
\r
1050 element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
\r
1051 XmlSchemaUtil.FinalAllowed);
\r
1052 if(innerex != null)
\r
1053 error (h,"some invalid values for final attribute were found",innerex);
\r
1055 else if(reader.Name == "fixed")
\r
1057 element.fixedValue = reader.Value;
\r
1059 else if(reader.Name == "form")
\r
1061 element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
\r
1062 if(innerex != null)
\r
1063 error(h,reader.Value + " is an invalid value for form attribute",innerex);
\r
1065 else if(reader.Name == "id")
\r
1067 element.Id = reader.Value;
\r
1069 else if(reader.Name == "maxOccurs")
\r
1073 element.MaxOccursString = reader.Value;
\r
1075 catch(Exception e)
\r
1077 error(h,reader.Value + " is an invalid value for maxOccurs",e);
\r
1080 else if(reader.Name == "minOccurs")
\r
1084 element.MinOccursString = reader.Value;
\r
1086 catch(Exception e)
\r
1088 error(h,reader.Value + " is an invalid value for minOccurs",e);
\r
1091 else if(reader.Name == "name")
\r
1093 element.Name = reader.Value;
\r
1095 else if(reader.Name == "nillable")
\r
1097 element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
\r
1098 if(innerex != null)
\r
1099 error(h,reader.Value + "is not a valid value for nillable",innerex);
\r
1101 else if(reader.Name == "ref")
\r
1103 element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1104 if(innerex != null)
\r
1105 error(h, reader.Value + " is not a valid value for ref attribute",innerex);
\r
1107 else if(reader.Name == "substitutionGroup")
\r
1109 element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1110 if(innerex != null)
\r
1111 error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
\r
1113 else if(reader.Name == "type")
\r
1115 element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1116 if(innerex != null)
\r
1117 error(h, reader.Value + " is not a valid value for type attribute",innerex);
\r
1119 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
\r
1121 error(h,reader.Name + " is not a valid attribute for element",null);
\r
1125 XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
\r
1129 reader.MoveToElement();
\r
1130 if(reader.IsEmptyElement)
\r
1133 // Content: annotation?,
\r
1134 // (simpleType | complexType)?,
\r
1135 // (unique | key | keyref)*
\r
1137 while(reader.ReadNextElement())
\r
1139 if(reader.NodeType == XmlNodeType.EndElement)
\r
1141 if(reader.LocalName != xmlname)
\r
1142 error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
\r
1145 if(level <= 1 && reader.LocalName == "annotation")
\r
1147 level = 2; //Only one annotation
\r
1148 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
\r
1149 if(annotation != null)
\r
1150 element.Annotation = annotation;
\r
1155 if(reader.LocalName == "simpleType")
\r
1158 XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
\r
1159 if(simple != null)
\r
1160 element.SchemaType = simple;
\r
1163 if(reader.LocalName == "complexType")
\r
1166 XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
\r
1167 if(complex != null)
\r
1169 element.SchemaType = complex;
\r
1176 if(reader.LocalName == "unique")
\r
1179 XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
\r
1180 if(unique != null)
\r
1181 element.constraints.Add(unique);
\r
1184 else if(reader.LocalName == "key")
\r
1187 XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
\r
1189 element.constraints.Add(key);
\r
1192 else if(reader.LocalName == "keyref")
\r
1195 XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
\r
1196 if(keyref != null)
\r
1197 element.constraints.Add(keyref);
\r
1201 reader.RaiseInvalidElementError();
\r