-//\r
-// System.Xml.Schema.XmlSchemaComplexType.cs\r
-//\r
-// Authors:\r
-// Dwivedi, Ajay kumar Adwiv@Yahoo.com\r
-// Enomoto, Atsushi ginga@kit.hi-ho.ne.jp\r
-//\r
+//
+// System.Xml.Schema.XmlSchemaComplexType.cs
+//
+// Authors:
+// Dwivedi, Ajay kumar Adwiv@Yahoo.com
+// Enomoto, Atsushi ginga@kit.hi-ho.ne.jp
+//
//
// Permission is hereby granted, free of charge, to any person obtaining
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;\r
-using System.Collections;\r
-using System.Xml;\r
-using System.ComponentModel;\r
-using System.Xml.Serialization;\r
-\r
-namespace System.Xml.Schema\r
-{\r
- /// <summary>\r
- /// Summary description for XmlSchemaComplexType.\r
- /// </summary>\r
- public class XmlSchemaComplexType : XmlSchemaType\r
- {\r
- private XmlSchemaAnyAttribute anyAttribute;\r
- private XmlSchemaObjectCollection attributes;\r
- private XmlSchemaObjectTable attributeUses;\r
- private XmlSchemaAnyAttribute attributeWildcard;\r
- private XmlSchemaDerivationMethod block;\r
- private XmlSchemaDerivationMethod blockResolved;\r
- private XmlSchemaContentModel contentModel;\r
- private XmlSchemaParticle validatableParticle;\r
- private XmlSchemaParticle contentTypeParticle;\r
- private bool isAbstract;\r
- private bool isMixed;\r
- private XmlSchemaParticle particle;\r
- private XmlSchemaContentType resolvedContentType;\r
-\r
- internal bool ValidatedIsAbstract;\r
- internal bool ParentIsSchema = false;\r
-\r
- const string xmlname = "complexType";\r
-\r
- private static XmlSchemaComplexType anyType;\r
-\r
- internal static XmlSchemaComplexType AnyType {\r
- get {\r
- if (anyType == null) {\r
- anyType = new XmlSchemaComplexType ();\r
- anyType.Name = ""; // In MS.NET, it is not "anyType"\r
- anyType.QNameInternal = XmlQualifiedName.Empty; // Not xs:anyType as well.\r
-#if BUGGY_MS_COMPLIANT\r
- anyType.validatableParticle = XmlSchemaParticle.Empty; // This code makes validator handles these schemas incorrectly: particlesIb001, mgM013, mgH014, ctE004, ctD004\r
-#else\r
- anyType.validatableParticle = XmlSchemaAny.AnyTypeContent;\r
-#endif\r
- anyType.contentTypeParticle = anyType.validatableParticle;\r
- anyType.DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;\r
- anyType.isMixed = true;\r
- anyType.resolvedContentType = XmlSchemaContentType.Mixed;\r
- }\r
- return anyType;\r
- }\r
- }\r
-\r
- internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);\r
-\r
- public XmlSchemaComplexType ()\r
- {\r
- attributes = new XmlSchemaObjectCollection();\r
- block = XmlSchemaDerivationMethod.None;\r
- attributeUses = new XmlSchemaObjectTable();\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- contentTypeParticle = validatableParticle;\r
- }\r
-\r
- #region Attributes\r
-\r
- [DefaultValue(false)]\r
- [System.Xml.Serialization.XmlAttribute("abstract")]\r
- public bool IsAbstract \r
- {\r
- get{ return isAbstract; }\r
- set{ isAbstract = value; }\r
- }\r
- [DefaultValue(XmlSchemaDerivationMethod.None)]\r
- [System.Xml.Serialization.XmlAttribute("block")]\r
- public XmlSchemaDerivationMethod Block\r
- {\r
- get{ return block; }\r
- set{ block = value; }\r
- }\r
- [DefaultValue(false)]\r
- [System.Xml.Serialization.XmlAttribute("mixed")]\r
- public override bool IsMixed\r
- {\r
- get{ return isMixed; }\r
- set{ isMixed = value; }\r
- }\r
- \r
- #endregion\r
- \r
- #region Elements\r
- \r
- [XmlElement("simpleContent",typeof(XmlSchemaSimpleContent))]\r
- [XmlElement("complexContent",typeof(XmlSchemaComplexContent))]\r
- public XmlSchemaContentModel ContentModel \r
- {\r
- get{ return contentModel; } \r
- set{ contentModel = value; }\r
- }\r
-\r
- //LAMESPEC: The default value for particle in Schema is of Type EmptyParticle (internal?)\r
- [XmlElement("group",typeof(XmlSchemaGroupRef))]\r
- [XmlElement("all",typeof(XmlSchemaAll))]\r
- [XmlElement("choice",typeof(XmlSchemaChoice))]\r
- [XmlElement("sequence",typeof(XmlSchemaSequence))]\r
- public XmlSchemaParticle Particle \r
- {\r
- get{ return particle; } \r
- set{ particle = value; }\r
- }\r
-\r
- [XmlElement("attribute",typeof(XmlSchemaAttribute))]\r
- [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]\r
- public XmlSchemaObjectCollection Attributes \r
- {\r
- get{ return attributes; }\r
- }\r
-\r
- [XmlElement("anyAttribute")]\r
- public XmlSchemaAnyAttribute AnyAttribute \r
- {\r
- get{ return anyAttribute; }\r
- set{ anyAttribute = value; }\r
- }\r
- #endregion\r
-\r
- #region XmlIgnore\r
- [XmlIgnore]\r
- public XmlSchemaContentType ContentType \r
- {\r
- get{ return resolvedContentType; }\r
- }\r
- [XmlIgnore]\r
- public XmlSchemaParticle ContentTypeParticle \r
- {\r
- get{ return contentTypeParticle; }\r
- }\r
- [XmlIgnore]\r
- public XmlSchemaDerivationMethod BlockResolved \r
- {\r
- get{ return blockResolved; }\r
- }\r
- [XmlIgnore]\r
- public XmlSchemaObjectTable AttributeUses \r
- {\r
- get{ return attributeUses; }\r
- }\r
- [XmlIgnore]\r
- public XmlSchemaAnyAttribute AttributeWildcard \r
- {\r
- get{ return attributeWildcard; }\r
- }\r
-\r
- #endregion\r
-\r
- internal XmlSchemaParticle ValidatableParticle \r
- {\r
- get{ return contentTypeParticle; }\r
- }\r
-\r
- /// <remarks>\r
- /// 1. If ContentModel is present, neither particle nor Attributes nor AnyAttribute can be present.\r
- /// 2. If particle is present, \r
- /// a. For a topLevelComplexType\r
- /// 1. name must be present and type NCName\r
- /// 2. if block is #all, blockdefault is #all, else List of (extension | restriction)\r
- /// 3. if final is #all, finaldefault is #all, else List of (extension | restriction)\r
- /// b. For a local Complex type \r
- /// 1. abstract must be false\r
- /// 2. Name must be absent\r
- /// 3. final must be absent\r
- /// 4. block must be absent\r
- /// \r
- /// </remarks>\r
- internal override int Compile (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- // If this is already compiled this time, simply skip.\r
- if (this.IsComplied (schema.CompilationId))\r
- return errorCount;\r
-\r
-#if NET_2_0\r
- if (ContentModel != null)\r
- ContentModel.Parent = this;\r
- if (Particle != null)\r
- Particle.Parent = this;\r
- if (AnyAttribute != null)\r
- AnyAttribute.Parent = this;\r
- foreach (XmlSchemaObject obj in Attributes)\r
- obj.Parent = this;\r
-#endif\r
-\r
- ValidatedIsAbstract = isAbstract;\r
-\r
- if (isRedefinedComponent) {\r
- if (Annotation != null)\r
- Annotation.isRedefinedComponent = true;\r
- if (AnyAttribute != null)\r
- AnyAttribute.isRedefinedComponent = true;\r
- foreach (XmlSchemaObject obj in Attributes)\r
- obj.isRedefinedComponent = true;\r
- if (ContentModel != null)\r
- ContentModel.isRedefinedComponent = true;\r
- if (Particle != null)\r
- Particle.isRedefinedComponent = true;\r
- }\r
-\r
- // block/final resolution\r
- if(ParentIsSchema || isRedefineChild)\r
- {\r
- if(this.Name == null || this.Name == string.Empty)\r
- error(h,"name must be present in a top level complex type");\r
- else if(!XmlSchemaUtil.CheckNCName(Name))\r
- error(h,"name must be a NCName");\r
- else\r
- this.QNameInternal = new XmlQualifiedName(Name, schema.TargetNamespace);\r
- \r
- if(Block != XmlSchemaDerivationMethod.None)\r
- {\r
- if(Block == XmlSchemaDerivationMethod.All)\r
- {\r
- blockResolved = XmlSchemaDerivationMethod.All;\r
- }\r
- else\r
- {\r
- if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)\r
- error (h, "Invalid block specification.");\r
- blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;\r
- }\r
- }\r
- else\r
- {\r
- switch (schema.BlockDefault) {\r
- case XmlSchemaDerivationMethod.All:\r
- blockResolved = XmlSchemaDerivationMethod.All;\r
- break;\r
- case XmlSchemaDerivationMethod.None:\r
- blockResolved = XmlSchemaDerivationMethod.Empty;\r
- break;\r
- default:\r
- blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;\r
- break;\r
- }\r
- }\r
-\r
- if(Final != XmlSchemaDerivationMethod.None)\r
- {\r
- if(Final == XmlSchemaDerivationMethod.All)\r
- finalResolved = XmlSchemaDerivationMethod.All;\r
- else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)\r
- error (h, "Invalid final specification.");\r
- else\r
- finalResolved = Final;\r
- }\r
- else\r
- {\r
- switch (schema.FinalDefault) {\r
- case XmlSchemaDerivationMethod.All:\r
- finalResolved = XmlSchemaDerivationMethod.All;\r
- break;\r
- case XmlSchemaDerivationMethod.None:\r
- finalResolved = XmlSchemaDerivationMethod.Empty;\r
- break;\r
- default:\r
- finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;\r
- break;\r
- }\r
- }\r
- }\r
- else // Not Top Level\r
- {\r
- if(isAbstract)\r
- error(h,"abstract must be false in a local complex type");\r
- if(Name != null)\r
- error(h,"name must be absent in a local complex type");\r
- if(Final != XmlSchemaDerivationMethod.None)\r
- error(h,"final must be absent in a local complex type");\r
- if(block != XmlSchemaDerivationMethod.None)\r
- error(h,"block must be absent in a local complex type");\r
- }\r
-\r
- // Process contents and BaseSchemaType\r
- if(contentModel != null)\r
- {\r
- if(anyAttribute != null || Attributes.Count != 0 || Particle != null)\r
- error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");\r
- errorCount += contentModel.Compile (h, schema);\r
-\r
- XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;\r
- if(smodel != null)\r
- {\r
- XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;\r
- if (sscx == null) {\r
- XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;\r
- if (sscr != null) {\r
- if (sscr.BaseType != null) {\r
- sscr.BaseType.Compile (h, schema);\r
- BaseXmlSchemaTypeInternal = sscr.BaseType;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- if (Particle != null)\r
- errorCount += Particle.Compile (h, schema);\r
-\r
- if(this.anyAttribute != null)\r
- {\r
- AnyAttribute.Compile(h,schema);\r
- }\r
- foreach(XmlSchemaObject obj in Attributes)\r
- {\r
- if(obj is XmlSchemaAttribute)\r
- {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
- errorCount += attr.Compile(h,schema);\r
- }\r
- else if(obj is XmlSchemaAttributeGroupRef)\r
- {\r
- XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;\r
- errorCount += atgrp.Compile(h,schema);\r
- }\r
- else\r
- error(h,obj.GetType() +" is not valid in this place::ComplexType");\r
- }\r
- }\r
-\r
- XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);\r
- this.CompilationId = schema.CompilationId;\r
- return errorCount;\r
- }\r
-\r
- Guid CollectProcessId;\r
-\r
- private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- if (CollectProcessId == schema.CompilationId)\r
- return;\r
- // Below are already contributed by Compile():\r
- // {name}, {namespace} => QualifiedName, QNameInternal\r
- // {abstract} => ValidatedIsAbstract\r
- // {prohibited substitutions} => BlockResolved\r
- // {final} => FinalResolved\r
- // {annotations} => Annotation (XmlSchemaAnnotated)\r
-\r
- // Below are different properties depending on simpleContent | complexContent.\r
- // {base type definition}\r
- // {derivation method}\r
- // {attribute uses} => AttributeUses (later)\r
- // {attribute wildcard} => AttributeWildcard (later)\r
- // {content type}\r
-\r
-\r
- // {base type definition} => baseSchemaTypeInternal (later)\r
- if (contentModel != null) {\r
- BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;\r
-\r
- BaseXmlSchemaTypeInternal = schema.SchemaTypes [BaseSchemaTypeName] as XmlSchemaType;\r
- }\r
- // Resolve redefine.\r
- if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {\r
- XmlSchemaType redType = (XmlSchemaType) redefinedObject;\r
- if (redType == null)\r
- error (h, "Redefinition base type was not found.");\r
- else\r
- BaseXmlSchemaTypeInternal = redType;\r
- }\r
-\r
- // {derivation method} => resolvedDerivedBy\r
- if (contentModel != null && contentModel.Content != null) {\r
- resolvedDerivedBy =\r
- contentModel.Content.IsExtension ?\r
- XmlSchemaDerivationMethod.Extension :\r
- XmlSchemaDerivationMethod.Restriction;\r
- }\r
- else\r
- resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;\r
-\r
-\r
- // {content type} => ContentType and ContentTypeParticle (later)\r
- if (ContentModel != null) {\r
- CollectContentTypeFromContentModel (h, schema);\r
- } else\r
- CollectContentTypeFromImmediateContent ();\r
- contentTypeParticle = validatableParticle.GetOptimizedParticle (true);\r
- if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
-\r
- CollectProcessId = schema.CompilationId;\r
- }\r
-\r
- #region {content type}\r
- private void CollectContentTypeFromImmediateContent ()\r
- {\r
- // leave resolvedDerivedBy as Empty\r
- if (Particle != null)\r
- validatableParticle = Particle;\r
- if (this == AnyType) {\r
- resolvedContentType = XmlSchemaContentType.Mixed;\r
- return;\r
- }\r
-\r
- if (validatableParticle == XmlSchemaParticle.Empty) {\r
- // note that this covers "Particle == null" case\r
- if (this.IsMixed)\r
- resolvedContentType = XmlSchemaContentType.TextOnly;\r
- else\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
- } else {\r
- if (this.IsMixed)\r
- resolvedContentType = XmlSchemaContentType.Mixed;\r
- else\r
- resolvedContentType = XmlSchemaContentType.ElementOnly;\r
- }\r
- if (this != AnyType)\r
- BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;\r
- }\r
-\r
- private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- if (ContentModel.Content == null) {\r
- // basically it is error. Recover by specifying empty content.\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
- return;\r
- }\r
-\r
- if (ContentModel.Content is XmlSchemaComplexContentExtension)\r
- CollectContentTypeFromComplexExtension (h, schema);\r
- if (ContentModel.Content is XmlSchemaComplexContentRestriction)\r
- CollectContentTypeFromComplexRestriction ();\r
- }\r
-\r
- private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;\r
- XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;\r
- if (baseComplexType != null)\r
- baseComplexType.CollectSchemaComponent (h ,schema);\r
-\r
- // It must exist, but consider validation error case.\r
- if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
- baseComplexType = XmlSchemaComplexType.AnyType;\r
-\r
- // On error case, it simple reject any contents\r
- if (baseComplexType == null) {\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
- return;\r
- }\r
-\r
- // 3.4.2 complex content {content type}\r
- if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {\r
- // - 2.1\r
- if (baseComplexType == null) {\r
- // Basically it is an error. Considering ValidationEventHandler.\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
- } else {\r
- validatableParticle = baseComplexType.ValidatableParticle;\r
- resolvedContentType = baseComplexType.resolvedContentType;\r
- }\r
- } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty\r
- || baseComplexType == XmlSchemaComplexType.AnyType) {\r
- // - 2.2\r
- validatableParticle = cce.Particle;\r
- resolvedContentType = GetComplexContentType (contentModel);\r
- } else {\r
- // - 2.3 : create a new sequences that merges both contents.\r
- XmlSchemaSequence seq = new XmlSchemaSequence ();\r
- this.CopyInfo (seq);\r
- seq.Items.Add (baseComplexType.validatableParticle);\r
- seq.Items.Add (cce.Particle);\r
- seq.Compile (h, schema);\r
- seq.Validate (h, schema);\r
- validatableParticle = seq;\r
- resolvedContentType = GetComplexContentType (contentModel);\r
- }\r
- if (validatableParticle == null)\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- }\r
-\r
- private void CollectContentTypeFromComplexRestriction ()\r
- {\r
- XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;\r
- // 3.4.2 complex content schema component {content type}\r
- // - 1.1.1\r
- bool isEmptyParticle = false;\r
- if (ccr.Particle == null) \r
- isEmptyParticle = true;\r
- else {\r
- XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;\r
- if (gb != null) {\r
- // - 1.1.2\r
- if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)\r
- isEmptyParticle = true;\r
- // - 1.1.3\r
- else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)\r
- isEmptyParticle = true;\r
- }\r
- }\r
- if (isEmptyParticle) {\r
- resolvedContentType = XmlSchemaContentType.Empty;\r
- validatableParticle = XmlSchemaParticle.Empty;\r
- } else {\r
- // - 1.2.1\r
- resolvedContentType = GetComplexContentType (contentModel);\r
- // - 1.2.2\r
- validatableParticle = ccr.Particle;\r
- }\r
- }\r
-\r
- // 3.4.2 Complex Content Schema Component {content type} 1.2.1\r
- private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)\r
- {\r
- if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)\r
- return XmlSchemaContentType.Mixed;\r
- else\r
- return XmlSchemaContentType.ElementOnly;\r
- }\r
- #endregion\r
-\r
- //\r
- // We have to validate:\r
- //\r
- // - 3.4.3 Complex Type Definition Representation OK\r
- // - 3.4.6 Type Definition Properties Correct\r
- // - 3.4.6 Derivation Valid (Extension)\r
- // - 3.4.6 Derivation Valid (Restriction, Complex)\r
- //\r
- // There are many schema errata:\r
- // http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
- //\r
- // E1-43 Derivation Valid (Restriction, Complex) 5.\r
- // E1-21 Derivation Valid (Restriction, Complex) 4.3.\r
- // E1-17 Type Derivation OK (Complex) 2.1.\r
- //\r
- // And E1-38, E1-37, E1-30, E1-27\r
- //\r
- internal override int Validate (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- if (IsValidated (schema.ValidationId))\r
- return errorCount;\r
- // FIXME: omitting it causes StackOverflowException\r
- // among the compilation of element and types, but\r
- // it may result in insufficient results.\r
- ValidationId = schema.ValidationId;\r
-\r
- CollectSchemaComponent (h, schema);\r
-\r
- // 3.4.6: Properties Correct\r
- // Term. 1 => 3.4.1 already done by CollectSchemaComponent()\r
- // except for {attribute uses} and {attribute wildcard}\r
- // Term. 2, 3 and 4 goes to ValidateContentModel().\r
- // Term. 5 follows in this method.\r
- //\r
- if (ContentModel != null)\r
- ValidateContentModel (h, schema);\r
- else {\r
- if (Particle != null)\r
- ValidateImmediateParticle (h, schema);\r
- ValidateImmediateAttributes (h, schema);\r
- }\r
-\r
- // Additional support for 3.8.6 All Group Limited\r
- if (ContentTypeParticle != null) {\r
- XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;\r
- if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.\r
- error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");\r
- }\r
-\r
-#if NET_2_0\r
- if (schema.Schemas.CompilationSettings != null &&\r
- schema.Schemas.CompilationSettings.EnableUpaCheck)\r
-#endif\r
- // This check is optional only after 2.0\r
- contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),\r
- new ArrayList (), h, schema);\r
- contentTypeParticle.ValidateUniqueTypeAttribution (\r
- new XmlSchemaObjectTable (), h, schema);\r
-\r
- // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)\r
- XmlSchemaAttribute idAttr = null;\r
- foreach (DictionaryEntry entry in attributeUses) {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
- XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;\r
- if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)\r
- continue;\r
- if (dt == null)\r
- dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;\r
- if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {\r
- if (idAttr != null)\r
- error (h, "Two or more ID typed attribute declarations in a complex type are found.");\r
- else\r
- idAttr = attr;\r
- }\r
- }\r
-\r
- ValidationId = schema.ValidationId;\r
- return errorCount;\r
- }\r
-\r
- private void ValidateImmediateParticle (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- errorCount += particle.Validate (h, schema);\r
- XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;\r
- if (pgrp != null) {\r
- if (pgrp.TargetGroup != null)\r
- errorCount += pgrp.TargetGroup.Validate (h,schema);\r
- // otherwise, it might be missing sub components.\r
- else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))\r
- error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");\r
- }\r
- }\r
-\r
- private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- // {attribute uses}\r
- // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)\r
- attributeUses = new XmlSchemaObjectTable ();\r
- XmlSchemaUtil.ValidateAttributesResolved (attributeUses,\r
- h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);\r
- }\r
-\r
- private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)\r
- {\r
- XmlSchemaType baseType = BaseXmlSchemaTypeInternal;\r
-\r
- // Here we check 3.4.6 Properties Correct :: 2. and 3.\r
- errorCount += contentModel.Validate (h, schema);\r
- XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;\r
- XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;\r
- XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;\r
- XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;\r
-\r
- XmlSchemaAnyAttribute localAnyAttribute = null;\r
- XmlSchemaAnyAttribute baseAnyAttribute = null;\r
-\r
- // 3.4.6 Properties Correct :: 3. Circular definition prohibited.\r
- if (ValidateRecursionCheck ())\r
- error (h, "Circular definition of schema types was found.");\r
- if (baseType != null) {\r
- baseType.Validate (h, schema);\r
- // Fill "Datatype" property.\r
- this.DatatypeInternal = baseType.Datatype;\r
- } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
+using System;
+using System.Collections;
+using System.Xml;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+namespace System.Xml.Schema
+{
+ /// <summary>
+ /// Summary description for XmlSchemaComplexType.
+ /// </summary>
+ public class XmlSchemaComplexType : XmlSchemaType
+ {
+ private XmlSchemaAnyAttribute anyAttribute;
+ private XmlSchemaObjectCollection attributes;
+ private XmlSchemaObjectTable attributeUses;
+ private XmlSchemaAnyAttribute attributeWildcard;
+ private XmlSchemaDerivationMethod block;
+ private XmlSchemaDerivationMethod blockResolved;
+ private XmlSchemaContentModel contentModel;
+ private XmlSchemaParticle validatableParticle;
+ private XmlSchemaParticle contentTypeParticle;
+ private bool isAbstract;
+ private bool isMixed;
+ private XmlSchemaParticle particle;
+ private XmlSchemaContentType resolvedContentType;
+
+ internal bool ValidatedIsAbstract;
+ internal bool ParentIsSchema {
+ get { return Parent is XmlSchema; }
+ }
+
+ const string xmlname = "complexType";
+
+ private static XmlSchemaComplexType anyType;
+
+ internal static XmlSchemaComplexType AnyType {
+ get {
+ if (anyType == null) {
+ anyType = new XmlSchemaComplexType ();
+ anyType.Name = "anyType";
+ anyType.QNameInternal = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
+ if (XmlSchemaUtil.StrictMsCompliant)
+ anyType.validatableParticle = XmlSchemaParticle.Empty; // This code makes validator handles these schemas incorrectly: particlesIb001, mgM013, mgH014, ctE004, ctD004
+ else
+ anyType.validatableParticle = XmlSchemaAny.AnyTypeContent;
+
+ anyType.contentTypeParticle = anyType.validatableParticle;
+ anyType.DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
+ anyType.isMixed = true;
+ anyType.resolvedContentType = XmlSchemaContentType.Mixed;
+ }
+ return anyType;
+ }
+ }
+
+ internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
+
+ public XmlSchemaComplexType ()
+ {
+ attributes = new XmlSchemaObjectCollection();
+ block = XmlSchemaDerivationMethod.None;
+ attributeUses = new XmlSchemaObjectTable();
+ validatableParticle = XmlSchemaParticle.Empty;
+ contentTypeParticle = validatableParticle;
+ }
+
+ #region Attributes
+
+ [DefaultValue(false)]
+ [System.Xml.Serialization.XmlAttribute("abstract")]
+ public bool IsAbstract
+ {
+ get{ return isAbstract; }
+ set{ isAbstract = value; }
+ }
+ [DefaultValue(XmlSchemaDerivationMethod.None)]
+ [System.Xml.Serialization.XmlAttribute("block")]
+ public XmlSchemaDerivationMethod Block
+ {
+ get{ return block; }
+ set{ block = value; }
+ }
+ [DefaultValue(false)]
+ [System.Xml.Serialization.XmlAttribute("mixed")]
+ public override bool IsMixed
+ {
+ get{ return isMixed; }
+ set{ isMixed = value; }
+ }
+
+ #endregion
+
+ #region Elements
+
+ [XmlElement("simpleContent",typeof(XmlSchemaSimpleContent))]
+ [XmlElement("complexContent",typeof(XmlSchemaComplexContent))]
+ public XmlSchemaContentModel ContentModel
+ {
+ get{ return contentModel; }
+ set{ contentModel = value; }
+ }
+
+ //LAMESPEC: The default value for particle in Schema is of Type EmptyParticle (internal?)
+ [XmlElement("group",typeof(XmlSchemaGroupRef))]
+ [XmlElement("all",typeof(XmlSchemaAll))]
+ [XmlElement("choice",typeof(XmlSchemaChoice))]
+ [XmlElement("sequence",typeof(XmlSchemaSequence))]
+ public XmlSchemaParticle Particle
+ {
+ get{ return particle; }
+ set{ particle = value; }
+ }
+
+ [XmlElement("attribute",typeof(XmlSchemaAttribute))]
+ [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]
+ public XmlSchemaObjectCollection Attributes
+ {
+ get{ return attributes; }
+ }
+
+ [XmlElement("anyAttribute")]
+ public XmlSchemaAnyAttribute AnyAttribute
+ {
+ get{ return anyAttribute; }
+ set{ anyAttribute = value; }
+ }
+ #endregion
+
+ #region XmlIgnore
+ [XmlIgnore]
+ public XmlSchemaContentType ContentType
+ {
+ get{ return resolvedContentType; }
+ }
+ [XmlIgnore]
+ public XmlSchemaParticle ContentTypeParticle
+ {
+ get{ return contentTypeParticle; }
+ }
+ [XmlIgnore]
+ public XmlSchemaDerivationMethod BlockResolved
+ {
+ get{ return blockResolved; }
+ }
+ [XmlIgnore]
+ public XmlSchemaObjectTable AttributeUses
+ {
+ get{ return attributeUses; }
+ }
+ [XmlIgnore]
+ public XmlSchemaAnyAttribute AttributeWildcard
+ {
+ get{ return attributeWildcard; }
+ }
+
+ #endregion
+
+ internal XmlSchemaParticle ValidatableParticle
+ {
+ get{ return contentTypeParticle; }
+ }
+
+ internal override void SetParent (XmlSchemaObject parent)
+ {
+ base.SetParent (parent);
+ if (ContentModel != null)
+ ContentModel.SetParent (this);
+ if (Particle != null)
+ Particle.SetParent (this);
+ if (AnyAttribute != null)
+ AnyAttribute.SetParent (this);
+ foreach (XmlSchemaObject obj in Attributes)
+ obj.SetParent (this);
+ }
+
+ /// <remarks>
+ /// 1. If ContentModel is present, neither particle nor Attributes nor AnyAttribute can be present.
+ /// 2. If particle is present,
+ /// a. For a topLevelComplexType
+ /// 1. name must be present and type NCName
+ /// 2. if block is #all, blockdefault is #all, else List of (extension | restriction)
+ /// 3. if final is #all, finaldefault is #all, else List of (extension | restriction)
+ /// b. For a local Complex type
+ /// 1. abstract must be false
+ /// 2. Name must be absent
+ /// 3. final must be absent
+ /// 4. block must be absent
+ ///
+ /// </remarks>
+ internal override int Compile (ValidationEventHandler h, XmlSchema schema)
+ {
+ // If this is already compiled this time, simply skip.
+ if (CompilationId == schema.CompilationId)
+ return errorCount;
+
+ ValidatedIsAbstract = isAbstract;
+ attributeUses.Clear();
+
+ if (isRedefinedComponent) {
+ if (Annotation != null)
+ Annotation.isRedefinedComponent = true;
+ if (AnyAttribute != null)
+ AnyAttribute.isRedefinedComponent = true;
+ foreach (XmlSchemaObject obj in Attributes)
+ obj.isRedefinedComponent = true;
+ if (ContentModel != null)
+ ContentModel.isRedefinedComponent = true;
+ if (Particle != null)
+ Particle.isRedefinedComponent = true;
+ }
+
+ // block/final resolution
+ if(ParentIsSchema || isRedefineChild)
+ {
+ if(this.Name == null || this.Name == string.Empty)
+ error(h,"name must be present in a top level complex type");
+ else if(!XmlSchemaUtil.CheckNCName(Name))
+ error(h,"name must be a NCName");
+ else
+ this.QNameInternal = new XmlQualifiedName(Name, AncestorSchema.TargetNamespace);
+
+ if(Block != XmlSchemaDerivationMethod.None)
+ {
+ if(Block == XmlSchemaDerivationMethod.All)
+ {
+ blockResolved = XmlSchemaDerivationMethod.All;
+ }
+ else
+ {
+ if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
+ error (h, "Invalid block specification.");
+ blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
+ }
+ }
+ else
+ {
+ switch (schema.BlockDefault) {
+ case XmlSchemaDerivationMethod.All:
+ blockResolved = XmlSchemaDerivationMethod.All;
+ break;
+ case XmlSchemaDerivationMethod.None:
+ blockResolved = XmlSchemaDerivationMethod.Empty;
+ break;
+ default:
+ blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
+ break;
+ }
+ }
+
+ if(Final != XmlSchemaDerivationMethod.None)
+ {
+ if(Final == XmlSchemaDerivationMethod.All)
+ finalResolved = XmlSchemaDerivationMethod.All;
+ else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
+ error (h, "Invalid final specification.");
+ else
+ finalResolved = Final;
+ }
+ else
+ {
+ switch (schema.FinalDefault) {
+ case XmlSchemaDerivationMethod.All:
+ finalResolved = XmlSchemaDerivationMethod.All;
+ break;
+ case XmlSchemaDerivationMethod.None:
+ finalResolved = XmlSchemaDerivationMethod.Empty;
+ break;
+ default:
+ finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
+ break;
+ }
+ }
+ }
+ else // Not Top Level
+ {
+ if(isAbstract)
+ error(h,"abstract must be false in a local complex type");
+ if(Name != null)
+ error(h,"name must be absent in a local complex type");
+ if(Final != XmlSchemaDerivationMethod.None)
+ error(h,"final must be absent in a local complex type");
+ if(block != XmlSchemaDerivationMethod.None)
+ error(h,"block must be absent in a local complex type");
+ }
+
+ // Process contents and BaseSchemaType
+ if(contentModel != null)
+ {
+ if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
+ error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
+ errorCount += contentModel.Compile (h, schema);
+
+ XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
+ if(smodel != null)
+ {
+ XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
+ if (sscx == null) {
+ XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
+ if (sscr != null) {
+ if (sscr.BaseType != null) {
+ sscr.BaseType.Compile (h, schema);
+ BaseXmlSchemaTypeInternal = sscr.BaseType;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (Particle != null)
+ errorCount += Particle.Compile (h, schema);
+
+ if(this.anyAttribute != null)
+ {
+ AnyAttribute.Compile(h,schema);
+ }
+ foreach(XmlSchemaObject obj in Attributes)
+ {
+ if(obj is XmlSchemaAttribute)
+ {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
+ errorCount += attr.Compile(h,schema);
+ }
+ else if(obj is XmlSchemaAttributeGroupRef)
+ {
+ XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
+ errorCount += atgrp.Compile(h,schema);
+ }
+ else
+ error(h,obj.GetType() +" is not valid in this place::ComplexType");
+ }
+ }
+
+ XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
+ this.CompilationId = schema.CompilationId;
+ return errorCount;
+ }
+
+ Guid CollectProcessId;
+
+ private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (CollectProcessId == schema.CompilationId)
+ return;
+ // Below are already contributed by Compile():
+ // {name}, {namespace} => QualifiedName, QNameInternal
+ // {abstract} => ValidatedIsAbstract
+ // {prohibited substitutions} => BlockResolved
+ // {final} => FinalResolved
+ // {annotations} => Annotation (XmlSchemaAnnotated)
+
+ // Below are different properties depending on simpleContent | complexContent.
+ // {base type definition}
+ // {derivation method}
+ // {attribute uses} => AttributeUses (later)
+ // {attribute wildcard} => AttributeWildcard (later)
+ // {content type}
+
+
+ // {base type definition} => baseSchemaTypeInternal (later)
+ if (contentModel != null) {
+ BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;
+
+ BaseXmlSchemaTypeInternal = schema.FindSchemaType(BaseSchemaTypeName);
+ }
+ // Resolve redefine.
+ if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {
+ XmlSchemaType redType = (XmlSchemaType) redefinedObject;
+ if (redType == null)
+ error (h, "Redefinition base type was not found.");
+ else
+ BaseXmlSchemaTypeInternal = redType;
+ }
+
+ // {derivation method} => resolvedDerivedBy
+ if (contentModel != null && contentModel.Content != null) {
+ resolvedDerivedBy =
+ contentModel.Content.IsExtension ?
+ XmlSchemaDerivationMethod.Extension :
+ XmlSchemaDerivationMethod.Restriction;
+ }
+ else
+ resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;
+ }
+
+ void FillContentTypeParticle (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (CollectProcessId == schema.CompilationId)
+ return;
+ CollectProcessId = schema.CompilationId;
+
+ var ct = BaseXmlSchemaType as XmlSchemaComplexType;
+ if (ct != null)
+ ct.FillContentTypeParticle (h, schema);
+
+ // {content type} => ContentType and ContentTypeParticle (later)
+ if (ContentModel != null) {
+ CollectContentTypeFromContentModel (h, schema);
+ } else
+ CollectContentTypeFromImmediateContent ();
+
+ contentTypeParticle = validatableParticle.GetOptimizedParticle (true);
+ if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)
+ resolvedContentType = XmlSchemaContentType.Empty;
+ }
+
+ #region {content type}
+ private void CollectContentTypeFromImmediateContent ()
+ {
+ // leave resolvedDerivedBy as Empty
+ if (Particle != null)
+ validatableParticle = Particle;
+ if (this == AnyType) {
+ resolvedContentType = XmlSchemaContentType.Mixed;
+ return;
+ }
+
+ if (validatableParticle == XmlSchemaParticle.Empty) {
+ // note that this covers "Particle == null" case
+ if (this.IsMixed)
+ resolvedContentType = XmlSchemaContentType.TextOnly;
+ else
+ resolvedContentType = XmlSchemaContentType.Empty;
+ } else {
+ if (this.IsMixed)
+ resolvedContentType = XmlSchemaContentType.Mixed;
+ else
+ resolvedContentType = XmlSchemaContentType.ElementOnly;
+ }
+ if (this != AnyType)
+ BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;
+ }
+
+ private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (ContentModel.Content == null) {
+ // basically it is error. Recover by specifying empty content.
+ validatableParticle = XmlSchemaParticle.Empty;
+ resolvedContentType = XmlSchemaContentType.Empty;
+ return;
+ }
+
+ if (ContentModel.Content is XmlSchemaComplexContentExtension)
+ CollectContentTypeFromComplexExtension (h, schema);
+ if (ContentModel.Content is XmlSchemaComplexContentRestriction)
+ CollectContentTypeFromComplexRestriction ();
+ }
+
+ private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)
+ {
+ XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;
+ XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;
+ if (baseComplexType != null)
+ baseComplexType.CollectSchemaComponent (h ,schema);
+
+ // It must exist, but consider validation error case.
+ if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
+ baseComplexType = XmlSchemaComplexType.AnyType;
+
+ // On error case, it simply rejects any contents
+ if (baseComplexType == null) {
+ validatableParticle = XmlSchemaParticle.Empty;
+ resolvedContentType = XmlSchemaContentType.Empty;
+ return;
+ }
+
+ // 3.4.2 complex content {content type}
+ // FIXME: this part is looking different than the spec. sections.
+ if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {
+ // - 2.1
+ if (baseComplexType == null) {
+ // Basically it is an error. Considering ValidationEventHandler.
+ validatableParticle = XmlSchemaParticle.Empty;
+ resolvedContentType = XmlSchemaContentType.Empty;
+ } else {
+ validatableParticle = baseComplexType.ValidatableParticle;
+ resolvedContentType = baseComplexType.resolvedContentType;
+ // Bug #501814
+ if (resolvedContentType == XmlSchemaContentType.Empty)
+ resolvedContentType = GetComplexContentType (contentModel);
+ }
+ } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty
+ || baseComplexType == XmlSchemaComplexType.AnyType) {
+ // - 2.2
+ validatableParticle = cce.Particle;
+ resolvedContentType = GetComplexContentType (contentModel);
+ } else {
+ // - 2.3 : create a new sequences that merges both contents.
+ XmlSchemaSequence seq = new XmlSchemaSequence ();
+ this.CopyInfo (seq);
+ seq.Items.Add (baseComplexType.validatableParticle);
+ seq.Items.Add (cce.Particle);
+ seq.Compile (h, schema);
+ seq.Validate (h, schema);
+ validatableParticle = seq;
+ resolvedContentType = GetComplexContentType (contentModel);
+ }
+ if (validatableParticle == null)
+ validatableParticle = XmlSchemaParticle.Empty;
+ }
+
+ private void CollectContentTypeFromComplexRestriction ()
+ {
+ XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;
+ // 3.4.2 complex content schema component {content type}
+ // - 1.1.1
+ bool isEmptyParticle = false;
+ if (ccr.Particle == null)
+ isEmptyParticle = true;
+ else {
+ XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;
+ if (gb != null) {
+ // - 1.1.2
+ if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)
+ isEmptyParticle = true;
+ // - 1.1.3
+ else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)
+ isEmptyParticle = true;
+ }
+ }
+ if (isEmptyParticle) {
+ resolvedContentType = XmlSchemaContentType.Empty;
+ validatableParticle = XmlSchemaParticle.Empty;
+ } else {
+ // - 1.2.1
+ resolvedContentType = GetComplexContentType (contentModel);
+ // - 1.2.2
+ validatableParticle = ccr.Particle;
+ }
+ }
+
+ // 3.4.2 Complex Content Schema Component {content type} 1.2.1
+ private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)
+ {
+ if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)
+ return XmlSchemaContentType.Mixed;
+ else
+ return XmlSchemaContentType.ElementOnly;
+ }
+ #endregion
+
+ //
+ // We have to validate:
+ //
+ // - 3.4.3 Complex Type Definition Representation OK
+ // - 3.4.6 Type Definition Properties Correct
+ // - 3.4.6 Derivation Valid (Extension)
+ // - 3.4.6 Derivation Valid (Restriction, Complex)
+ //
+ // There are many schema errata:
+ // http://www.w3.org/2001/05/xmlschema-errata#Errata1
+ //
+ // E1-43 Derivation Valid (Restriction, Complex) 5.
+ // E1-21 Derivation Valid (Restriction, Complex) 4.3.
+ // E1-17 Type Derivation OK (Complex) 2.1.
+ //
+ // And E1-38, E1-37, E1-30, E1-27
+ //
+ internal override int Validate (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (IsValidated (schema.ValidationId))
+ return errorCount;
+ // FIXME: omitting it causes StackOverflowException
+ // among the compilation of element and types, but
+ // it may result in insufficient results.
+ ValidationId = schema.ValidationId;
+
+ CollectSchemaComponent (h, schema);
+
+ ValidateBaseXmlSchemaType (h, schema);
+
+ ValidateParticle (h, schema);
+
+ FillContentTypeParticle (h, schema);
+
+ // 3.4.6: Properties Correct
+ // Term. 1 => 3.4.1 already done by CollectSchemaComponent()
+ // except for {attribute uses} and {attribute wildcard}
+ // Term. 2, 3 and 4 goes to ValidateContentModel().
+ // Term. 5 follows in this method.
+ //
+ if (ContentModel != null)
+ ValidateContentModel (h, schema);
+ else
+ ValidateImmediateAttributes (h, schema);
+
+ // Additional support for 3.8.6 All Group Limited
+ if (ContentTypeParticle != null) {
+ XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;
+ if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.
+ error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
+ }
+
+#if NET_2_0
+ if (schema.Schemas.CompilationSettings != null &&
+ schema.Schemas.CompilationSettings.EnableUpaCheck)
+#endif
+ // This check is optional only after 2.0
+ contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
+ new ArrayList (), h, schema);
+ contentTypeParticle.ValidateUniqueTypeAttribution (
+ new XmlSchemaObjectTable (), h, schema);
+
+ // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
+ XmlSchemaAttribute idAttr = null;
+ foreach (DictionaryEntry entry in attributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+ XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
+ if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
+ continue;
+ if (dt == null)
+ dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
+ if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
+ if (idAttr != null)
+ error (h, "Two or more ID typed attribute declarations in a complex type are found.");
+ else
+ idAttr = attr;
+ }
+ }
+
+ ValidationId = schema.ValidationId;
+ return errorCount;
+ }
+
+ private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
+ {
+ // {attribute uses}
+ // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
+ attributeUses = new XmlSchemaObjectTable ();
+ XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
+ h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);
+ }
+
+ private void ValidateBaseXmlSchemaType (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (ContentModel != null && BaseXmlSchemaTypeInternal != null)
+ errorCount += BaseXmlSchemaTypeInternal.Validate (h, schema);
+ }
+
+ private void ValidateParticle (ValidationEventHandler h, XmlSchema schema)
+ {
+ if (ContentModel == null && Particle != null) {
+ errorCount += particle.Validate (h, schema);
+ XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
+ if (pgrp != null) {
+ if (pgrp.TargetGroup != null)
+ errorCount += pgrp.TargetGroup.Validate (h,schema);
+ // otherwise, it might be missing sub components.
+ else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))
+ error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
+ }
+ }
+ }
+
+ private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
+ {
+ errorCount += contentModel.Validate (h, schema);
+
+ XmlSchemaType baseType = BaseXmlSchemaTypeInternal;
+
+ // Here we check 3.4.6 Properties Correct :: 2. and 3.
+ XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
+ XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
+ XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
+ XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
+
+ XmlSchemaAnyAttribute localAnyAttribute = null;
+ XmlSchemaAnyAttribute baseAnyAttribute = null;
+
+ // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
+ if (ValidateRecursionCheck ())
+ error (h, "Circular definition of schema types was found.");
+ if (baseType != null) {
+ // Fill "Datatype" property.
+ this.DatatypeInternal = baseType.Datatype;
+ } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
- else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {\r
- DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);\r
- }\r
-\r
- XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;\r
- XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;\r
-\r
- // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.\r
- if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)\r
- error (h, "Specified derivation is specified as final by derived schema type.");\r
-\r
- // 3.4.6 Properties Correct :: 2.\r
- // Simple {base type definition} and restriction {derivation method} not allowed.\r
- if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)\r
- error (h, "If the base schema type is a simple type, then this type must be extension.");\r
-\r
- // Common to complexContent\r
- if (cce != null || ccr != null) {\r
- // 3.4.3 Complex Type Definition Representation OK :: 1.\r
- // base\r
- if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
- baseComplexType = XmlSchemaComplexType.AnyType;\r
- else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))\r
- error (h, "Referenced base schema type is XML Schema datatype.");\r
- else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))\r
- error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");\r
- }\r
- // Common to simpleContent \r
- else {\r
- // ContentType of {content type}\r
- resolvedContentType = XmlSchemaContentType.TextOnly;\r
-\r
- // 3.4.3 Complex Type Definition Representation OK :: 1.\r
- // base\r
- if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
+ else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
+ DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);
+ }
+
+ XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
+ XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
+
+ // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
+ if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
+ error (h, "Specified derivation is specified as final by derived schema type.");
+
+ // 3.4.6 Properties Correct :: 2.
+ // Simple {base type definition} and restriction {derivation method} not allowed.
+ if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
+ error (h, "If the base schema type is a simple type, then this type must be extension.");
+
+ // Common to complexContent
+ if (cce != null || ccr != null) {
+ // 3.4.3 Complex Type Definition Representation OK :: 1.
+ // base
+ if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
baseComplexType = XmlSchemaComplexType.AnyType;
-\r
- if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {\r
- error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);\r
- } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {\r
- error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);\r
- } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {\r
- // do nothing for particle.\r
- }\r
- // otherwise, it might be missing sub components.\r
- else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))\r
- error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");\r
-\r
- // 3.4.3 Complex Type Definition Representation OK :: 2.\r
- // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)\r
- if (baseComplexType != null) {\r
- if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {\r
- // 2.1.1\r
- // Here "baseComplexType.Particle != null" is required for error-ignorant case\r
- } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {\r
- // 2.1.2 && 2.2: OK\r
- }\r
- else\r
- error (h, "Base complex type of a simple content restriction must be text only.");\r
- } else {\r
- if (sce != null && baseComplexType == null) {\r
- // 2.1.3 : OK\r
- }\r
- else\r
- error (h, "Not allowed base type of a simple content restriction.");\r
- }\r
- }\r
-\r
- // complexType/complexContent/extension\r
- if (cce != null) {\r
- // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2\r
- // is constraining anything here, since 3.4.2 {attribute uses}\r
- // defines as to include base type's attribute uses.\r
- localAnyAttribute = cce.AnyAttribute;\r
- if (baseComplexType != null) {\r
- foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
- XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
- }\r
- baseAnyAttribute = baseComplexType.AttributeWildcard;\r
- }\r
- // attributes\r
- errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
- this.attributeUses, h, schema, cce.Attributes, \r
- cce.AnyAttribute , ref attributeWildcard, null, true);\r
-\r
- // After adding them, test extension validity.\r
- if (baseComplexType != null)\r
- this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);\r
- else if (baseSimpleType != null)\r
- this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);\r
- }\r
- // complexType/complexContent/restriction\r
- if (ccr != null) {\r
- // For ValidationEventHandler.\r
- if (baseComplexType == null)\r
- baseComplexType = XmlSchemaComplexType.AnyType;\r
- if (ccr.Particle != null)\r
- ccr.Particle.Validate (h, schema);\r
-\r
- // attributes\r
- localAnyAttribute = ccr.AnyAttribute;\r
- this.attributeWildcard = localAnyAttribute;\r
- if (baseComplexType != null)\r
- baseAnyAttribute = baseComplexType.AttributeWildcard;\r
- if (baseAnyAttribute != null && localAnyAttribute != null)\r
- // 1.3 attribute wildcard subset. (=> 3.10.6)\r
- localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
-\r
- // 3.4.2 Complex Type Definition with complex content Schema Component\r
- // and its {attribute uses} and {attribute wildcard} are done here (descendantly)\r
- errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
- this.attributeUses, h, schema, ccr.Attributes, \r
- ccr.AnyAttribute, ref attributeWildcard, null, false);\r
- foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
- if (attributeUses [attr.QualifiedName] == null)\r
- XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
- }\r
-\r
- // Derivation Valid (Restriction, Complex) :: 5.\r
- // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
- // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)\r
- this.ValidateDerivationValidRestriction (baseComplexType, h, schema);\r
- }\r
- // complexType/simpleContent/extension\r
- if (sce != null) {\r
- errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
- this.attributeUses, h, schema, sce.Attributes, \r
- sce.AnyAttribute, ref attributeWildcard, null, true);\r
-\r
- // Attributes\r
- // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2\r
- // is constraining anything here, since 3.4.2 {attribute uses}\r
- // defines as to include base type's attribute uses.\r
- localAnyAttribute = sce.AnyAttribute;\r
-\r
- if (baseComplexType != null) {\r
- baseAnyAttribute = baseComplexType.AttributeWildcard;\r
-\r
- foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
-#if BUGGY_MS_COMPLIANT\r
- if (attr.Use != XmlSchemaUse.Prohibited)\r
- XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
-#endif\r
- XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
- }\r
- }\r
- if (baseAnyAttribute != null && localAnyAttribute != null)\r
- // 1.3 attribute wildcard subset. (=> 3.10.6)\r
- localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
- }\r
- // complexType/simpleContent/restriction\r
- if (scr != null) {\r
- // Attributes\r
- baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;\r
-\r
- localAnyAttribute = scr.AnyAttribute;\r
- if (localAnyAttribute != null && baseAnyAttribute != null)\r
- // 1.3 attribute wildcard subset. (=> 3.10.6)\r
- localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
- // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!\r
- // http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
-\r
- // 3.4.2 Complex Type Definition with simple content Schema Component\r
- // and its {attribute uses} and {attribute wildcard} are done here (descendantly)\r
- errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
- this.attributeUses, h, schema, scr.Attributes, \r
- scr.AnyAttribute, ref attributeWildcard, null, false);\r
- }\r
-\r
- // Common process of AttributeWildcard.\r
- if (localAnyAttribute != null) {\r
- this.attributeWildcard = localAnyAttribute;\r
- }\r
- else\r
- this.attributeWildcard = baseAnyAttribute;\r
- }\r
-\r
- // 3.4.6 Type Derivation OK (Complex)\r
- internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)\r
- {\r
- // AnyType derives from AnyType itself.\r
- if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)\r
- return;\r
-\r
- XmlSchemaType bst = b as XmlSchemaType;\r
- if (b == this) // 1 and 2.1\r
- return;\r
- if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.\r
- error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");\r
- // FIXME: here BaseSchemaType should be \r
- // BaseXmlSchemaType, however for some case it \r
- // seems not working.\r
- if (BaseSchemaType == b) // 2.2\r
- return;\r
- if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1\r
- error (h, "Derived type's base schema type is anyType.");\r
- return;\r
- }\r
- // 2.3.2.1\r
- XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;\r
- if (dbct != null) {\r
- dbct.ValidateTypeDerivationOK (b, h, schema);\r
- return;\r
- }\r
- // 2.3.2.2\r
- XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;\r
- if (dbst != null) {\r
- dbst.ValidateTypeDerivationOK (b, h, schema, true);\r
- return;\r
- }\r
- }\r
-\r
- // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)\r
- internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,\r
- ValidationEventHandler h, XmlSchema schema)\r
- {\r
- // 1.1\r
- if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
- error (h, "Derivation by extension is prohibited.");\r
- // 1.2\r
- foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
- XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;\r
- XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;\r
- if (da == null)\r
- error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");\r
- }\r
- // 1.3 -> 3.10.6 Wildcard Subset.\r
- if (AnyAttribute != null) {\r
- if (baseComplexType.AnyAttribute == null)\r
- error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");\r
- else\r
- baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);\r
- }\r
-\r
- // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).\r
- // 1.4.2.1\r
-// if (contentTypeParticle == null)\r
-// error (h, "Extended complex type's content type must not be empty.");\r
- // 1.4.2.2.1\r
- if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {\r
- // 1.4.2.2.2.1\r
- if (this.ContentType != baseComplexType.ContentType)\r
-// if (this.GetContentType (false) != baseComplexType.GetContentType (false))\r
- error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");\r
- // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)\r
- else if (this.contentTypeParticle == null ||\r
- !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {\r
- XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;\r
- if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))\r
- error (h, "Invalid complex content extension was found.");\r
- else {\r
- // Identical sequence item should be checked, but\r
- // I think it is naturally achieved as coded above.\r
- }\r
- }\r
- }\r
- }\r
-\r
- // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)\r
- internal void ValidateSimpleBaseDerivationValidExtension (object baseType,\r
- ValidationEventHandler h, XmlSchema schema)\r
- {\r
- XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;\r
- if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
- error (h, "Extension is prohibited by the base type.");\r
-\r
- XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;\r
- if (dt == null)\r
- dt = st.Datatype;\r
- if (dt != this.Datatype)\r
- error (h, "To extend simple type, a complex type must have the same content type as the base type.");\r
- }\r
-\r
- internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,\r
- ValidationEventHandler h, XmlSchema schema)\r
- {\r
- // 1.\r
- if (baseType == null) {\r
- error (h, "Base schema type is not a complex type.");\r
- return;\r
- }\r
- if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {\r
- error (h, "Prohibited derivation by restriction by base schema type.");\r
- return;\r
- }\r
-\r
- // 2.\r
- foreach (DictionaryEntry entry in this.AttributeUses) {\r
- XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
- XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;\r
- if (baseAttr != null) {\r
- // 2.1\r
- // 2.1.1\r
- if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)\r
- error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
- // 2.1.2\r
- XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;\r
- XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;\r
- bool typeError = false;\r
- if (attrSimpleType != null)\r
- attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);\r
- else if (attrSimpleType == null && baseAttrSimpleType != null)\r
- typeError = true;\r
- else {\r
- Type t1 = attr.AttributeType.GetType ();\r
- Type t2 = baseAttr.AttributeType.GetType ();\r
- if (t1 != t2 && t1.IsSubclassOf (t2))\r
- typeError = true;\r
- }\r
- if (typeError)\r
- error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");\r
- // 2.1.3\r
- if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)\r
- error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");\r
- } else {\r
- // 2.2\r
- if (baseType.AttributeWildcard != null)\r
- if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (\r
- attr.QualifiedName.Namespace, schema) &&\r
- !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))\r
- error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
- }\r
- }\r
- // I think 3. is considered in 2.\r
- // 4.\r
- if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {\r
- if (baseType.AttributeWildcard == null)\r
- error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");\r
- else\r
- AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);\r
- }\r
-\r
- // 5.\r
- if (this == AnyType)\r
- return;\r
- if (contentTypeParticle == XmlSchemaParticle.Empty) {\r
- // 5.1\r
- if (ContentType != XmlSchemaContentType.Empty) {\r
- // TODO: 5.1.1\r
-// XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;\r
- // 5.1.2\r
- if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())\r
- error (h, "Invalid content type derivation.");\r
-\r
- } else {\r
- // 5.2\r
- if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&\r
- !baseType.ContentTypeParticle.ValidateIsEmptiable ())\r
- error (h, "Invalid content type derivation.");\r
- }\r
- } else {\r
- // 5.3 => 3.9.6 Particle Valid (Restriction)\r
- if (baseType.ContentTypeParticle != null) {\r
- // 3.9.6 - 1 : same particle.\r
- // 3.9.6 - 2 is covered by using ActualParticle.\r
- if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))\r
- contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);\r
- }\r
- }\r
- }\r
-\r
-#region Read\r
- //<complexType\r
- // abstract = boolean : false\r
- // block = (#all | List of (extension | restriction)) \r
- // final = (#all | List of (extension | restriction)) \r
- // id = ID\r
- // mixed = boolean : false\r
- // name = NCName\r
- // {any attributes with non-schema namespace . . .}>\r
- // Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))\r
- //</complexType>\r
- internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)\r
- {\r
- XmlSchemaComplexType ctype = new XmlSchemaComplexType();\r
- reader.MoveToElement();\r
- Exception innerex;\r
-\r
- if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
- {\r
- error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
- reader.SkipToEnd();\r
- return null;\r
- }\r
-\r
- ctype.LineNumber = reader.LineNumber;\r
- ctype.LinePosition = reader.LinePosition;\r
- ctype.SourceUri = reader.BaseURI;\r
-\r
- while(reader.MoveToNextAttribute())\r
- {\r
- if(reader.Name == "abstract")\r
- {\r
- ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
- if(innerex != null)\r
- error(h,reader.Value + " is invalid value for abstract",innerex);\r
- }\r
- else if(reader.Name == "block")\r
- {\r
- ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",\r
- XmlSchemaUtil.ComplexTypeBlockAllowed);\r
- if(innerex != null)\r
- error (h,"some invalid values for block attribute were found",innerex);\r
- }\r
- else if(reader.Name == "final")\r
- {\r
- ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",\r
- XmlSchemaUtil.FinalAllowed);\r
- if(innerex != null)\r
- error (h,"some invalid values for final attribute were found",innerex);\r
- }\r
- else if(reader.Name == "id")\r
- {\r
- ctype.Id = reader.Value;\r
- }\r
- else if(reader.Name == "mixed")\r
- {\r
- ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
- if(innerex != null)\r
- error(h,reader.Value + " is invalid value for mixed",innerex);\r
- }\r
- else if(reader.Name == "name")\r
- {\r
- ctype.Name = reader.Value;\r
- }\r
- else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
- {\r
- error(h,reader.Name + " is not a valid attribute for complexType",null);\r
- }\r
- else\r
- {\r
- XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);\r
- }\r
- }\r
- \r
- reader.MoveToElement();\r
- if(reader.IsEmptyElement)\r
- return ctype;\r
-\r
- //Content: 1. annotation?, \r
- // 2. simpleContent | 2. complexContent | \r
- // (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))\r
- int level = 1;\r
- while(reader.ReadNextElement())\r
- {\r
- if(reader.NodeType == XmlNodeType.EndElement)\r
- {\r
- if(reader.LocalName != xmlname)\r
- error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
- break;\r
- }\r
- if(level <= 1 && reader.LocalName == "annotation")\r
- {\r
- level = 2; //Only one annotation\r
- XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
- if(annotation != null)\r
- ctype.Annotation = annotation;\r
- continue;\r
- }\r
- if(level <=2)\r
- {\r
- if(reader.LocalName == "simpleContent")\r
- {\r
- level = 6;\r
- XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);\r
- if(simple != null)\r
- ctype.ContentModel = simple;\r
- continue;\r
- }\r
- if(reader.LocalName == "complexContent")\r
- {\r
- level = 6;\r
- XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);\r
- if(complex != null)\r
- ctype.contentModel = complex;\r
- continue;\r
- }\r
- }\r
- if(level <= 3)\r
- {\r
- if(reader.LocalName == "group")\r
- {\r
- level = 4;\r
- XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);\r
- if(group != null)\r
- ctype.particle = group;\r
- continue;\r
- }\r
- if(reader.LocalName == "all")\r
- {\r
- level = 4;\r
- XmlSchemaAll all = XmlSchemaAll.Read(reader,h);\r
- if(all != null)\r
- ctype.particle = all;\r
- continue;\r
- }\r
- if(reader.LocalName == "choice")\r
- {\r
- level = 4;\r
- XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);\r
- if(choice != null)\r
- ctype.particle = choice;\r
- continue;\r
- }\r
- if(reader.LocalName == "sequence")\r
- {\r
- level = 4;\r
- XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);\r
- if(sequence != null)\r
- ctype.particle = sequence;\r
- continue;\r
- }\r
- }\r
- if(level <= 4)\r
- {\r
- if(reader.LocalName == "attribute")\r
- {\r
- level = 4;\r
- XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
- if(attr != null)\r
- ctype.Attributes.Add(attr);\r
- continue;\r
- }\r
- if(reader.LocalName == "attributeGroup")\r
- {\r
- level = 4;\r
- XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);\r
- if(attr != null)\r
- ctype.attributes.Add(attr);\r
- continue;\r
- }\r
- }\r
- if(level <= 5 && reader.LocalName == "anyAttribute")\r
- {\r
- level = 6;\r
- XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);\r
- if(anyattr != null)\r
- ctype.AnyAttribute = anyattr;\r
- continue;\r
- }\r
- reader.RaiseInvalidElementError();\r
- }\r
- return ctype;\r
- }\r
-#endregion\r
- }\r
-}\r
+ else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))
+ error (h, "Referenced base schema type is XML Schema datatype.");
+ else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
+ error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");
+ }
+ // Common to simpleContent
+ else {
+ // ContentType of {content type}
+ resolvedContentType = XmlSchemaContentType.TextOnly;
+
+ // 3.4.3 Complex Type Definition Representation OK :: 1.
+ // base
+ if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
+ baseComplexType = XmlSchemaComplexType.AnyType;
+
+ if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
+ error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);
+ } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {
+ error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);
+ } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
+ // do nothing for particle.
+ }
+ // otherwise, it might be missing sub components.
+ else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
+ error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");
+
+ // 3.4.3 Complex Type Definition Representation OK :: 2.
+ // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)
+ if (baseComplexType != null) {
+ if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {
+ // 2.1.1
+ // Here "baseComplexType.Particle != null" is required for error-ignorant case
+ } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {
+ // 2.1.2 && 2.2: OK
+ }
+ else
+ error (h, "Base complex type of a simple content restriction must be text only.");
+ } else {
+ if (sce != null && baseComplexType == null) {
+ // 2.1.3 : OK
+ }
+ else
+ error (h, "Not allowed base type of a simple content restriction.");
+ }
+ }
+
+ // complexType/complexContent/extension
+ if (cce != null) {
+ // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
+ // is constraining anything here, since 3.4.2 {attribute uses}
+ // defines as to include base type's attribute uses.
+ localAnyAttribute = cce.AnyAttribute;
+ if (baseComplexType != null) {
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+ }
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
+ }
+ // attributes
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+ this.attributeUses, h, schema, cce.Attributes,
+ cce.AnyAttribute , ref attributeWildcard, null, true);
+
+ // After adding them, test extension validity.
+ if (baseComplexType != null)
+ this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
+ else if (baseSimpleType != null)
+ this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
+ }
+ // complexType/complexContent/restriction
+ if (ccr != null) {
+ // For ValidationEventHandler.
+ if (baseComplexType == null)
+ baseComplexType = XmlSchemaComplexType.AnyType;
+
+ // attributes
+ localAnyAttribute = ccr.AnyAttribute;
+ this.attributeWildcard = localAnyAttribute;
+ if (baseComplexType != null)
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
+ if (baseAnyAttribute != null && localAnyAttribute != null)
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
+ localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
+
+ // 3.4.2 Complex Type Definition with complex content Schema Component
+ // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+ this.attributeUses, h, schema, ccr.Attributes,
+ ccr.AnyAttribute, ref attributeWildcard, null, false);
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+ if (attributeUses [attr.QualifiedName] == null)
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+ }
+
+ // Derivation Valid (Restriction, Complex) :: 5.
+ // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
+ // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
+ this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
+ }
+ // complexType/simpleContent/extension
+ if (sce != null) {
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+ this.attributeUses, h, schema, sce.Attributes,
+ sce.AnyAttribute, ref attributeWildcard, null, true);
+
+ // Attributes
+ // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
+ // is constraining anything here, since 3.4.2 {attribute uses}
+ // defines as to include base type's attribute uses.
+ localAnyAttribute = sce.AnyAttribute;
+
+ if (baseComplexType != null) {
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
+
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+#if BUGGY_MS_COMPLIANT
+ if (attr.Use != XmlSchemaUse.Prohibited)
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+#endif
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+ }
+ }
+ if (baseAnyAttribute != null && localAnyAttribute != null)
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
+ localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
+ }
+ // complexType/simpleContent/restriction
+ if (scr != null) {
+ // attributes
+ localAnyAttribute = scr.AnyAttribute;
+ this.attributeWildcard = localAnyAttribute;
+ if (baseComplexType != null)
+ baseAnyAttribute = baseComplexType.AttributeWildcard;
+ if (baseAnyAttribute != null && localAnyAttribute != null)
+ // 1.3 attribute wildcard subset. (=> 3.10.6)
+ localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
+ // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
+ // http://www.w3.org/2001/05/xmlschema-errata#Errata1
+
+ // 3.4.2 Complex Type Definition with simple content Schema Component
+ // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
+ errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+ this.attributeUses, h, schema, scr.Attributes,
+ scr.AnyAttribute, ref attributeWildcard, null, false);
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+ if (attributeUses [attr.QualifiedName] == null)
+ XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+ }
+ }
+
+ // Common process of AttributeWildcard.
+ if (localAnyAttribute != null) {
+ this.attributeWildcard = localAnyAttribute;
+ }
+ else
+ this.attributeWildcard = baseAnyAttribute;
+ }
+
+ // 3.4.6 Type Derivation OK (Complex)
+ internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
+ {
+ // AnyType derives from AnyType itself.
+ if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)
+ return;
+
+ XmlSchemaType bst = b as XmlSchemaType;
+ if (b == this) // 1 and 2.1
+ return;
+ if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.
+ error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
+ // FIXME: here BaseSchemaType should be
+ // BaseXmlSchemaType, however for some case it
+ // seems not working.
+ if (BaseSchemaType == b) // 2.2
+ return;
+ if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
+ error (h, "Derived type's base schema type is anyType.");
+ return;
+ }
+ // 2.3.2.1
+ XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;
+ if (dbct != null) {
+ dbct.ValidateTypeDerivationOK (b, h, schema);
+ return;
+ }
+ // 2.3.2.2
+ XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;
+ if (dbst != null) {
+ dbst.ValidateTypeDerivationOK (b, h, schema, true);
+ return;
+ }
+ }
+
+ // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)
+ internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
+ ValidationEventHandler h, XmlSchema schema)
+ {
+ // 1.1
+ if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
+ error (h, "Derivation by extension is prohibited.");
+ // 1.2
+ foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
+ XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;
+ XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
+ if (da == null)
+ error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
+ }
+ // 1.3 -> 3.10.6 Wildcard Subset.
+ if (AnyAttribute != null) {
+ if (baseComplexType.AnyAttribute == null)
+ error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
+ else
+ baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
+ }
+
+ // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
+ // 1.4.2.1
+// if (contentTypeParticle == null)
+// error (h, "Extended complex type's content type must not be empty.");
+ // 1.4.2.2.1
+ if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
+ // 1.4.2.2.2.1
+ if (this.ContentType != baseComplexType.ContentType)
+// if (this.GetContentType (false) != baseComplexType.GetContentType (false))
+ error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");
+ // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)
+ else if (this.contentTypeParticle == null ||
+ !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {
+ XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
+ if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))
+ error (h, "Invalid complex content extension was found.");
+ else {
+ // Identical sequence item should be checked, but
+ // I think it is naturally achieved as coded above.
+ }
+ }
+ }
+ }
+
+ // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)
+ internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
+ ValidationEventHandler h, XmlSchema schema)
+ {
+ XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
+ if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
+ error (h, "Extension is prohibited by the base type.");
+
+ XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
+ if (dt == null)
+ dt = st.Datatype;
+ if (dt != this.Datatype)
+ error (h, "To extend simple type, a complex type must have the same content type as the base type.");
+ }
+
+ internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
+ ValidationEventHandler h, XmlSchema schema)
+ {
+ // 1.
+ if (baseType == null) {
+ error (h, "Base schema type is not a complex type.");
+ return;
+ }
+ if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
+ error (h, "Prohibited derivation by restriction by base schema type.");
+ return;
+ }
+
+ // 2.
+ foreach (DictionaryEntry entry in this.AttributeUses) {
+ XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
+ XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;
+ if (baseAttr != null) {
+ // 2.1
+ // 2.1.1
+ if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)
+ error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
+ // 2.1.2
+ XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;
+ XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;
+ bool typeError = false;
+ if (attrSimpleType != null)
+ attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);
+ else if (attrSimpleType == null && baseAttrSimpleType != null)
+ typeError = true;
+ else {
+ Type t1 = attr.AttributeType.GetType ();
+ Type t2 = baseAttr.AttributeType.GetType ();
+ if (t1 != t2 && t1.IsSubclassOf (t2))
+ typeError = true;
+ }
+ if (typeError)
+ error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");
+ // 2.1.3
+ if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)
+ error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");
+ } else {
+ // 2.2
+ if (baseType.AttributeWildcard != null)
+ if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (
+ attr.QualifiedName.Namespace, schema) &&
+ !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))
+ error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
+ }
+ }
+ // I think 3. is considered in 2.
+ // 4.
+ if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {
+ if (baseType.AttributeWildcard == null)
+ error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");
+ else
+ AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);
+ }
+
+ // 5.
+ if (this == AnyType)
+ return;
+ if (contentTypeParticle == XmlSchemaParticle.Empty) {
+ // 5.1
+ if (ContentType != XmlSchemaContentType.Empty) {
+ // TODO: 5.1.1
+// XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;
+ // 5.1.2
+ if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())
+ error (h, "Invalid content type derivation.");
+
+ } else {
+ // 5.2
+ if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
+ !baseType.ContentTypeParticle.ValidateIsEmptiable ())
+ error (h, "Invalid content type derivation.");
+ }
+ } else {
+ // 5.3 => 3.9.6 Particle Valid (Restriction)
+ if (baseType.ContentTypeParticle != null) {
+ // 3.9.6 - 1 : same particle.
+ // 3.9.6 - 2 is covered by using ActualParticle.
+ if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))
+ contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);
+ }
+ }
+ }
+
+#region Read
+ //<complexType
+ // abstract = boolean : false
+ // block = (#all | List of (extension | restriction))
+ // final = (#all | List of (extension | restriction))
+ // id = ID
+ // mixed = boolean : false
+ // name = NCName
+ // {any attributes with non-schema namespace . . .}>
+ // Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
+ //</complexType>
+ internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)
+ {
+ XmlSchemaComplexType ctype = new XmlSchemaComplexType();
+ reader.MoveToElement();
+ Exception innerex;
+
+ if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
+ {
+ error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);
+ reader.SkipToEnd();
+ return null;
+ }
+
+ ctype.LineNumber = reader.LineNumber;
+ ctype.LinePosition = reader.LinePosition;
+ ctype.SourceUri = reader.BaseURI;
+
+ while(reader.MoveToNextAttribute())
+ {
+ if(reader.Name == "abstract")
+ {
+ ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
+ if(innerex != null)
+ error(h,reader.Value + " is invalid value for abstract",innerex);
+ }
+ else if(reader.Name == "block")
+ {
+ ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
+ XmlSchemaUtil.ComplexTypeBlockAllowed);
+ if(innerex != null)
+ error (h,"some invalid values for block attribute were found",innerex);
+ }
+ else if(reader.Name == "final")
+ {
+ ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
+ XmlSchemaUtil.FinalAllowed);
+ if(innerex != null)
+ error (h,"some invalid values for final attribute were found",innerex);
+ }
+ else if(reader.Name == "id")
+ {
+ ctype.Id = reader.Value;
+ }
+ else if(reader.Name == "mixed")
+ {
+ ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
+ if(innerex != null)
+ error(h,reader.Value + " is invalid value for mixed",innerex);
+ }
+ else if(reader.Name == "name")
+ {
+ ctype.Name = reader.Value;
+ }
+ else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
+ {
+ error(h,reader.Name + " is not a valid attribute for complexType",null);
+ }
+ else
+ {
+ XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);
+ }
+ }
+
+ reader.MoveToElement();
+ if(reader.IsEmptyElement)
+ return ctype;
+
+ //Content: 1. annotation?,
+ // 2. simpleContent | 2. complexContent |
+ // (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))
+ int level = 1;
+ while(reader.ReadNextElement())
+ {
+ if(reader.NodeType == XmlNodeType.EndElement)
+ {
+ if(reader.LocalName != xmlname)
+ error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);
+ break;
+ }
+ if(level <= 1 && reader.LocalName == "annotation")
+ {
+ level = 2; //Only one annotation
+ XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
+ if(annotation != null)
+ ctype.Annotation = annotation;
+ continue;
+ }
+ if(level <=2)
+ {
+ if(reader.LocalName == "simpleContent")
+ {
+ level = 6;
+ XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);
+ if(simple != null)
+ ctype.ContentModel = simple;
+ continue;
+ }
+ if(reader.LocalName == "complexContent")
+ {
+ level = 6;
+ XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);
+ if(complex != null)
+ ctype.contentModel = complex;
+ continue;
+ }
+ }
+ if(level <= 3)
+ {
+ if(reader.LocalName == "group")
+ {
+ level = 4;
+ XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
+ if(group != null)
+ ctype.particle = group;
+ continue;
+ }
+ if(reader.LocalName == "all")
+ {
+ level = 4;
+ XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
+ if(all != null)
+ ctype.particle = all;
+ continue;
+ }
+ if(reader.LocalName == "choice")
+ {
+ level = 4;
+ XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
+ if(choice != null)
+ ctype.particle = choice;
+ continue;
+ }
+ if(reader.LocalName == "sequence")
+ {
+ level = 4;
+ XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
+ if(sequence != null)
+ ctype.particle = sequence;
+ continue;
+ }
+ }
+ if(level <= 4)
+ {
+ if(reader.LocalName == "attribute")
+ {
+ level = 4;
+ XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
+ if(attr != null)
+ ctype.Attributes.Add(attr);
+ continue;
+ }
+ if(reader.LocalName == "attributeGroup")
+ {
+ level = 4;
+ XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
+ if(attr != null)
+ ctype.attributes.Add(attr);
+ continue;
+ }
+ }
+ if(level <= 5 && reader.LocalName == "anyAttribute")
+ {
+ level = 6;
+ XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
+ if(anyattr != null)
+ ctype.AnyAttribute = anyattr;
+ continue;
+ }
+ reader.RaiseInvalidElementError();
+ }
+ return ctype;
+ }
+#endregion
+ }
+}