2006-07-27 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaElement.cs
old mode 100755 (executable)
new mode 100644 (file)
index 2979211..944a270
@@ -1,6 +1,33 @@
-// Author: Dwivedi, Ajay kumar\r
-//            Adwiv@Yahoo.com\r
+//\r
+// System.Xml.Schema.XmlSchemaElement.cs\r
+//\r
+// Authors:\r
+//     Dwivedi, Ajay kumar  Adwiv@Yahoo.com\r
+//     Enomoto, Atsushi     ginga@kit.hi-ho.ne.jp\r
+//\r
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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.Xml.Serialization;\r
 using System.ComponentModel;\r
@@ -13,38 +40,66 @@ namespace System.Xml.Schema
        public class XmlSchemaElement : XmlSchemaParticle\r
        {\r
                private XmlSchemaDerivationMethod block;\r
-               private XmlSchemaDerivationMethod blockResolved;\r
                private XmlSchemaObjectCollection constraints;\r
                private string defaultValue;\r
                private object elementType;\r
+#if NET_2_0\r
+               private XmlSchemaType elementSchemaType;\r
+#endif\r
                private XmlSchemaDerivationMethod final;\r
-               private XmlSchemaDerivationMethod finalResolved;\r
                private string fixedValue;\r
                private XmlSchemaForm form;\r
                private bool isAbstract;\r
                private bool isNillable;\r
                private string name;\r
-               private XmlQualifiedName qName;\r
                private XmlQualifiedName refName;\r
                private XmlSchemaType schemaType;\r
                private XmlQualifiedName schemaTypeName;\r
                private XmlQualifiedName substitutionGroup;\r
+\r
+               // Post compilation items.\r
+               XmlSchema schema;\r
                internal bool parentIsSchema = false;\r
-               private string targetNamespace;\r
-               private string hash;\r
+               private XmlQualifiedName qName;\r
+               private XmlSchemaDerivationMethod blockResolved;\r
+               private XmlSchemaDerivationMethod finalResolved;\r
+//             private XmlSchemaParticle substChoice;\r
+               private XmlSchemaElement referencedElement;\r
+               private ArrayList substitutingElements = new ArrayList ();\r
+               private XmlSchemaElement substitutionGroupElement;\r
+               private bool actualIsAbstract;\r
+               private bool actualIsNillable;\r
+               private string validatedDefaultValue;\r
+               private string validatedFixedValue;\r
 \r
-               private static string xmlname = "element";\r
+               const string xmlname = "element";\r
 \r
                public XmlSchemaElement()\r
                {\r
                        block = XmlSchemaDerivationMethod.None;\r
                        final = XmlSchemaDerivationMethod.None;\r
                        constraints = new XmlSchemaObjectCollection();\r
-                       qName = XmlQualifiedName.Empty;\r
                        refName = XmlQualifiedName.Empty;\r
                        schemaTypeName = XmlQualifiedName.Empty;\r
                        substitutionGroup = XmlQualifiedName.Empty;\r
-                       substitutionGroup = XmlQualifiedName.Empty;\r
+                       InitPostCompileInformations ();\r
+               }\r
+\r
+               private void InitPostCompileInformations ()\r
+               {\r
+                       qName = XmlQualifiedName.Empty;\r
+                       schema = null;\r
+//                     parentIsSchema = false; ... it is set in Schema's Compile()\r
+                       blockResolved = XmlSchemaDerivationMethod.None;\r
+                       finalResolved = XmlSchemaDerivationMethod.None;\r
+//                     substChoice = null;\r
+                       referencedElement = null;\r
+                       substitutingElements.Clear ();\r
+                       substitutionGroupElement = null;\r
+                       actualIsAbstract = false;\r
+                       actualIsNillable = false;\r
+                       validatedDefaultValue = null;\r
+                       validatedFixedValue = null;\r
                }\r
 \r
                #region Attributes\r
@@ -96,7 +151,7 @@ namespace System.Xml.Schema
                        set{ form = value; }\r
                }\r
 \r
-               [DefaultValue(null)]\r
+               [DefaultValue("")]\r
                [System.Xml.Serialization.XmlAttribute("name")]\r
                public string Name \r
                {\r
@@ -132,23 +187,28 @@ namespace System.Xml.Schema
                        get{ return  schemaTypeName; }\r
                        set{ schemaTypeName = value; }\r
                }\r
+               #endregion\r
 \r
