2 // System.Xml.Schema.XmlSchemaComplexType.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.ComponentModel;
33 using System.Xml.Serialization;
35 namespace System.Xml.Schema
38 /// Summary description for XmlSchemaComplexType.
40 public class XmlSchemaComplexType : XmlSchemaType
42 private XmlSchemaAnyAttribute anyAttribute;
43 private XmlSchemaObjectCollection attributes;
44 private XmlSchemaObjectTable attributeUses;
45 private XmlSchemaAnyAttribute attributeWildcard;
46 private XmlSchemaDerivationMethod block;
47 private XmlSchemaDerivationMethod blockResolved;
48 private XmlSchemaContentModel contentModel;
49 private XmlSchemaParticle validatableParticle;
50 private XmlSchemaParticle contentTypeParticle;
51 private bool isAbstract;
53 private XmlSchemaParticle particle;
54 private XmlSchemaContentType resolvedContentType;
56 internal bool ValidatedIsAbstract;
57 internal bool ParentIsSchema {
58 get { return Parent is XmlSchema; }
61 const string xmlname = "complexType";
63 private static XmlSchemaComplexType anyType;
65 internal static XmlSchemaComplexType AnyType {
67 if (anyType == null) {
68 anyType = new XmlSchemaComplexType ();
69 anyType.Name = "anyType";
70 anyType.QNameInternal = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
71 if (XmlSchemaUtil.StrictMsCompliant)
72 anyType.validatableParticle = XmlSchemaParticle.Empty; // This code makes validator handles these schemas incorrectly: particlesIb001, mgM013, mgH014, ctE004, ctD004
74 anyType.validatableParticle = XmlSchemaAny.AnyTypeContent;
76 anyType.contentTypeParticle = anyType.validatableParticle;
77 anyType.DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
78 anyType.isMixed = true;
79 anyType.resolvedContentType = XmlSchemaContentType.Mixed;
85 internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
87 public XmlSchemaComplexType ()
89 attributes = new XmlSchemaObjectCollection();
90 block = XmlSchemaDerivationMethod.None;
91 attributeUses = new XmlSchemaObjectTable();
92 validatableParticle = XmlSchemaParticle.Empty;
93 contentTypeParticle = validatableParticle;
99 [System.Xml.Serialization.XmlAttribute("abstract")]
100 public bool IsAbstract
102 get{ return isAbstract; }
103 set{ isAbstract = value; }
105 [DefaultValue(XmlSchemaDerivationMethod.None)]
106 [System.Xml.Serialization.XmlAttribute("block")]
107 public XmlSchemaDerivationMethod Block
110 set{ block = value; }
112 [DefaultValue(false)]
113 [System.Xml.Serialization.XmlAttribute("mixed")]
114 public override bool IsMixed
116 get{ return isMixed; }
117 set{ isMixed = value; }
124 [XmlElement("simpleContent",typeof(XmlSchemaSimpleContent))]
125 [XmlElement("complexContent",typeof(XmlSchemaComplexContent))]
126 public XmlSchemaContentModel ContentModel
128 get{ return contentModel; }
129 set{ contentModel = value; }
132 //LAMESPEC: The default value for particle in Schema is of Type EmptyParticle (internal?)
133 [XmlElement("group",typeof(XmlSchemaGroupRef))]
134 [XmlElement("all",typeof(XmlSchemaAll))]
135 [XmlElement("choice",typeof(XmlSchemaChoice))]
136 [XmlElement("sequence",typeof(XmlSchemaSequence))]
137 public XmlSchemaParticle Particle
139 get{ return particle; }
140 set{ particle = value; }
143 [XmlElement("attribute",typeof(XmlSchemaAttribute))]
144 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]
145 public XmlSchemaObjectCollection Attributes
147 get{ return attributes; }
150 [XmlElement("anyAttribute")]
151 public XmlSchemaAnyAttribute AnyAttribute
153 get{ return anyAttribute; }
154 set{ anyAttribute = value; }
160 public XmlSchemaContentType ContentType
162 get{ return resolvedContentType; }
165 public XmlSchemaParticle ContentTypeParticle
167 get{ return contentTypeParticle; }
170 public XmlSchemaDerivationMethod BlockResolved
172 get{ return blockResolved; }
175 public XmlSchemaObjectTable AttributeUses
177 get{ return attributeUses; }
180 public XmlSchemaAnyAttribute AttributeWildcard
182 get{ return attributeWildcard; }
187 internal XmlSchemaParticle ValidatableParticle
189 get{ return contentTypeParticle; }
192 internal override void SetParent (XmlSchemaObject parent)
194 base.SetParent (parent);
195 if (ContentModel != null)
196 ContentModel.SetParent (this);
197 if (Particle != null)
198 Particle.SetParent (this);
199 if (AnyAttribute != null)
200 AnyAttribute.SetParent (this);
201 foreach (XmlSchemaObject obj in Attributes)
202 obj.SetParent (this);
206 /// 1. If ContentModel is present, neither particle nor Attributes nor AnyAttribute can be present.
207 /// 2. If particle is present,
208 /// a. For a topLevelComplexType
209 /// 1. name must be present and type NCName
210 /// 2. if block is #all, blockdefault is #all, else List of (extension | restriction)
211 /// 3. if final is #all, finaldefault is #all, else List of (extension | restriction)
212 /// b. For a local Complex type
213 /// 1. abstract must be false
214 /// 2. Name must be absent
215 /// 3. final must be absent
216 /// 4. block must be absent
219 internal override int Compile (ValidationEventHandler h, XmlSchema schema)
221 // If this is already compiled this time, simply skip.
222 if (CompilationId == schema.CompilationId)
225 ValidatedIsAbstract = isAbstract;
226 attributeUses.Clear();
228 if (isRedefinedComponent) {
229 if (Annotation != null)
230 Annotation.isRedefinedComponent = true;
231 if (AnyAttribute != null)
232 AnyAttribute.isRedefinedComponent = true;
233 foreach (XmlSchemaObject obj in Attributes)
234 obj.isRedefinedComponent = true;
235 if (ContentModel != null)
236 ContentModel.isRedefinedComponent = true;
237 if (Particle != null)
238 Particle.isRedefinedComponent = true;
241 // block/final resolution
242 if(ParentIsSchema || isRedefineChild)
244 if(this.Name == null || this.Name == string.Empty)
245 error(h,"name must be present in a top level complex type");
246 else if(!XmlSchemaUtil.CheckNCName(Name))
247 error(h,"name must be a NCName");
249 this.QNameInternal = new XmlQualifiedName(Name, AncestorSchema.TargetNamespace);
251 if(Block != XmlSchemaDerivationMethod.None)
253 if(Block == XmlSchemaDerivationMethod.All)
255 blockResolved = XmlSchemaDerivationMethod.All;
259 if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
260 error (h, "Invalid block specification.");
261 blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
266 switch (schema.BlockDefault) {
267 case XmlSchemaDerivationMethod.All:
268 blockResolved = XmlSchemaDerivationMethod.All;
270 case XmlSchemaDerivationMethod.None:
271 blockResolved = XmlSchemaDerivationMethod.Empty;
274 blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
279 if(Final != XmlSchemaDerivationMethod.None)
281 if(Final == XmlSchemaDerivationMethod.All)
282 finalResolved = XmlSchemaDerivationMethod.All;
283 else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
284 error (h, "Invalid final specification.");
286 finalResolved = Final;
290 switch (schema.FinalDefault) {
291 case XmlSchemaDerivationMethod.All:
292 finalResolved = XmlSchemaDerivationMethod.All;
294 case XmlSchemaDerivationMethod.None:
295 finalResolved = XmlSchemaDerivationMethod.Empty;
298 finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
303 else // Not Top Level
306 error(h,"abstract must be false in a local complex type");
308 error(h,"name must be absent in a local complex type");
309 if(Final != XmlSchemaDerivationMethod.None)
310 error(h,"final must be absent in a local complex type");
311 if(block != XmlSchemaDerivationMethod.None)
312 error(h,"block must be absent in a local complex type");
315 // Process contents and BaseSchemaType
316 if(contentModel != null)
318 if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
319 error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
320 errorCount += contentModel.Compile (h, schema);
322 XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
325 XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
327 XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
329 if (sscr.BaseType != null) {
330 sscr.BaseType.Compile (h, schema);
331 BaseXmlSchemaTypeInternal = sscr.BaseType;
339 if (Particle != null)
340 errorCount += Particle.Compile (h, schema);
342 if(this.anyAttribute != null)
344 AnyAttribute.Compile(h,schema);
346 foreach(XmlSchemaObject obj in Attributes)
348 if(obj is XmlSchemaAttribute)
350 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
351 errorCount += attr.Compile(h,schema);
353 else if(obj is XmlSchemaAttributeGroupRef)
355 XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
356 errorCount += atgrp.Compile(h,schema);
359 error(h,obj.GetType() +" is not valid in this place::ComplexType");
363 XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
364 this.CompilationId = schema.CompilationId;
368 Guid CollectProcessId;
370 private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)
372 if (CollectProcessId == schema.CompilationId)
374 // Below are already contributed by Compile():
375 // {name}, {namespace} => QualifiedName, QNameInternal
376 // {abstract} => ValidatedIsAbstract
377 // {prohibited substitutions} => BlockResolved
378 // {final} => FinalResolved
379 // {annotations} => Annotation (XmlSchemaAnnotated)
381 // Below are different properties depending on simpleContent | complexContent.
382 // {base type definition}
383 // {derivation method}
384 // {attribute uses} => AttributeUses (later)
385 // {attribute wildcard} => AttributeWildcard (later)
389 // {base type definition} => baseSchemaTypeInternal (later)
390 if (contentModel != null) {
391 BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;
393 BaseXmlSchemaTypeInternal = schema.FindSchemaType(BaseSchemaTypeName);
396 if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {
397 XmlSchemaType redType = (XmlSchemaType) redefinedObject;
399 error (h, "Redefinition base type was not found.");
401 BaseXmlSchemaTypeInternal = redType;
404 // {derivation method} => resolvedDerivedBy
405 if (contentModel != null && contentModel.Content != null) {
407 contentModel.Content.IsExtension ?
408 XmlSchemaDerivationMethod.Extension :
409 XmlSchemaDerivationMethod.Restriction;
412 resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;
415 void FillContentTypeParticle (ValidationEventHandler h, XmlSchema schema)
417 // {content type} => ContentType and ContentTypeParticle (later)
418 if (ContentModel != null) {
419 CollectContentTypeFromContentModel (h, schema);
421 CollectContentTypeFromImmediateContent ();
423 contentTypeParticle = validatableParticle.GetOptimizedParticle (true);
424 if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)
425 resolvedContentType = XmlSchemaContentType.Empty;
427 CollectProcessId = schema.CompilationId;
430 #region {content type}
431 private void CollectContentTypeFromImmediateContent ()
433 // leave resolvedDerivedBy as Empty
434 if (Particle != null)
435 validatableParticle = Particle;
436 if (this == AnyType) {
437 resolvedContentType = XmlSchemaContentType.Mixed;
441 if (validatableParticle == XmlSchemaParticle.Empty) {
442 // note that this covers "Particle == null" case
444 resolvedContentType = XmlSchemaContentType.TextOnly;
446 resolvedContentType = XmlSchemaContentType.Empty;
449 resolvedContentType = XmlSchemaContentType.Mixed;
451 resolvedContentType = XmlSchemaContentType.ElementOnly;
454 BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;
457 private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)
459 if (ContentModel.Content == null) {
460 // basically it is error. Recover by specifying empty content.
461 validatableParticle = XmlSchemaParticle.Empty;
462 resolvedContentType = XmlSchemaContentType.Empty;
466 if (ContentModel.Content is XmlSchemaComplexContentExtension)
467 CollectContentTypeFromComplexExtension (h, schema);
468 if (ContentModel.Content is XmlSchemaComplexContentRestriction)
469 CollectContentTypeFromComplexRestriction ();
472 private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)
474 XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;
475 XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;
476 if (baseComplexType != null)
477 baseComplexType.CollectSchemaComponent (h ,schema);
479 // It must exist, but consider validation error case.
480 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
481 baseComplexType = XmlSchemaComplexType.AnyType;
483 // On error case, it simple reject any contents
484 if (baseComplexType == null) {
485 validatableParticle = XmlSchemaParticle.Empty;
486 resolvedContentType = XmlSchemaContentType.Empty;
490 // 3.4.2 complex content {content type}
491 if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {
493 if (baseComplexType == null) {
494 // Basically it is an error. Considering ValidationEventHandler.
495 validatableParticle = XmlSchemaParticle.Empty;
496 resolvedContentType = XmlSchemaContentType.Empty;
498 validatableParticle = baseComplexType.ValidatableParticle;
499 resolvedContentType = baseComplexType.resolvedContentType;
501 if (resolvedContentType == XmlSchemaContentType.Empty)
502 resolvedContentType = GetComplexContentType (contentModel);
504 } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty
505 || baseComplexType == XmlSchemaComplexType.AnyType) {
507 validatableParticle = cce.Particle;
508 resolvedContentType = GetComplexContentType (contentModel);
510 // - 2.3 : create a new sequences that merges both contents.
511 XmlSchemaSequence seq = new XmlSchemaSequence ();
513 seq.Items.Add (baseComplexType.validatableParticle);
514 seq.Items.Add (cce.Particle);
515 seq.Compile (h, schema);
516 seq.Validate (h, schema);
517 validatableParticle = seq;
518 resolvedContentType = GetComplexContentType (contentModel);
520 if (validatableParticle == null)
521 validatableParticle = XmlSchemaParticle.Empty;
524 private void CollectContentTypeFromComplexRestriction ()
526 XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;
527 // 3.4.2 complex content schema component {content type}
529 bool isEmptyParticle = false;
530 if (ccr.Particle == null)
531 isEmptyParticle = true;
533 XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;
536 if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)
537 isEmptyParticle = true;
539 else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)
540 isEmptyParticle = true;
543 if (isEmptyParticle) {
544 resolvedContentType = XmlSchemaContentType.Empty;
545 validatableParticle = XmlSchemaParticle.Empty;
548 resolvedContentType = GetComplexContentType (contentModel);
550 validatableParticle = ccr.Particle;
554 // 3.4.2 Complex Content Schema Component {content type} 1.2.1
555 private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)
557 if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)
558 return XmlSchemaContentType.Mixed;
560 return XmlSchemaContentType.ElementOnly;
565 // We have to validate:
567 // - 3.4.3 Complex Type Definition Representation OK
568 // - 3.4.6 Type Definition Properties Correct
569 // - 3.4.6 Derivation Valid (Extension)
570 // - 3.4.6 Derivation Valid (Restriction, Complex)
572 // There are many schema errata:
573 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
575 // E1-43 Derivation Valid (Restriction, Complex) 5.
576 // E1-21 Derivation Valid (Restriction, Complex) 4.3.
577 // E1-17 Type Derivation OK (Complex) 2.1.
579 // And E1-38, E1-37, E1-30, E1-27
581 internal override int Validate (ValidationEventHandler h, XmlSchema schema)
583 if (IsValidated (schema.ValidationId))
585 // FIXME: omitting it causes StackOverflowException
586 // among the compilation of element and types, but
587 // it may result in insufficient results.
588 ValidationId = schema.ValidationId;
590 CollectSchemaComponent (h, schema);
592 ValidateBaseXmlSchemaType (h, schema);
594 ValidateParticle (h, schema);
596 FillContentTypeParticle (h, schema);
598 // 3.4.6: Properties Correct
599 // Term. 1 => 3.4.1 already done by CollectSchemaComponent()
600 // except for {attribute uses} and {attribute wildcard}
601 // Term. 2, 3 and 4 goes to ValidateContentModel().
602 // Term. 5 follows in this method.
604 if (ContentModel != null)
605 ValidateContentModel (h, schema);
607 ValidateImmediateAttributes (h, schema);
609 // Additional support for 3.8.6 All Group Limited
610 if (ContentTypeParticle != null) {
611 XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;
612 if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.
613 error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
617 if (schema.Schemas.CompilationSettings != null &&
618 schema.Schemas.CompilationSettings.EnableUpaCheck)
620 // This check is optional only after 2.0
621 contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
622 new ArrayList (), h, schema);
623 contentTypeParticle.ValidateUniqueTypeAttribution (
624 new XmlSchemaObjectTable (), h, schema);
626 // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
627 XmlSchemaAttribute idAttr = null;
628 foreach (DictionaryEntry entry in attributeUses) {
629 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
630 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
631 if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
634 dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
635 if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
637 error (h, "Two or more ID typed attribute declarations in a complex type are found.");
643 ValidationId = schema.ValidationId;
647 private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
650 // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
651 attributeUses = new XmlSchemaObjectTable ();
652 XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
653 h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);
656 private void ValidateBaseXmlSchemaType (ValidationEventHandler h, XmlSchema schema)
658 if (ContentModel != null && BaseXmlSchemaTypeInternal != null)
659 errorCount += BaseXmlSchemaTypeInternal.Validate (h, schema);
662 private void ValidateParticle (ValidationEventHandler h, XmlSchema schema)
664 if (ContentModel == null && Particle != null) {
665 errorCount += particle.Validate (h, schema);
666 XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
668 if (pgrp.TargetGroup != null)
669 errorCount += pgrp.TargetGroup.Validate (h,schema);
670 // otherwise, it might be missing sub components.
671 else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))
672 error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
677 private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
679 errorCount += contentModel.Validate (h, schema);
681 XmlSchemaType baseType = BaseXmlSchemaTypeInternal;
683 // Here we check 3.4.6 Properties Correct :: 2. and 3.
684 XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
685 XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
686 XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
687 XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
689 XmlSchemaAnyAttribute localAnyAttribute = null;
690 XmlSchemaAnyAttribute baseAnyAttribute = null;
692 // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
693 if (ValidateRecursionCheck ())
694 error (h, "Circular definition of schema types was found.");
695 if (baseType != null) {
696 // Fill "Datatype" property.
697 this.DatatypeInternal = baseType.Datatype;
698 } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
699 DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
700 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
701 DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);
704 XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
705 XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
707 // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
708 if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
709 error (h, "Specified derivation is specified as final by derived schema type.");
711 // 3.4.6 Properties Correct :: 2.
712 // Simple {base type definition} and restriction {derivation method} not allowed.
713 if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
714 error (h, "If the base schema type is a simple type, then this type must be extension.");
716 // Common to complexContent
717 if (cce != null || ccr != null) {
718 // 3.4.3 Complex Type Definition Representation OK :: 1.
720 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
721 baseComplexType = XmlSchemaComplexType.AnyType;
722 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))
723 error (h, "Referenced base schema type is XML Schema datatype.");
724 else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
725 error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");
727 // Common to simpleContent
729 // ContentType of {content type}
730 resolvedContentType = XmlSchemaContentType.TextOnly;
732 // 3.4.3 Complex Type Definition Representation OK :: 1.
734 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
735 baseComplexType = XmlSchemaComplexType.AnyType;
737 if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
738 error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);
739 } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {
740 error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);
741 } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
742 // do nothing for particle.
744 // otherwise, it might be missing sub components.
745 else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
746 error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");
748 // 3.4.3 Complex Type Definition Representation OK :: 2.
749 // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)
750 if (baseComplexType != null) {
751 if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {
753 // Here "baseComplexType.Particle != null" is required for error-ignorant case
754 } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {
758 error (h, "Base complex type of a simple content restriction must be text only.");
760 if (sce != null && baseComplexType == null) {
764 error (h, "Not allowed base type of a simple content restriction.");
768 // complexType/complexContent/extension
770 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
771 // is constraining anything here, since 3.4.2 {attribute uses}
772 // defines as to include base type's attribute uses.
773 localAnyAttribute = cce.AnyAttribute;
774 if (baseComplexType != null) {
775 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
776 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
777 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
779 baseAnyAttribute = baseComplexType.AttributeWildcard;
782 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
783 this.attributeUses, h, schema, cce.Attributes,
784 cce.AnyAttribute , ref attributeWildcard, null, true);
786 // After adding them, test extension validity.
787 if (baseComplexType != null)
788 this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
789 else if (baseSimpleType != null)
790 this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
792 // complexType/complexContent/restriction
794 // For ValidationEventHandler.
795 if (baseComplexType == null)
796 baseComplexType = XmlSchemaComplexType.AnyType;
799 localAnyAttribute = ccr.AnyAttribute;
800 this.attributeWildcard = localAnyAttribute;
801 if (baseComplexType != null)
802 baseAnyAttribute = baseComplexType.AttributeWildcard;
803 if (baseAnyAttribute != null && localAnyAttribute != null)
804 // 1.3 attribute wildcard subset. (=> 3.10.6)
805 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
807 // 3.4.2 Complex Type Definition with complex content Schema Component
808 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
809 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
810 this.attributeUses, h, schema, ccr.Attributes,
811 ccr.AnyAttribute, ref attributeWildcard, null, false);
812 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
813 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
814 if (attributeUses [attr.QualifiedName] == null)
815 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
818 // Derivation Valid (Restriction, Complex) :: 5.
819 // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
820 // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
821 this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
823 // complexType/simpleContent/extension
825 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
826 this.attributeUses, h, schema, sce.Attributes,
827 sce.AnyAttribute, ref attributeWildcard, null, true);
830 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
831 // is constraining anything here, since 3.4.2 {attribute uses}
832 // defines as to include base type's attribute uses.
833 localAnyAttribute = sce.AnyAttribute;
835 if (baseComplexType != null) {
836 baseAnyAttribute = baseComplexType.AttributeWildcard;
838 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
839 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
840 #if BUGGY_MS_COMPLIANT
841 if (attr.Use != XmlSchemaUse.Prohibited)
842 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
844 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
847 if (baseAnyAttribute != null && localAnyAttribute != null)
848 // 1.3 attribute wildcard subset. (=> 3.10.6)
849 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
851 // complexType/simpleContent/restriction
854 baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;
856 localAnyAttribute = scr.AnyAttribute;
857 if (localAnyAttribute != null && baseAnyAttribute != null)
858 // 1.3 attribute wildcard subset. (=> 3.10.6)
859 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
860 // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
861 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
863 // 3.4.2 Complex Type Definition with simple content Schema Component
864 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
865 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
866 this.attributeUses, h, schema, scr.Attributes,
867 scr.AnyAttribute, ref attributeWildcard, null, false);
870 // Common process of AttributeWildcard.
871 if (localAnyAttribute != null) {
872 this.attributeWildcard = localAnyAttribute;
875 this.attributeWildcard = baseAnyAttribute;
878 // 3.4.6 Type Derivation OK (Complex)
879 internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
881 // AnyType derives from AnyType itself.
882 if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)
885 XmlSchemaType bst = b as XmlSchemaType;
886 if (b == this) // 1 and 2.1
888 if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.
889 error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
890 // FIXME: here BaseSchemaType should be
891 // BaseXmlSchemaType, however for some case it
892 // seems not working.
893 if (BaseSchemaType == b) // 2.2
895 if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
896 error (h, "Derived type's base schema type is anyType.");
900 XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;
902 dbct.ValidateTypeDerivationOK (b, h, schema);
906 XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;
908 dbst.ValidateTypeDerivationOK (b, h, schema, true);
913 // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)
914 internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
915 ValidationEventHandler h, XmlSchema schema)
918 if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
919 error (h, "Derivation by extension is prohibited.");
921 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
922 XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;
923 XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
925 error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
927 // 1.3 -> 3.10.6 Wildcard Subset.
928 if (AnyAttribute != null) {
929 if (baseComplexType.AnyAttribute == null)
930 error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
932 baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
935 // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
937 // if (contentTypeParticle == null)
938 // error (h, "Extended complex type's content type must not be empty.");
940 if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
942 if (this.ContentType != baseComplexType.ContentType)
943 // if (this.GetContentType (false) != baseComplexType.GetContentType (false))
944 error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");
945 // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)
946 else if (this.contentTypeParticle == null ||
947 !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {
948 XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
949 if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))
950 error (h, "Invalid complex content extension was found.");
952 // Identical sequence item should be checked, but
953 // I think it is naturally achieved as coded above.
959 // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)
960 internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
961 ValidationEventHandler h, XmlSchema schema)
963 XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
964 if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
965 error (h, "Extension is prohibited by the base type.");
967 XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
970 if (dt != this.Datatype)
971 error (h, "To extend simple type, a complex type must have the same content type as the base type.");
974 internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
975 ValidationEventHandler h, XmlSchema schema)
978 if (baseType == null) {
979 error (h, "Base schema type is not a complex type.");
982 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
983 error (h, "Prohibited derivation by restriction by base schema type.");
988 foreach (DictionaryEntry entry in this.AttributeUses) {
989 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
990 XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;
991 if (baseAttr != null) {
994 if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)
995 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
997 XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;
998 XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;
999 bool typeError = false;
1000 if (attrSimpleType != null)
1001 attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);
1002 else if (attrSimpleType == null && baseAttrSimpleType != null)
1005 Type t1 = attr.AttributeType.GetType ();
1006 Type t2 = baseAttr.AttributeType.GetType ();
1007 if (t1 != t2 && t1.IsSubclassOf (t2))
1011 error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");
1013 if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)
1014 error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");
1017 if (baseType.AttributeWildcard != null)
1018 if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (
1019 attr.QualifiedName.Namespace, schema) &&
1020 !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))
1021 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
1024 // I think 3. is considered in 2.
1026 if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {
1027 if (baseType.AttributeWildcard == null)
1028 error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");
1030 AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);
1034 if (this == AnyType)
1036 if (contentTypeParticle == XmlSchemaParticle.Empty) {
1038 if (ContentType != XmlSchemaContentType.Empty) {
1040 // XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;
1042 if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1043 error (h, "Invalid content type derivation.");
1047 if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
1048 !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1049 error (h, "Invalid content type derivation.");
1052 // 5.3 => 3.9.6 Particle Valid (Restriction)
1053 if (baseType.ContentTypeParticle != null) {
1054 // 3.9.6 - 1 : same particle.
1055 // 3.9.6 - 2 is covered by using ActualParticle.
1056 if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))
1057 contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);
1064 // abstract = boolean : false
1065 // block = (#all | List of (extension | restriction))
1066 // final = (#all | List of (extension | restriction))
1068 // mixed = boolean : false
1070 // {any attributes with non-schema namespace . . .}>
1071 // Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1073 internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)
1075 XmlSchemaComplexType ctype = new XmlSchemaComplexType();
1076 reader.MoveToElement();
1079 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1081 error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);
1086 ctype.LineNumber = reader.LineNumber;
1087 ctype.LinePosition = reader.LinePosition;
1088 ctype.SourceUri = reader.BaseURI;
1090 while(reader.MoveToNextAttribute())
1092 if(reader.Name == "abstract")
1094 ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1096 error(h,reader.Value + " is invalid value for abstract",innerex);
1098 else if(reader.Name == "block")
1100 ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1101 XmlSchemaUtil.ComplexTypeBlockAllowed);
1103 error (h,"some invalid values for block attribute were found",innerex);
1105 else if(reader.Name == "final")
1107 ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1108 XmlSchemaUtil.FinalAllowed);
1110 error (h,"some invalid values for final attribute were found",innerex);
1112 else if(reader.Name == "id")
1114 ctype.Id = reader.Value;
1116 else if(reader.Name == "mixed")
1118 ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1120 error(h,reader.Value + " is invalid value for mixed",innerex);
1122 else if(reader.Name == "name")
1124 ctype.Name = reader.Value;
1126 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1128 error(h,reader.Name + " is not a valid attribute for complexType",null);
1132 XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);
1136 reader.MoveToElement();
1137 if(reader.IsEmptyElement)
1140 //Content: 1. annotation?,
1141 // 2. simpleContent | 2. complexContent |
1142 // (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))
1144 while(reader.ReadNextElement())
1146 if(reader.NodeType == XmlNodeType.EndElement)
1148 if(reader.LocalName != xmlname)
1149 error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);
1152 if(level <= 1 && reader.LocalName == "annotation")
1154 level = 2; //Only one annotation
1155 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1156 if(annotation != null)
1157 ctype.Annotation = annotation;
1162 if(reader.LocalName == "simpleContent")
1165 XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);
1167 ctype.ContentModel = simple;
1170 if(reader.LocalName == "complexContent")
1173 XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);
1175 ctype.contentModel = complex;
1181 if(reader.LocalName == "group")
1184 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
1186 ctype.particle = group;
1189 if(reader.LocalName == "all")
1192 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
1194 ctype.particle = all;
1197 if(reader.LocalName == "choice")
1200 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
1202 ctype.particle = choice;
1205 if(reader.LocalName == "sequence")
1208 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
1209 if(sequence != null)
1210 ctype.particle = sequence;
1216 if(reader.LocalName == "attribute")
1219 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
1221 ctype.Attributes.Add(attr);
1224 if(reader.LocalName == "attributeGroup")
1227 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
1229 ctype.attributes.Add(attr);
1233 if(level <= 5 && reader.LocalName == "anyAttribute")
1236 XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
1238 ctype.AnyAttribute = anyattr;
1241 reader.RaiseInvalidElementError();