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
;
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
),Namespace
="http://www.w3.org/2001/XMLSchema")]
195 [XmlElement("complexType",typeof(XmlSchemaComplexType
),Namespace
="http://www.w3.org/2001/XMLSchema")]
196 public XmlSchemaType SchemaType
198 get{ return schemaType; }
199 set{ schemaType = value; }
202 [XmlElement("unique",typeof(XmlSchemaUnique
),Namespace
="http://www.w3.org/2001/XMLSchema")]
203 [XmlElement("key",typeof(XmlSchemaKey
),Namespace
="http://www.w3.org/2001/XMLSchema")]
204 [XmlElement("keyref",typeof(XmlSchemaKeyref
),Namespace
="http://www.w3.org/2001/XMLSchema")]
205 public XmlSchemaObjectCollection Constraints
207 get{ return constraints; }
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
;
326 /// a) If Element has parent as schema:
327 /// 1. name must be present and of type NCName.
328 /// 2. ref must be absent
329 /// 3. form must be absent
330 /// 4. minOccurs must be absent
331 /// 5. maxOccurs must be absent
332 /// b) If Element has parent is not schema and ref is absent
333 /// 1. name must be present and of type NCName.
334 /// 2. if form equals qualified or form is absent and schema's formdefault is qualifed,
335 /// targetNamespace is schema's targetnamespace else empty.
336 /// 3. type and either <simpleType> or <complexType> are mutually exclusive
337 /// 4. default and fixed must not both be present.
338 /// 5. substitutiongroup must be absent
339 /// 6. final must be absent
340 /// 7. abstract must be absent
341 /// c) if the parent is not schema and ref is set
342 /// 1. name must not be present
343 /// 2. all of <simpleType>,<complexType>, <key>, <keyref>, <unique>, nillable,
344 /// default, fixed, form, block and type, must be absent.
345 /// 3. substitutiongroup is prohibited
346 /// 4. final is prohibited
347 /// 5. abstract is prohibited
348 /// 6. default and fixed must not both be present.(Actually both are absent)
350 internal override int Compile(ValidationEventHandler h
, XmlSchema schema
)
352 // If this is already compiled this time, simply skip.
353 if (this.IsComplied (schema
.CompilationId
))
355 InitPostCompileInformations ();
356 this.schema
= schema
;
358 if(this.defaultValue
!= null && this.fixedValue
!= null)
359 error(h
,"both default and fixed can't be present");
361 if(parentIsSchema
|| isRedefineChild
)
363 if(this.refName
!= null && !RefName
.IsEmpty
)
364 error(h
,"ref must be absent");
366 if(this.name
== null) //b1
367 error(h
,"Required attribute name must be present");
368 else if(!XmlSchemaUtil
.CheckNCName(this.name
)) // b1.2
369 error(h
,"attribute name must be NCName");
371 this.qName
= new XmlQualifiedName (this.name
, schema
.TargetNamespace
);
373 if(form
!= XmlSchemaForm
.None
)
374 error(h
,"form must be absent");
375 if(MinOccursString
!= null)
376 error(h
,"minOccurs must be absent");
377 if(MaxOccursString
!= null)
378 error(h
,"maxOccurs must be absent");
380 XmlSchemaDerivationMethod allfinal
= (XmlSchemaDerivationMethod
.Extension
| XmlSchemaDerivationMethod
.Restriction
);
381 if(final
== XmlSchemaDerivationMethod
.All
)
382 finalResolved
= allfinal
;
383 else if(final
== XmlSchemaDerivationMethod
.None
)
384 finalResolved
= XmlSchemaDerivationMethod
.Empty
;
387 // if((final & ~allfinal) != 0)
388 if ((final
| XmlSchemaUtil
.FinalAllowed
) != XmlSchemaUtil
.FinalAllowed
)
389 error (h
,"some values for final are invalid in this context");
390 finalResolved
= final
& allfinal
;
393 if(schemaType
!= null && schemaTypeName
!= null && !schemaTypeName
.IsEmpty
)
395 error(h
,"both schemaType and content can't be present");
398 //Even if both are present, read both of them.
399 if(schemaType
!= null)
401 if(schemaType
is XmlSchemaSimpleType
)
403 errorCount
+= ((XmlSchemaSimpleType
)schemaType
).Compile(h
,schema
);
405 else if(schemaType
is XmlSchemaComplexType
)
407 errorCount
+= ((XmlSchemaComplexType
)schemaType
).Compile(h
,schema
);
410 error(h
,"only simpletype or complextype is allowed");
412 if(schemaTypeName
!= null && !schemaTypeName
.IsEmpty
)
414 if(!XmlSchemaUtil
.CheckQName(SchemaTypeName
))
415 error(h
,"SchemaTypeName must be an XmlQualifiedName");
417 if(SubstitutionGroup
!= null && !SubstitutionGroup
.IsEmpty
)
419 if(!XmlSchemaUtil
.CheckQName(SubstitutionGroup
))
420 error(h
,"SubstitutionGroup must be a valid XmlQualifiedName");
423 foreach(XmlSchemaObject obj
in constraints
)
425 if(obj
is XmlSchemaUnique
)
426 errorCount
+= ((XmlSchemaUnique
)obj
).Compile(h
,schema
);
427 else if(obj
is XmlSchemaKey
)
428 errorCount
+= ((XmlSchemaKey
)obj
).Compile(h
,schema
);
429 else if(obj
is XmlSchemaKeyref
)
430 errorCount
+= ((XmlSchemaKeyref
)obj
).Compile(h
,schema
);
435 if(substitutionGroup
!= null && !substitutionGroup
.IsEmpty
)
436 error(h
,"substitutionGroup must be absent");
437 if(final
!= XmlSchemaDerivationMethod
.None
)
438 error(h
,"final must be absent");
440 CompileOccurence (h
, schema
);
442 if(refName
== null || RefName
.IsEmpty
)
444 string targetNamespace
= String
.Empty
;
446 if(form
== XmlSchemaForm
.Qualified
|| (form
== XmlSchemaForm
.None
&& schema
.ElementFormDefault
== XmlSchemaForm
.Qualified
))
447 targetNamespace
= schema
.TargetNamespace
;
449 if(this.name
== null) //b1
450 error(h
,"Required attribute name must be present");
451 else if(!XmlSchemaUtil
.CheckNCName(this.name
)) // b1.2
452 error(h
,"attribute name must be NCName");
454 this.qName
= new XmlQualifiedName(this.name
, targetNamespace
);
456 if(schemaType
!= null && schemaTypeName
!= null && !schemaTypeName
.IsEmpty
)
458 error(h
,"both schemaType and content can't be present");
461 //Even if both are present, read both of them.
462 if(schemaType
!= null)
464 if(schemaType
is XmlSchemaSimpleType
)
466 errorCount
+= ((XmlSchemaSimpleType
)schemaType
).Compile(h
,schema
);
468 else if(schemaType
is XmlSchemaComplexType
)
470 errorCount
+= ((XmlSchemaComplexType
)schemaType
).Compile(h
,schema
);
473 error(h
,"only simpletype or complextype is allowed");
475 if(schemaTypeName
!= null && !schemaTypeName
.IsEmpty
)
477 if(!XmlSchemaUtil
.CheckQName(SchemaTypeName
))
478 error(h
,"SchemaTypeName must be an XmlQualifiedName");
480 if(SubstitutionGroup
!= null && !SubstitutionGroup
.IsEmpty
)
482 if(!XmlSchemaUtil
.CheckQName(SubstitutionGroup
))
483 error(h
,"SubstitutionGroup must be a valid XmlQualifiedName");
486 foreach(XmlSchemaObject obj
in constraints
)
488 if(obj
is XmlSchemaUnique
)
489 errorCount
+= ((XmlSchemaUnique
)obj
).Compile(h
,schema
);
490 else if(obj
is XmlSchemaKey
)
491 errorCount
+= ((XmlSchemaKey
)obj
).Compile(h
,schema
);
492 else if(obj
is XmlSchemaKeyref
)
493 errorCount
+= ((XmlSchemaKeyref
)obj
).Compile(h
,schema
);
498 if(!XmlSchemaUtil
.CheckQName(RefName
))
499 error(h
,"RefName must be a XmlQualifiedName");
502 error(h
,"name must not be present when ref is present");
503 if(Constraints
.Count
!= 0)
504 error(h
,"key, keyref and unique must be absent");
506 error(h
,"nillable must be absent");
507 if(defaultValue
!= null)
508 error(h
,"default must be absent");
509 if(fixedValue
!= null)
510 error(h
,"fixed must be null");
511 if(form
!= XmlSchemaForm
.None
)
512 error(h
,"form must be absent");
513 if(block
!= XmlSchemaDerivationMethod
.None
)
514 error(h
,"block must be absent");
515 if(schemaTypeName
!= null && !schemaTypeName
.IsEmpty
)
516 error(h
,"type must be absent");
517 if(SchemaType
!= null)
518 error(h
,"simpleType or complexType must be absent");
525 case XmlSchemaDerivationMethod
.All
:
526 blockResolved
= XmlSchemaDerivationMethod
.All
;
528 case XmlSchemaDerivationMethod
.None
:
529 blockResolved
= XmlSchemaDerivationMethod
.Empty
;
532 if ((block
| XmlSchemaUtil
.ElementBlockAllowed
) != XmlSchemaUtil
.ElementBlockAllowed
)
533 error (h
,"Some of the values for block are invalid in this context");
534 blockResolved
= block
;
538 if (Constraints
!= null) {
539 XmlSchemaObjectTable table
= new XmlSchemaObjectTable ();
540 foreach (XmlSchemaIdentityConstraint c
in Constraints
) {
541 XmlSchemaUtil
.AddToTable (table
, c
, c
.QualifiedName
, h
);
545 XmlSchemaUtil
.CompileID(Id
,this,schema
.IDCollection
,h
);
547 this.CompilationId
= schema
.CompilationId
;
551 [MonoTODO ("Return clone in case when it returns itself")]
552 internal override XmlSchemaParticle
GetOptimizedParticle (bool isTop
)
554 if (OptimizedParticle
!= null)
555 return OptimizedParticle
;
556 if (RefName
!= null && RefName
!= XmlQualifiedName
.Empty
) {
557 referencedElement
= schema
.Elements
[RefName
] as XmlSchemaElement
;
560 // if (this.referencedElement != null)
561 // OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);
563 if (ValidatedMaxOccurs
== 0)
564 OptimizedParticle
= XmlSchemaParticle
.Empty
;
565 // Substitution Group
566 else if (SubstitutingElements
!= null && SubstitutingElements
.Count
> 0) {
567 XmlSchemaChoice choice
= new XmlSchemaChoice ();
568 choice
.MinOccurs
= MinOccurs
;
569 choice
.MaxOccurs
= MaxOccurs
;
570 substChoice
= choice
;
571 choice
.Compile (null, schema
); // compute Validated Min/Max Occurs.
572 XmlSchemaElement item
= this.MemberwiseClone () as XmlSchemaElement
;
575 item
.substitutionGroupElement
= null;
576 item
.substitutingElements
= null;
577 for (int i
= 0; i
< SubstitutingElements
.Count
; i
++) {
578 XmlSchemaElement se
= SubstitutingElements
[i
] as XmlSchemaElement
;
579 // choice.Items.Add (se);
580 // choice.CompiledItems.Add (se);
581 this.AddSubstElementRecursively (choice
.Items
, se
);
582 this.AddSubstElementRecursively (choice
.CompiledItems
, se
);
584 if (!choice
.Items
.Contains (item
)) {
585 choice
.Items
.Add (item
);
586 choice
.CompiledItems
.Add (item
);
588 OptimizedParticle
= choice
;
591 OptimizedParticle
= this;//.MemberwiseClone () as XmlSchemaElement;
592 return OptimizedParticle
;
595 private void AddSubstElementRecursively (XmlSchemaObjectCollection col
, XmlSchemaElement el
)
597 if (el
.SubstitutingElements
!= null)
598 for (int i
= 0; i
< el
.SubstitutingElements
.Count
; i
++)
599 this.AddSubstElementRecursively (col
, el
.SubstitutingElements
[i
] as XmlSchemaElement
);
600 if (!col
.Contains (el
))
604 internal void FillSubstitutionElementInfo ()
606 if (this.substitutionGroupElement
!= null)
609 if (this.SubstitutionGroup
!= XmlQualifiedName
.Empty
) {
610 XmlSchemaElement substElem
= schema
.Elements
[SubstitutionGroup
] as XmlSchemaElement
;
611 this.substitutionGroupElement
= substElem
;
612 if (substElem
!= null)
613 substElem
.substitutingElements
.Add (this);
617 internal override int Validate(ValidationEventHandler h
, XmlSchema schema
)
619 if (IsValidated (schema
.CompilationId
))
622 // See XML Schema Structures 3.6 for the complete description.
624 // Element Declaration Properties Correct
625 // 1. = 3.3.1 (modulo 5.3)
628 // {annotation} is as is.
629 // {name}, {target namespace}, {scope}, {disallowed substitution},
630 // {substitution group exclusions} (handled the same as 'disallowed substitution')
631 // and {identity-constraint-definitions} are Compile()d.
632 // {value constraint} is going to be filled in step 2.
634 // actual {nillable}, {abstract}
635 this.actualIsNillable
= IsNillable
;
636 this.actualIsAbstract
= IsAbstract
;
638 // Before determining element type, we need to validate substituting element
639 if (this.SubstitutionGroup
!= XmlQualifiedName
.Empty
) {
640 XmlSchemaElement substElem
= substitutionGroupElement
;
641 if (substElem
!= null)
642 substElem
.Validate (h
, schema
);
646 XmlSchemaDatatype datatype
= null;
647 if (schemaType
!= null)
648 elementType
= schemaType
;
649 else if (SchemaTypeName
!= XmlQualifiedName
.Empty
) {
650 XmlSchemaType type
= schema
.SchemaTypes
[SchemaTypeName
] as XmlSchemaType
;
652 type
.Validate (h
, schema
);
655 else if (SchemaTypeName
== XmlSchemaComplexType
.AnyTypeName
)
656 elementType
= XmlSchemaComplexType
.AnyType
;
657 else if (XmlSchemaUtil
.IsBuiltInDatatypeName (SchemaTypeName
)) {
658 datatype
= XmlSchemaDatatype
.FromName (SchemaTypeName
);
659 if (datatype
== null)
660 error (h
, "Invalid schema datatype was specified.");
662 elementType
= datatype
;
664 // otherwise, it might be missing sub components.
665 else if (!schema
.IsNamespaceAbsent (SchemaTypeName
.Namespace
))
666 error (h
, "Referenced element schema type " + SchemaTypeName
+ " was not found in the corresponding schema.");
668 else if (RefName
!= XmlQualifiedName
.Empty
)
670 XmlSchemaElement refElem
= schema
.Elements
[RefName
] as XmlSchemaElement
;
671 // If el is null, then it is missing sub components .
672 if (refElem
!= null) {
673 this.referencedElement
= refElem
;
674 errorCount
+= refElem
.Validate (h
, schema
);
676 // otherwise, it might be missing sub components.
677 else if (!schema
.IsNamespaceAbsent (RefName
.Namespace
))
678 error (h
, "Referenced element " + RefName
+ " was not found in the corresponding schema.");
681 // Otherwise if there are substitution group, then the type of the substitution group element.
682 if (referencedElement
== null) {
683 if (elementType
== null && this.substitutionGroupElement
!= null)
684 elementType
= substitutionGroupElement
.ElementType
;
685 // Otherwise, the -ur type- definition.
686 if (elementType
== null)
687 elementType
= XmlSchemaComplexType
.AnyType
;
690 XmlSchemaType xsType
= elementType
as XmlSchemaType
;
691 if (xsType
!= null) {
692 errorCount
+= xsType
.Validate (h
, schema
);
693 datatype
= xsType
.Datatype
;
695 // basic {type} is now filled, except for derivation by {substitution group}.
697 // {substitution group affiliation}
698 // 3. subsitution group's type derivation check.
699 if (this.SubstitutionGroup
!= XmlQualifiedName
.Empty
) {
700 XmlSchemaElement substElem
= schema
.Elements
[SubstitutionGroup
] as XmlSchemaElement
;
701 // If el is null, then it is missing sub components .
702 if (substElem
!= null) {
703 XmlSchemaType substSchemaType
= substElem
.ElementType
as XmlSchemaType
;
704 if (substSchemaType
!= null) {
705 // 3.3.6 Properties Correct 3.
706 if ((substElem
.FinalResolved
& XmlSchemaDerivationMethod
.Substitution
) != 0)
707 error (h
, "Substituted element blocks substitution.");
708 if (xsType
!= null && (substElem
.FinalResolved
& xsType
.DerivedBy
) != 0)
709 error (h
, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType
.DerivedBy
+ ".");
711 XmlSchemaComplexType xsComplexType
= xsType
as XmlSchemaComplexType
;
712 if (xsComplexType
!= null)
713 xsComplexType
.ValidateTypeDerivationOK (substElem
.ElementType
, h
, schema
);
715 XmlSchemaSimpleType xsSimpleType
= xsType
as XmlSchemaSimpleType
;
716 if (xsSimpleType
!= null)
717 xsSimpleType
.ValidateTypeDerivationOK (substElem
.ElementType
, h
, schema
, true);
721 // otherwise, it might be missing sub components.
722 else if (!schema
.IsNamespaceAbsent (SubstitutionGroup
.Namespace
))
723 error (h
, "Referenced element type " + SubstitutionGroup
+ " was not found in the corresponding schema.");
726 // 2. ElementDefaultValid
727 // 4. ID with {value constraint} is prohibited.
728 if (defaultValue
!= null || fixedValue
!= null) {
729 ValidateElementDefaultValidImmediate (h
, schema
);
730 if (datatype
!= null && // Such situation is basically an error. For ValidationEventHandler.
731 datatype
.TokenizedType
== XmlTokenizedType
.ID
)
732 error (h
, "Element type is ID, which does not allows default or fixed values.");
735 // Identity constraints (3.11.3 / 3.11.6)
736 foreach (XmlSchemaIdentityConstraint ident
in Constraints
)
737 ident
.Validate (h
, schema
);
740 elementSchemaType
= elementType
as XmlSchemaType
;
741 if (elementSchemaType
== null && elementType
!= null)
742 elementSchemaType
= XmlSchemaType
.GetBuiltInType (((XmlSchemaDatatype
) elementType
).TypeCode
);
745 ValidationId
= schema
.ValidationId
;
749 internal override bool ParticleEquals (XmlSchemaParticle other
)
751 XmlSchemaElement element
= other
as XmlSchemaElement
;
754 if (this.ValidatedMaxOccurs
!= element
.ValidatedMaxOccurs
||
755 this.ValidatedMinOccurs
!= element
.ValidatedMinOccurs
)
757 if (this.QualifiedName
!= element
.QualifiedName
||
758 this.ElementType
!= element
.ElementType
||
759 this.Constraints
.Count
!= element
.Constraints
.Count
)
761 for (int i
= 0; i
< this.Constraints
.Count
; i
++) {
762 XmlSchemaIdentityConstraint c1
= Constraints
[i
] as XmlSchemaIdentityConstraint
;
763 XmlSchemaIdentityConstraint c2
= element
.Constraints
[i
] as XmlSchemaIdentityConstraint
;
764 if (c1
.QualifiedName
!= c2
.QualifiedName
||
765 c1
.Selector
.XPath
!= c2
.Selector
.XPath
||
766 c1
.Fields
.Count
!= c2
.Fields
.Count
)
768 for (int f
= 0; f
< c1
.Fields
.Count
; f
++) {
769 XmlSchemaXPath f1
= c1
.Fields
[f
] as XmlSchemaXPath
;
770 XmlSchemaXPath f2
= c2
.Fields
[f
] as XmlSchemaXPath
;
771 if (f1
.XPath
!= f2
.XPath
)
775 if (this.BlockResolved
!= element
.BlockResolved
||
776 this.FinalResolved
!= element
.FinalResolved
||
777 this.ValidatedDefaultValue
!= element
.ValidatedDefaultValue
||
778 this.ValidatedFixedValue
!= element
.ValidatedFixedValue
)
783 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle
,
784 ValidationEventHandler h
, XmlSchema schema
, bool raiseError
)
786 // element - NameAndTypeOK
787 XmlSchemaElement baseElement
= baseParticle
as XmlSchemaElement
;
788 if (baseElement
!= null) {
789 return ValidateDerivationByRestrictionNameAndTypeOK (baseElement
, h
, schema
, raiseError
);
793 XmlSchemaAny baseAny
= baseParticle
as XmlSchemaAny
;
794 if (baseAny
!= null) {
796 if (!baseAny
.ValidateWildcardAllowsNamespaceName (this.QualifiedName
.Namespace
, h
, schema
, raiseError
))
798 return ValidateOccurenceRangeOK (baseAny
, h
, schema
, raiseError
);
802 // choice - RecurseAsIfGroup
803 XmlSchemaGroupBase gb
= null;
804 if (baseParticle
is XmlSchemaSequence
)
805 gb
= new XmlSchemaSequence ();
806 else if (baseParticle
is XmlSchemaChoice
)
807 gb
= new XmlSchemaChoice ();
808 else if (baseParticle
is XmlSchemaAll
)
809 gb
= new XmlSchemaAll ();
813 gb
.Compile (h
, schema
);
814 gb
.Validate (h
, schema
);
815 // It looks weird, but here we never think about
816 // _pointlessness_ of this groupbase particle.
817 return gb
.ValidateDerivationByRestriction (baseParticle
, h
, schema
, raiseError
);
823 private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement
,
824 ValidationEventHandler h
, XmlSchema schema
, bool raiseError
)
827 if (this.QualifiedName
!= baseElement
.QualifiedName
) {
829 error (h
, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
833 if (this.isNillable
&& !baseElement
.isNillable
) {
835 error (h
, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
839 if (!ValidateOccurenceRangeOK (baseElement
, h
, schema
, raiseError
))
842 if (baseElement
.ValidatedFixedValue
!= null &&
843 baseElement
.ValidatedFixedValue
!= this.ValidatedFixedValue
) {
845 error (h
, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
848 // 5. TODO: What is "identity constraints subset" ???
851 if ((baseElement
.BlockResolved
| this.BlockResolved
) != this.BlockResolved
) {
853 error (h
, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
857 if (baseElement
.ElementType
!= null) {
858 XmlSchemaComplexType derivedCType
= this.ElementType
as XmlSchemaComplexType
;
859 if (derivedCType
!= null) {
860 // FIXME: W3C REC says that it is Type Derivation OK to be check, but
861 // in fact it should be DerivationValid (Restriction, Complex).
862 derivedCType
.ValidateDerivationValidRestriction (
863 baseElement
.ElementType
as XmlSchemaComplexType
, h
, schema
);
864 derivedCType
.ValidateTypeDerivationOK (baseElement
.ElementType
, h
, schema
);
866 XmlSchemaSimpleType derivedSType
= this.ElementType
as XmlSchemaSimpleType
;
867 if (derivedSType
!= null)
868 derivedSType
.ValidateTypeDerivationOK (baseElement
.ElementType
, h
, schema
, true);
869 else if (baseElement
.ElementType
!= XmlSchemaComplexType
.AnyType
&& baseElement
.ElementType
!= this.ElementType
) {
871 error (h
, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
879 internal override void CheckRecursion (int depth
, ValidationEventHandler h
, XmlSchema schema
)
881 XmlSchemaComplexType ct
= this.ElementType
as XmlSchemaComplexType
;
882 if (ct
== null || ct
.Particle
== null)
884 ct
.Particle
.CheckRecursion (depth
+ 1, h
, schema
);
887 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames
, ArrayList nsNames
,
888 ValidationEventHandler h
, XmlSchema schema
)
890 if (qnames
.Contains (this.QualifiedName
))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))
891 error (h
, "Ambiguous element label was detected: " + this.QualifiedName
);
893 foreach (XmlSchemaAny any
in nsNames
) {
894 if (any
.ValidatedMaxOccurs
== 0)
896 if (any
.HasValueAny
||
897 any
.HasValueLocal
&& this.QualifiedName
.Namespace
== "" ||
898 any
.HasValueOther
&& this.QualifiedName
.Namespace
!= this.QualifiedName
.Namespace
||
899 any
.HasValueTargetNamespace
&& this.QualifiedName
.Namespace
== this.QualifiedName
.Namespace
) {
900 error (h
, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName
);
902 } else if (!any
.HasValueOther
) {
904 foreach (string ns
in any
.ResolvedNamespaces
) {
905 if (ns
== this.QualifiedName
.Namespace
) {
911 error (h
, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName
);
915 if (any
.TargetNamespace
.Length
== 0 ||
916 any
.TargetNamespace
!= this.QualifiedName
.Namespace
)
917 error (h
, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName
);
920 qnames
.Add (this.QualifiedName
, this);
924 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels
,
925 ValidationEventHandler h
, XmlSchema schema
)
927 XmlSchemaElement labeled
= labels
[this.QualifiedName
] as XmlSchemaElement
;
929 labels
.Add (this.QualifiedName
, this);
930 else if (labeled
.ElementType
!= this.ElementType
)
931 error (h
, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName
);
935 // 3.3.6 Element Default Valid (Immediate)
936 private void ValidateElementDefaultValidImmediate (ValidationEventHandler h
, XmlSchema schema
)
938 // This presumes that ElementType is already filled.
940 XmlSchemaDatatype datatype
= elementType
as XmlSchemaDatatype
;
941 XmlSchemaSimpleType simpleType
= elementType
as XmlSchemaSimpleType
;
942 if (simpleType
!= null)
943 datatype
= simpleType
.Datatype
;
945 if (datatype
== null) {
946 XmlSchemaComplexType complexType
= elementType
as XmlSchemaComplexType
;
947 switch (complexType
.ContentType
) {
948 case XmlSchemaContentType
.Empty
:
949 case XmlSchemaContentType
.ElementOnly
:
950 error (h
, "Element content type must be simple type or mixed.");
953 datatype
= XmlSchemaSimpleType
.AnySimpleType
;
956 XmlNamespaceManager nsmgr
= null;
957 if (datatype
.TokenizedType
== XmlTokenizedType
.QName
) {
958 if (this.Namespaces
!= null)
959 foreach (XmlQualifiedName qname
in Namespaces
.ToArray ())
960 nsmgr
.AddNamespace (qname
.Name
, qname
.Namespace
);
964 if (defaultValue
!= null) {
965 validatedDefaultValue
= datatype
.Normalize (defaultValue
);
966 datatype
.ParseValue (validatedDefaultValue
, null, nsmgr
);
968 } catch (Exception ex
) {
969 // FIXME: This is not a good way to handle exception, but
970 // I think there is no remedy for such Framework specification.
971 error (h
, "The Element's default value is invalid with respect to its type definition.", ex
);
974 if (fixedValue
!= null) {
975 validatedFixedValue
= datatype
.Normalize (fixedValue
);
976 datatype
.ParseValue (validatedFixedValue
, null, nsmgr
);
978 } catch (Exception ex
) {
979 // FIXME: This is not a good way to handle exception.
980 error (h
, "The Element's fixed value is invalid with its type definition.", ex
);
985 // abstract = boolean : false
986 // block = (#all | List of (extension | restriction | substitution))
988 // final = (#all | List of (extension | restriction))
990 // form = (qualified | unqualified)
992 // maxOccurs = (nonNegativeInteger | unbounded) : 1
993 // minOccurs = nonNegativeInteger : 1
995 // nillable = boolean : false
997 // substitutionGroup = QName
999 // {any attributes with non-schema namespace . . .}>
1000 // Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
1003 internal static XmlSchemaElement
Read(XmlSchemaReader reader
, ValidationEventHandler h
)
1005 XmlSchemaElement element
= new XmlSchemaElement();
1007 reader
.MoveToElement();
1009 if(reader
.NamespaceURI
!= XmlSchema
.Namespace
|| reader
.LocalName
!= xmlname
)
1011 error(h
,"Should not happen :1: XmlSchemaElement.Read, name="+reader
.Name
,null);
1016 element
.LineNumber
= reader
.LineNumber
;
1017 element
.LinePosition
= reader
.LinePosition
;
1018 element
.SourceUri
= reader
.BaseURI
;
1020 while(reader
.MoveToNextAttribute())
1022 if(reader
.Name
== "abstract")
1024 element
.IsAbstract
= XmlSchemaUtil
.ReadBoolAttribute(reader
,out innerex
);
1026 error(h
,reader
.Value
+ " is invalid value for abstract",innerex
);
1028 else if(reader
.Name
== "block")
1030 element
.block
= XmlSchemaUtil
.ReadDerivationAttribute(reader
,out innerex
, "block",
1031 XmlSchemaUtil
.ElementBlockAllowed
);
1033 error (h
,"some invalid values for block attribute were found",innerex
);
1035 else if(reader
.Name
== "default")
1037 element
.defaultValue
= reader
.Value
;
1039 else if(reader
.Name
== "final")
1041 element
.Final
= XmlSchemaUtil
.ReadDerivationAttribute(reader
,out innerex
, "final",
1042 XmlSchemaUtil
.FinalAllowed
);
1044 error (h
,"some invalid values for final attribute were found",innerex
);
1046 else if(reader
.Name
== "fixed")
1048 element
.fixedValue
= reader
.Value
;
1050 else if(reader
.Name
== "form")
1052 element
.form
= XmlSchemaUtil
.ReadFormAttribute(reader
,out innerex
);
1054 error(h
,reader
.Value
+ " is an invalid value for form attribute",innerex
);
1056 else if(reader
.Name
== "id")
1058 element
.Id
= reader
.Value
;
1060 else if(reader
.Name
== "maxOccurs")
1064 element
.MaxOccursString
= reader
.Value
;
1068 error(h
,reader
.Value
+ " is an invalid value for maxOccurs",e
);
1071 else if(reader
.Name
== "minOccurs")
1075 element
.MinOccursString
= reader
.Value
;
1079 error(h
,reader
.Value
+ " is an invalid value for minOccurs",e
);
1082 else if(reader
.Name
== "name")
1084 element
.Name
= reader
.Value
;
1086 else if(reader
.Name
== "nillable")
1088 element
.IsNillable
= XmlSchemaUtil
.ReadBoolAttribute(reader
,out innerex
);
1090 error(h
,reader
.Value
+ "is not a valid value for nillable",innerex
);
1092 else if(reader
.Name
== "ref")
1094 element
.refName
= XmlSchemaUtil
.ReadQNameAttribute(reader
,out innerex
);
1096 error(h
, reader
.Value
+ " is not a valid value for ref attribute",innerex
);
1098 else if(reader
.Name
== "substitutionGroup")
1100 element
.substitutionGroup
= XmlSchemaUtil
.ReadQNameAttribute(reader
,out innerex
);
1102 error(h
, reader
.Value
+ " is not a valid value for substitutionGroup attribute",innerex
);
1104 else if(reader
.Name
== "type")
1106 element
.SchemaTypeName
= XmlSchemaUtil
.ReadQNameAttribute(reader
,out innerex
);
1108 error(h
, reader
.Value
+ " is not a valid value for type attribute",innerex
);
1110 else if((reader
.NamespaceURI
== "" && reader
.Name
!= "xmlns") || reader
.NamespaceURI
== XmlSchema
.Namespace
)
1112 error(h
,reader
.Name
+ " is not a valid attribute for element",null);
1116 XmlSchemaUtil
.ReadUnhandledAttribute(reader
,element
);
1120 reader
.MoveToElement();
1121 if(reader
.IsEmptyElement
)
1124 // Content: annotation?,
1125 // (simpleType | complexType)?,
1126 // (unique | key | keyref)*
1128 while(reader
.ReadNextElement())
1130 if(reader
.NodeType
== XmlNodeType
.EndElement
)
1132 if(reader
.LocalName
!= xmlname
)
1133 error(h
,"Should not happen :2: XmlSchemaElement.Read, name="+reader
.Name
,null);
1136 if(level
<= 1 && reader
.LocalName
== "annotation")
1138 level
= 2; //Only one annotation
1139 XmlSchemaAnnotation annotation
= XmlSchemaAnnotation
.Read(reader
,h
);
1140 if(annotation
!= null)
1141 element
.Annotation
= annotation
;
1146 if(reader
.LocalName
== "simpleType")
1149 XmlSchemaSimpleType simple
= XmlSchemaSimpleType
.Read(reader
,h
);
1151 element
.SchemaType
= simple
;
1154 if(reader
.LocalName
== "complexType")
1157 XmlSchemaComplexType complex
= XmlSchemaComplexType
.Read(reader
,h
);
1160 element
.SchemaType
= complex
;
1167 if(reader
.LocalName
== "unique")
1170 XmlSchemaUnique unique
= XmlSchemaUnique
.Read(reader
,h
);
1172 element
.constraints
.Add(unique
);
1175 else if(reader
.LocalName
== "key")
1178 XmlSchemaKey key
= XmlSchemaKey
.Read(reader
,h
);
1180 element
.constraints
.Add(key
);
1183 else if(reader
.LocalName
== "keyref")
1186 XmlSchemaKeyref keyref
= XmlSchemaKeyref
.Read(reader
,h
);
1188 element
.constraints
.Add(keyref
);
1192 reader
.RaiseInvalidElementError();