-               [XmlElement("simpleType",typeof(XmlSchemaSimpleType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
-               [XmlElement("complexType",typeof(XmlSchemaComplexType),Namespace="http://www.w3.org/2001/XMLSchema")]\r
+               #region Elements\r
+\r
+               [XmlElement("simpleType",typeof(XmlSchemaSimpleType))]\r
+               [XmlElement("complexType",typeof(XmlSchemaComplexType))]\r
                public XmlSchemaType SchemaType \r
                {\r
                        get{ return  schemaType; }\r
                        set{ schemaType = value; }\r
                }\r
 \r
-               [XmlElement("unique",typeof(XmlSchemaUnique),Namespace="http://www.w3.org/2001/XMLSchema")]\r
-               [XmlElement("key",typeof(XmlSchemaKey),Namespace="http://www.w3.org/2001/XMLSchema")]\r
-               [XmlElement("keyref",typeof(XmlSchemaKeyref),Namespace="http://www.w3.org/2001/XMLSchema")]\r
+               [XmlElement("unique",typeof(XmlSchemaUnique))]\r
+               [XmlElement("key",typeof(XmlSchemaKey))]\r
+               [XmlElement("keyref",typeof(XmlSchemaKeyref))]\r
                public XmlSchemaObjectCollection Constraints \r
                {\r
                        get{ return constraints; }\r
                }\r
+               #endregion\r
 \r
+               #region Post Compilation Schema Info\r
                [XmlIgnore]\r
                public XmlQualifiedName QualifiedName \r
                {\r
@@ -156,21 +216,108 @@ namespace System.Xml.Schema
                }\r
 \r
                [XmlIgnore]\r
+#if NET_2_0\r
+               [Obsolete]\r
+#endif\r
                public object ElementType \r
                {\r
-                       get{ return elementType; }\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ElementType;\r
+                               else\r
+                                       return elementType;\r
+                       }\r
                }\r
-               \r
+\r
+#if NET_2_0\r
+               [XmlIgnore]\r
+               public XmlSchemaType ElementSchemaType\r
+               {\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ElementSchemaType;\r
+                               else\r
+                                       return elementSchemaType;\r
+                       }\r
+               }\r
+#endif\r
+\r
                [XmlIgnore]\r
                public XmlSchemaDerivationMethod BlockResolved \r
                {\r
-                       get{ return blockResolved; }\r
+                       get{\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.BlockResolved;\r
+                               else\r
+                                       return blockResolved;\r
+                       }\r
                }\r
                \r
                [XmlIgnore]\r
                public XmlSchemaDerivationMethod FinalResolved \r
                {\r
-                       get{ return finalResolved; }\r
+                       get{\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.FinalResolved;\r
+                               else\r
+                                       return finalResolved;\r
+                       }\r
+               }\r
+\r
+               internal bool ActualIsNillable {\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ActualIsNillable;\r
+                               else\r
+                                       return actualIsNillable;\r
+                       }\r
+               }\r
+               \r
+               internal bool ActualIsAbstract {\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ActualIsAbstract;\r
+                               else\r
+                                       return actualIsAbstract;\r
+                       }\r
+               }\r
+               \r
+               // Post compilation default value (normalized)\r
+               internal string ValidatedDefaultValue {\r
+                       get{\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ValidatedDefaultValue;\r
+                               else\r
+                                       return validatedDefaultValue;\r
+                       }\r
+               }\r
+\r
+               // Post compilation fixed value (normalized)\r
+               internal string ValidatedFixedValue {\r
+                       get{\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.ValidatedFixedValue;\r
+                               else\r
+                                       return validatedFixedValue;\r
+                       }\r
+               }\r
+\r
+               internal ArrayList SubstitutingElements {\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.SubstitutingElements;\r
+                               else\r
+                                       return this.substitutingElements;\r
+                       }\r
+               }\r
+\r
+               internal XmlSchemaElement SubstitutionGroupElement {\r
+                       get {\r
+                               if (referencedElement != null)\r
+                                       return referencedElement.SubstitutionGroupElement;\r
+                               else\r
+                                       return substitutionGroupElement;\r
+                       }\r
                }\r
 \r
                #endregion\r
@@ -200,17 +347,24 @@ namespace System.Xml.Schema
                ///             5. abstract is prohibited\r
                ///             6. default and fixed must not both be present.(Actually both are absent)\r
                /// </remarks>  \r
