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 = ""; // In MS.NET, it is not "anyType"
70 anyType.QNameInternal = XmlQualifiedName.Empty; // Not xs:anyType as well.
71 #if BUGGY_MS_COMPLIANT
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;
227 if (isRedefinedComponent) {
228 if (Annotation != null)
229 Annotation.isRedefinedComponent = true;
230 if (AnyAttribute != null)
231 AnyAttribute.isRedefinedComponent = true;
232 foreach (XmlSchemaObject obj in Attributes)
233 obj.isRedefinedComponent = true;
234 if (ContentModel != null)
235 ContentModel.isRedefinedComponent = true;
236 if (Particle != null)
237 Particle.isRedefinedComponent = true;
240 // block/final resolution
241 if(ParentIsSchema || isRedefineChild)
243 if(this.Name == null || this.Name == string.Empty)
244 error(h,"name must be present in a top level complex type");
245 else if(!XmlSchemaUtil.CheckNCName(Name))
246 error(h,"name must be a NCName");
248 this.QNameInternal = new XmlQualifiedName(Name, AncestorSchema.TargetNamespace);
250 if(Block != XmlSchemaDerivationMethod.None)
252 if(Block == XmlSchemaDerivationMethod.All)
254 blockResolved = XmlSchemaDerivationMethod.All;
258 if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
259 error (h, "Invalid block specification.");
260 blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
265 switch (schema.BlockDefault) {
266 case XmlSchemaDerivationMethod.All:
267 blockResolved = XmlSchemaDerivationMethod.All;
269 case XmlSchemaDerivationMethod.None:
270 blockResolved = XmlSchemaDerivationMethod.Empty;
273 blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
278 if(Final != XmlSchemaDerivationMethod.None)
280 if(Final == XmlSchemaDerivationMethod.All)
281 finalResolved = XmlSchemaDerivationMethod.All;
282 else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
283 error (h, "Invalid final specification.");
285 finalResolved = Final;
289 switch (schema.FinalDefault) {
290 case XmlSchemaDerivationMethod.All:
291 finalResolved = XmlSchemaDerivationMethod.All;
293 case XmlSchemaDerivationMethod.None:
294 finalResolved = XmlSchemaDerivationMethod.Empty;
297 finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
302 else // Not Top Level
305 error(h,"abstract must be false in a local complex type");
307 error(h,"name must be absent in a local complex type");
308 if(Final != XmlSchemaDerivationMethod.None)
309 error(h,"final must be absent in a local complex type");
310 if(block != XmlSchemaDerivationMethod.None)
311 error(h,"block must be absent in a local complex type");
314 // Process contents and BaseSchemaType
315 if(contentModel != null)
317 if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
318 error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
319 errorCount += contentModel.Compile (h, schema);
321 XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
324 XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
326 XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
328 if (sscr.BaseType != null) {
329 sscr.BaseType.Compile (h, schema);
330 BaseXmlSchemaTypeInternal = sscr.BaseType;
338 if (Particle != null)
339 errorCount += Particle.Compile (h, schema);
341 if(this.anyAttribute != null)
343 AnyAttribute.Compile(h,schema);
345 foreach(XmlSchemaObject obj in Attributes)
347 if(obj is XmlSchemaAttribute)
349 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
350 errorCount += attr.Compile(h,schema);
352 else if(obj is XmlSchemaAttributeGroupRef)
354 XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
355 errorCount += atgrp.Compile(h,schema);
358 error(h,obj.GetType() +" is not valid in this place::ComplexType");
362 XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
363 this.CompilationId = schema.CompilationId;
367 Guid CollectProcessId;
369 private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)
371 if (CollectProcessId == schema.CompilationId)
373 // Below are already contributed by Compile():
374 // {name}, {namespace} => QualifiedName, QNameInternal
375 // {abstract} => ValidatedIsAbstract
376 // {prohibited substitutions} => BlockResolved
377 // {final} => FinalResolved
378 // {annotations} => Annotation (XmlSchemaAnnotated)
380 // Below are different properties depending on simpleContent | complexContent.
381 // {base type definition}
382 // {derivation method}
383 // {attribute uses} => AttributeUses (later)
384 // {attribute wildcard} => AttributeWildcard (later)
388 // {base type definition} => baseSchemaTypeInternal (later)
389 if (contentModel != null) {
390 BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;
392 BaseXmlSchemaTypeInternal = schema.FindSchemaType(BaseSchemaTypeName);
395 if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {
396 XmlSchemaType redType = (XmlSchemaType) redefinedObject;
398 error (h, "Redefinition base type was not found.");
400 BaseXmlSchemaTypeInternal = redType;
403 // {derivation method} => resolvedDerivedBy
404 if (contentModel != null && contentModel.Content != null) {
406 contentModel.Content.IsExtension ?
407 XmlSchemaDerivationMethod.Extension :
408 XmlSchemaDerivationMethod.Restriction;
411 resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;
414 void FillContentTypeParticle (ValidationEventHandler h, XmlSchema schema)
416 // {content type} => ContentType and ContentTypeParticle (later)
417 if (ContentModel != null) {
418 CollectContentTypeFromContentModel (h, schema);
420 CollectContentTypeFromImmediateContent ();
422 contentTypeParticle = validatableParticle.GetOptimizedParticle (true);
423 if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)
424 resolvedContentType = XmlSchemaContentType.Empty;
426 CollectProcessId = schema.CompilationId;
429 #region {content type}
430 private void CollectContentTypeFromImmediateContent ()
432 // leave resolvedDerivedBy as Empty
433 if (Particle != null)
434 validatableParticle = Particle;
435 if (this == AnyType) {
436 resolvedContentType = XmlSchemaContentType.Mixed;
440 if (validatableParticle == XmlSchemaParticle.Empty) {
441 // note that this covers "Particle == null" case
443 resolvedContentType = XmlSchemaContentType.TextOnly;
445 resolvedContentType = XmlSchemaContentType.Empty;
448 resolvedContentType = XmlSchemaContentType.Mixed;
450 resolvedContentType = XmlSchemaContentType.ElementOnly;
453 BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;
456 private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)
458 if (ContentModel.Content == null) {
459 // basically it is error. Recover by specifying empty content.
460 validatableParticle = XmlSchemaParticle.Empty;
461 resolvedContentType = XmlSchemaContentType.Empty;
465 if (ContentModel.Content is XmlSchemaComplexContentExtension)
466 CollectContentTypeFromComplexExtension (h, schema);
467 if (ContentModel.Content is XmlSchemaComplexContentRestriction)
468 CollectContentTypeFromComplexRestriction ();
471 private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)
473 XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;
474 XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;
475 if (baseComplexType != null)
476 baseComplexType.CollectSchemaComponent (h ,schema);
478 // It must exist, but consider validation error case.
479 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
480 baseComplexType = XmlSchemaComplexType.AnyType;
482 // On error case, it simple reject any contents
483 if (baseComplexType == null) {
484 validatableParticle = XmlSchemaParticle.Empty;
485 resolvedContentType = XmlSchemaContentType.Empty;
489 // 3.4.2 complex content {content type}
490 if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {
492 if (baseComplexType == null) {
493 // Basically it is an error. Considering ValidationEventHandler.
494 validatableParticle = XmlSchemaParticle.Empty;
495 resolvedContentType = XmlSchemaContentType.Empty;
497 validatableParticle = baseComplexType.ValidatableParticle;
498 resolvedContentType = baseComplexType.resolvedContentType;
500 } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty
501 || baseComplexType == XmlSchemaComplexType.AnyType) {
503 validatableParticle = cce.Particle;
504 resolvedContentType = GetComplexContentType (contentModel);
506 // - 2.3 : create a new sequences that merges both contents.
507 XmlSchemaSequence seq = new XmlSchemaSequence ();
509 seq.Items.Add (baseComplexType.validatableParticle);
510 seq.Items.Add (cce.Particle);
511 seq.Compile (h, schema);
512 seq.Validate (h, schema);
513 validatableParticle = seq;
514 resolvedContentType = GetComplexContentType (contentModel);
516 if (validatableParticle == null)
517 validatableParticle = XmlSchemaParticle.Empty;
520 private void CollectContentTypeFromComplexRestriction ()
522 XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;
523 // 3.4.2 complex content schema component {content type}
525 bool isEmptyParticle = false;
526 if (ccr.Particle == null)
527 isEmptyParticle = true;
529 XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;
532 if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)
533 isEmptyParticle = true;
535 else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)
536 isEmptyParticle = true;
539 if (isEmptyParticle) {
540 resolvedContentType = XmlSchemaContentType.Empty;
541 validatableParticle = XmlSchemaParticle.Empty;
544 resolvedContentType = GetComplexContentType (contentModel);
546 validatableParticle = ccr.Particle;
550 // 3.4.2 Complex Content Schema Component {content type} 1.2.1
551 private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)
553 if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)
554 return XmlSchemaContentType.Mixed;
556 return XmlSchemaContentType.ElementOnly;
561 // We have to validate:
563 // - 3.4.3 Complex Type Definition Representation OK
564 // - 3.4.6 Type Definition Properties Correct
565 // - 3.4.6 Derivation Valid (Extension)
566 // - 3.4.6 Derivation Valid (Restriction, Complex)
568 // There are many schema errata:
569 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
571 // E1-43 Derivation Valid (Restriction, Complex) 5.
572 // E1-21 Derivation Valid (Restriction, Complex) 4.3.
573 // E1-17 Type Derivation OK (Complex) 2.1.
575 // And E1-38, E1-37, E1-30, E1-27
577 internal override int Validate (ValidationEventHandler h, XmlSchema schema)
579 if (IsValidated (schema.ValidationId))
581 // FIXME: omitting it causes StackOverflowException
582 // among the compilation of element and types, but
583 // it may result in insufficient results.
584 ValidationId = schema.ValidationId;
586 CollectSchemaComponent (h, schema);
588 ValidateContentFirstPass (h, schema);
590 FillContentTypeParticle (h, schema);
592 // 3.4.6: Properties Correct
593 // Term. 1 => 3.4.1 already done by CollectSchemaComponent()
594 // except for {attribute uses} and {attribute wildcard}
595 // Term. 2, 3 and 4 goes to ValidateContentModel().
596 // Term. 5 follows in this method.
598 if (ContentModel != null)
599 ValidateContentModel (h, schema);
601 ValidateImmediateAttributes (h, schema);
603 // Additional support for 3.8.6 All Group Limited
604 if (ContentTypeParticle != null) {
605 XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;
606 if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.
607 error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
611 if (schema.Schemas.CompilationSettings != null &&
612 schema.Schemas.CompilationSettings.EnableUpaCheck)
614 // This check is optional only after 2.0
615 contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
616 new ArrayList (), h, schema);
617 contentTypeParticle.ValidateUniqueTypeAttribution (
618 new XmlSchemaObjectTable (), h, schema);
620 // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
621 XmlSchemaAttribute idAttr = null;
622 foreach (DictionaryEntry entry in attributeUses) {
623 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
624 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
625 if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
628 dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
629 if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
631 error (h, "Two or more ID typed attribute declarations in a complex type are found.");
637 ValidationId = schema.ValidationId;
641 private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
644 // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
645 attributeUses = new XmlSchemaObjectTable ();
646 XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
647 h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);
650 private void ValidateContentFirstPass (ValidationEventHandler h, XmlSchema schema)
652 if (ContentModel != null) {
653 errorCount += contentModel.Validate (h, schema);
654 if (BaseXmlSchemaTypeInternal != null)
655 errorCount += BaseXmlSchemaTypeInternal.Validate (h, schema);
657 else if (Particle != null) {
658 errorCount += particle.Validate (h, schema);
659 XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
661 if (pgrp.TargetGroup != null)
662 errorCount += pgrp.TargetGroup.Validate (h,schema);
663 // otherwise, it might be missing sub components.
664 else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))
665 error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
670 private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
672 XmlSchemaType baseType = BaseXmlSchemaTypeInternal;
674 // Here we check 3.4.6 Properties Correct :: 2. and 3.
675 XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
676 XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
677 XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
678 XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
680 XmlSchemaAnyAttribute localAnyAttribute = null;
681 XmlSchemaAnyAttribute baseAnyAttribute = null;
683 // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
684 if (ValidateRecursionCheck ())
685 error (h, "Circular definition of schema types was found.");
686 if (baseType != null) {
687 // Fill "Datatype" property.
688 this.DatatypeInternal = baseType.Datatype;
689 } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
690 DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
691 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
692 DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);
695 XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
696 XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
698 // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
699 if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
700 error (h, "Specified derivation is specified as final by derived schema type.");
702 // 3.4.6 Properties Correct :: 2.
703 // Simple {base type definition} and restriction {derivation method} not allowed.
704 if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
705 error (h, "If the base schema type is a simple type, then this type must be extension.");
707 // Common to complexContent
708 if (cce != null || ccr != null) {
709 // 3.4.3 Complex Type Definition Representation OK :: 1.
711 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
712 baseComplexType = XmlSchemaComplexType.AnyType;
713 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))
714 error (h, "Referenced base schema type is XML Schema datatype.");
715 else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
716 error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");
718 // Common to simpleContent
720 // ContentType of {content type}
721 resolvedContentType = XmlSchemaContentType.TextOnly;
723 // 3.4.3 Complex Type Definition Representation OK :: 1.
725 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
726 baseComplexType = XmlSchemaComplexType.AnyType;
728 if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
729 error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);
730 } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {
731 error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);
732 } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
733 // do nothing for particle.
735 // otherwise, it might be missing sub components.
736 else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
737 error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");
739 // 3.4.3 Complex Type Definition Representation OK :: 2.
740 // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)
741 if (baseComplexType != null) {
742 if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {
744 // Here "baseComplexType.Particle != null" is required for error-ignorant case
745 } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {
749 error (h, "Base complex type of a simple content restriction must be text only.");
751 if (sce != null && baseComplexType == null) {
755 error (h, "Not allowed base type of a simple content restriction.");
759 // complexType/complexContent/extension
761 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
762 // is constraining anything here, since 3.4.2 {attribute uses}
763 // defines as to include base type's attribute uses.
764 localAnyAttribute = cce.AnyAttribute;
765 if (baseComplexType != null) {
766 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
767 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
768 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
770 baseAnyAttribute = baseComplexType.AttributeWildcard;
773 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
774 this.attributeUses, h, schema, cce.Attributes,
775 cce.AnyAttribute , ref attributeWildcard, null, true);
777 // After adding them, test extension validity.
778 if (baseComplexType != null)
779 this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
780 else if (baseSimpleType != null)
781 this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
783 // complexType/complexContent/restriction
785 // For ValidationEventHandler.
786 if (baseComplexType == null)
787 baseComplexType = XmlSchemaComplexType.AnyType;
790 localAnyAttribute = ccr.AnyAttribute;
791 this.attributeWildcard = localAnyAttribute;
792 if (baseComplexType != null)
793 baseAnyAttribute = baseComplexType.AttributeWildcard;
794 if (baseAnyAttribute != null && localAnyAttribute != null)
795 // 1.3 attribute wildcard subset. (=> 3.10.6)
796 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
798 // 3.4.2 Complex Type Definition with complex content Schema Component
799 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
800 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
801 this.attributeUses, h, schema, ccr.Attributes,
802 ccr.AnyAttribute, ref attributeWildcard, null, false);
803 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
804 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
805 if (attributeUses [attr.QualifiedName] == null)
806 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
809 // Derivation Valid (Restriction, Complex) :: 5.
810 // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
811 // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
812 this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
814 // complexType/simpleContent/extension
816 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
817 this.attributeUses, h, schema, sce.Attributes,
818 sce.AnyAttribute, ref attributeWildcard, null, true);
821 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
822 // is constraining anything here, since 3.4.2 {attribute uses}
823 // defines as to include base type's attribute uses.
824 localAnyAttribute = sce.AnyAttribute;
826 if (baseComplexType != null) {
827 baseAnyAttribute = baseComplexType.AttributeWildcard;
829 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
830 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
831 #if BUGGY_MS_COMPLIANT
832 if (attr.Use != XmlSchemaUse.Prohibited)
833 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
835 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
838 if (baseAnyAttribute != null && localAnyAttribute != null)
839 // 1.3 attribute wildcard subset. (=> 3.10.6)
840 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
842 // complexType/simpleContent/restriction
845 baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;
847 localAnyAttribute = scr.AnyAttribute;
848 if (localAnyAttribute != null && baseAnyAttribute != null)
849 // 1.3 attribute wildcard subset. (=> 3.10.6)
850 localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
851 // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
852 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
854 // 3.4.2 Complex Type Definition with simple content Schema Component
855 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
856 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
857 this.attributeUses, h, schema, scr.Attributes,
858 scr.AnyAttribute, ref attributeWildcard, null, false);
861 // Common process of AttributeWildcard.
862 if (localAnyAttribute != null) {
863 this.attributeWildcard = localAnyAttribute;
866 this.attributeWildcard = baseAnyAttribute;
869 // 3.4.6 Type Derivation OK (Complex)
870 internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
872 // AnyType derives from AnyType itself.
873 if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)
876 XmlSchemaType bst = b as XmlSchemaType;
877 if (b == this) // 1 and 2.1
879 if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.
880 error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
881 // FIXME: here BaseSchemaType should be
882 // BaseXmlSchemaType, however for some case it
883 // seems not working.
884 if (BaseSchemaType == b) // 2.2
886 if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
887 error (h, "Derived type's base schema type is anyType.");
891 XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;
893 dbct.ValidateTypeDerivationOK (b, h, schema);
897 XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;
899 dbst.ValidateTypeDerivationOK (b, h, schema, true);
904 // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)
905 internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
906 ValidationEventHandler h, XmlSchema schema)
909 if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
910 error (h, "Derivation by extension is prohibited.");
912 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
913 XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;
914 XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
916 error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
918 // 1.3 -> 3.10.6 Wildcard Subset.
919 if (AnyAttribute != null) {
920 if (baseComplexType.AnyAttribute == null)
921 error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
923 baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
926 // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
928 // if (contentTypeParticle == null)
929 // error (h, "Extended complex type's content type must not be empty.");
931 if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
933 if (this.ContentType != baseComplexType.ContentType)
934 // if (this.GetContentType (false) != baseComplexType.GetContentType (false))
935 error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");
936 // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)
937 else if (this.contentTypeParticle == null ||
938 !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {
939 XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
940 if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))
941 error (h, "Invalid complex content extension was found.");
943 // Identical sequence item should be checked, but
944 // I think it is naturally achieved as coded above.
950 // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)
951 internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
952 ValidationEventHandler h, XmlSchema schema)
954 XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
955 if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
956 error (h, "Extension is prohibited by the base type.");
958 XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
961 if (dt != this.Datatype)
962 error (h, "To extend simple type, a complex type must have the same content type as the base type.");
965 internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
966 ValidationEventHandler h, XmlSchema schema)
969 if (baseType == null) {
970 error (h, "Base schema type is not a complex type.");
973 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
974 error (h, "Prohibited derivation by restriction by base schema type.");
979 foreach (DictionaryEntry entry in this.AttributeUses) {
980 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
981 XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;
982 if (baseAttr != null) {
985 if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)
986 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
988 XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;
989 XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;
990 bool typeError = false;
991 if (attrSimpleType != null)
992 attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);
993 else if (attrSimpleType == null && baseAttrSimpleType != null)
996 Type t1 = attr.AttributeType.GetType ();
997 Type t2 = baseAttr.AttributeType.GetType ();
998 if (t1 != t2 && t1.IsSubclassOf (t2))
1002 error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");
1004 if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)
1005 error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");
1008 if (baseType.AttributeWildcard != null)
1009 if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (
1010 attr.QualifiedName.Namespace, schema) &&
1011 !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))
1012 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
1015 // I think 3. is considered in 2.
1017 if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {
1018 if (baseType.AttributeWildcard == null)
1019 error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");
1021 AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);
1025 if (this == AnyType)
1027 if (contentTypeParticle == XmlSchemaParticle.Empty) {
1029 if (ContentType != XmlSchemaContentType.Empty) {
1031 // XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;
1033 if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1034 error (h, "Invalid content type derivation.");
1038 if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
1039 !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1040 error (h, "Invalid content type derivation.");
1043 // 5.3 => 3.9.6 Particle Valid (Restriction)
1044 if (baseType.ContentTypeParticle != null) {
1045 // 3.9.6 - 1 : same particle.
1046 // 3.9.6 - 2 is covered by using ActualParticle.
1047 if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))
1048 contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);
1055 // abstract = boolean : false
1056 // block = (#all | List of (extension | restriction))
1057 // final = (#all | List of (extension | restriction))
1059 // mixed = boolean : false
1061 // {any attributes with non-schema namespace . . .}>
1062 // Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1064 internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)
1066 XmlSchemaComplexType ctype = new XmlSchemaComplexType();
1067 reader.MoveToElement();
1070 if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1072 error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);
1077 ctype.LineNumber = reader.LineNumber;
1078 ctype.LinePosition = reader.LinePosition;
1079 ctype.SourceUri = reader.BaseURI;
1081 while(reader.MoveToNextAttribute())
1083 if(reader.Name == "abstract")
1085 ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1087 error(h,reader.Value + " is invalid value for abstract",innerex);
1089 else if(reader.Name == "block")
1091 ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1092 XmlSchemaUtil.ComplexTypeBlockAllowed);
1094 error (h,"some invalid values for block attribute were found",innerex);
1096 else if(reader.Name == "final")
1098 ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1099 XmlSchemaUtil.FinalAllowed);
1101 error (h,"some invalid values for final attribute were found",innerex);
1103 else if(reader.Name == "id")
1105 ctype.Id = reader.Value;
1107 else if(reader.Name == "mixed")
1109 ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1111 error(h,reader.Value + " is invalid value for mixed",innerex);
1113 else if(reader.Name == "name")
1115 ctype.Name = reader.Value;
1117 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1119 error(h,reader.Name + " is not a valid attribute for complexType",null);
1123 XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);
1127 reader.MoveToElement();
1128 if(reader.IsEmptyElement)
1131 //Content: 1. annotation?,
1132 // 2. simpleContent | 2. complexContent |
1133 // (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))
1135 while(reader.ReadNextElement())
1137 if(reader.NodeType == XmlNodeType.EndElement)
1139 if(reader.LocalName != xmlname)
1140 error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);
1143 if(level <= 1 && reader.LocalName == "annotation")
1145 level = 2; //Only one annotation
1146 XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1147 if(annotation != null)
1148 ctype.Annotation = annotation;
1153 if(reader.LocalName == "simpleContent")
1156 XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);
1158 ctype.ContentModel = simple;
1161 if(reader.LocalName == "complexContent")
1164 XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);
1166 ctype.contentModel = complex;
1172 if(reader.LocalName == "group")
1175 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
1177 ctype.particle = group;
1180 if(reader.LocalName == "all")
1183 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
1185 ctype.particle = all;
1188 if(reader.LocalName == "choice")
1191 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
1193 ctype.particle = choice;
1196 if(reader.LocalName == "sequence")
1199 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
1200 if(sequence != null)
1201 ctype.particle = sequence;
1207 if(reader.LocalName == "attribute")
1210 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
1212 ctype.Attributes.Add(attr);
1215 if(reader.LocalName == "attributeGroup")
1218 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
1220 ctype.attributes.Add(attr);
1224 if(level <= 5 && reader.LocalName == "anyAttribute")
1227 XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
1229 ctype.AnyAttribute = anyattr;
1232 reader.RaiseInvalidElementError();