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 XmlSchemaDerivationMethod blockResolved;
\r
44 private XmlSchemaObjectCollection constraints;
\r
45 private string defaultValue;
\r
46 private object elementType;
\r
47 private XmlSchemaDerivationMethod final;
\r
48 private XmlSchemaDerivationMethod finalResolved;
\r
49 private string fixedValue;
\r
50 private XmlSchemaForm form;
\r
51 private bool isAbstract;
\r
52 private bool isNillable;
\r
53 private string name;
\r
54 private XmlQualifiedName qName;
\r
55 private XmlQualifiedName refName;
\r
56 private XmlSchemaType schemaType;
\r
57 private XmlQualifiedName schemaTypeName;
\r
58 private XmlQualifiedName substitutionGroup;
\r
59 internal bool parentIsSchema = false;
\r
60 private string validatedDefaultValue;
\r
61 private string validatedFixedValue;
\r
62 private bool actualIsAbstract;
\r
63 private bool actualIsNillable;
\r
64 private XmlSchemaElement substitutionGroupElement;
\r
65 private ArrayList substitutingElements = new ArrayList ();
\r
66 private XmlSchemaElement referencedElement;
\r
68 // Post compilation items. It should be added on all schema components.
\r
71 const string xmlname = "element";
\r
73 public XmlSchemaElement()
\r
75 block = XmlSchemaDerivationMethod.None;
\r
76 final = XmlSchemaDerivationMethod.None;
\r
77 constraints = new XmlSchemaObjectCollection();
\r
78 qName = XmlQualifiedName.Empty;
\r
79 refName = XmlQualifiedName.Empty;
\r
80 schemaTypeName = XmlQualifiedName.Empty;
\r
81 substitutionGroup = XmlQualifiedName.Empty;
\r
86 [DefaultValue(false)]
\r
87 [System.Xml.Serialization.XmlAttribute("abstract")]
\r
88 public bool IsAbstract
\r
90 get{ return isAbstract; }
\r
91 set{ isAbstract = value; }
\r
94 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
95 [System.Xml.Serialization.XmlAttribute("block")]
\r
96 public XmlSchemaDerivationMethod Block
\r
98 get{ return block; }
\r
99 set{ block = value; }
\r
102 [DefaultValue(null)]
\r
103 [System.Xml.Serialization.XmlAttribute("default")]
\r
104 public string DefaultValue
\r
106 get{ return defaultValue; }
\r
107 set{ defaultValue = value; }
\r
110 [DefaultValue(XmlSchemaDerivationMethod.None)]
\r
111 [System.Xml.Serialization.XmlAttribute("final")]
\r
112 public XmlSchemaDerivationMethod Final
\r
114 get{ return final; }
\r
115 set{ final = value; }
\r
118 [DefaultValue(null)]
\r
119 [System.Xml.Serialization.XmlAttribute("fixed")]
\r
120 public string FixedValue
\r
122 get{ return fixedValue; }
\r
123 set{ fixedValue = value; }
\r
125 [DefaultValue(XmlSchemaForm.None)]
\r
126 [System.Xml.Serialization.XmlAttribute("form")]
\r
127 public XmlSchemaForm Form
\r
129 get{ return form; }
\r
130 set{ form = value; }
\r
133 [DefaultValue(null)]
\r
134 [System.Xml.Serialization.XmlAttribute("name")]
\r
135 public string Name
\r
137 get{ return name; }
\r
138 set{ name = value; }
\r
141 [DefaultValue(false)]
\r
142 [System.Xml.Serialization.XmlAttribute("nillable")]
\r
143 public bool IsNillable
\r
145 get{ return isNillable; }
\r
146 set{ isNillable = value; }
\r
149 [System.Xml.Serialization.XmlAttribute("ref")]
\r
150 public XmlQualifiedName RefName
\r
152 get{ return refName; }
\r
153 set{ refName = value;}
\r
156 [System.Xml.Serialization.XmlAttribute("substitutionGroup")]
\r
157 public XmlQualifiedName SubstitutionGroup
\r
159 get{ return substitutionGroup; }
\r
160 set{ substitutionGroup = value; }
\r
163 [System.Xml.Serialization.XmlAttribute("type")]
\r
164 public XmlQualifiedName SchemaTypeName
\r
166 get{ return schemaTypeName; }
\r
167 set{ schemaTypeName = value; }
\r
173 [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
174 [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
175 public XmlSchemaType SchemaType
\r
177 get{ return schemaType; }
\r
178 set{ schemaType = value; }
\r
181 [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
182 [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
183 [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]
\r
184 public XmlSchemaObjectCollection Constraints
\r
186 get{ return constraints; }
\r
190 #region Post Compilation Schema Info
\r
192 public XmlQualifiedName QualifiedName
\r
194 get{ return qName; }
\r
198 public object ElementType
\r
201 if (referencedElement != null)
\r
202 return referencedElement.ElementType;
\r
204 return elementType;
\r
209 public XmlSchemaDerivationMethod BlockResolved
\r
212 if (referencedElement != null)
\r
213 return referencedElement.BlockResolved;
\r
215 return blockResolved;
\r
220 public XmlSchemaDerivationMethod FinalResolved
\r
223 if (referencedElement != null)
\r
224 return referencedElement.FinalResolved;
\r
226 return finalResolved;
\r
230 internal bool ActualIsNillable {
\r
232 if (referencedElement != null)
\r
233 return referencedElement.ActualIsNillable;
\r
235 return actualIsNillable;
\r
239 internal bool ActualIsAbstract {
\r
241 if (referencedElement != null)
\r
242 return referencedElement.ActualIsAbstract;
\r
244 return actualIsAbstract;
\r
248 // Post compilation default value (normalized)
\r
249 internal string ValidatedDefaultValue {
\r
251 if (referencedElement != null)
\r
252 return referencedElement.ValidatedDefaultValue;
\r
254 return validatedDefaultValue;
\r
258 // Post compilation fixed value (normalized)
\r
259 internal string ValidatedFixedValue {
\r
261 if (referencedElement != null)
\r
262 return referencedElement.ValidatedFixedValue;
\r
264 return validatedFixedValue;
\r
268 internal ArrayList SubstitutingElements {
\r
270 if (referencedElement != null)
\r
271 return referencedElement.SubstitutingElements;
\r
273 return this.substitutingElements;
\r
277 internal XmlSchemaElement SubstitutionGroupElement {
\r
279 if (referencedElement != null)
\r
280 return referencedElement.SubstitutionGroupElement;
\r
282 return substitutionGroupElement;
\r
288 private XmlSchemaParticle substChoice;
\r
291 /// a) If Element has parent as schema:
\r
292 /// 1. name must be present and of type NCName.
\r
293 /// 2. ref must be absent
\r
294 /// 3. form must be absent
\r
295 /// 4. minOccurs must be absent
\r
296 /// 5. maxOccurs must be absent
\r
297 /// b) If Element has parent is not schema and ref is absent
\r
298 /// 1. name must be present and of type NCName.
\r
299 /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
\r
300 /// targetNamespace is schema's targetnamespace else empty.
\r
301 /// 3. type and either <simpleType> or <complexType> are mutually exclusive
\r
302 /// 4. default and fixed must not both be present.
\r
303 /// 5. substitutiongroup must be absent
\r
304 /// 6. final must be absent
\r
305 /// 7. abstract must be absent
\r
306 /// c) if the parent is not schema and ref is set
\r
307 /// 1. name must not be present
\r
308 /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
\r
309 /// default, fixed, form, block and type, must be absent.
\r
310 /// 3. substitutiongroup is prohibited
\r
311 /// 4. final is prohibited
\r
312 /// 5. abstract is prohibited
\r
313 /// 6. default and fixed must not both be present.(Actually both are absent)
\r
315 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
\r
317 // If this is already compiled this time, simply skip.
\r
318 if (this.IsComplied (schema.CompilationId))
\r
320 this.schema = schema;
\r
322 if(this.defaultValue != null && this.fixedValue != null)
\r
323 error(h,"both default and fixed can't be present");
\r
325 if(parentIsSchema || isRedefineChild)
\r
327 if(this.refName != null && !RefName.IsEmpty)
\r
328 error(h,"ref must be absent");
\r
330 if(this.name == null) //b1
\r
331 error(h,"Required attribute name must be present");
\r
332 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
\r
333 error(h,"attribute name must be NCName");
\r
335 this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);
\r
337 if(form != XmlSchemaForm.None)
\r
338 error(h,"form must be absent");
\r
339 if(MinOccursString != null)
\r
340 error(h,"minOccurs must be absent");
\r
341 if(MaxOccursString != null)
\r
342 error(h,"maxOccurs must be absent");
\r
344 XmlSchemaDerivationMethod allfinal = (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
\r
345 if(final == XmlSchemaDerivationMethod.All)
\r
346 finalResolved = allfinal;
\r
347 else if(final == XmlSchemaDerivationMethod.None)
\r
348 finalResolved = XmlSchemaDerivationMethod.Empty;
\r
351 // if((final & ~allfinal) != 0)
\r
352 if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)
\r
353 error (h,"some values for final are invalid in this context");
\r
354 finalResolved = final & allfinal;
\r
357 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
359 error(h,"both schemaType and content can't be present");
\r
362 //Even if both are present, read both of them.
\r
363 if(schemaType != null)
\r
365 if(schemaType is XmlSchemaSimpleType)
\r
367 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
\r
369 else if(schemaType is XmlSchemaComplexType)
\r
371 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
\r
374 error(h,"only simpletype or complextype is allowed");
\r
376 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
378 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
\r
379 error(h,"SchemaTypeName must be an XmlQualifiedName");
\r
381 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
\r
383 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
\r
384 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
\r
387 foreach(XmlSchemaObject obj in constraints)
\r
389 if(obj is XmlSchemaUnique)
\r
390 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
\r
391 else if(obj is XmlSchemaKey)
\r
392 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
\r
393 else if(obj is XmlSchemaKeyref)
\r
394 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
\r
399 if(substitutionGroup != null && !substitutionGroup.IsEmpty)
\r
400 error(h,"substitutionGroup must be absent");
\r
401 if(final != XmlSchemaDerivationMethod.None)
\r
402 error(h,"final must be absent");
\r
404 CompileOccurence (h, schema);
\r
406 if(refName == null || RefName.IsEmpty)
\r
408 string targetNamespace = String.Empty;
\r
410 if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))
\r
411 targetNamespace = schema.TargetNamespace;
\r
413 if(this.name == null) //b1
\r
414 error(h,"Required attribute name must be present");
\r
415 else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
\r
416 error(h,"attribute name must be NCName");
\r
418 this.qName = new XmlQualifiedName(this.name, targetNamespace);
\r
420 if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
422 error(h,"both schemaType and content can't be present");
\r
425 //Even if both are present, read both of them.
\r
426 if(schemaType != null)
\r
428 if(schemaType is XmlSchemaSimpleType)
\r
430 errorCount += ((XmlSchemaSimpleType)schemaType).Compile(h,schema);
\r
432 else if(schemaType is XmlSchemaComplexType)
\r
434 errorCount += ((XmlSchemaComplexType)schemaType).Compile(h,schema);
\r
437 error(h,"only simpletype or complextype is allowed");
\r
439 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
441 if(!XmlSchemaUtil.CheckQName(SchemaTypeName))
\r
442 error(h,"SchemaTypeName must be an XmlQualifiedName");
\r
444 if(SubstitutionGroup != null && !SubstitutionGroup.IsEmpty)
\r
446 if(!XmlSchemaUtil.CheckQName(SubstitutionGroup))
\r
447 error(h,"SubstitutionGroup must be a valid XmlQualifiedName");
\r
450 foreach(XmlSchemaObject obj in constraints)
\r
452 if(obj is XmlSchemaUnique)
\r
453 errorCount += ((XmlSchemaUnique)obj).Compile(h,schema);
\r
454 else if(obj is XmlSchemaKey)
\r
455 errorCount += ((XmlSchemaKey)obj).Compile(h,schema);
\r
456 else if(obj is XmlSchemaKeyref)
\r
457 errorCount += ((XmlSchemaKeyref)obj).Compile(h,schema);
\r
462 if(!XmlSchemaUtil.CheckQName(RefName))
\r
463 error(h,"RefName must be a XmlQualifiedName");
\r
466 error(h,"name must not be present when ref is present");
\r
467 if(Constraints.Count != 0)
\r
468 error(h,"key, keyref and unique must be absent");
\r
470 error(h,"nillable must be absent");
\r
471 if(defaultValue != null)
\r
472 error(h,"default must be absent");
\r
473 if(fixedValue != null)
\r
474 error(h,"fixed must be null");
\r
475 if(form != XmlSchemaForm.None)
\r
476 error(h,"form must be absent");
\r
477 if(block != XmlSchemaDerivationMethod.None)
\r
478 error(h,"block must be absent");
\r
479 if(schemaTypeName != null && !schemaTypeName.IsEmpty)
\r
480 error(h,"type must be absent");
\r
481 if(SchemaType != null)
\r
482 error(h,"simpleType or complexType must be absent");
\r
489 case XmlSchemaDerivationMethod.All:
\r
490 blockResolved = XmlSchemaDerivationMethod.All;
\r
492 case XmlSchemaDerivationMethod.None:
\r
493 blockResolved = XmlSchemaDerivationMethod.Empty;
\r
496 if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
\r
497 error (h,"Some of the values for block are invalid in this context");
\r
498 blockResolved = block;
\r
502 if (Constraints != null) {
\r
503 XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
\r
504 foreach (XmlSchemaIdentityConstraint c in Constraints) {
\r
505 XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
\r
509 XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
\r
511 this.CompilationId = schema.CompilationId;
\r
515 [MonoTODO ("Return clone in case when it returns itself")]
\r
516 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
\r
518 if (OptimizedParticle != null)
\r
519 return OptimizedParticle;
\r
520 if (RefName != null && RefName != XmlQualifiedName.Empty) {
\r
521 referencedElement = schema.Elements [RefName] as XmlSchemaElement;
\r
524 // if (this.referencedElement != null)
\r
525 // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
\r
527 if (ValidatedMaxOccurs == 0)
\r
528 OptimizedParticle = XmlSchemaParticle.Empty;
\r
529 // Substitution Group
\r
530 else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {
\r
531 XmlSchemaChoice choice = new XmlSchemaChoice ();
\r
532 choice.MinOccurs = MinOccurs;
\r
533 choice.MaxOccurs = MaxOccurs;
\r
534 substChoice = choice;
\r
535 choice.Compile (null, schema); // compute Validated Min/Max Occurs.
\r
536 XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;
\r
537 item.MinOccurs = 1;
\r
538 item.MaxOccurs = 1;
\r
539 item.substitutionGroupElement = null;
\r
540 item.substitutingElements = null;
\r
541 for (int i = 0; i < SubstitutingElements.Count; i++) {
\r
542 XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;
\r
543 // choice.Items.Add (se);
\r
544 // choice.CompiledItems.Add (se);
\r
545 this.AddSubstElementRecursively (choice.Items, se);
\r
546 this.AddSubstElementRecursively (choice.CompiledItems, se);
\r
548 if (!choice.Items.Contains (item)) {
\r
549 choice.Items.Add (item);
\r
550 choice.CompiledItems.Add (item);
\r
552 OptimizedParticle = choice;
\r
555 OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;
\r
556 return OptimizedParticle;
\r
559 private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)
\r
561 if (el.SubstitutingElements != null)
\r
562 for (int i = 0; i < el.SubstitutingElements.Count; i++)
\r
563 this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);
\r
564 if (!col.Contains (el))
\r
568 internal void FillSubstitutionElementInfo ()
\r
570 if (this.substitutionGroupElement != null)
\r
573 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
574 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
\r
575 this.substitutionGroupElement = substElem;
\r
576 if (substElem != null)
\r
577 substElem.substitutingElements.Add (this);
\r
581 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
\r
583 if (IsValidated (schema.CompilationId))
\r
586 // See XML Schema Structures 3.6 for the complete description.
\r
588 // Element Declaration Properties Correct
\r
589 // 1. = 3.3.1 (modulo 5.3)
\r
592 // {annotation} is as is.
\r
593 // {name}, {target namespace}, {scope}, {disallowed substitution},
\r
594 // {substitution group exclusions} (handled the same as 'disallowed substitution')
\r
595 // and {identity-constraint-definitions} are Compile()d.
\r
596 // {value constraint} is going to be filled in step 2.
\r
598 // actual {nillable}, {abstract}
\r
599 this.actualIsNillable = IsNillable;
\r
600 this.actualIsAbstract = IsAbstract;
\r
602 // Before determining element type, we need to validate substituting element
\r
603 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
604 XmlSchemaElement substElem = substitutionGroupElement;
\r
605 if (substElem != null)
\r
606 substElem.Validate (h, schema);
\r
609 // {type} from here
\r
610 XmlSchemaDatatype datatype = null;
\r
611 if (schemaType != null)
\r
612 elementType = schemaType;
\r
613 else if (SchemaTypeName != XmlQualifiedName.Empty) {
\r
614 XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
\r
615 // If el is null, then it is missing sub components .
\r
616 if (type != null) {
\r
617 type.Validate (h, schema);
\r
618 elementType = type;
\r
620 else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
\r
621 elementType = XmlSchemaComplexType.AnyType;
622 else if (XmlSchemaUtil.IsBuiltInDatatypeName (SchemaTypeName)) {
\r
623 datatype = XmlSchemaDatatype.FromName (SchemaTypeName);
\r
624 if (datatype == null)
\r
625 error (h, "Invalid schema datatype was specified.");
\r
627 elementType = datatype;
\r
629 // otherwise, it might be missing sub components.
\r
630 else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))
\r
631 error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");
\r
633 else if (RefName != XmlQualifiedName.Empty)
\r
635 XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;
\r
636 // If el is null, then it is missing sub components .
\r
637 if (refElem != null) {
\r
638 this.referencedElement = refElem;
\r
639 errorCount += refElem.Validate (h, schema);
\r
641 // otherwise, it might be missing sub components.
\r
642 else if (!schema.IsNamespaceAbsent (RefName.Namespace))
\r
643 error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");
\r
646 // Otherwise if there are substitution group, then the type of the substitution group element.
\r
647 if (referencedElement == null) {
\r
648 if (elementType == null && this.substitutionGroupElement != null)
\r
649 elementType = substitutionGroupElement.ElementType;
\r
650 // Otherwise, the -ur type- definition.
\r
651 if (elementType == null)
\r
652 elementType = XmlSchemaComplexType.AnyType;
\r
655 XmlSchemaType xsType = elementType as XmlSchemaType;
\r
656 if (xsType != null) {
\r
657 errorCount += xsType.Validate (h, schema);
\r
658 datatype = xsType.Datatype;
\r
660 // basic {type} is now filled, except for derivation by {substitution group}.
\r
662 // {substitution group affiliation}
\r
663 // 3. subsitution group's type derivation check.
\r
664 if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
\r
665 XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
\r
666 // If el is null, then it is missing sub components .
\r
667 if (substElem != null) {
\r
668 XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;
\r
669 if (substSchemaType != null) {
\r
670 // 3.3.6 Properties Correct 3.
\r
671 if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)
\r
672 error (h, "Substituted element blocks substitution.");
\r
673 if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)
\r
674 error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");
\r
676 XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
\r
677 if (xsComplexType != null)
\r
678 xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
\r
680 XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
\r
681 if (xsSimpleType != null)
\r
682 xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
\r
686 // otherwise, it might be missing sub components.
\r
687 else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))
\r
688 error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");
\r
691 // 2. ElementDefaultValid
\r
692 // 4. ID with {value constraint} is prohibited.
\r
693 if (defaultValue != null || fixedValue != null) {
\r
694 ValidateElementDefaultValidImmediate (h, schema);
\r
695 if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.
\r
696 datatype.TokenizedType == XmlTokenizedType.ID)
\r
697 error (h, "Element type is ID, which does not allows default or fixed values.");
\r
700 // Identity constraints (3.11.3 / 3.11.6)
\r
701 foreach (XmlSchemaIdentityConstraint ident in Constraints)
\r
702 ident.Validate (h, schema);
\r
704 ValidationId = schema.ValidationId;
\r
708 internal override bool ParticleEquals (XmlSchemaParticle other)
\r
710 XmlSchemaElement element = other as XmlSchemaElement;
\r
711 if (element == null)
\r
713 if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||
\r
714 this.ValidatedMinOccurs != element.ValidatedMinOccurs)
\r
716 if (this.QualifiedName != element.QualifiedName ||
\r
717 this.ElementType != element.ElementType ||
\r
718 this.Constraints.Count != element.Constraints.Count)
\r
720 for (int i = 0; i < this.Constraints.Count; i++) {
\r
721 XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;
\r
722 XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;
\r
723 if (c1.QualifiedName != c2.QualifiedName ||
\r
724 c1.Selector.XPath != c2.Selector.XPath ||
\r
725 c1.Fields.Count != c2.Fields.Count)
\r
727 for (int f = 0; f < c1.Fields.Count; f++) {
\r
728 XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;
\r
729 XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;
\r
730 if (f1.XPath != f2.XPath)
\r
734 if (this.BlockResolved != element.BlockResolved ||
\r
735 this.FinalResolved != element.FinalResolved ||
\r
736 this.ValidatedDefaultValue != element.ValidatedDefaultValue ||
\r
737 this.ValidatedFixedValue != element.ValidatedFixedValue)
\r
742 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
\r
743 ValidationEventHandler h, XmlSchema schema, bool raiseError)
\r
745 // element - NameAndTypeOK
\r
746 XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
\r
747 if (baseElement != null) {
\r
748 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);
\r
752 XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
\r
753 if (baseAny != null) {
\r
755 if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))
\r
757 return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);
\r
761 // choice - RecurseAsIfGroup
\r
762 XmlSchemaGroupBase gb = null;
\r
763 if (baseParticle is XmlSchemaSequence)
\r
764 gb = new XmlSchemaSequence ();
\r
765 else if (baseParticle is XmlSchemaChoice)
\r
766 gb = new XmlSchemaChoice ();
\r
767 else if (baseParticle is XmlSchemaAll)
\r
768 gb = new XmlSchemaAll ();
\r
771 gb.Items.Add (this);
\r
772 gb.Compile (h, schema);
\r
773 gb.Validate (h, schema);
\r
774 // It looks weird, but here we never think about
\r
775 // _pointlessness_ of this groupbase particle.
\r
776 return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);
\r
782 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
\r
783 ValidationEventHandler h, XmlSchema schema, bool raiseError)
\r
786 if (this.QualifiedName != baseElement.QualifiedName) {
\r
788 error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
\r
792 if (this.isNillable && !baseElement.isNillable) {
\r
794 error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
\r
798 if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))
\r
801 if (baseElement.ValidatedFixedValue != null &&
\r
802 baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {
\r
804 error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
\r
807 // 5. TODO: What is "identity constraints subset" ???
\r
810 if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {
\r
812 error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
\r
816 if (baseElement.ElementType != null) {
\r
817 XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;
\r
818 if (derivedCType != null) {
\r
819 // FIXME: W3C REC says that it is Type Derivation OK to be check, but
\r
820 // in fact it should be DerivationValid (Restriction, Complex).
\r
821 derivedCType.ValidateDerivationValidRestriction (
\r
822 baseElement.ElementType as XmlSchemaComplexType, h, schema);
\r
823 derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);
\r
825 XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;
\r
826 if (derivedSType != null)
\r
827 derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);
\r
828 else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {
\r
830 error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
\r
838 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
\r
840 XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
\r
841 if (ct == null || ct.Particle == null)
\r
843 ct.Particle.CheckRecursion (depth + 1, h, schema);
\r
846 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
\r
847 ValidationEventHandler h, XmlSchema schema)
\r
849 if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
\r
850 error (h, "Ambiguous element label was detected: " + this.QualifiedName);
\r
852 foreach (XmlSchemaAny any in nsNames) {
\r
853 if (any.ValidatedMaxOccurs == 0)
\r
855 if (any.HasValueAny ||
\r
856 any.HasValueLocal && this.QualifiedName.Namespace == "" ||
\r
857 any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||
\r
858 any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {
\r
859 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
\r
861 } else if (!any.HasValueOther) {
\r
863 foreach (string ns in any.ResolvedNamespaces) {
\r
864 if (ns == this.QualifiedName.Namespace) {
\r
870 error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
\r
874 if (any.TargetNamespace.Length == 0 ||
\r
875 any.TargetNamespace != this.QualifiedName.Namespace)
\r
876 error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);
\r
879 qnames.Add (this.QualifiedName, this);
\r
883 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
\r
884 ValidationEventHandler h, XmlSchema schema)
\r
886 XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
\r
887 if (labeled == null)
\r
888 labels.Add (this.QualifiedName, this);
\r
889 else if (labeled.ElementType != this.ElementType)
\r
890 error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);
\r
894 // 3.3.6 Element Default Valid (Immediate)
\r
895 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
\r
897 // This presumes that ElementType is already filled.
\r
899 XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
\r
900 XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
\r
901 if (simpleType != null)
\r
902 datatype = simpleType.Datatype;
\r
904 if (datatype == null) {
\r
905 XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;
\r
906 switch (complexType.ContentType) {
\r
907 case XmlSchemaContentType.Empty:
\r
908 case XmlSchemaContentType.ElementOnly:
\r
909 error (h, "Element content type must be simple type or mixed.");
\r
912 datatype = XmlSchemaSimpleType.AnySimpleType;
\r
915 XmlNamespaceManager nsmgr = null;
\r
916 if (datatype.TokenizedType == XmlTokenizedType.QName) {
\r
917 if (this.Namespaces != null)
\r
918 foreach (XmlQualifiedName qname in Namespaces.ToArray ())
\r
919 nsmgr.AddNamespace (qname.Name, qname.Namespace);
\r
923 if (defaultValue != null) {
\r
924 validatedDefaultValue = datatype.Normalize (defaultValue);
\r
925 datatype.ParseValue (validatedDefaultValue, null, nsmgr);
\r
927 } catch (Exception ex) {
\r
928 // FIXME: This is not a good way to handle exception, but
\r
929 // I think there is no remedy for such Framework specification.
\r
930 error (h, "The Element's default value is invalid with respect to its type definition.", ex);
\r
933 if (fixedValue != null) {
\r
934 validatedFixedValue = datatype.Normalize (fixedValue);
\r
935 datatype.ParseValue (validatedFixedValue, null, nsmgr);
\r
937 } catch (Exception ex) {
\r
938 // FIXME: This is not a good way to handle exception.
\r
939 error (h, "The Element's fixed value is invalid with its type definition.", ex);
\r
944 // abstract = boolean : false
\r
945 // block = (#all | List of (extension | restriction | substitution))
\r
946 // default = string
\r
947 // final = (#all | List of (extension | restriction))
\r
949 // form = (qualified | unqualified)
\r
951 // maxOccurs = (nonNegativeInteger | unbounded) : 1
\r
952 // minOccurs = nonNegativeInteger : 1
\r
954 // nillable = boolean : false
\r
956 // substitutionGroup = QName
\r
958 // {any attributes with non-schema namespace . . .}>
\r
959 // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
\r
962 internal static XmlSchemaElement Read(XmlSchemaReader reader, ValidationEventHandler h)
\r
964 XmlSchemaElement element = new XmlSchemaElement();
\r
966 reader.MoveToElement();
\r
968 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
\r
970 error(h,"Should not happen :1: XmlSchemaElement.Read, name="+reader.Name,null);
\r
975 element.LineNumber = reader.LineNumber;
\r
976 element.LinePosition = reader.LinePosition;
\r
977 element.SourceUri = reader.BaseURI;
\r
979 while(reader.MoveToNextAttribute())
\r
981 if(reader.Name == "abstract")
\r
983 element.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
\r
984 if(innerex != null)
\r
985 error(h,reader.Value + " is invalid value for abstract",innerex);
\r
987 else if(reader.Name == "block")
\r
989 element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
\r
990 XmlSchemaUtil.ElementBlockAllowed);
\r
991 if(innerex != null)
\r
992 error (h,"some invalid values for block attribute were found",innerex);
\r
994 else if(reader.Name == "default")
\r
996 element.defaultValue = reader.Value;
\r
998 else if(reader.Name == "final")
\r
1000 element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
\r
1001 XmlSchemaUtil.FinalAllowed);
\r
1002 if(innerex != null)
\r
1003 error (h,"some invalid values for final attribute were found",innerex);
\r
1005 else if(reader.Name == "fixed")
\r
1007 element.fixedValue = reader.Value;
\r
1009 else if(reader.Name == "form")
\r
1011 element.form = XmlSchemaUtil.ReadFormAttribute(reader,out innerex);
\r
1012 if(innerex != null)
\r
1013 error(h,reader.Value + " is an invalid value for form attribute",innerex);
\r
1015 else if(reader.Name == "id")
\r
1017 element.Id = reader.Value;
\r
1019 else if(reader.Name == "maxOccurs")
\r
1023 element.MaxOccursString = reader.Value;
\r
1025 catch(Exception e)
\r
1027 error(h,reader.Value + " is an invalid value for maxOccurs",e);
\r
1030 else if(reader.Name == "minOccurs")
\r
1034 element.MinOccursString = reader.Value;
\r
1036 catch(Exception e)
\r
1038 error(h,reader.Value + " is an invalid value for minOccurs",e);
\r
1041 else if(reader.Name == "name")
\r
1043 element.Name = reader.Value;
\r
1045 else if(reader.Name == "nillable")
\r
1047 element.IsNillable = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
\r
1048 if(innerex != null)
\r
1049 error(h,reader.Value + "is not a valid value for nillable",innerex);
\r
1051 else if(reader.Name == "ref")
\r
1053 element.refName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1054 if(innerex != null)
\r
1055 error(h, reader.Value + " is not a valid value for ref attribute",innerex);
\r
1057 else if(reader.Name == "substitutionGroup")
\r
1059 element.substitutionGroup = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1060 if(innerex != null)
\r
1061 error(h, reader.Value + " is not a valid value for substitutionGroup attribute",innerex);
\r
1063 else if(reader.Name == "type")
\r
1065 element.SchemaTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
\r
1066 if(innerex != null)
\r
1067 error(h, reader.Value + " is not a valid value for type attribute",innerex);
\r
1069 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
\r
1071 error(h,reader.Name + " is not a valid attribute for element",null);
\r
1075 XmlSchemaUtil.ReadUnhandledAttribute(reader,element);
\r
1079 reader.MoveToElement();
\r
1080 if(reader.IsEmptyElement)
\r
1083 // Content: annotation?,
\r
1084 // (simpleType | complexType)?,
\r
1085 // (unique | key | keyref)*
\r
1087 while(reader.ReadNextElement())
\r
1089 if(reader.NodeType == XmlNodeType.EndElement)
\r
1091 if(reader.LocalName != xmlname)
\r
1092 error(h,"Should not happen :2: XmlSchemaElement.Read, name="+reader.Name,null);
\r
1095 if(level <= 1 && reader.LocalName == "annotation")
\r
1097 level = 2; //Only one annotation
\r
1098 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
\r
1099 if(annotation != null)
\r
1100 element.Annotation = annotation;
\r
1105 if(reader.LocalName == "simpleType")
\r
1108 XmlSchemaSimpleType simple = XmlSchemaSimpleType.Read(reader,h);
\r
1109 if(simple != null)
\r
1110 element.SchemaType = simple;
\r
1113 if(reader.LocalName == "complexType")
\r
1116 XmlSchemaComplexType complex = XmlSchemaComplexType.Read(reader,h);
\r
1117 if(complex != null)
\r
1119 element.SchemaType = complex;
\r
1126 if(reader.LocalName == "unique")
\r
1129 XmlSchemaUnique unique = XmlSchemaUnique.Read(reader,h);
\r
1130 if(unique != null)
\r
1131 element.constraints.Add(unique);
\r
1134 else if(reader.LocalName == "key")
\r
1137 XmlSchemaKey key = XmlSchemaKey.Read(reader,h);
\r
1139 element.constraints.Add(key);
\r
1142 else if(reader.LocalName == "keyref")
\r
1145 XmlSchemaKeyref keyref = XmlSchemaKeyref.Read(reader,h);
\r
1146 if(keyref != null)
\r
1147 element.constraints.Add(keyref);
\r
1151 reader.RaiseInvalidElementError();
\r