-               [MonoTODO]\r
-               internal int Compile(ValidationEventHandler h, XmlSchema schema)\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
+                       if (CompilationId == schema.CompilationId)\r
                                return 0;\r
+                       InitPostCompileInformations ();\r
+                       this.schema = schema;\r
+#if NET_2_0\r
+                       if (SchemaType != null)\r
+                               SchemaType.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Constraints)\r
+                               obj.Parent = this;\r
+#endif\r
 \r
                        if(this.defaultValue != null && this.fixedValue != null)\r
                                error(h,"both default and fixed can't be present");\r
 \r
-                       if(parentIsSchema)\r
+                       if(parentIsSchema || isRedefineChild)\r
                        {\r
                                if(this.refName != null && !RefName.IsEmpty)\r
                                        error(h,"ref must be absent");\r
@@ -220,8 +374,8 @@ namespace System.Xml.Schema
                                else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2\r
                                        error(h,"attribute name must be NCName");\r
                                else\r
-                                       this.qName = new XmlQualifiedName(this.name, schema.TargetNamespace);\r
-                               \r
+                                       this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);\r
+\r
                                if(form != XmlSchemaForm.None)\r
                                        error(h,"form must be absent");\r
                                if(MinOccursString != null)\r
@@ -233,28 +387,15 @@ namespace System.Xml.Schema
                                if(final == XmlSchemaDerivationMethod.All)\r
                                        finalResolved = allfinal;\r
                                else if(final == XmlSchemaDerivationMethod.None)\r
-                                       finalResolved = allfinal;\r
+                                       finalResolved = XmlSchemaDerivationMethod.Empty;\r
                                else \r
                                {\r
-                                       if((final & ~allfinal) != 0)\r
-                                               warn(h,"some values for final are invalid in this context");\r
+//                                     if((final & ~allfinal) != 0)\r
+                                       if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)\r
+                                               error (h,"some values for final are invalid in this context");\r
                                        finalResolved = final & allfinal;\r
                                }\r
 \r
-                               XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension | \r
-                                       XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;\r
-\r
-                               if(block == XmlSchemaDerivationMethod.All)\r
-                                       blockResolved = allblock;\r
-                               else if(block == XmlSchemaDerivationMethod.None)\r
-                                       blockResolved = allblock;\r
-                               else\r
-                               {\r
-                                       if((block & ~allblock) != 0)\r
-                                               warn(h,"Some of the values for block are invalid in this context");\r
-                                       blockResolved = block & allblock;\r
-                               }\r
-\r
                                if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)\r
                                {\r
                                        error(h,"both schemaType and content can't be present");\r
@@ -301,41 +442,23 @@ namespace System.Xml.Schema
                                        error(h,"substitutionGroup must be absent");\r
                                if(final != XmlSchemaDerivationMethod.None)\r
                                        error(h,"final must be absent");\r
-                               if(isAbstract)\r
-                                       error(h,"abstract must be absent");\r
 \r
-                               //FIXME: Should we reset the values\r
-                               if(MinOccurs > MaxOccurs)\r
-                                       error(h,"minOccurs must be less than or equal to maxOccurs");\r
+                               CompileOccurence (h, schema);\r
 \r
                                if(refName == null || RefName.IsEmpty)\r
                                {\r
+                                       string targetNamespace = String.Empty;\r
+\r
                                        if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))\r
-                                               this.targetNamespace = schema.TargetNamespace;\r
-                                       else\r
-                                               this.targetNamespace = string.Empty;\r
+                                               targetNamespace = schema.TargetNamespace;\r
 \r
                                        if(this.name == null)   //b1\r
                                                error(h,"Required attribute name must be present");\r
                                        else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2\r
                                                error(h,"attribute name must be NCName");\r
                                        else\r
-                                               this.qName = new XmlQualifiedName(this.name, this.targetNamespace);\r
+                                               this.qName = new XmlQualifiedName(this.name, targetNamespace);\r
                                \r
-                                       XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension | \r
-                                               XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;\r
-\r
-                                       if(block == XmlSchemaDerivationMethod.All)\r
-                                               blockResolved = allblock;\r
-                                       else if(block == XmlSchemaDerivationMethod.None)\r
-                                               blockResolved = allblock;\r
-                                       else\r
-                                       {\r
-                                               if((block & ~allblock) != 0)\r
-                                                       warn(h,"Some of the values for block are invalid in this context");\r
-                                               blockResolved = block & allblock;\r
-                                       }\r
-\r
                                        if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)\r
                                        {\r
                                                error(h,"both schemaType and content can't be present");\r
@@ -401,40 +524,472 @@ namespace System.Xml.Schema
                                                error(h,"simpleType or complexType must be absent");\r
 \r
                                        qName = RefName;\r
-                                       schema.MissingElementTypeRefs.Add (this, qName);\r
                                }\r
                        }\r
 \r
