2004-01-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaComplexType.cs
1 //\r
2 // System.Xml.Schema.XmlSchemaComplexType.cs\r
3 //\r
4 // Authors:\r
5 //      Dwivedi, Ajay kumar  Adwiv@Yahoo.com\r
6 //      Enomoto, Atsushi     ginga@kit.hi-ho.ne.jp\r
7 //\r
8 using System;\r
9 using System.Collections;\r
10 using System.Xml;\r
11 using System.ComponentModel;\r
12 using System.Xml.Serialization;\r
13 \r
14 namespace System.Xml.Schema\r
15 {\r
16         /// <summary>\r
17         /// Summary description for XmlSchemaComplexType.\r
18         /// </summary>\r
19         public class XmlSchemaComplexType : XmlSchemaType\r
20         {\r
21                 private XmlSchemaAnyAttribute anyAttribute;\r
22                 private XmlSchemaObjectCollection attributes;\r
23                 private XmlSchemaObjectTable attributeUses;\r
24                 private XmlSchemaAnyAttribute attributeWildcard;\r
25                 private XmlSchemaDerivationMethod block;\r
26                 private XmlSchemaDerivationMethod blockResolved;\r
27                 private XmlSchemaContentModel contentModel;\r
28                 private XmlSchemaParticle contentTypeParticle;\r
29                 private bool isAbstract;\r
30                 private bool isMixed;\r
31                 private XmlSchemaParticle particle;\r
32                 private XmlSchemaContentType resolvedContentType;\r
33 \r
34                 internal bool ValidatedIsAbstract;\r
35                 internal bool ParentIsSchema = false;\r
36 \r
37                 private static string xmlname = "complexType";\r
38 \r
39                 private static XmlSchemaComplexType anyType;\r
40 \r
41                 internal static XmlSchemaComplexType AnyType {\r
42                         get {\r
43                                 if (anyType == null) {\r
44                                         anyType = new XmlSchemaComplexType ();\r
45                                         anyType.Name = "";      // In MS.NET, it is not "anyType"\r
46                                         anyType.QNameInternal = XmlQualifiedName.Empty; // Not xs:anyType as well.\r
47                                         anyType.contentTypeParticle = XmlSchemaAny.AnyTypeContent;\r
48 //                                      anyType.baseSchemaTypeInternal = anyType;\r
49                                         anyType.datatypeInternal = XmlSchemaSimpleType.AnySimpleType;\r
50                                         anyType.isMixed = true;\r
51                                 }\r
52                                 return anyType;\r
53                         }\r
54                 }\r
55 \r
56                 internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);\r
57 \r
58                 public XmlSchemaComplexType ()\r
59                 {\r
60                         attributes = new XmlSchemaObjectCollection();\r
61                         block = XmlSchemaDerivationMethod.None;\r
62                         attributeUses = new XmlSchemaObjectTable();\r
63                         contentTypeParticle = XmlSchemaParticle.Empty;\r
64                 }\r
65 \r
66                 #region Attributes\r
67 \r
68                 [DefaultValue(false)]\r
69                 [System.Xml.Serialization.XmlAttribute("abstract")]\r
70                 public bool IsAbstract \r
71                 {\r
72                         get{ return  isAbstract; }\r
73                         set{ isAbstract = value; }\r
74                 }\r
75                 [DefaultValue(XmlSchemaDerivationMethod.None)]\r
76                 [System.Xml.Serialization.XmlAttribute("block")]\r
77                 public XmlSchemaDerivationMethod Block\r
78                 {\r
79                         get{ return  block; }\r
80                         set{ block = value; }\r
81                 }\r
82                 [DefaultValue(false)]\r
83                 [System.Xml.Serialization.XmlAttribute("mixed")]\r
84                 public override bool IsMixed\r
85                 {\r
86                         get{ return  isMixed; }\r
87                         set{ isMixed = value; }\r
88                 }\r
89                 \r
90                 #endregion\r
91                 \r
92                 #region Elements\r
93                                 \r
94                 [XmlElement("simpleContent",typeof(XmlSchemaSimpleContent),Namespace="http://www.w3.org/2001/XMLSchema")]\r
95                 [XmlElement("complexContent",typeof(XmlSchemaComplexContent),Namespace="http://www.w3.org/2001/XMLSchema")]\r
96                 public XmlSchemaContentModel ContentModel \r
97                 {\r
98                         get{ return  contentModel; } \r
99                         set{ contentModel = value; }\r
100                 }\r
101 \r
102                 //LAMESPEC: The default value for particle in Schema is of Type EmptyParticle (internal?)\r
103                 [XmlElement("group",typeof(XmlSchemaGroupRef),Namespace="http://www.w3.org/2001/XMLSchema")]\r
104                 [XmlElement("all",typeof(XmlSchemaAll),Namespace="http://www.w3.org/2001/XMLSchema")]\r
105                 [XmlElement("choice",typeof(XmlSchemaChoice),Namespace="http://www.w3.org/2001/XMLSchema")]\r
106                 [XmlElement("sequence",typeof(XmlSchemaSequence),Namespace="http://www.w3.org/2001/XMLSchema")]\r
107                 public XmlSchemaParticle Particle \r
108                 {\r
109                         get{ return  particle; } \r
110                         set{ particle = value; }\r
111                 }\r
112 \r
113                 [XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace="http://www.w3.org/2001/XMLSchema")]\r
114                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef),Namespace="http://www.w3.org/2001/XMLSchema")]\r
115                 public XmlSchemaObjectCollection Attributes \r
116                 {\r
117                         get{ return attributes; }\r
118                 }\r
119 \r
120                 [XmlElement("anyAttribute",Namespace="http://www.w3.org/2001/XMLSchema")]\r
121                 public XmlSchemaAnyAttribute AnyAttribute \r
122                 {\r
123                         get{ return  anyAttribute; }\r
124                         set{ anyAttribute = value; }\r
125                 }\r
126                 #endregion\r
127 \r
128                 #region XmlIgnore\r
129                 [XmlIgnore]\r
130                 public XmlSchemaContentType ContentType \r
131                 {\r
132                         get{ return resolvedContentType; }\r
133                 }\r
134                 [XmlIgnore]\r
135                 public XmlSchemaParticle ContentTypeParticle \r
136                 {\r
137                         get{ return contentTypeParticle; }\r
138                 }\r
139                 [XmlIgnore]\r
140                 public XmlSchemaDerivationMethod BlockResolved \r
141                 {\r
142                         get{ return blockResolved; }\r
143                 }\r
144                 [XmlIgnore]\r
145                 public XmlSchemaObjectTable AttributeUses \r
146                 {\r
147                         get{ return attributeUses; }\r
148                 }\r
149                 [XmlIgnore]\r
150                 public XmlSchemaAnyAttribute AttributeWildcard \r
151                 {\r
152                         get{ return attributeWildcard; }\r
153                 }\r
154                 #endregion\r
155 \r
156                 /// <remarks>\r
157                 /// 1. If ContentModel is present, neither particle nor Attributes nor AnyAttribute can be present.\r
158                 /// 2. If particle is present, \r
159                 /// a. For a topLevelComplexType\r
160                 ///             1. name must be present and type NCName\r
161                 ///             2. if block is #all, blockdefault is #all, else List of (extension | restriction)\r
162                 ///             3. if final is #all, finaldefault is #all, else List of (extension | restriction)\r
163                 ///     b. For a local Complex type \r
164                 ///             1. abstract must be false\r
165                 ///             2. Name must be absent\r
166                 ///             3. final must be absent\r
167                 ///             4. block must be absent\r
168                 ///             \r
169                 /// </remarks>\r
170                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
171                 {\r
172                         // If this is already compiled this time, simply skip.\r
173                         if (this.IsComplied (schema.CompilationId))\r
174                                 return errorCount;\r
175 \r
176                         ValidatedIsAbstract = isAbstract;\r
177 \r
178                         if (isRedefinedComponent) {\r
179                                 if (Annotation != null)\r
180                                         Annotation.isRedefinedComponent = true;\r
181                                 if (AnyAttribute != null)\r
182                                         AnyAttribute.isRedefinedComponent = true;\r
183                                 foreach (XmlSchemaObject obj in Attributes)\r
184                                         obj.isRedefinedComponent = true;\r
185                                 if (ContentModel != null)\r
186                                         ContentModel.isRedefinedComponent = true;\r
187                                 if (Particle != null)\r
188                                         Particle.isRedefinedComponent = true;\r
189                         }\r
190 \r
191                         // block/final resolution\r
192                         if(ParentIsSchema || isRedefineChild)\r
193                         {\r
194                                 if(this.Name == null || this.Name == string.Empty)\r
195                                         error(h,"name must be present in a top level complex type");\r
196                                 else if(!XmlSchemaUtil.CheckNCName(Name))\r
197                                         error(h,"name must be a NCName");\r
198                                 else\r
199                                         this.QNameInternal = new XmlQualifiedName(Name, schema.TargetNamespace);\r
200                                 \r
201                                 if(Block != XmlSchemaDerivationMethod.None)\r
202                                 {\r
203                                         if(Block == XmlSchemaDerivationMethod.All)\r
204                                         {\r
205                                                 blockResolved = XmlSchemaDerivationMethod.All;\r
206                                         }\r
207                                         else\r
208                                         {\r
209                                                 //TODO: Check what all is not allowed\r
210                                                 if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)\r
211                                                         error (h, "Invalid block specification.");\r
212                                                 blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;\r
213                                         }\r
214                                 }\r
215                                 else\r
216                                 {\r
217                                         switch (schema.BlockDefault) {\r
218                                         case XmlSchemaDerivationMethod.All:\r
219                                                 blockResolved = XmlSchemaDerivationMethod.All;\r
220                                                 break;\r
221                                         case XmlSchemaDerivationMethod.None:\r
222                                                 blockResolved = XmlSchemaDerivationMethod.Empty;\r
223                                                 break;\r
224                                         default:\r
225                                                 blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;\r
226                                                 break;\r
227                                         }\r
228                                 }\r
229 \r
230                                 if(Final != XmlSchemaDerivationMethod.None)\r
231                                 {\r
232                                         if(Final == XmlSchemaDerivationMethod.All)\r
233                                                 finalResolved = XmlSchemaDerivationMethod.All;\r
234                                         else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)\r
235                                                 error (h, "Invalid final specification.");\r
236                                         else\r
237                                                 finalResolved = Final;\r
238                                 }\r
239                                 else\r
240                                 {\r
241                                         switch (schema.FinalDefault) {\r
242                                         case XmlSchemaDerivationMethod.All:\r
243                                                 finalResolved = XmlSchemaDerivationMethod.All;\r
244                                                 break;\r
245                                         case XmlSchemaDerivationMethod.None:\r
246                                                 finalResolved = XmlSchemaDerivationMethod.Empty;\r
247                                                 break;\r
248                                         default:\r
249                                                 finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;\r
250                                                 break;\r
251                                         }\r
252                                 }\r
253                         }\r
254                         else // Not Top Level\r
255                         {\r
256                                 if(isAbstract)\r
257                                         error(h,"abstract must be false in a local complex type");\r
258                                 if(Name != null)\r
259                                         error(h,"name must be absent in a local complex type");\r
260                                 if(Final != XmlSchemaDerivationMethod.None)\r
261                                         error(h,"final must be absent in a local complex type");\r
262                                 if(block != XmlSchemaDerivationMethod.None)\r
263                                         error(h,"block must be absent in a local complex type");\r
264                         }\r
265 \r
266                         // Process contents and BaseSchemaType\r
267                         if(contentModel != null)\r
268                         {\r
269                                 if(anyAttribute != null || Attributes.Count != 0 || Particle != null)\r
270                                         error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");\r
271                                 errorCount += contentModel.Compile (h, schema);\r
272 \r
273                                 XmlQualifiedName baseTypeName = null;\r
274                                 XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;\r
275                                 if(smodel != null)\r
276                                 {\r
277                                         XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;\r
278                                         if (sscx != null)\r
279                                                 baseTypeName = sscx.BaseTypeName;\r
280                                         else {\r
281                                                 XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;\r
282                                                 if (sscr != null) {\r
283                                                         baseTypeName = sscr.BaseTypeName;\r
284                                                         if (sscr.BaseType != null) {\r
285                                                                 sscr.BaseType.Compile (h, schema);\r
286                                                                 baseSchemaTypeInternal = sscr.BaseType;\r
287                                                         }\r
288                                                 }\r
289                                         }\r
290                                         contentTypeParticle = XmlSchemaParticle.Empty;\r
291                                 }\r
292                                 else\r
293                                 {\r
294                                         XmlSchemaComplexContent cmodel = (XmlSchemaComplexContent) ContentModel;\r
295                                         XmlSchemaComplexContentExtension sccx = cmodel.Content as XmlSchemaComplexContentExtension;\r
296                                         if (sccx != null) {\r
297                                                 contentTypeParticle = sccx.Particle;\r
298                                                 baseTypeName = sccx.BaseTypeName;\r
299                                         }\r
300                                         else {\r
301                                                 XmlSchemaComplexContentRestriction sccr = (XmlSchemaComplexContentRestriction) cmodel.Content;\r
302                                                 if (sccr != null) {\r
303                                                         contentTypeParticle = sccr.Particle;\r
304                                                         baseTypeName = sccr.BaseTypeName;\r
305                                                 }\r
306                                         }\r
307                                 }\r
308                         }\r
309                         else\r
310                         {\r
311                                 if(Particle is XmlSchemaGroupRef)\r
312                                 {\r
313                                         XmlSchemaGroupRef xsgr = (XmlSchemaGroupRef)Particle;\r
314                                         errorCount += xsgr.Compile(h,schema);\r
315                                 }\r
316                                 else if(Particle is XmlSchemaAll)\r
317                                 {\r
318                                         XmlSchemaAll xsa = (XmlSchemaAll)Particle;\r
319                                         errorCount += xsa.Compile(h,schema);\r
320                                 }\r
321                                 else if(Particle is XmlSchemaChoice)\r
322                                 {\r
323                                         XmlSchemaChoice xsc = (XmlSchemaChoice)Particle;\r
324                                         errorCount += xsc.Compile(h,schema);\r
325                                 }\r
326                                 else if(Particle is XmlSchemaSequence)\r
327                                 {\r
328                                         XmlSchemaSequence xss = (XmlSchemaSequence)Particle;\r
329                                         errorCount += xss.Compile(h,schema);\r
330                                 }\r
331                                 this.contentTypeParticle = Particle;\r
332 \r
333                                 if(this.anyAttribute != null)\r
334                                 {\r
335                                         AnyAttribute.Compile(h,schema);\r
336                                 }\r
337                                 foreach(XmlSchemaObject obj in Attributes)\r
338                                 {\r
339                                         if(obj is XmlSchemaAttribute)\r
340                                         {\r
341                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
342                                                 errorCount += attr.Compile(h,schema);\r
343                                         }\r
344                                         else if(obj is XmlSchemaAttributeGroupRef)\r
345                                         {\r
346                                                 XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;\r
347                                                 errorCount += atgrp.Compile(h,schema);\r
348                                         }\r
349                                         else\r
350                                                 error(h,obj.GetType() +" is not valid in this place::ComplexType");\r
351                                 }\r
352                         }\r
353 \r
354                         XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);\r
355                         this.CompilationId = schema.CompilationId;\r
356                         return errorCount;\r
357                 }\r
358 \r
359                 //\r
360                 // We have to validate:\r
361                 //\r
362                 //      - Type Definition Properties Correct\r
363                 //\r
364                 // and it subsequently delegates:\r
365                 //\r
366                 //      - Derivation Valid (Extension)\r
367                 //      - Derivation Valid (Restriction, Complex)\r
368                 //      - Type Derivation OK (Complex)\r
369                 //\r
370                 // There are many schema errata:\r
371                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
372                 //\r
373                 // E1-43 Derivation Valid (Restriction, Complex) 5.\r
374                 // E1-21 Derivation Valid (Restriction, Complex) 4.3.\r
375                 // E1-17 Type Derivation OK (Complex) 2.1.\r
376                 //\r
377                 // And E1-38, E1-37, E1-30 and E1-27\r
378                 //\r
379                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
380                 {\r
381                         if (IsValidated (schema.ValidationId))\r
382                                 return errorCount;\r
383                         // FIXME: omitting it causes StackOverflowException\r
384                         // among the compilation of element and types, but\r
385                         // it may result in insufficient results.\r
386                         ValidationId = schema.ValidationId;\r
387 \r
388                         // 3.4.6: Properties Correct\r
389                         // Term. 1 => 3.4.1\r
390                         // Term. 2, 3 and 4 goes ValidateContentModel().\r
391                         // Term. 5 follows in this method.\r
392                         //\r
393                         // 3.4.1:  Complex Type Definitions Properties Correct\r
394                         // Schema component to CLR type property mapping:\r
395                         // {derivation method} => resolvedDerivedBy\r
396                         // {annotations} are as is.\r
397                         // {name}, {namespace} => QualifiedName\r
398                         // {final} and {prohibited substitutions} are Compile()d.\r
399                         // {abstract} => ValidatedIsAbstract\r
400 \r
401                         // Below are different properties depending on simpleContent | complexContent.\r
402                         // {base type definition} => BaseSchemaType (later)\r
403                         // {attribute uses} => AttributeUses (later)\r
404                         // {content type} => ContentType and ContentTypeParticle (later)\r
405                         if (ContentModel != null)\r
406                                 ValidateContentModel (h, schema);\r
407                         else {\r
408                                 // leave resolvedDerivedBy as Empty\r
409                                 if (Particle != null)\r
410                                         ValidateImmediateParticle (h, schema);\r
411                                 if (contentTypeParticle == null || contentTypeParticle == XmlSchemaParticle.Empty) {\r
412                                         // note that this covers "Particle == null" case\r
413                                         if (this.IsMixed)\r
414                                                 resolvedContentType = XmlSchemaContentType.TextOnly;\r
415                                         else\r
416                                                 resolvedContentType = XmlSchemaContentType.Empty;\r
417                                 } else {\r
418                                         if (this.IsMixed)\r
419                                                 resolvedContentType = XmlSchemaContentType.Mixed;\r
420                                         else\r
421                                                 resolvedContentType = XmlSchemaContentType.ElementOnly;\r
422                                 }\r
423                                 // ContentModel never has them.\r
424                                 ValidateImmediateAttributes (h, schema);\r
425                         }\r
426                         // Additional support for 3.8.6 All Group Limited\r
427                         if (contentTypeParticle != null) {\r
428                                 XmlSchemaAll termAll = contentTypeParticle.ActualParticle as XmlSchemaAll;\r
429                                 if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence. FIXME: In the future contentTypeParticle will remove group references.\r
430                                         error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");\r
431                         }\r
432 \r
433                         // {content type} is going to be finished.\r
434                         if (contentTypeParticle == null)\r
435                                 contentTypeParticle = XmlSchemaParticle.Empty;\r
436                         contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),\r
437                                 new ArrayList (), h, schema);\r
438                         contentTypeParticle.ValidateUniqueTypeAttribution (\r
439                                 new XmlSchemaObjectTable (), h, schema);\r
440 //                      contentTypeParticle = contentTypeParticle.GetParticleithoutPointless ();\r
441 \r
442                         // FIXME: move to ValidateContentModel()\r
443                         if (contentModel != null && contentModel is XmlSchemaSimpleContent)\r
444                                 resolvedContentType = GetContentType (true);\r
445 \r
446                         // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)\r
447                         XmlSchemaAttribute idAttr = null;\r
448                         foreach (DictionaryEntry entry in attributeUses) {\r
449                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
450                                 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;\r
451                                 if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)\r
452                                         continue;\r
453                                 if (dt == null)\r
454                                         dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;\r
455                                 if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {\r
456                                         if (idAttr != null)\r
457                                                 error (h, "Two or more ID typed attribute declarations in a complex type are found.");\r
458                                         else\r
459                                                 idAttr = attr;\r
460                                 }\r
461                         }\r
462 \r
463                         ValidationId = schema.ValidationId;\r
464                         return errorCount;\r
465                 }\r
466 \r
467                 private void ValidateImmediateParticle (ValidationEventHandler h, XmlSchema schema)\r
468                 {\r
469                         // {content type} as a particle.\r
470                         errorCount += particle.Validate (h, schema);\r
471                         contentTypeParticle = Particle;\r
472                         XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;\r
473                         if (pgrp != null) {\r
474                                 if (pgrp.TargetGroup != null)\r
475                                         errorCount += pgrp.TargetGroup.Validate (h,schema);\r
476                                 // otherwise, it might be missing sub components.\r
477                                 else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))\r
478                                         error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");\r
479                         }\r
480                 }\r
481 \r
482                 private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)\r
483                 {\r
484                         // {attribute uses}\r
485                         // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)\r
486                         attributeUses = new XmlSchemaObjectTable ();\r
487                         XmlSchemaUtil.ValidateAttributesResolved (attributeUses,\r
488                                 h, schema, attributes, anyAttribute, ref attributeWildcard, null);\r
489                 }\r
490 \r
491                 private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)\r
492                 {\r
493                         // Here we check 3.4.6 Properties Correct :: 2. and 3.\r
494                         errorCount += contentModel.Validate (h, schema);\r
495                         XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;\r
496                         XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;\r
497                         XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;\r
498                         XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;\r
499 \r
500                         XmlSchemaAnyAttribute localAnyAttribute = null;\r
501                         XmlSchemaAnyAttribute baseAnyAttribute = null;\r
502 \r
503                         XmlQualifiedName baseTypeName = null;\r
504                         if (cce != null)\r
505                                 baseTypeName = cce.BaseTypeName;\r
506                         else if (ccr != null)\r
507                                 baseTypeName = ccr.BaseTypeName;\r
508                         else if (sce != null)\r
509                                 baseTypeName = sce.BaseTypeName;\r
510                         else\r
511                                 baseTypeName = scr.BaseTypeName;\r
512 \r
513                         XmlSchemaType baseType = schema.SchemaTypes [baseTypeName] as XmlSchemaType;\r
514                         // Resolve redefine.\r
515                         if (this.isRedefineChild && baseType != null && this.QualifiedName == baseTypeName) {\r
516                                 baseType = (XmlSchemaType) redefinedObject;\r
517                                 if (baseType == null)\r
518                                         error (h, "Redefinition base type was not found.");\r
519                                 else\r
520                                         baseType.Validate (h, schema);\r
521                         }\r
522                         // 3.4.6 Properties Correct :: 3. Circular definition prohibited.\r
523                         if (ValidateRecursionCheck ())\r
524                                 error (h, "Circular definition of schema types was found.");\r
525                         if (baseType != null) {\r
526                                 baseType.Validate (h, schema);\r
527                                 // Fill "Datatype" property.\r
528                                 this.datatypeInternal = baseType.Datatype;\r
529                         } else if (baseTypeName == XmlSchemaComplexType.AnyTypeName)\r
530                                 datatypeInternal = XmlSchemaSimpleType.AnySimpleType;
531                         else if (baseTypeName.Namespace == XmlSchema.Namespace) {\r
532                                 datatypeInternal = XmlSchemaDatatype.FromName (baseTypeName);\r
533                         }\r
534 \r
535                         // {derivation method}\r
536                         XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;\r
537                         XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;\r
538                         if (cce != null || sce != null)\r
539                                 resolvedDerivedBy = XmlSchemaDerivationMethod.Extension;\r
540                         else\r
541                                 resolvedDerivedBy = XmlSchemaDerivationMethod.Restriction;\r
542 \r
543                         // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.\r
544                         if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)\r
545                                         error (h, "Specified derivation is specified as final by derived schema type.");\r
546 \r
547                         // 3.4.6 Properties Correct :: 2.\r
548                         // Simple {base type definition} and restriction {derivation method} not allowed.\r
549                         if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)\r
550                                 error (h, "If the base schema type is a simple type, then this type must be extension.");\r
551 \r
552                         // Common to complexContent\r
553                         if (cce != null || ccr != null) {\r
554                                 // 3.4.3 Complex Type Definition Representation OK :: 1.\r
555                                 // base\r
556                                 if (baseTypeName == XmlSchemaComplexType.AnyTypeName)\r
557                                         baseComplexType = XmlSchemaComplexType.AnyType;\r
558                                 else if (baseTypeName.Namespace == XmlSchema.Namespace)\r
559                                         error (h, "Referenced base schema type is XML Schema datatype.");\r
560                                 else if (baseComplexType == null && !schema.IsNamespaceAbsent (baseTypeName.Namespace))\r
561                                         error (h, "Referenced base schema type " + baseTypeName + " was not complex type or not found in the corresponding schema.");\r
562                         }\r
563                         // Common to simpleContent \r
564                         else {\r
565                                 // 3.4.3 Complex Type Definition Representation OK :: 1.\r
566                                 // base\r
567                                 if (baseTypeName == XmlSchemaComplexType.AnyTypeName)\r
568                                         baseComplexType = XmlSchemaComplexType.AnyType;
569 \r
570                                 if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {\r
571                                         error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + baseTypeName);\r
572                                 } else if (sce == null && (baseSimpleType != null && baseTypeName.Namespace != XmlSchema.Namespace)) {\r
573                                         error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + baseTypeName);\r
574                                 } else if (baseTypeName.Namespace == XmlSchema.Namespace) {\r
575                                         if (XmlSchemaDatatype.FromName (baseTypeName) == null)\r
576                                                 error (h, "Invalid schema data type was specified: " + baseTypeName);\r
577                                         // do nothing for particle.\r
578                                 }\r
579                                 // otherwise, it might be missing sub components.\r
580                                 else if (baseType == null && !schema.IsNamespaceAbsent (baseTypeName.Namespace))// && schema.Schemas [baseTypeName.Namespace] != null)\r
581                                         error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");\r
582 \r
583                                 // 3.4.3 Complex Type Definition Representation OK :: 2.\r
584                                 // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)\r
585                                 if (baseComplexType != null) {\r
586                                         if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {\r
587                                                 // 2.1.1\r
588                                         } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {\r
589                                                 // 2.1.2 && 2.2: OK\r
590                                         }\r
591                                         else\r
592                                                 error (h, "Base complex type of a simple content restriction must be text only.");\r
593                                 } else {\r
594                                         if (sce != null && baseComplexType == null) {\r
595                                                 // 2.1.3 : OK\r
596                                         }\r
597                                         else\r
598                                                 error (h, "Not allowed base type of a simple content restriction.");\r
599                                 }\r
600                         }\r
601 \r
602                         // complexType/complexContent/extension\r
603                         if (cce != null) {\r
604                                 // 3.4.2 complex content {content type}\r
605                                 if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {\r
606                                         // - 2.1\r
607                                         if (baseComplexType == null) {\r
608                                                 // Basically it is an error. Considering ValidationEventHandler.\r
609                                                 contentTypeParticle = XmlSchemaParticle.Empty;\r
610                                                 resolvedContentType = XmlSchemaContentType.Empty;\r
611                                         } else {\r
612                                                 contentTypeParticle = baseComplexType.ContentTypeParticle;\r
613                                                 resolvedContentType = baseComplexType.resolvedContentType;\r
614                                         }\r
615                                 } else if (baseComplexType.ContentTypeParticle == XmlSchemaParticle.Empty\r
616                                         || baseComplexType == XmlSchemaComplexType.AnyType) {\r
617                                         // - 2.2\r
618                                         contentTypeParticle = cce.Particle;\r
619                                         resolvedContentType = GetComplexContentType (contentModel);\r
620                                 } else {\r
621                                         // - 2.3 : create a new sequences that merges both contents.\r
622                                         XmlSchemaSequence seq = new XmlSchemaSequence ();\r
623                                         seq.Items.Add (baseComplexType.ContentTypeParticle);\r
624                                         seq.Items.Add (cce.Particle);\r
625                                         seq.Compile (h, schema);\r
626                                         seq.Validate (h, schema);\r
627                                         contentTypeParticle = seq;\r
628                                         resolvedContentType = GetComplexContentType (contentModel);\r
629                                 }\r
630                                 if (contentTypeParticle == null)\r
631                                         contentTypeParticle = XmlSchemaParticle.Empty;\r
632 \r
633                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2\r
634                                 // is constraining anything here, since 3.4.2 {attribute uses}\r
635                                 // defines as to include base type's attribute uses.\r
636                                 localAnyAttribute = cce.AnyAttribute;\r
637                                 if (baseComplexType != null) {\r
638                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
639                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
640                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
641                                         }\r
642                                         baseAnyAttribute = baseComplexType.AttributeWildcard;\r
643                                 }\r
644                                 // attributes\r
645                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
646                                         this.attributeUses, h, schema, cce.Attributes, \r
647                                         cce.AnyAttribute , ref attributeWildcard, null);\r
648 \r
649                                 // After adding them, test extension validity.\r
650                                 if (baseComplexType != null)\r
651                                         this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);\r
652                                 else if (baseSimpleType != null)\r
653                                         this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);\r
654                         }\r
655                         // complexType/complexContent/restriction\r
656                         if (ccr != null) {\r
657                                 // For ValidationEventHandler.\r
658                                 if (baseComplexType == null)\r
659                                         baseComplexType = XmlSchemaComplexType.AnyType;\r
660 \r
661                                 // 3.4.2 complex content schema component {content type}\r
662                                 // - 1.1.1\r
663                                 bool isEmptyParticle = false;\r
664                                 if (ccr.Particle == null) \r
665                                         isEmptyParticle = true;\r
666                                 else {\r
667                                         ccr.Particle.Validate (h, schema);\r
668 \r
669                                         XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;\r
670                                         if (gb != null) {\r
671                                                 // - 1.1.2\r
672                                                 if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)\r
673                                                         isEmptyParticle = true;\r
674                                                 // - 1.1.3\r
675                                                 else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)\r
676                                                         isEmptyParticle = true;\r
677                                         }\r
678                                 }\r
679                                 if (isEmptyParticle) {\r
680                                         contentTypeParticle = XmlSchemaParticle.Empty;\r
681                                         resolvedContentType = XmlSchemaContentType.Empty;\r
682                                 } else {\r
683                                         // - 1.2.1\r
684                                         resolvedContentType = GetComplexContentType (contentModel);\r
685                                         // - 1.2.2\r
686                                         contentTypeParticle = ccr.Particle;\r
687                                 }\r
688 \r
689                                 // attributes\r
690                                 localAnyAttribute = ccr.AnyAttribute;\r
691                                 this.attributeWildcard = localAnyAttribute;\r
692                                 if (baseComplexType != null)\r
693                                         baseAnyAttribute = baseComplexType.AttributeWildcard;\r
694                                 if (baseAnyAttribute != null && localAnyAttribute != null)\r
695                                         // 1.3 attribute wildcard subset. (=> 3.10.6)\r
696                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
697 \r
698                                 // FIXME: Check 3.4.2 Complex Type Definition with complex content Schema Component\r
699                                 // and its {attribute uses} and {attribute wildcard}\r
700                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
701                                         this.attributeUses, h, schema, ccr.Attributes, \r
702                                         ccr.AnyAttribute, ref attributeWildcard, null);\r
703                                 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
704                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
705                                         if (attributeUses [attr.QualifiedName] == null)\r
706                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
707                                 }\r
708 \r
709                                 // Derivation Valid (Restriction, Complex) :: 5.\r
710                                 // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
711                                 // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)\r
712                                 this.ValidateDerivationValidRestriction (baseComplexType, h, schema);\r
713                         }\r
714                         // complexType/simpleContent/extension\r
715                         if (sce != null) {\r
716                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
717                                         this.attributeUses, h, schema, sce.Attributes, \r
718                                         sce.AnyAttribute, ref attributeWildcard, null);\r
719 \r
720                                 // Attributes\r
721                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2\r
722                                 // is constraining anything here, since 3.4.2 {attribute uses}\r
723                                 // defines as to include base type's attribute uses.\r
724                                 localAnyAttribute = sce.AnyAttribute;\r
725 \r
726                                 if (baseComplexType != null) {\r
727                                         baseAnyAttribute = baseComplexType.AttributeWildcard;\r
728 \r
729                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
730                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
731                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);\r
732                                         }\r
733                                 }\r
734                                 if (baseAnyAttribute != null && localAnyAttribute != null)\r
735                                         // 1.3 attribute wildcard subset. (=> 3.10.6)\r
736                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
737                         }\r
738                         // complexType/simpleContent/restriction\r
739                         if (scr != null) {\r
740                                 // Attributes\r
741                                 baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;\r
742 \r
743                                 localAnyAttribute = scr.AnyAttribute;\r
744                                 if (localAnyAttribute != null && baseAnyAttribute != null)\r
745                                         // 1.3 attribute wildcard subset. (=> 3.10.6)\r
746                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);\r
747                                 // TODO: 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!\r
748                                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1\r
749 \r
750                                 // FIXME: Check 3.4.2 Complex Type Definition with simple content Schema Component\r
751                                 // and its {attribute uses} and {attribute wildcard}\r
752                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (\r
753                                         this.attributeUses, h, schema, scr.Attributes, \r
754                                         scr.AnyAttribute, ref attributeWildcard, null);\r
755                         }\r
756 \r
757                         // Common process of AttributeWildcard.\r
758                         // TODO: Check 3.4.2 {attribute wildcard} to fill the complete wildcard.\r
759                         if (localAnyAttribute != null) {\r
760                                 this.attributeWildcard = localAnyAttribute;\r
761                         }\r
762                         else\r
763                                 this.attributeWildcard = baseAnyAttribute;\r
764                         this.baseSchemaTypeInternal = baseType;\r
765                 }\r
766 \r
767                 // 3.4.2 Complex Content Schema Component {content type} 1.2.1\r
768                 private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)\r
769                 {\r
770                         if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)\r
771                                 return XmlSchemaContentType.Mixed;\r
772                         else\r
773                                 return XmlSchemaContentType.ElementOnly;\r
774                 }\r
775 \r
776                 // It was formerly placed directly in ContentType property.\r
777                 // I get it out, since ContentType is _post_ compilation property value.\r
778                 private XmlSchemaContentType GetContentType (bool usePointlessCutParticle)\r
779                 {\r
780                         if (this.isMixed)\r
781                                 return XmlSchemaContentType.Mixed;\r
782                         XmlSchemaComplexContent xcc = \r
783                                 ContentModel as XmlSchemaComplexContent;\r
784                         if (xcc != null && xcc.IsMixed)\r
785                                 return XmlSchemaContentType.Mixed;\r
786 \r
787                         XmlSchemaSimpleContent xsc = ContentModel as XmlSchemaSimpleContent;\r
788                         if (xsc != null)\r
789                                 return XmlSchemaContentType.TextOnly;\r
790 \r
791                         XmlSchemaParticle p = usePointlessCutParticle ?\r
792                                 contentTypeParticle : Particle;\r
793 \r
794                         return p != XmlSchemaParticle.Empty ?\r
795                                 XmlSchemaContentType.ElementOnly :\r
796                                 XmlSchemaContentType.Empty;\r
797                 }\r
798 \r
799                 // 3.4.6 Type Derivation OK (Complex)\r
800                 internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)\r
801                 {\r
802                         // AnyType derives from AnyType itself.\r
803                         if (this == XmlSchemaComplexType.AnyType && BaseSchemaType == this)\r
804                                 return;\r
805 \r
806                         XmlSchemaType bst = b as XmlSchemaType;\r
807                         if (b == this)  // 1 and 2.1\r
808                                 return;\r
809                         if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.\r
810                                 error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");\r
811                         if (BaseSchemaType == b) // 2.2\r
812                                 return;\r
813                         if (BaseSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1\r
814                                 error (h, "Derived type's base schema type is anyType.");\r
815                                 return;\r
816                         }\r
817                         // 2.3.2.1\r
818                         XmlSchemaComplexType dbct = BaseSchemaType as XmlSchemaComplexType;\r
819                         if (dbct != null) {\r
820                                 dbct.ValidateTypeDerivationOK (b, h, schema);\r
821                                 return;\r
822                         }\r
823                         // 2.3.2.2\r
824                         XmlSchemaSimpleType dbst = BaseSchemaType as XmlSchemaSimpleType;\r
825                         if (dbst != null) {\r
826                                 dbst.ValidateTypeDerivationOK (b, h, schema, true);\r
827                                 return;\r
828                         }\r
829                 }\r
830 \r
831                 // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)\r
832                 internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,\r
833                         ValidationEventHandler h, XmlSchema schema)\r
834                 {\r
835                         // 1.1\r
836                         if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
837                                 error (h, "Derivation by extension is prohibited.");\r
838                         // 1.2\r
839                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {\r
840                                 XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;\r
841                                 XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;\r
842                                 if (da == null)\r
843                                         error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");\r
844                                 // TODO: How to evaluate "equal" type ...?\r
845                         }\r
846                         // 1.3 -> 3.10.6 Wildcard Subset.\r
847                         if (AnyAttribute != null) {\r
848                                 if (baseComplexType.AnyAttribute == null)\r
849                                         error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");\r
850                                 else\r
851                                         baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);\r
852                         }\r
853 \r
854                         // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).\r
855                         // 1.4.2.1\r
856 //                      if (contentTypeParticle == null)\r
857 //                              error (h, "Extended complex type's content type must not be empty.");\r
858                         // 1.4.2.2.1\r
859                         if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {\r
860                                 // 1.4.2.2.2.1\r
861                                 if (this.GetContentType (false) != baseComplexType.GetContentType (false))\r
862                                         error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");\r
863                                 // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)\r
864                                 else if (this.contentTypeParticle == null ||\r
865                                         !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {\r
866                                         XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;\r
867                                         if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))\r
868                                                 error (h, "Invalid complex content extension was found.");\r
869                                         else {\r
870                                                 // Identical sequence item should be checked, but\r
871                                                 // I think it is naturally achieved as coded above.\r
872                                         }\r
873                                 }\r
874                         }\r
875                 }\r
876 \r
877                 // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)\r
878                 internal void ValidateSimpleBaseDerivationValidExtension (object baseType,\r
879                         ValidationEventHandler h, XmlSchema schema)\r
880                 {\r
881                         XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;\r
882                         if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
883                                 error (h, "Extension is prohibited by the base type.");\r
884 \r
885                         XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;\r
886                         if (dt == null)\r
887                                 dt = st.Datatype;\r
888                         if (dt != this.Datatype)\r
889                                 error (h, "To extend simple type, a complex type must have the same content type as the base type.");\r
890 \r
891                         /*\r
892                         switch (resolvedContentType) {\r
893                         case XmlSchemaContentType.Mixed:\r
894                         case XmlSchemaContentType.TextOnly:\r
895                                 XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;\r
896                                 if ((st == null && Datatype != baseType) ||\r
897                                         (st != null && st.Datatype != Datatype))\r
898                                         goto case XmlSchemaContentType.ElementOnly;\r
899                                 if (st != null\r
900                                         && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)\r
901                                         error (h, "Extension is prohibited by the base type.");\r
902                                 break;\r
903                         case XmlSchemaContentType.ElementOnly:\r
904                         case XmlSchemaContentType.Empty:\r
905                                 error (h, "To extend simple type, a complex type must have the same content type as the base type.");\r
906                                 break;\r
907                         }\r
908                         */\r
909                 }\r
910 \r
911                 internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,\r
912                         ValidationEventHandler h, XmlSchema schema)\r
913                 {\r
914                         // 1.\r
915                         if (baseType == null) {\r
916                                 error (h, "Base schema type is not a complex type.");\r
917                                 return;\r
918                         }\r
919                         if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {\r
920                                 error (h, "Prohibited derivation by restriction by base schema type.");\r
921                                 return;\r
922                         }\r
923 \r
924                         // 2.\r
925                         foreach (DictionaryEntry entry in this.AttributeUses) {\r
926                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;\r
927                                 XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;\r
928                                 if (baseAttr != null) {\r
929                                         // 2.1\r
930                                         // 2.1.1\r
931                                         if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)\r
932                                                 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
933                                         // 2.1.2\r
934                                         XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;\r
935                                         XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;\r
936                                         bool typeError = false;\r
937                                         if (attrSimpleType != null)\r
938                                                 attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);\r
939                                         else if (attrSimpleType == null && baseAttrSimpleType != null)\r
940                                                 typeError = true;\r
941                                         else {\r
942                                                 Type t1 = attr.AttributeType.GetType ();\r
943                                                 Type t2 = baseAttr.AttributeType.GetType ();\r
944                                                 if (t1 != t2 && t1.IsSubclassOf (t2))\r
945                                                         typeError = true;\r
946                                         }\r
947                                         if (typeError)\r
948                                                 error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");\r
949                                         // 2.1.3\r
950                                         if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)\r
951                                                 error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");\r
952                                 } else {\r
953                                         // 2.2\r
954                                         if (baseType.AttributeWildcard != null)\r
955                                                 if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (\r
956                                                         attr.QualifiedName.Namespace, schema) &&\r
957                                                         !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))\r
958                                                         error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");\r
959                                 }\r
960                         }\r
961                         // I think 3. is considered in 2.\r
962                         // 4.\r
963                         if (this.AttributeWildcard != null) {\r
964                                 if (baseType.AttributeWildcard == null)\r
965                                         error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");\r
966                                 else\r
967                                         AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);\r
968                         }\r
969 \r
970                         // 5.\r
971                         if (contentTypeParticle == XmlSchemaParticle.Empty) {\r
972                                 // TODO: 5.1\r
973                                 // 5.2\r
974                                 if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&\r
975                                         !baseType.ContentTypeParticle.ValidateIsEmptiable ())\r
976                                 error (h, "Invalid content type derivation.");\r
977                         } else {\r
978                                 // 5.3 => 3.9.6 Particle Valid (Restriction)\r
979                                 if (baseType.ContentTypeParticle != null) {\r
980                                         // 3.9.6 - 1 : same particle.\r
981                                         // 3.9.6 - 2 is covered by using ActualParticle.\r
982                                         if (!contentTypeParticle.ActualParticle.ParticleEquals (baseType.ContentTypeParticle.ActualParticle))\r
983                                                 contentTypeParticle.ActualParticle.ValidateDerivationByRestriction (\r
984                                                         baseType.ContentTypeParticle.ActualParticle, h, schema);\r
985                                 }\r
986                         }\r
987                 }\r
988 \r
989 #region Read\r
990                 //<complexType\r
991                 //  abstract = boolean : false\r
992                 //  block = (#all | List of (extension | restriction)) \r
993                 //  final = (#all | List of (extension | restriction)) \r
994                 //  id = ID\r
995                 //  mixed = boolean : false\r
996                 //  name = NCName\r
997                 //  {any attributes with non-schema namespace . . .}>\r
998                 //  Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))\r
999                 //</complexType>\r
1000                 internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)\r
1001                 {\r
1002                         XmlSchemaComplexType ctype = new XmlSchemaComplexType();\r
1003                         reader.MoveToElement();\r
1004                         Exception innerex;\r
1005 \r
1006                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
1007                         {\r
1008                                 error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
1009                                 reader.SkipToEnd();\r
1010                                 return null;\r
1011                         }\r
1012 \r
1013                         ctype.LineNumber = reader.LineNumber;\r
1014                         ctype.LinePosition = reader.LinePosition;\r
1015                         ctype.SourceUri = reader.BaseURI;\r
1016 \r
1017                         while(reader.MoveToNextAttribute())\r
1018                         {\r
1019                                 if(reader.Name == "abstract")\r
1020                                 {\r
1021                                         ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
1022                                         if(innerex != null)\r
1023                                                 error(h,reader.Value + " is invalid value for abstract",innerex);\r
1024                                 }\r
1025                                 else if(reader.Name == "block")\r
1026                                 {\r
1027                                         ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",\r
1028                                                 XmlSchemaUtil.ComplexTypeBlockAllowed);\r
1029                                         if(innerex != null)\r
1030                                                 error (h,"some invalid values for block attribute were found",innerex);\r
1031                                 }\r
1032                                 else if(reader.Name == "final")\r
1033                                 {\r
1034                                         ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",\r
1035                                                 XmlSchemaUtil.FinalAllowed);\r
1036                                         if(innerex != null)\r
1037                                                 error (h,"some invalid values for final attribute were found",innerex);\r
1038                                 }\r
1039                                 else if(reader.Name == "id")\r
1040                                 {\r
1041                                         ctype.Id = reader.Value;\r
1042                                 }\r
1043                                 else if(reader.Name == "mixed")\r
1044                                 {\r
1045                                         ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);\r
1046                                         if(innerex != null)\r
1047                                                 error(h,reader.Value + " is invalid value for mixed",innerex);\r
1048                                 }\r
1049                                 else if(reader.Name == "name")\r
1050                                 {\r
1051                                         ctype.Name = reader.Value;\r
1052                                 }\r
1053                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
1054                                 {\r
1055                                         error(h,reader.Name + " is not a valid attribute for complexType",null);\r
1056                                 }\r
1057                                 else\r
1058                                 {\r
1059                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);\r
1060                                 }\r
1061                         }\r
1062                         \r
1063                         reader.MoveToElement();\r
1064                         if(reader.IsEmptyElement)\r
1065                                 return ctype;\r
1066 \r
1067                         //Content: 1. annotation?, \r
1068                         //                 2. simpleContent | 2. complexContent | \r
1069                         //                      (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))\r
1070                         int level = 1;\r
1071                         while(reader.ReadNextElement())\r
1072                         {\r
1073                                 if(reader.NodeType == XmlNodeType.EndElement)\r
1074                                 {\r
1075                                         if(reader.LocalName != xmlname)\r
1076                                                 error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);\r
1077                                         break;\r
1078                                 }\r
1079                                 if(level <= 1 && reader.LocalName == "annotation")\r
1080                                 {\r
1081                                         level = 2; //Only one annotation\r
1082                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
1083                                         if(annotation != null)\r
1084                                                 ctype.Annotation = annotation;\r
1085                                         continue;\r
1086                                 }\r
1087                                 if(level <=2)\r
1088                                 {\r
1089                                         if(reader.LocalName == "simpleContent")\r
1090                                         {\r
1091                                                 level = 6;\r
1092                                                 XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);\r
1093                                                 if(simple != null)\r
1094                                                         ctype.ContentModel = simple;\r
1095                                                 continue;\r
1096                                         }\r
1097                                         if(reader.LocalName == "complexContent")\r
1098                                         {\r
1099                                                 level = 6;\r
1100                                                 XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);\r
1101                                                 if(complex != null)\r
1102                                                         ctype.contentModel = complex;\r
1103                                                 continue;\r
1104                                         }\r
1105                                 }\r
1106                                 if(level <= 3)\r
1107                                 {\r
1108                                         if(reader.LocalName == "group")\r
1109                                         {\r
1110                                                 level = 4;\r
1111                                                 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);\r
1112                                                 if(group != null)\r
1113                                                         ctype.particle = group;\r
1114                                                 continue;\r
1115                                         }\r
1116                                         if(reader.LocalName == "all")\r
1117                                         {\r
1118                                                 level = 4;\r
1119                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);\r
1120                                                 if(all != null)\r
1121                                                         ctype.particle = all;\r
1122                                                 continue;\r
1123                                         }\r
1124                                         if(reader.LocalName == "choice")\r
1125                                         {\r
1126                                                 level = 4;\r
1127                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);\r
1128                                                 if(choice != null)\r
1129                                                         ctype.particle = choice;\r
1130                                                 continue;\r
1131                                         }\r
1132                                         if(reader.LocalName == "sequence")\r
1133                                         {\r
1134                                                 level = 4;\r
1135                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);\r
1136                                                 if(sequence != null)\r
1137                                                         ctype.particle = sequence;\r
1138                                                 continue;\r
1139                                         }\r
1140                                 }\r
1141                                 if(level <= 4)\r
1142                                 {\r
1143                                         if(reader.LocalName == "attribute")\r
1144                                         {\r
1145                                                 level = 4;\r
1146                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
1147                                                 if(attr != null)\r
1148                                                         ctype.Attributes.Add(attr);\r
1149                                                 continue;\r
1150                                         }\r
1151                                         if(reader.LocalName == "attributeGroup")\r
1152                                         {\r
1153                                                 level = 4;\r
1154                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);\r
1155                                                 if(attr != null)\r
1156                                                         ctype.attributes.Add(attr);\r
1157                                                 continue;\r
1158                                         }\r
1159                                 }\r
1160                                 if(level <= 5 && reader.LocalName == "anyAttribute")\r
1161                                 {\r
1162                                         level = 6;\r
1163                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);\r
1164                                         if(anyattr != null)\r
1165                                                 ctype.AnyAttribute = anyattr;\r
1166                                         continue;\r
1167                                 }\r
1168                                 reader.RaiseInvalidElementError();\r
1169                         }\r
1170                         return ctype;\r
1171                 }\r
1172 #endregion\r
1173         }\r
1174 }\r