-                       // PSVI contribution for XmlSchemaElement\r
-                       if(refName == null || RefName.IsEmpty) {\r
-                               if (this.schemaType != null)\r
-                                       this.elementType = schemaType;\r
-                               else {\r
-                                       XmlSchemaType xsType = schema.SchemaTypes [schemaTypeName] as XmlSchemaType;\r
-                                       if (xsType != null)\r
-                                               this.elementType = xsType;\r
-                                       else\r
-                                               this.elementType = XmlSchemaDatatype.FromName (schemaTypeName);\r
+                       switch (block) {\r
+                       case XmlSchemaDerivationMethod.All:\r
+                               blockResolved = XmlSchemaDerivationMethod.All;\r
+                               break;\r
+                       case XmlSchemaDerivationMethod.None:\r
+                               blockResolved = XmlSchemaDerivationMethod.Empty;\r
+                               break;\r
+                       default:\r
+                               if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)\r
+                                       error (h,"Some of the values for block are invalid in this context");\r
+                               blockResolved = block;\r
+                               break;\r
+                       }\r
+\r
+                       if (Constraints != null) {\r
+                               XmlSchemaObjectTable table = new XmlSchemaObjectTable ();\r
+                               foreach (XmlSchemaIdentityConstraint c in Constraints) {\r
+                                       XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);\r
                                }\r
                        }\r
-               \r
+\r
                        XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
 \r
                        this.CompilationId = schema.CompilationId;\r
                        return errorCount;\r
                }\r
 \r
-               internal void SetReferedElementInfo (XmlSchemaElement element)\r
+               [MonoTODO ("Return clone in case when it returns itself")]\r
+               internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)\r
+               {\r
+                       if (OptimizedParticle != null)\r
+                               return OptimizedParticle;\r
+                       if (RefName != null && RefName != XmlQualifiedName.Empty) {\r
+                               referencedElement = schema.Elements [RefName] as XmlSchemaElement;\r
+                       }\r
+\r
+//                     if (this.referencedElement != null)\r
+//                             OptimizedParticle = referencedElement.GetOptimizedParticle (isTop);\r
+//                     else \r
+                       if (ValidatedMaxOccurs == 0)\r
+                               OptimizedParticle = XmlSchemaParticle.Empty;\r
+                       // Substitution Group\r
+                       else if (SubstitutingElements != null && SubstitutingElements.Count > 0) {\r
+                               XmlSchemaChoice choice = new XmlSchemaChoice ();\r
+                               choice.MinOccurs = MinOccurs;\r
+                               choice.MaxOccurs = MaxOccurs;\r
+//                             substChoice = choice;\r
+                               choice.Compile (null, schema); // compute Validated Min/Max Occurs.\r
+                               XmlSchemaElement item = this.MemberwiseClone () as XmlSchemaElement;\r
+                               item.MinOccurs = 1;\r
+                               item.MaxOccurs = 1;\r
+                               item.substitutionGroupElement = null;\r
+                               item.substitutingElements = null;\r
+                               for (int i = 0; i < SubstitutingElements.Count; i++) {\r
+                                       XmlSchemaElement se = SubstitutingElements [i] as XmlSchemaElement;\r
+//                                     choice.Items.Add (se);\r
+//                                     choice.CompiledItems.Add (se);\r
+                                       this.AddSubstElementRecursively (choice.Items, se);\r
+                                       this.AddSubstElementRecursively (choice.CompiledItems, se);\r
+                               }\r
+                               if (!choice.Items.Contains (item)) {\r
+                                       choice.Items.Add (item);\r
+                                       choice.CompiledItems.Add (item);\r
+                               }\r
+                               OptimizedParticle = choice;\r
+                       }\r
+                       else\r
+                               OptimizedParticle = this;//.MemberwiseClone () as XmlSchemaElement;\r
+                       return OptimizedParticle;\r
+               }\r
+\r
+               private void AddSubstElementRecursively (XmlSchemaObjectCollection col, XmlSchemaElement el)\r
                {\r
-                       this.elementType = element.elementType;\r
+                       if (el.SubstitutingElements != null)\r
+                               for (int i = 0; i < el.SubstitutingElements.Count; i++)\r
+                                       this.AddSubstElementRecursively (col, el.SubstitutingElements [i] as XmlSchemaElement);\r
+                       if (!col.Contains (el))\r
+                               col.Add (el);\r
                }\r
-               \r
-               [MonoTODO]\r
-               internal int Validate(ValidationEventHandler h)\r
+\r
+               internal void FillSubstitutionElementInfo ()\r
                {\r
+                       if (this.substitutionGroupElement != null)\r
+                               return;\r
+\r
+                       if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
+                               XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;\r
+                               this.substitutionGroupElement = substElem;\r
+                               if (substElem != null)\r
+                                       substElem.substitutingElements.Add (this);\r
+                       }\r
+               }\r
+\r
+               internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
+               {\r
+                       if (IsValidated (schema.CompilationId))\r
+                               return errorCount;\r
+\r
+                       // See XML Schema Structures 3.6 for the complete description.\r
+\r
+                       // Element Declaration Properties Correct\r
+                       // 1. = 3.3.1 (modulo 5.3)\r
+\r
+                       // 3.3.1:\r
+                       // {annotation} is as is.\r
+                       // {name}, {target namespace}, {scope}, {disallowed substitution},\r
+                       // {substitution group exclusions} (handled the same as 'disallowed substitution')\r
+                       // and {identity-constraint-definitions} are Compile()d.\r
+                       // {value constraint} is going to be filled in step 2.\r
+\r
+                       // actual {nillable}, {abstract} \r
+                       this.actualIsNillable = IsNillable;\r
+                       this.actualIsAbstract = IsAbstract;\r
+\r
+                       // Before determining element type, we need to validate substituting element\r
+                       if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
+                               XmlSchemaElement substElem = substitutionGroupElement;\r
+                               if (substElem != null)\r
+                                       substElem.Validate (h, schema);\r
+                       }\r
+\r
+                       // {type} from here\r
+                       XmlSchemaDatatype datatype = null;\r
+                       if (schemaType != null)\r
+                               elementType = schemaType;\r
+                       else if (SchemaTypeName != XmlQualifiedName.Empty) {\r
+                               XmlSchemaType type = schema.FindSchemaType (SchemaTypeName);\r
+                               if (type != null) {\r
+                                       type.Validate (h, schema);\r
+                                       elementType = type;\r
+                               }\r
+                               else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
+                                       elementType = XmlSchemaComplexType.AnyType;
+                               else if (XmlSchemaUtil.IsBuiltInDatatypeName (SchemaTypeName)) {\r
+                                       datatype = XmlSchemaDatatype.FromName (SchemaTypeName);\r
+                                       if (datatype == null)\r
+                                               error (h, "Invalid schema datatype was specified.");\r
+                                       else\r
+                                               elementType = datatype;\r
+                               }\r
+                               // otherwise, it might be missing sub components.\r
+                               else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))\r
+                                       error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");\r
+                       }\r
+                       else if (RefName != XmlQualifiedName.Empty)\r
+                       {\r
+                               XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;\r
+                               // If el is null, then it is missing sub components .\r
+                               if (refElem != null) {\r
+                                       this.referencedElement = refElem;\r
+                                       errorCount += refElem.Validate (h, schema);\r
+                               }\r
+                               // otherwise, it might be missing sub components.\r
+                               else if (!schema.IsNamespaceAbsent (RefName.Namespace))\r
+                                       error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");\r
+                       }\r
+                       \r
+                       // Otherwise if there are substitution group, then the type of the substitution group element.\r
+                       if (referencedElement == null) {\r
+                               if (elementType == null && this.substitutionGroupElement != null)\r
+                                       elementType = substitutionGroupElement.ElementType;\r
+                               // Otherwise, the -ur type- definition.\r
+                               if (elementType == null)\r
+                                       elementType = XmlSchemaComplexType.AnyType;\r
+                       }\r
+\r
+                       XmlSchemaType xsType = elementType as XmlSchemaType;\r
+                       if (xsType != null) {\r
+                               errorCount += xsType.Validate (h, schema);\r
+                               datatype = xsType.Datatype;\r
+                       }\r
+                       // basic {type} is now filled, except for derivation by {substitution group}.\r
+\r
+                       // {substitution group affiliation}\r
+                       // 3. subsitution group's type derivation check.\r
+                       if (this.SubstitutionGroup != XmlQualifiedName.Empty) {\r
+                               XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;\r
+                               // If el is null, then it is missing sub components .\r
+                               if (substElem != null) {\r
+                                       XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;\r
+                                       if (substSchemaType != null) {\r
+                                               // 3.3.6 Properties Correct 3.\r
+                                               if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)\r
+                                                       error (h, "Substituted element blocks substitution.");\r
+                                               if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)\r
+                                                       error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");\r
+                                       }\r
+                                       XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;\r
+                                       if (xsComplexType != null)\r
+                                               xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);\r
+                                       else {\r
+                                               XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;\r
+                                               if (xsSimpleType != null)\r
+                                                       xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);\r
+                                       }\r
+\r
+                               }\r
+                               // otherwise, it might be missing sub components.\r
+                               else if (!schema.IsNamespaceAbsent (SubstitutionGroup.Namespace))\r
+                                       error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");\r
+                       }\r
+\r
+                       // 2. ElementDefaultValid\r
+                       // 4. ID with {value constraint} is prohibited.\r
+                       if (defaultValue != null || fixedValue != null) {\r
+                               ValidateElementDefaultValidImmediate (h, schema);\r
+                               if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.\r
+                                       datatype.TokenizedType == XmlTokenizedType.ID)\r
+                                       error (h, "Element type is ID, which does not allows default or fixed values.");\r
+                       }\r
+\r
+                       // Identity constraints (3.11.3 / 3.11.6)\r
+                       foreach (XmlSchemaIdentityConstraint ident in Constraints)\r
+                               ident.Validate (h, schema);\r
+\r
+#if NET_2_0\r
+                       if (elementType != null) {\r
+                               elementSchemaType = elementType as XmlSchemaType;\r
+                               if (elementType == XmlSchemaSimpleType.AnySimpleType)\r
+                                       elementSchemaType = XmlSchemaSimpleType.XsAnySimpleType;\r
+                               if (elementSchemaType == null)\r
+                                       elementSchemaType = XmlSchemaType.GetBuiltInSimpleType (SchemaTypeName);\r
+                       }\r
+#endif\r
+\r
+                       ValidationId = schema.ValidationId;\r
                        return errorCount;\r
                }\r
 \r
+               internal override bool ParticleEquals (XmlSchemaParticle other)\r
+               {\r
+                       XmlSchemaElement element = other as XmlSchemaElement;\r
+                       if (element == null)\r
+                               return false;\r
+                       if (this.ValidatedMaxOccurs != element.ValidatedMaxOccurs ||\r
+                               this.ValidatedMinOccurs != element.ValidatedMinOccurs)\r
+                               return false;\r
+                       if (this.QualifiedName != element.QualifiedName ||\r
+                               this.ElementType != element.ElementType ||\r
+                               this.Constraints.Count != element.Constraints.Count)\r
+                               return false;\r
+                       for (int i = 0; i < this.Constraints.Count; i++) {\r
+                               XmlSchemaIdentityConstraint c1 = Constraints [i] as XmlSchemaIdentityConstraint;\r
+                               XmlSchemaIdentityConstraint c2 = element.Constraints [i] as XmlSchemaIdentityConstraint;\r
+                               if (c1.QualifiedName != c2.QualifiedName ||\r
+                                       c1.Selector.XPath != c2.Selector.XPath ||\r
+                                       c1.Fields.Count != c2.Fields.Count)\r
+                                       return false;\r
+                               for (int f = 0; f < c1.Fields.Count; f++) {\r
+                                       XmlSchemaXPath f1 = c1.Fields [f] as XmlSchemaXPath;\r
+                                       XmlSchemaXPath f2 = c2.Fields [f] as XmlSchemaXPath;\r
+                                       if (f1.XPath != f2.XPath)\r
+                                               return false;\r
+                               }\r
+                       }\r
+                       if (this.BlockResolved != element.BlockResolved ||\r
+                               this.FinalResolved != element.FinalResolved ||\r
+                               this.ValidatedDefaultValue != element.ValidatedDefaultValue ||\r
+                               this.ValidatedFixedValue != element.ValidatedFixedValue)\r
+                               return false;\r
+                       return true;\r
+               }\r
+\r
+               internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
+                       ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
+               {\r
+                       // element - NameAndTypeOK\r
+                       XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;\r
+                       if (baseElement != null) {\r
+                               return ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema, raiseError);\r
+                       }\r
+\r
+                       // any - NSCompat\r
+                       XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;\r
+                       if (baseAny != null) {\r
+                               // NSCompat\r
+                               if (!baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, raiseError))\r
+                                       return false;\r
+                               return ValidateOccurenceRangeOK (baseAny, h, schema, raiseError);\r
+                       }\r
+\r
+//*\r
+                       // choice - RecurseAsIfGroup\r
+                       XmlSchemaGroupBase gb = null;\r
+                       if (baseParticle is XmlSchemaSequence)\r
+                               gb = new XmlSchemaSequence ();\r
+                       else if (baseParticle is XmlSchemaChoice)\r
+                               gb = new XmlSchemaChoice ();\r
+                       else if (baseParticle is XmlSchemaAll)\r
+                               gb = new XmlSchemaAll ();\r
+\r
+                       if (gb != null) {\r
+                               gb.Items.Add (this);\r
+                               gb.Compile (h, schema);\r
+                               gb.Validate (h, schema);\r
+                               // It looks weird, but here we never think about \r
+                               // _pointlessness_ of this groupbase particle.\r
+                               return gb.ValidateDerivationByRestriction (baseParticle, h, schema, raiseError);\r
+                       }\r
+//*/\r
+                       return true;\r
+               }\r
+\r
+               private bool ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,\r
+                       ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
+               {\r
+                       // 1.\r
+                       if (this.QualifiedName != baseElement.QualifiedName) {\r
+                               if (raiseError)\r
+                                       error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");\r
+                               return false;\r
+                       }\r
+                       // 2.\r
+                       if (this.isNillable && !baseElement.isNillable) {\r
+                               if (raiseError)\r
+                                       error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");\r
+                               return false;\r
+                       }\r
+                       // 3.\r
+                       if (!ValidateOccurenceRangeOK (baseElement, h, schema, raiseError))\r
+                               return false;\r
+                       // 4.\r
+                       if (baseElement.ValidatedFixedValue != null &&\r
+                               baseElement.ValidatedFixedValue != this.ValidatedFixedValue) {\r
+                               if (raiseError)\r
+                                       error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");\r
+                               return false;\r
+                       }\r
+                       // 5. TODO: What is "identity constraints subset" ???\r
+\r
+                       // 6. \r
+                       if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved) {\r
+                               if (raiseError)\r
+                                       error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");\r
+                               return false;\r
+                       }\r
+                       // 7.\r
+                       if (baseElement.ElementType != null) {\r
+                               XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;\r
+                               if (derivedCType != null) {\r
+                                       // FIXME: W3C REC says that it is Type Derivation OK to be check, but\r
+                                       // in fact it should be DerivationValid (Restriction, Complex).\r
+                                       derivedCType.ValidateDerivationValidRestriction (\r
+                                               baseElement.ElementType as XmlSchemaComplexType, h, schema);\r
+                                       derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);\r
+                               } else {\r
+                                       XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;\r
+                                       if (derivedSType != null)\r
+                                               derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);\r
+                                       else if (baseElement.ElementType != XmlSchemaComplexType.AnyType && baseElement.ElementType != this.ElementType) {\r
+                                               if (raiseError)\r
+                                                       error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");\r
+                                               return false;\r
+                                       }\r
+                               }\r
+                       }\r
+                       return true;\r
+               }\r
+\r
+               internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)\r
+               {\r
+                       XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;\r
+                       if (ct == null || ct.Particle == null)\r
+                               return;\r
+                       ct.Particle.CheckRecursion (depth + 1, h, schema);\r
+               }\r
+\r
+               internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,\r
+                       ValidationEventHandler h, XmlSchema schema)\r
+               {\r
+                       if (qnames.Contains (this.QualifiedName))// && !this.ParticleEquals ((XmlSchemaParticle) qnames [this.QualifiedName]))\r
+                               error (h, "Ambiguous element label was detected: " + this.QualifiedName);\r
+                       else {\r
+                               foreach (XmlSchemaAny any in nsNames) {\r
+                                       if (any.ValidatedMaxOccurs == 0)\r
+                                               continue;\r
+                                       if (any.HasValueAny ||\r
+                                               any.HasValueLocal && this.QualifiedName.Namespace == "" ||\r
+                                               any.HasValueOther && this.QualifiedName.Namespace != this.QualifiedName.Namespace ||\r
+                                               any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.QualifiedName.Namespace) {\r
+                                               error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);\r
+                                               break;\r
+                                       } else if (!any.HasValueOther) {\r
+                                               bool bad = false;\r
+                                               foreach (string ns in any.ResolvedNamespaces) {\r
+                                                       if (ns == this.QualifiedName.Namespace) {\r
+                                                               bad = true;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                               if (bad) {\r
+                                                       error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);\r
+                                                       break;\r
+                                               }\r
+                                       } else {\r
+                                               if (any.TargetNamespace != this.QualifiedName.Namespace)\r
+                                                       error (h, "Ambiguous element label which is contained by -any- particle with ##other value was detected: " + this.QualifiedName);\r
+                                       }\r
+                               }\r
+                               qnames.Add (this.QualifiedName, this);\r
+                       }\r
+               }\r
+\r
+               internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
+                       ValidationEventHandler h, XmlSchema schema)\r
+               {\r
+                       XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;\r
+                       if (labeled == null)\r
+                               labels.Add (this.QualifiedName, this);\r
+                       else if (labeled.ElementType != this.ElementType)\r
+                               error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);\r
+               }\r
+\r
+\r
+               // 3.3.6 Element Default Valid (Immediate)\r
+               private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)\r
+               {\r
+                       // This presumes that ElementType is already filled.\r
+\r
+                       XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;\r
+                       XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;\r
+                       if (simpleType != null)\r
+                               datatype = simpleType.Datatype;\r
+\r
+                       if (datatype == null) {\r
+                               XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;\r
+                               switch (complexType.ContentType) {\r
+                               case XmlSchemaContentType.Empty:\r
+                               case XmlSchemaContentType.ElementOnly:\r
+                                       error (h, "Element content type must be simple type or mixed.");\r
+                                       break;\r
+                               }\r
+                               datatype = XmlSchemaSimpleType.AnySimpleType;\r
+                       }\r
+\r
+                       XmlNamespaceManager nsmgr = null;\r
+                       if (datatype.TokenizedType == XmlTokenizedType.QName) {\r
+                               if (this.Namespaces != null)\r
+                                       foreach (XmlQualifiedName qname in Namespaces.ToArray ())\r
+                                               nsmgr.AddNamespace (qname.Name, qname.Namespace);\r
+                       }\r
+\r
+                       try {\r
+                               if (defaultValue != null) {\r
+                                       validatedDefaultValue = datatype.Normalize (defaultValue);\r
+                                       datatype.ParseValue (validatedDefaultValue, null, nsmgr);\r
+                               }\r
+                       } catch (Exception ex) {\r
+                               // FIXME: This is not a good way to handle exception, but\r
+                               // I think there is no remedy for such Framework specification.\r
+                               error (h, "The Element's default value is invalid with respect to its type definition.", ex);\r
+                       }\r
+                       try {\r
+                               if (fixedValue != null) {\r
+                                       validatedFixedValue = datatype.Normalize (fixedValue);\r
+                                       datatype.ParseValue (validatedFixedValue, null, nsmgr);\r
+                               }\r
+                       } catch (Exception ex) {\r
+                               // FIXME: This is not a good way to handle exception.\r
+                               error (h, "The Element's fixed value is invalid with its type definition.", ex);\r
+                       }\r
+               }\r
+\r
                //<element\r
                //  abstract = boolean : false\r
                //  block = (#all | List of (extension | restriction | substitution)) \r
@@ -481,9 +1036,10 @@ namespace System.Xml.Schema
                                }\r
                                else if(reader.Name == "block")\r
                                {\r
-                                       element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");\r
+                                       element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",\r
+                                               XmlSchemaUtil.ElementBlockAllowed);\r
                                        if(innerex != null)\r
-                                               warn(h,"some invalid values for block attribute were found",innerex);\r
+                                               error (h,"some invalid values for block attribute were found",innerex);\r
                                }\r
                                else if(reader.Name == "default")\r
                                {\r
@@ -491,9 +1047,10 @@ namespace System.Xml.Schema
                                }\r
                                else if(reader.Name == "final")\r
                                {\r
-                                       element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");\r
+                                       element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",\r
+                                               XmlSchemaUtil.FinalAllowed);\r
                                        if(innerex != null)\r
-                                               warn(h,"some invalid values for final attribute were found",innerex);\r
+                                               error (h,"some invalid values for final attribute were found",innerex);\r
                                }\r
                                else if(reader.Name == "fixed")\r
                                {\r