The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ SchemaCollectionCompiler

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Compiler.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">priyal</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Schema
  17. {
  18.    
  19.     using System;
  20.     using System.Collections;
  21.     using System.Globalization;
  22.     using System.Text;
  23.     using System.Diagnostics;
  24.    
  25.     internal sealed class SchemaCollectionCompiler : BaseProcessor
  26.     {
  27.         bool compileContentModel;
  28.         XmlSchemaObjectTable examplars = new XmlSchemaObjectTable();
  29.         Stack complexTypeStack = new Stack();
  30.         XmlSchema schema;
  31.        
  32.         public SchemaCollectionCompiler(XmlNameTable nameTable, ValidationEventHandler eventHandler) : base(nameTable, null, eventHandler)
  33.         {
  34.         }
  35.        
  36.         public bool Execute(XmlSchema schema, SchemaInfo schemaInfo, bool compileContentModel)
  37.         {
  38.             this.compileContentModel = compileContentModel;
  39.             this.schema = schema;
  40.             Prepare();
  41.             Cleanup();
  42.             Compile();
  43.             if (!HasErrors) {
  44.                 Output(schemaInfo);
  45.             }
  46.             return !HasErrors;
  47.         }
  48.        
  49.         private void Prepare()
  50.         {
  51.             foreach (XmlSchemaElement element in this.schema.Elements.Values) {
  52.                 if (!element.SubstitutionGroup.IsEmpty) {
  53.                     XmlSchemaSubstitutionGroup substitutionGroup = (XmlSchemaSubstitutionGroup)this.examplars[element.SubstitutionGroup];
  54.                     if (substitutionGroup == null) {
  55.                         substitutionGroup = new XmlSchemaSubstitutionGroupV1Compat();
  56.                         substitutionGroup.Examplar = element.SubstitutionGroup;
  57.                         examplars.Add(element.SubstitutionGroup, substitutionGroup);
  58.                     }
  59.                     ArrayList members = substitutionGroup.Members;
  60.                     Debug.Assert(!members.Contains(element));
  61.                     members.Add(element);
  62.                 }
  63.             }
  64.         }
  65.        
  66.         private void Cleanup()
  67.         {
  68.             foreach (XmlSchemaGroup group in this.schema.Groups.Values) {
  69.                 CleanupGroup(group);
  70.             }
  71.             foreach (XmlSchemaAttributeGroup attributeGroup in this.schema.AttributeGroups.Values) {
  72.                 CleanupAttributeGroup(attributeGroup);
  73.             }
  74.             foreach (XmlSchemaType type in this.schema.SchemaTypes.Values) {
  75.                 if (type is XmlSchemaComplexType) {
  76.                     CleanupComplexType((XmlSchemaComplexType)type);
  77.                 }
  78.                 else {
  79.                     CleanupSimpleType((XmlSchemaSimpleType)type);
  80.                 }
  81.             }
  82.             foreach (XmlSchemaElement element in this.schema.Elements.Values) {
  83.                 CleanupElement(element);
  84.             }
  85.             foreach (XmlSchemaAttribute attribute in this.schema.Attributes.Values) {
  86.                 CleanupAttribute(attribute);
  87.             }
  88.         }
  89.        
  90.        
  91.         static internal void Cleanup(XmlSchema schema)
  92.         {
  93.             foreach (XmlSchemaExternal include in schema.Includes) {
  94.                 if (include.Schema != null) {
  95.                     Cleanup(include.Schema);
  96.                 }
  97.                 if (include is XmlSchemaRedefine) {
  98.                     XmlSchemaRedefine rdef = include as XmlSchemaRedefine;
  99.                     rdef.AttributeGroups.Clear();
  100.                     rdef.Groups.Clear();
  101.                     rdef.SchemaTypes.Clear();
  102.                    
  103.                     foreach (object item in rdef.Items) {
  104.                         if (item is XmlSchemaAttribute) {
  105.                             CleanupAttribute((XmlSchemaAttribute)item);
  106.                         }
  107.                         else if (item is XmlSchemaAttributeGroup) {
  108.                             CleanupAttributeGroup((XmlSchemaAttributeGroup)item);
  109.                         }
  110.                         else if (item is XmlSchemaComplexType) {
  111.                             CleanupComplexType((XmlSchemaComplexType)item);
  112.                         }
  113.                         else if (item is XmlSchemaSimpleType) {
  114.                             CleanupSimpleType((XmlSchemaSimpleType)item);
  115.                         }
  116.                         else if (item is XmlSchemaElement) {
  117.                             CleanupElement((XmlSchemaElement)item);
  118.                         }
  119.                         else if (item is XmlSchemaGroup) {
  120.                             CleanupGroup((XmlSchemaGroup)item);
  121.                         }
  122.                     }
  123.                 }
  124.                
  125.             }
  126.            
  127.             foreach (object item in schema.Items) {
  128.                 if (item is XmlSchemaAttribute) {
  129.                     CleanupAttribute((XmlSchemaAttribute)item);
  130.                 }
  131.                 else if (item is XmlSchemaAttributeGroup) {
  132.                     CleanupAttributeGroup((XmlSchemaAttributeGroup)item);
  133.                 }
  134.                 else if (item is XmlSchemaComplexType) {
  135.                     CleanupComplexType((XmlSchemaComplexType)item);
  136.                 }
  137.                 else if (item is XmlSchemaSimpleType) {
  138.                     CleanupSimpleType((XmlSchemaSimpleType)item);
  139.                 }
  140.                 else if (item is XmlSchemaElement) {
  141.                     CleanupElement((XmlSchemaElement)item);
  142.                 }
  143.                 else if (item is XmlSchemaGroup) {
  144.                     CleanupGroup((XmlSchemaGroup)item);
  145.                 }
  146.             }
  147.             schema.Attributes.Clear();
  148.             schema.AttributeGroups.Clear();
  149.             schema.SchemaTypes.Clear();
  150.             schema.Elements.Clear();
  151.             schema.Groups.Clear();
  152.             schema.Notations.Clear();
  153.             schema.Ids.Clear();
  154.             schema.IdentityConstraints.Clear();
  155.         }
  156.        
  157.         private void Compile()
  158.         {
  159.             this.schema.SchemaTypes.Insert(DatatypeImplementation.QnAnyType, XmlSchemaComplexType.AnyType);
  160.            
  161.             foreach (XmlSchemaSubstitutionGroupV1Compat substitutionGroup in examplars.Values) {
  162.                 CompileSubstitutionGroup(substitutionGroup);
  163.             }
  164.             foreach (XmlSchemaGroup group in this.schema.Groups.Values) {
  165.                 CompileGroup(group);
  166.             }
  167.             foreach (XmlSchemaAttributeGroup attributeGroup in this.schema.AttributeGroups.Values) {
  168.                 CompileAttributeGroup(attributeGroup);
  169.             }
  170.             foreach (XmlSchemaType type in this.schema.SchemaTypes.Values) {
  171.                 if (type is XmlSchemaComplexType) {
  172.                     CompileComplexType((XmlSchemaComplexType)type);
  173.                 }
  174.                 else {
  175.                     CompileSimpleType((XmlSchemaSimpleType)type);
  176.                 }
  177.             }
  178.             foreach (XmlSchemaElement element in this.schema.Elements.Values) {
  179.                 if (element.ElementDecl == null) {
  180.                     CompileElement(element);
  181.                 }
  182.             }
  183.             foreach (XmlSchemaAttribute attribute in this.schema.Attributes.Values) {
  184.                 if (attribute.AttDef == null) {
  185.                     CompileAttribute(attribute);
  186.                 }
  187.             }
  188.             foreach (XmlSchemaIdentityConstraint identityConstraint in this.schema.IdentityConstraints.Values) {
  189.                 if (identityConstraint.CompiledConstraint == null) {
  190.                     CompileIdentityConstraint(identityConstraint);
  191.                 }
  192.             }
  193.             while (this.complexTypeStack.Count > 0) {
  194.                 XmlSchemaComplexType type = (XmlSchemaComplexType)complexTypeStack.Pop();
  195.                 CompileCompexTypeElements(type);
  196.             }
  197.             foreach (XmlSchemaType type in this.schema.SchemaTypes.Values) {
  198.                 if (type is XmlSchemaComplexType) {
  199.                     CheckParticleDerivation((XmlSchemaComplexType)type);
  200.                 }
  201.             }
  202.             foreach (XmlSchemaElement element in this.schema.Elements.Values) {
  203.                 if (element.ElementSchemaType is XmlSchemaComplexType && element.SchemaTypeName == XmlQualifiedName.Empty) {
  204.                     // only local schemaTypes
  205.                     CheckParticleDerivation((XmlSchemaComplexType)element.ElementSchemaType);
  206.                 }
  207.             }
  208.             foreach (XmlSchemaSubstitutionGroup substitutionGroup in examplars.Values) {
  209.                 CheckSubstitutionGroup(substitutionGroup);
  210.             }
  211.            
  212.             this.schema.SchemaTypes.Remove(DatatypeImplementation.QnAnyType);
  213.             //For backward compatibility
  214.         }
  215.        
  216.         private void Output(SchemaInfo schemaInfo)
  217.         {
  218.             foreach (XmlSchemaElement element in this.schema.Elements.Values) {
  219.                 schemaInfo.TargetNamespaces[element.QualifiedName.Namespace] = true;
  220.                 schemaInfo.ElementDecls.Add(element.QualifiedName, element.ElementDecl);
  221.             }
  222.             foreach (XmlSchemaAttribute attribute in this.schema.Attributes.Values) {
  223.                 schemaInfo.TargetNamespaces[attribute.QualifiedName.Namespace] = true;
  224.                 schemaInfo.AttributeDecls.Add(attribute.QualifiedName, attribute.AttDef);
  225.             }
  226.             foreach (XmlSchemaType type in this.schema.SchemaTypes.Values) {
  227.                 schemaInfo.TargetNamespaces[type.QualifiedName.Namespace] = true;
  228.                 XmlSchemaComplexType complexType = type as XmlSchemaComplexType;
  229.                 if (complexType == null || (!complexType.IsAbstract && type != XmlSchemaComplexType.AnyType)) {
  230.                     schemaInfo.ElementDeclsByType.Add(type.QualifiedName, type.ElementDecl);
  231.                 }
  232.             }
  233.             foreach (XmlSchemaNotation notation in this.schema.Notations.Values) {
  234.                 schemaInfo.TargetNamespaces[notation.QualifiedName.Namespace] = true;
  235.                 SchemaNotation no = new SchemaNotation(notation.QualifiedName);
  236.                 no.SystemLiteral = notation.System;
  237.                 no.Pubid = notation.Public;
  238.                 if (schemaInfo.Notations[no.Name.Name] == null) {
  239.                     schemaInfo.Notations.Add(no.Name.Name, no);
  240.                 }
  241.             }
  242.         }
  243.        
  244.         private static void CleanupAttribute(XmlSchemaAttribute attribute)
  245.         {
  246.             if (attribute.SchemaType != null) {
  247.                 CleanupSimpleType((XmlSchemaSimpleType)attribute.SchemaType);
  248.             }
  249.             attribute.AttDef = null;
  250.         }
  251.        
  252.         private static void CleanupAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  253.         {
  254.             CleanupAttributes(attributeGroup.Attributes);
  255.             attributeGroup.AttributeUses.Clear();
  256.             attributeGroup.AttributeWildcard = null;
  257.         }
  258.        
  259.         private static void CleanupComplexType(XmlSchemaComplexType complexType)
  260.         {
  261.             if (complexType.ContentModel != null) {
  262.                 //simpleContent or complexContent
  263.                 if (complexType.ContentModel is XmlSchemaSimpleContent) {
  264.                     XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel;
  265.                     if (simpleContent.Content is XmlSchemaSimpleContentExtension) {
  266.                         XmlSchemaSimpleContentExtension simpleExtension = (XmlSchemaSimpleContentExtension)simpleContent.Content;
  267.                         CleanupAttributes(simpleExtension.Attributes);
  268.                     }
  269.                     else {
  270.                         //simpleContent.Content is XmlSchemaSimpleContentRestriction
  271.                         XmlSchemaSimpleContentRestriction simpleRestriction = (XmlSchemaSimpleContentRestriction)simpleContent.Content;
  272.                         CleanupAttributes(simpleRestriction.Attributes);
  273.                     }
  274.                 }
  275.                 else {
  276.                     // complexType.ContentModel is XmlSchemaComplexContent
  277.                     XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)complexType.ContentModel;
  278.                     if (complexContent.Content is XmlSchemaComplexContentExtension) {
  279.                         XmlSchemaComplexContentExtension complexExtension = (XmlSchemaComplexContentExtension)complexContent.Content;
  280.                         CleanupParticle(complexExtension.Particle);
  281.                         CleanupAttributes(complexExtension.Attributes);
  282.                        
  283.                     }
  284.                     else {
  285.                         //XmlSchemaComplexContentRestriction
  286.                         XmlSchemaComplexContentRestriction complexRestriction = (XmlSchemaComplexContentRestriction)complexContent.Content;
  287.                         CleanupParticle(complexRestriction.Particle);
  288.                         CleanupAttributes(complexRestriction.Attributes);
  289.                     }
  290.                 }
  291.             }
  292.             else {
  293.                 //equals XmlSchemaComplexContent with baseType is anyType
  294.                 CleanupParticle(complexType.Particle);
  295.                 CleanupAttributes(complexType.Attributes);
  296.             }
  297.             complexType.LocalElements.Clear();
  298.             complexType.AttributeUses.Clear();
  299.             complexType.SetAttributeWildcard(null);
  300.             complexType.SetContentTypeParticle(XmlSchemaParticle.Empty);
  301.             complexType.ElementDecl = null;
  302.         }
  303.        
  304.         private static void CleanupSimpleType(XmlSchemaSimpleType simpleType)
  305.         {
  306.             simpleType.ElementDecl = null;
  307.         }
  308.        
  309.         private static void CleanupElement(XmlSchemaElement element)
  310.         {
  311.             if (element.SchemaType != null) {
  312.                 XmlSchemaComplexType complexType = element.SchemaType as XmlSchemaComplexType;
  313.                 if (complexType != null) {
  314.                     CleanupComplexType(complexType);
  315.                 }
  316.                 else {
  317.                     CleanupSimpleType((XmlSchemaSimpleType)element.SchemaType);
  318.                 }
  319.             }
  320.             foreach (XmlSchemaIdentityConstraint constr in element.Constraints) {
  321.                 constr.CompiledConstraint = null;
  322.             }
  323.             element.ElementDecl = null;
  324.         }
  325.        
  326.         private static void CleanupAttributes(XmlSchemaObjectCollection attributes)
  327.         {
  328.             foreach (XmlSchemaObject obj in attributes) {
  329.                 if (obj is XmlSchemaAttribute) {
  330.                     CleanupAttribute((XmlSchemaAttribute)obj);
  331.                 }
  332.             }
  333.         }
  334.        
  335.         private static void CleanupGroup(XmlSchemaGroup group)
  336.         {
  337.             CleanupParticle(group.Particle);
  338.             group.CanonicalParticle = null;
  339.         }
  340.        
  341.         private static void CleanupParticle(XmlSchemaParticle particle)
  342.         {
  343.             if (particle is XmlSchemaElement) {
  344.                 CleanupElement((XmlSchemaElement)particle);
  345.             }
  346.             else if (particle is XmlSchemaGroupBase) {
  347.                 foreach (XmlSchemaParticle p in ((XmlSchemaGroupBase)particle).Items) {
  348.                     CleanupParticle(p);
  349.                 }
  350.             }
  351.         }
  352.        
  353.         private void CompileSubstitutionGroup(XmlSchemaSubstitutionGroupV1Compat substitutionGroup)
  354.         {
  355.             if (substitutionGroup.IsProcessing) {
  356.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  357.                     SendValidationEvent(Res.Sch_SubstitutionCircularRef, element);
  358.                     return;
  359.                 }
  360.             }
  361.             XmlSchemaElement examplar = (XmlSchemaElement)this.schema.Elements[substitutionGroup.Examplar];
  362.             if (substitutionGroup.Members.Contains(examplar)) {
  363.                 // already checked
  364.                 return;
  365.             }
  366.             substitutionGroup.IsProcessing = true;
  367.             if (examplar != null) {
  368.                 if (examplar.FinalResolved == XmlSchemaDerivationMethod.All) {
  369.                     SendValidationEvent(Res.Sch_InvalidExamplar, examplar);
  370.                 }
  371.                
  372.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  373.                    
  374.                     //Chain to other head's that are members of this head's substGroup
  375.                     XmlSchemaSubstitutionGroupV1Compat g = (XmlSchemaSubstitutionGroupV1Compat)examplars[element.QualifiedName];
  376.                     if (g != null) {
  377.                         CompileSubstitutionGroup(g);
  378.                         foreach (XmlSchemaElement element1 in g.Choice.Items) {
  379.                             substitutionGroup.Choice.Items.Add(element1);
  380.                         }
  381.                     }
  382.                     else {
  383.                         substitutionGroup.Choice.Items.Add(element);
  384.                     }
  385.                 }
  386.                 substitutionGroup.Choice.Items.Add(examplar);
  387.                 substitutionGroup.Members.Add(examplar);
  388.                 // Compiled mark
  389.             }
  390.             else {
  391.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  392.                     SendValidationEvent(Res.Sch_NoExamplar, element);
  393.                     break;
  394.                 }
  395.             }
  396.             substitutionGroup.IsProcessing = false;
  397.         }
  398.        
  399.         private void CheckSubstitutionGroup(XmlSchemaSubstitutionGroup substitutionGroup)
  400.         {
  401.             XmlSchemaElement examplar = (XmlSchemaElement)this.schema.Elements[substitutionGroup.Examplar];
  402.             if (examplar != null) {
  403.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  404.                     if (element != examplar) {
  405.                         if (!XmlSchemaType.IsDerivedFrom(element.ElementSchemaType, examplar.ElementSchemaType, examplar.FinalResolved)) {
  406.                             SendValidationEvent(Res.Sch_InvalidSubstitutionMember, (element.QualifiedName).ToString(), (examplar.QualifiedName).ToString(), element);
  407.                         }
  408.                     }
  409.                 }
  410.             }
  411.         }
  412.        
  413.         private void CompileGroup(XmlSchemaGroup group)
  414.         {
  415.             if (group.IsProcessing) {
  416.                 SendValidationEvent(Res.Sch_GroupCircularRef, group);
  417.                 group.CanonicalParticle = XmlSchemaParticle.Empty;
  418.             }
  419.             else {
  420.                 group.IsProcessing = true;
  421.                 if (group.CanonicalParticle == null) {
  422.                     group.CanonicalParticle = CannonicalizeParticle(group.Particle, true, true);
  423.                 }
  424.                 Debug.Assert(group.CanonicalParticle != null);
  425.                 group.IsProcessing = false;
  426.             }
  427.         }
  428.        
  429.         private void CompileSimpleType(XmlSchemaSimpleType simpleType)
  430.         {
  431.             if (simpleType.IsProcessing) {
  432.                 throw new XmlSchemaException(Res.Sch_TypeCircularRef, simpleType);
  433.             }
  434.             if (simpleType.ElementDecl != null) {
  435.                 // already compiled
  436.                 return;
  437.             }
  438.             simpleType.IsProcessing = true;
  439.             try {
  440.                 if (simpleType.Content is XmlSchemaSimpleTypeList) {
  441.                     XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content;
  442.                     XmlSchemaDatatype datatype;
  443.                     simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType);
  444.                     if (list.ItemTypeName.IsEmpty) {
  445.                         CompileSimpleType(list.ItemType);
  446.                         list.BaseItemType = list.ItemType;
  447.                         datatype = list.ItemType.Datatype;
  448.                     }
  449.                     else {
  450.                         XmlSchemaSimpleType type = GetSimpleType(list.ItemTypeName);
  451.                         if (type != null) {
  452.                             if ((type.FinalResolved & XmlSchemaDerivationMethod.List) != 0) {
  453.                                 SendValidationEvent(Res.Sch_BaseFinalList, simpleType);
  454.                             }
  455.                             list.BaseItemType = type;
  456.                             datatype = type.Datatype;
  457.                         }
  458.                         else {
  459.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, list.ItemTypeName.ToString(), simpleType);
  460.                         }
  461.                     }
  462.                     simpleType.SetDatatype(datatype.DeriveByList(simpleType));
  463.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.List);
  464.                 }
  465.                 else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) {
  466.                     XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content;
  467.                     XmlSchemaDatatype datatype;
  468.                     if (restriction.BaseTypeName.IsEmpty) {
  469.                         CompileSimpleType(restriction.BaseType);
  470.                         simpleType.SetBaseSchemaType(restriction.BaseType);
  471.                         datatype = restriction.BaseType.Datatype;
  472.                     }
  473.                     else if (simpleType.Redefined != null && restriction.BaseTypeName == simpleType.Redefined.QualifiedName) {
  474.                         CompileSimpleType((XmlSchemaSimpleType)simpleType.Redefined);
  475.                         simpleType.SetBaseSchemaType(simpleType.Redefined.BaseXmlSchemaType);
  476.                         datatype = simpleType.Redefined.Datatype;
  477.                     }
  478.                     else {
  479.                         if (restriction.BaseTypeName.Equals(DatatypeImplementation.QnAnySimpleType)) {
  480.                             throw new XmlSchemaException(Res.Sch_InvalidSimpleTypeRestriction, restriction.BaseTypeName.ToString(), simpleType);
  481.                         }
  482.                         XmlSchemaSimpleType type = GetSimpleType(restriction.BaseTypeName);
  483.                         if (type != null) {
  484.                             if ((type.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  485.                                 SendValidationEvent(Res.Sch_BaseFinalRestriction, simpleType);
  486.                             }
  487.                             simpleType.SetBaseSchemaType(type);
  488.                             datatype = type.Datatype;
  489.                         }
  490.                         else {
  491.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, restriction.BaseTypeName.ToString(), simpleType);
  492.                         }
  493.                     }
  494.                     simpleType.SetDatatype(datatype.DeriveByRestriction(restriction.Facets, NameTable, simpleType));
  495.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  496.                 }
  497.                 else {
  498.                     //simpleType.Content is XmlSchemaSimpleTypeUnion
  499.                     XmlSchemaSimpleType[] baseTypes = CompileBaseMemberTypes(simpleType);
  500.                     simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType);
  501.                     simpleType.SetDatatype(XmlSchemaDatatype.DeriveByUnion(baseTypes, simpleType));
  502.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.Union);
  503.                 }
  504.             }
  505.             catch (XmlSchemaException e) {
  506.                 if (e.SourceSchemaObject == null) {
  507.                     e.SetSource(simpleType);
  508.                 }
  509.                 SendValidationEvent(e);
  510.                 simpleType.SetDatatype(DatatypeImplementation.AnySimpleType.Datatype);
  511.             }
  512.             finally {
  513.                 SchemaElementDecl decl = new SchemaElementDecl();
  514.                 decl.ContentValidator = ContentValidator.TextOnly;
  515.                 decl.SchemaType = simpleType;
  516.                 decl.Datatype = simpleType.Datatype;
  517.                 simpleType.ElementDecl = decl;
  518.                 simpleType.IsProcessing = false;
  519.             }
  520.         }
  521.        
  522.         private XmlSchemaSimpleType[] CompileBaseMemberTypes(XmlSchemaSimpleType simpleType)
  523.         {
  524.             XmlSchemaSimpleType unionMember;
  525.             ArrayList memberTypeDefinitions = new ArrayList();
  526.            
  527.             XmlSchemaSimpleTypeUnion mainUnion = (XmlSchemaSimpleTypeUnion)simpleType.Content;
  528.            
  529.             Array mainMemberTypes = mainUnion.MemberTypes;
  530.             if (mainMemberTypes != null) {
  531.                 foreach (XmlQualifiedName memberName in mainMemberTypes) {
  532.                     unionMember = GetSimpleType(memberName);
  533.                     if (unionMember != null) {
  534.                         if (unionMember.Datatype.Variety == XmlSchemaDatatypeVariety.Union) {
  535.                             //union of union
  536.                             CheckUnionType(unionMember, memberTypeDefinitions, simpleType);
  537.                         }
  538.                         else {
  539.                             //its list or atomic
  540.                             memberTypeDefinitions.Add(unionMember);
  541.                         }
  542.                         //Check derivation method of the member that is referenced
  543.                         if ((unionMember.FinalResolved & XmlSchemaDerivationMethod.Union) != 0) {
  544.                             SendValidationEvent(Res.Sch_BaseFinalUnion, simpleType);
  545.                         }
  546.                     }
  547.                     else {
  548.                         throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, memberName.ToString(), simpleType);
  549.                     }
  550.                 }
  551.             }
  552.            
  553.             //Now add the baseTypes that are defined inside the union itself
  554.             XmlSchemaObjectCollection mainBaseTypes = mainUnion.BaseTypes;
  555.             //TODO check for null
  556.             if (mainBaseTypes != null) {
  557.                 foreach (XmlSchemaSimpleType st in mainBaseTypes) {
  558.                     CompileSimpleType(st);
  559.                     if (st.Datatype.Variety == XmlSchemaDatatypeVariety.Union) {
  560.                         //union of union
  561.                         CheckUnionType(st, memberTypeDefinitions, simpleType);
  562.                     }
  563.                     else {
  564.                         //its list or atomic
  565.                         memberTypeDefinitions.Add(st);
  566.                     }
  567.                 }
  568.             }
  569.             //set all types
  570.             mainUnion.SetBaseMemberTypes(memberTypeDefinitions.ToArray(typeof(XmlSchemaSimpleType)) as XmlSchemaSimpleType[]);
  571.             return mainUnion.BaseMemberTypes;
  572.         }
  573.        
  574.         private void CheckUnionType(XmlSchemaSimpleType unionMember, ArrayList memberTypeDefinitions, XmlSchemaSimpleType parentType)
  575.         {
  576.             XmlSchemaDatatype unionDatatype = unionMember.Datatype;
  577.             if (unionMember.DerivedBy == XmlSchemaDerivationMethod.Restriction && (unionDatatype.HasLexicalFacets || unionDatatype.HasValueFacets)) {
  578.                 SendValidationEvent(Res.Sch_UnionFromUnion, parentType);
  579.             }
  580.             else {
  581.                 Datatype_union uniondt = unionMember.Datatype as Datatype_union;
  582.                 memberTypeDefinitions.AddRange(uniondt.BaseMemberTypes);
  583.             }
  584.         }
  585.        
  586.         private void CompileComplexType(XmlSchemaComplexType complexType)
  587.         {
  588.             if (complexType.ElementDecl != null) {
  589.                 //already compiled
  590.                 return;
  591.             }
  592.             if (complexType.IsProcessing) {
  593.                 SendValidationEvent(Res.Sch_TypeCircularRef, complexType);
  594.                 return;
  595.             }
  596.             complexType.IsProcessing = true;
  597.             if (complexType.ContentModel != null) {
  598.                 //simpleContent or complexContent
  599.                 if (complexType.ContentModel is XmlSchemaSimpleContent) {
  600.                     XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel;
  601.                     complexType.SetContentType(XmlSchemaContentType.TextOnly);
  602.                     if (simpleContent.Content is XmlSchemaSimpleContentExtension) {
  603.                         CompileSimpleContentExtension(complexType, (XmlSchemaSimpleContentExtension)simpleContent.Content);
  604.                     }
  605.                     else {
  606.                         //simpleContent.Content is XmlSchemaSimpleContentRestriction
  607.                         CompileSimpleContentRestriction(complexType, (XmlSchemaSimpleContentRestriction)simpleContent.Content);
  608.                     }
  609.                 }
  610.                 else {
  611.                     // complexType.ContentModel is XmlSchemaComplexContent
  612.                     XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)complexType.ContentModel;
  613.                     if (complexContent.Content is XmlSchemaComplexContentExtension) {
  614.                         CompileComplexContentExtension(complexType, complexContent, (XmlSchemaComplexContentExtension)complexContent.Content);
  615.                     }
  616.                     else {
  617.                         // complexContent.Content is XmlSchemaComplexContentRestriction
  618.                         CompileComplexContentRestriction(complexType, complexContent, (XmlSchemaComplexContentRestriction)complexContent.Content);
  619.                     }
  620.                 }
  621.             }
  622.             else {
  623.                 //equals XmlSchemaComplexContent with baseType is anyType
  624.                 complexType.SetBaseSchemaType(XmlSchemaComplexType.AnyType);
  625.                 CompileLocalAttributes(XmlSchemaComplexType.AnyType, complexType, complexType.Attributes, complexType.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  626.                 complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  627.                 complexType.SetContentTypeParticle(CompileContentTypeParticle(complexType.Particle, true));
  628.                 complexType.SetContentType(GetSchemaContentType(complexType, null, complexType.ContentTypeParticle));
  629.             }
  630.             bool hasID = false;
  631.             foreach (XmlSchemaAttribute attribute in complexType.AttributeUses.Values) {
  632.                 if (attribute.Use != XmlSchemaUse.Prohibited) {
  633.                     XmlSchemaDatatype datatype = attribute.Datatype;
  634.                     if (datatype != null && datatype.TokenizedType == XmlTokenizedType.ID) {
  635.                         if (hasID) {
  636.                             SendValidationEvent(Res.Sch_TwoIdAttrUses, complexType);
  637.                         }
  638.                         else {
  639.                             hasID = true;
  640.                         }
  641.                     }
  642.                 }
  643.             }
  644.             SchemaElementDecl decl = new SchemaElementDecl();
  645.             decl.ContentValidator = CompileComplexContent(complexType);
  646.             decl.SchemaType = complexType;
  647.             decl.IsAbstract = complexType.IsAbstract;
  648.             decl.Datatype = complexType.Datatype;
  649.             decl.Block = complexType.BlockResolved;
  650.             decl.AnyAttribute = complexType.AttributeWildcard;
  651.             foreach (XmlSchemaAttribute attribute in complexType.AttributeUses.Values) {
  652.                 if (attribute.Use == XmlSchemaUse.Prohibited) {
  653.                     if (decl.ProhibitedAttributes[attribute.QualifiedName] == null) {
  654.                         decl.ProhibitedAttributes.Add(attribute.QualifiedName, attribute.QualifiedName);
  655.                     }
  656.                 }
  657.                 else {
  658.                     if (decl.AttDefs[attribute.QualifiedName] == null && attribute.AttDef != null && attribute.AttDef.Name != XmlQualifiedName.Empty && attribute.AttDef != SchemaAttDef.Empty) {
  659.                         decl.AddAttDef(attribute.AttDef);
  660.                     }
  661.                 }
  662.             }
  663.             decl.EndAddAttDef();
  664.            
  665.             complexType.ElementDecl = decl;
  666.            
  667.             complexType.IsProcessing = false;
  668.         }
  669.        
  670.        
  671.         private void CompileSimpleContentExtension(XmlSchemaComplexType complexType, XmlSchemaSimpleContentExtension simpleExtension)
  672.         {
  673.             XmlSchemaComplexType baseType = null;
  674.             if (complexType.Redefined != null && simpleExtension.BaseTypeName == complexType.Redefined.QualifiedName) {
  675.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  676.                 CompileComplexType(baseType);
  677.                 complexType.SetBaseSchemaType(baseType);
  678.                 complexType.SetDatatype(baseType.Datatype);
  679.             }
  680.             else {
  681.                 XmlSchemaType bto = GetAnySchemaType(simpleExtension.BaseTypeName);
  682.                 if (bto == null) {
  683.                     SendValidationEvent(Res.Sch_UndeclaredType, simpleExtension.BaseTypeName.ToString(), complexType);
  684.                 }
  685.                 else {
  686.                     complexType.SetBaseSchemaType(bto);
  687.                     complexType.SetDatatype(bto.Datatype);
  688.                 }
  689.                 baseType = bto as XmlSchemaComplexType;
  690.             }
  691.             if (baseType != null) {
  692.                 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0) {
  693.                     SendValidationEvent(Res.Sch_BaseFinalExtension, complexType);
  694.                 }
  695.                 if (baseType.ContentType != XmlSchemaContentType.TextOnly) {
  696.                     SendValidationEvent(Res.Sch_NotSimpleContent, complexType);
  697.                 }
  698.             }
  699.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Extension);
  700.             CompileLocalAttributes(baseType, complexType, simpleExtension.Attributes, simpleExtension.AnyAttribute, XmlSchemaDerivationMethod.Extension);
  701.         }
  702.        
  703.         private void CompileSimpleContentRestriction(XmlSchemaComplexType complexType, XmlSchemaSimpleContentRestriction simpleRestriction)
  704.         {
  705.             XmlSchemaComplexType baseType = null;
  706.             XmlSchemaDatatype datatype = null;
  707.             if (complexType.Redefined != null && simpleRestriction.BaseTypeName == complexType.Redefined.QualifiedName) {
  708.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  709.                 CompileComplexType(baseType);
  710.                 datatype = baseType.Datatype;
  711.             }
  712.             else {
  713.                 baseType = GetComplexType(simpleRestriction.BaseTypeName);
  714.                 if (baseType == null) {
  715.                     SendValidationEvent(Res.Sch_UndefBaseRestriction, simpleRestriction.BaseTypeName.ToString(), simpleRestriction);
  716.                     return;
  717.                 }
  718.                 if (baseType.ContentType == XmlSchemaContentType.TextOnly) {
  719.                     if (simpleRestriction.BaseType == null) {
  720.                         datatype = baseType.Datatype;
  721.                         //There is a bug here. Need to check if simpleRestriction has facets.
  722.                         //If yes, Need tp apply these facets as well.
  723.                     }
  724.                     else {
  725.                         CompileSimpleType(simpleRestriction.BaseType);
  726.                         if (!XmlSchemaType.IsDerivedFromDatatype(simpleRestriction.BaseType.Datatype, baseType.Datatype, XmlSchemaDerivationMethod.None)) {
  727.                             SendValidationEvent(Res.Sch_DerivedNotFromBase, simpleRestriction);
  728.                         }
  729.                         datatype = simpleRestriction.BaseType.Datatype;
  730.                     }
  731.                 }
  732.                 else if (baseType.ContentType == XmlSchemaContentType.Mixed && baseType.ElementDecl.ContentValidator.IsEmptiable) {
  733.                     if (simpleRestriction.BaseType != null) {
  734.                         CompileSimpleType(simpleRestriction.BaseType);
  735.                         complexType.SetBaseSchemaType(simpleRestriction.BaseType);
  736.                         datatype = simpleRestriction.BaseType.Datatype;
  737.                     }
  738.                     else {
  739.                         SendValidationEvent(Res.Sch_NeedSimpleTypeChild, simpleRestriction);
  740.                     }
  741.                 }
  742.                 else {
  743.                     SendValidationEvent(Res.Sch_NotSimpleContent, complexType);
  744.                 }
  745.             }
  746.             if (baseType != null && baseType.ElementDecl != null) {
  747.                 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  748.                     SendValidationEvent(Res.Sch_BaseFinalRestriction, complexType);
  749.                 }
  750.             }
  751.             if (baseType != null) {
  752.                 complexType.SetBaseSchemaType(baseType);
  753.             }
  754.             if (datatype != null) {
  755.                 try {
  756.                     complexType.SetDatatype(datatype.DeriveByRestriction(simpleRestriction.Facets, NameTable, complexType));
  757.                 }
  758.                 catch (XmlSchemaException e) {
  759.                     if (e.SourceSchemaObject == null) {
  760.                         e.SetSource(complexType);
  761.                     }
  762.                     SendValidationEvent(e);
  763.                     complexType.SetDatatype(DatatypeImplementation.AnySimpleType.Datatype);
  764.                 }
  765.             }
  766.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  767.             CompileLocalAttributes(baseType, complexType, simpleRestriction.Attributes, simpleRestriction.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  768.         }
  769.        
  770.         private void CompileComplexContentExtension(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaComplexContentExtension complexExtension)
  771.         {
  772.             XmlSchemaComplexType baseType = null;
  773.             if (complexType.Redefined != null && complexExtension.BaseTypeName == complexType.Redefined.QualifiedName) {
  774.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  775.                 CompileComplexType(baseType);
  776.             }
  777.             else {
  778.                 baseType = GetComplexType(complexExtension.BaseTypeName);
  779.                 if (baseType == null) {
  780.                     SendValidationEvent(Res.Sch_UndefBaseExtension, complexExtension.BaseTypeName.ToString(), complexExtension);
  781.                     return;
  782.                 }
  783.             }
  784.             if (baseType != null && baseType.ElementDecl != null) {
  785.                 if (baseType.ContentType == XmlSchemaContentType.TextOnly) {
  786.                     SendValidationEvent(Res.Sch_NotComplexContent, complexType);
  787.                     return;
  788.                 }
  789.             }
  790.             complexType.SetBaseSchemaType(baseType);
  791.             if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0) {
  792.                 SendValidationEvent(Res.Sch_BaseFinalExtension, complexType);
  793.             }
  794.             CompileLocalAttributes(baseType, complexType, complexExtension.Attributes, complexExtension.AnyAttribute, XmlSchemaDerivationMethod.Extension);
  795.            
  796.             XmlSchemaParticle baseParticle = baseType.ContentTypeParticle;
  797.             XmlSchemaParticle extendedParticle = CannonicalizeParticle(complexExtension.Particle, true, true);
  798.             if (baseParticle != XmlSchemaParticle.Empty) {
  799.                 if (extendedParticle != XmlSchemaParticle.Empty) {
  800.                     XmlSchemaSequence compiledParticle = new XmlSchemaSequence();
  801.                     compiledParticle.Items.Add(baseParticle);
  802.                     compiledParticle.Items.Add(extendedParticle);
  803.                     complexType.SetContentTypeParticle(CompileContentTypeParticle(compiledParticle, false));
  804.                 }
  805.                 else {
  806.                     complexType.SetContentTypeParticle(baseParticle);
  807.                 }
  808.                 XmlSchemaContentType contentType = GetSchemaContentType(complexType, complexContent, extendedParticle);
  809.                 if (contentType == XmlSchemaContentType.Empty) {
  810.                     //Derived content type is empty, Get ContentType from base
  811.                     contentType = baseType.ContentType;
  812.                 }
  813.                 complexType.SetContentType(contentType);
  814.                 if (complexType.ContentType != baseType.ContentType) {
  815.                     SendValidationEvent(Res.Sch_DifContentType, complexType);
  816.                 }
  817.             }
  818.             else {
  819.                 complexType.SetContentTypeParticle(extendedParticle);
  820.                 complexType.SetContentType(GetSchemaContentType(complexType, complexContent, complexType.ContentTypeParticle));
  821.             }
  822.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Extension);
  823.         }
  824.        
  825.         private void CompileComplexContentRestriction(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaComplexContentRestriction complexRestriction)
  826.         {
  827.             XmlSchemaComplexType baseType = null;
  828.             if (complexType.Redefined != null && complexRestriction.BaseTypeName == complexType.Redefined.QualifiedName) {
  829.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  830.                 CompileComplexType(baseType);
  831.             }
  832.             else {
  833.                 baseType = GetComplexType(complexRestriction.BaseTypeName);
  834.                 if (baseType == null) {
  835.                     SendValidationEvent(Res.Sch_UndefBaseRestriction, complexRestriction.BaseTypeName.ToString(), complexRestriction);
  836.                     return;
  837.                 }
  838.             }
  839.             if (baseType != null && baseType.ElementDecl != null) {
  840.                 if (baseType.ContentType == XmlSchemaContentType.TextOnly) {
  841.                     SendValidationEvent(Res.Sch_NotComplexContent, complexType);
  842.                     return;
  843.                 }
  844.             }
  845.             complexType.SetBaseSchemaType(baseType);
  846.             if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  847.                 SendValidationEvent(Res.Sch_BaseFinalRestriction, complexType);
  848.             }
  849.             CompileLocalAttributes(baseType, complexType, complexRestriction.Attributes, complexRestriction.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  850.            
  851.             complexType.SetContentTypeParticle(CompileContentTypeParticle(complexRestriction.Particle, true));
  852.             complexType.SetContentType(GetSchemaContentType(complexType, complexContent, complexType.ContentTypeParticle));
  853.             if (complexType.ContentType == XmlSchemaContentType.Empty) {
  854.                 if (baseType.ElementDecl != null) {
  855.                     Debug.Assert(baseType.ElementDecl.ContentValidator != null);
  856.                 }
  857.                 if (baseType.ElementDecl != null && !baseType.ElementDecl.ContentValidator.IsEmptiable) {
  858.                     SendValidationEvent(Res.Sch_InvalidContentRestriction, complexType);
  859.                 }
  860.             }
  861.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  862.         }
  863.        
  864.         private void CheckParticleDerivation(XmlSchemaComplexType complexType)
  865.         {
  866.             XmlSchemaComplexType baseType = complexType.BaseXmlSchemaType as XmlSchemaComplexType;
  867.             if (baseType != null && baseType != XmlSchemaComplexType.AnyType && complexType.DerivedBy == XmlSchemaDerivationMethod.Restriction) {
  868.                 if (!IsValidRestriction(complexType.ContentTypeParticle, baseType.ContentTypeParticle)) {
  869.                     #if DEBUG
  870.                     if (complexType.ContentTypeParticle != null && baseType.ContentTypeParticle != null) {
  871.                         string position = string.Empty;
  872.                         if (complexType.SourceUri != null) {
  873.                             position = " in " + complexType.SourceUri + "(" + complexType.LineNumber + ", " + complexType.LinePosition + ")";
  874.                         }
  875.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType content restriction" + position);
  876.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpContentModel(baseType.ContentTypeParticle));
  877.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpContentModel(complexType.ContentTypeParticle));
  878.                     }
  879.                     #endif
  880.                     SendValidationEvent(Res.Sch_InvalidParticleRestriction, complexType);
  881.                 }
  882.             }
  883.         }
  884.        
  885.         private XmlSchemaParticle CompileContentTypeParticle(XmlSchemaParticle particle, bool substitution)
  886.         {
  887.             XmlSchemaParticle ctp = CannonicalizeParticle(particle, true, substitution);
  888.             XmlSchemaChoice choice = ctp as XmlSchemaChoice;
  889.             if (choice != null && choice.Items.Count == 0) {
  890.                 if (choice.MinOccurs != decimal.Zero) {
  891.                     SendValidationEvent(Res.Sch_EmptyChoice, choice, XmlSeverityType.Warning);
  892.                 }
  893.                 return XmlSchemaParticle.Empty;
  894.             }
  895.             return ctp;
  896.         }
  897.        
  898.         private XmlSchemaParticle CannonicalizeParticle(XmlSchemaParticle particle, bool root, bool substitution)
  899.         {
  900.             if (particle == null || particle.IsEmpty) {
  901.                 return XmlSchemaParticle.Empty;
  902.             }
  903.             else if (particle is XmlSchemaElement) {
  904.                 return CannonicalizeElement((XmlSchemaElement)particle, substitution);
  905.             }
  906.             else if (particle is XmlSchemaGroupRef) {
  907.                 return CannonicalizeGroupRef((XmlSchemaGroupRef)particle, root, substitution);
  908.             }
  909.             else if (particle is XmlSchemaAll) {
  910.                 return CannonicalizeAll((XmlSchemaAll)particle, root, substitution);
  911.             }
  912.             else if (particle is XmlSchemaChoice) {
  913.                 return CannonicalizeChoice((XmlSchemaChoice)particle, root, substitution);
  914.             }
  915.             else if (particle is XmlSchemaSequence) {
  916.                 return CannonicalizeSequence((XmlSchemaSequence)particle, root, substitution);
  917.             }
  918.             else {
  919.                 return particle;
  920.             }
  921.         }
  922.        
  923.         private XmlSchemaParticle CannonicalizeElement(XmlSchemaElement element, bool substitution)
  924.         {
  925.             if (!element.RefName.IsEmpty && substitution && (element.BlockResolved & XmlSchemaDerivationMethod.Substitution) == 0) {
  926.                 XmlSchemaSubstitutionGroupV1Compat substitutionGroup = (XmlSchemaSubstitutionGroupV1Compat)examplars[element.QualifiedName];
  927.                 if (substitutionGroup == null) {
  928.                     return element;
  929.                 }
  930.                 else {
  931.                     XmlSchemaChoice choice = (XmlSchemaChoice)substitutionGroup.Choice.Clone();
  932.                     choice.MinOccurs = element.MinOccurs;
  933.                     choice.MaxOccurs = element.MaxOccurs;
  934.                     return choice;
  935.                 }
  936.             }
  937.             else {
  938.                 return element;
  939.             }
  940.         }
  941.        
  942.         private XmlSchemaParticle CannonicalizeGroupRef(XmlSchemaGroupRef groupRef, bool root, bool substitution)
  943.         {
  944.             XmlSchemaGroup group;
  945.             if (groupRef.Redefined != null) {
  946.                 group = groupRef.Redefined;
  947.             }
  948.             else {
  949.                 group = (XmlSchemaGroup)this.schema.Groups[groupRef.RefName];
  950.             }
  951.             if (group == null) {
  952.                 SendValidationEvent(Res.Sch_UndefGroupRef, groupRef.RefName.ToString(), groupRef);
  953.                 return XmlSchemaParticle.Empty;
  954.             }
  955.             if (group.CanonicalParticle == null) {
  956.                 CompileGroup(group);
  957.             }
  958.             if (group.CanonicalParticle == XmlSchemaParticle.Empty) {
  959.                 return XmlSchemaParticle.Empty;
  960.             }
  961.             XmlSchemaGroupBase groupBase = (XmlSchemaGroupBase)group.CanonicalParticle;
  962.             if (groupBase is XmlSchemaAll) {
  963.                 if (!root) {
  964.                     SendValidationEvent(Res.Sch_AllRefNotRoot, "", groupRef);
  965.                     return XmlSchemaParticle.Empty;
  966.                 }
  967.                 if (groupRef.MinOccurs != decimal.One || groupRef.MaxOccurs != decimal.One) {
  968.                     SendValidationEvent(Res.Sch_AllRefMinMax, groupRef);
  969.                     return XmlSchemaParticle.Empty;
  970.                 }
  971.             }
  972.             else if (groupBase is XmlSchemaChoice && groupBase.Items.Count == 0) {
  973.                 if (groupRef.MinOccurs != decimal.Zero) {
  974.                     SendValidationEvent(Res.Sch_EmptyChoice, groupRef, XmlSeverityType.Warning);
  975.                 }
  976.                 return XmlSchemaParticle.Empty;
  977.             }
  978.             XmlSchemaGroupBase groupRefBase = ((groupBase is XmlSchemaSequence) ? (XmlSchemaGroupBase)new XmlSchemaSequence() : (groupBase is XmlSchemaChoice) ? (XmlSchemaGroupBase)new XmlSchemaChoice() : (XmlSchemaGroupBase)new XmlSchemaAll());
  979.             groupRefBase.MinOccurs = groupRef.MinOccurs;
  980.             groupRefBase.MaxOccurs = groupRef.MaxOccurs;
  981.             foreach (XmlSchemaParticle particle in groupBase.Items) {
  982.                 groupRefBase.Items.Add(particle);
  983.             }
  984.             groupRef.SetParticle(groupRefBase);
  985.             return groupRefBase;
  986.         }
  987.        
  988.         private XmlSchemaParticle CannonicalizeAll(XmlSchemaAll all, bool root, bool substitution)
  989.         {
  990.             if (all.Items.Count > 0) {
  991.                 XmlSchemaAll newAll = new XmlSchemaAll();
  992.                 newAll.MinOccurs = all.MinOccurs;
  993.                 newAll.MaxOccurs = all.MaxOccurs;
  994.                 newAll.SourceUri = all.SourceUri;
  995.                 // all is the only one that might need and error message
  996.                 newAll.LineNumber = all.LineNumber;
  997.                 newAll.LinePosition = all.LinePosition;
  998.                 foreach (XmlSchemaElement e in all.Items) {
  999.                     XmlSchemaParticle p = CannonicalizeParticle(e, false, substitution);
  1000.                     if (p != XmlSchemaParticle.Empty) {
  1001.                         newAll.Items.Add(p);
  1002.                     }
  1003.                 }
  1004.                 all = newAll;
  1005.             }
  1006.             if (all.Items.Count == 0) {
  1007.                 return XmlSchemaParticle.Empty;
  1008.             }
  1009.             else if (root && all.Items.Count == 1) {
  1010.                 XmlSchemaSequence newSequence = new XmlSchemaSequence();
  1011.                 newSequence.MinOccurs = all.MinOccurs;
  1012.                 newSequence.MaxOccurs = all.MaxOccurs;
  1013.                 newSequence.Items.Add((XmlSchemaParticle)all.Items[0]);
  1014.                 return newSequence;
  1015.             }
  1016.             else if (!root && all.Items.Count == 1 && all.MinOccurs == decimal.One && all.MaxOccurs == decimal.One) {
  1017.                 return (XmlSchemaParticle)all.Items[0];
  1018.             }
  1019.             else if (!root) {
  1020.                 SendValidationEvent(Res.Sch_NotAllAlone, all);
  1021.                 return XmlSchemaParticle.Empty;
  1022.             }
  1023.             else {
  1024.                 return all;
  1025.             }
  1026.         }
  1027.        
  1028.         private XmlSchemaParticle CannonicalizeChoice(XmlSchemaChoice choice, bool root, bool substitution)
  1029.         {
  1030.             XmlSchemaChoice oldChoice = choice;
  1031.             if (choice.Items.Count > 0) {
  1032.                 XmlSchemaChoice newChoice = new XmlSchemaChoice();
  1033.                 newChoice.MinOccurs = choice.MinOccurs;
  1034.                 newChoice.MaxOccurs = choice.MaxOccurs;
  1035.                 foreach (XmlSchemaParticle p in choice.Items) {
  1036.                     XmlSchemaParticle p1 = CannonicalizeParticle(p, false, substitution);
  1037.                     if (p1 != XmlSchemaParticle.Empty) {
  1038.                         if (p1.MinOccurs == decimal.One && p1.MaxOccurs == decimal.One && p1 is XmlSchemaChoice) {
  1039.                             foreach (XmlSchemaParticle p2 in ((XmlSchemaChoice)p1).Items) {
  1040.                                 newChoice.Items.Add(p2);
  1041.                             }
  1042.                         }
  1043.                         else {
  1044.                             newChoice.Items.Add(p1);
  1045.                         }
  1046.                     }
  1047.                 }
  1048.                 choice = newChoice;
  1049.             }
  1050.             if (!root && choice.Items.Count == 0) {
  1051.                 if (choice.MinOccurs != decimal.Zero) {
  1052.                     SendValidationEvent(Res.Sch_EmptyChoice, oldChoice, XmlSeverityType.Warning);
  1053.                 }
  1054.                 return XmlSchemaParticle.Empty;
  1055.             }
  1056.             else if (!root && choice.Items.Count == 1 && choice.MinOccurs == decimal.One && choice.MaxOccurs == decimal.One) {
  1057.                 return (XmlSchemaParticle)choice.Items[0];
  1058.             }
  1059.             else {
  1060.                 return choice;
  1061.             }
  1062.         }
  1063.        
  1064.         private XmlSchemaParticle CannonicalizeSequence(XmlSchemaSequence sequence, bool root, bool substitution)
  1065.         {
  1066.             if (sequence.Items.Count > 0) {
  1067.                 XmlSchemaSequence newSequence = new XmlSchemaSequence();
  1068.                 newSequence.MinOccurs = sequence.MinOccurs;
  1069.                 newSequence.MaxOccurs = sequence.MaxOccurs;
  1070.                 foreach (XmlSchemaParticle p in sequence.Items) {
  1071.                     XmlSchemaParticle p1 = CannonicalizeParticle(p, false, substitution);
  1072.                     if (p1 != XmlSchemaParticle.Empty) {
  1073.                         if (p1.MinOccurs == decimal.One && p1.MaxOccurs == decimal.One && p1 is XmlSchemaSequence) {
  1074.                             foreach (XmlSchemaParticle p2 in ((XmlSchemaSequence)p1).Items) {
  1075.                                 newSequence.Items.Add(p2);
  1076.                             }
  1077.                         }
  1078.                         else {
  1079.                             newSequence.Items.Add(p1);
  1080.                         }
  1081.                     }
  1082.                 }
  1083.                 sequence = newSequence;
  1084.             }
  1085.             if (sequence.Items.Count == 0) {
  1086.                 return XmlSchemaParticle.Empty;
  1087.             }
  1088.             else if (!root && sequence.Items.Count == 1 && sequence.MinOccurs == decimal.One && sequence.MaxOccurs == decimal.One) {
  1089.                 return (XmlSchemaParticle)sequence.Items[0];
  1090.             }
  1091.             else {
  1092.                 return sequence;
  1093.             }
  1094.         }
  1095.        
  1096.         private bool IsValidRestriction(XmlSchemaParticle derivedParticle, XmlSchemaParticle baseParticle)
  1097.         {
  1098.             if (derivedParticle == baseParticle) {
  1099.                 return true;
  1100.             }
  1101.             else if (derivedParticle == null || derivedParticle == XmlSchemaParticle.Empty) {
  1102.                 return IsParticleEmptiable(baseParticle);
  1103.             }
  1104.             else if (baseParticle == null || baseParticle == XmlSchemaParticle.Empty) {
  1105.                 return false;
  1106.             }
  1107.             if (baseParticle is XmlSchemaElement) {
  1108.                 if (derivedParticle is XmlSchemaElement) {
  1109.                     return IsElementFromElement((XmlSchemaElement)derivedParticle, (XmlSchemaElement)baseParticle);
  1110.                 }
  1111.                 else {
  1112.                     return false;
  1113.                 }
  1114.             }
  1115.             else if (baseParticle is XmlSchemaAny) {
  1116.                 if (derivedParticle is XmlSchemaElement) {
  1117.                     return IsElementFromAny((XmlSchemaElement)derivedParticle, (XmlSchemaAny)baseParticle);
  1118.                 }
  1119.                 else if (derivedParticle is XmlSchemaAny) {
  1120.                     return IsAnyFromAny((XmlSchemaAny)derivedParticle, (XmlSchemaAny)baseParticle);
  1121.                 }
  1122.                 else {
  1123.                     return IsGroupBaseFromAny((XmlSchemaGroupBase)derivedParticle, (XmlSchemaAny)baseParticle);
  1124.                 }
  1125.             }
  1126.             else if (baseParticle is XmlSchemaAll) {
  1127.                 if (derivedParticle is XmlSchemaElement) {
  1128.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle, true);
  1129.                 }
  1130.                 else if (derivedParticle is XmlSchemaAll) {
  1131.                     return IsGroupBaseFromGroupBase((XmlSchemaGroupBase)derivedParticle, (XmlSchemaGroupBase)baseParticle, true);
  1132.                 }
  1133.                 else if (derivedParticle is XmlSchemaSequence) {
  1134.                     return IsSequenceFromAll((XmlSchemaSequence)derivedParticle, (XmlSchemaAll)baseParticle);
  1135.                 }
  1136.             }
  1137.             else if (baseParticle is XmlSchemaChoice) {
  1138.                 if (derivedParticle is XmlSchemaElement) {
  1139.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle, false);
  1140.                 }
  1141.                 else if (derivedParticle is XmlSchemaChoice) {
  1142.                     return IsGroupBaseFromGroupBase((XmlSchemaGroupBase)derivedParticle, (XmlSchemaGroupBase)baseParticle, false);
  1143.                 }
  1144.                 else if (derivedParticle is XmlSchemaSequence) {
  1145.                     return IsSequenceFromChoice((XmlSchemaSequence)derivedParticle, (XmlSchemaChoice)baseParticle);
  1146.                 }
  1147.             }
  1148.             else if (baseParticle is XmlSchemaSequence) {
  1149.                 if (derivedParticle is XmlSchemaElement) {
  1150.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle, true);
  1151.                 }
  1152.                 else if (derivedParticle is XmlSchemaSequence) {
  1153.                     return IsGroupBaseFromGroupBase((XmlSchemaGroupBase)derivedParticle, (XmlSchemaGroupBase)baseParticle, true);
  1154.                 }
  1155.             }
  1156.             else {
  1157.                 Debug.Assert(false);
  1158.             }
  1159.            
  1160.             return false;
  1161.         }
  1162.        
  1163.         private bool IsElementFromElement(XmlSchemaElement derivedElement, XmlSchemaElement baseElement)
  1164.         {
  1165.             return (derivedElement.QualifiedName == baseElement.QualifiedName) && (derivedElement.IsNillable == baseElement.IsNillable) && IsValidOccurrenceRangeRestriction(derivedElement, baseElement) && (baseElement.FixedValue == null || baseElement.FixedValue == derivedElement.FixedValue) && ((derivedElement.BlockResolved | baseElement.BlockResolved) == derivedElement.BlockResolved) && (derivedElement.ElementSchemaType != null) && (baseElement.ElementSchemaType != null) && XmlSchemaType.IsDerivedFrom(derivedElement.ElementSchemaType, baseElement.ElementSchemaType, ~XmlSchemaDerivationMethod.Restriction);
  1166.         }
  1167.        
  1168.         private bool IsElementFromAny(XmlSchemaElement derivedElement, XmlSchemaAny baseAny)
  1169.         {
  1170.             return baseAny.Allows(derivedElement.QualifiedName) && IsValidOccurrenceRangeRestriction(derivedElement, baseAny);
  1171.         }
  1172.        
  1173.         private bool IsAnyFromAny(XmlSchemaAny derivedAny, XmlSchemaAny baseAny)
  1174.         {
  1175.             return IsValidOccurrenceRangeRestriction(derivedAny, baseAny) && NamespaceList.IsSubset(derivedAny.NamespaceList, baseAny.NamespaceList);
  1176.         }
  1177.        
  1178.         private bool IsGroupBaseFromAny(XmlSchemaGroupBase derivedGroupBase, XmlSchemaAny baseAny)
  1179.         {
  1180.             decimal minOccurs;
  1181.             decimal maxOccurs;
  1182.             CalculateEffectiveTotalRange(derivedGroupBase, out minOccurs, out maxOccurs);
  1183.             if (!IsValidOccurrenceRangeRestriction(minOccurs, maxOccurs, baseAny.MinOccurs, baseAny.MaxOccurs)) {
  1184.                 return false;
  1185.             }
  1186.             // eliminate occurrance range check
  1187.             string minOccursAny = baseAny.MinOccursString;
  1188.             baseAny.MinOccurs = decimal.Zero;
  1189.            
  1190.             foreach (XmlSchemaParticle p in derivedGroupBase.Items) {
  1191.                 if (!IsValidRestriction(p, baseAny)) {
  1192.                     baseAny.MinOccursString = minOccursAny;
  1193.                     return false;
  1194.                 }
  1195.             }
  1196.             baseAny.MinOccursString = minOccursAny;
  1197.             return true;
  1198.         }
  1199.        
  1200.         private bool IsElementFromGroupBase(XmlSchemaElement derivedElement, XmlSchemaGroupBase baseGroupBase, bool skipEmptableOnly)
  1201.         {
  1202.             bool isMatched = false;
  1203.             foreach (XmlSchemaParticle baseParticle in baseGroupBase.Items) {
  1204.                 if (!isMatched) {
  1205.                     string minOccursElement = baseParticle.MinOccursString;
  1206.                     string maxOccursElement = baseParticle.MaxOccursString;
  1207.                     baseParticle.MinOccurs *= baseGroupBase.MinOccurs;
  1208.                     if (baseParticle.MaxOccurs != decimal.MaxValue) {
  1209.                         if (baseGroupBase.MaxOccurs == decimal.MaxValue)
  1210.                             baseParticle.MaxOccurs = decimal.MaxValue;
  1211.                         else
  1212.                             baseParticle.MaxOccurs *= baseGroupBase.MaxOccurs;
  1213.                     }
  1214.                     isMatched = IsValidRestriction(derivedElement, baseParticle);
  1215.                     baseParticle.MinOccursString = minOccursElement;
  1216.                     baseParticle.MaxOccursString = maxOccursElement;
  1217.                 }
  1218.                 else if (skipEmptableOnly && !IsParticleEmptiable(baseParticle)) {
  1219.                     return false;
  1220.                 }
  1221.             }
  1222.             return isMatched;
  1223.         }
  1224.        
  1225.         private bool IsGroupBaseFromGroupBase(XmlSchemaGroupBase derivedGroupBase, XmlSchemaGroupBase baseGroupBase, bool skipEmptableOnly)
  1226.         {
  1227.             if (!IsValidOccurrenceRangeRestriction(derivedGroupBase, baseGroupBase) || derivedGroupBase.Items.Count > baseGroupBase.Items.Count) {
  1228.                 return false;
  1229.             }
  1230.             int count = 0;
  1231.             foreach (XmlSchemaParticle baseParticle in baseGroupBase.Items) {
  1232.                 if ((count < derivedGroupBase.Items.Count) && IsValidRestriction((XmlSchemaParticle)derivedGroupBase.Items[count], baseParticle)) {
  1233.                     count++;
  1234.                 }
  1235.                 else if (skipEmptableOnly && !IsParticleEmptiable(baseParticle)) {
  1236.                     return false;
  1237.                 }
  1238.             }
  1239.             if (count < derivedGroupBase.Items.Count) {
  1240.                 return false;
  1241.             }
  1242.             return true;
  1243.         }
  1244.        
  1245.         private bool IsSequenceFromAll(XmlSchemaSequence derivedSequence, XmlSchemaAll baseAll)
  1246.         {
  1247.             if (!IsValidOccurrenceRangeRestriction(derivedSequence, baseAll) || derivedSequence.Items.Count > baseAll.Items.Count) {
  1248.                 return false;
  1249.             }
  1250.             BitSet map = new BitSet(baseAll.Items.Count);
  1251.             foreach (XmlSchemaParticle p in derivedSequence.Items) {
  1252.                 int i = GetMappingParticle(p, baseAll.Items);
  1253.                 if (i >= 0) {
  1254.                     if (map[i]) {
  1255.                         return false;
  1256.                     }
  1257.                     else {
  1258.                         map.Set(i);
  1259.                     }
  1260.                 }
  1261.                 else {
  1262.                     return false;
  1263.                 }
  1264.             }
  1265.             for (int i = 0; i < baseAll.Items.Count; i++) {
  1266.                 if (!map[i] && !IsParticleEmptiable((XmlSchemaParticle)baseAll.Items[i])) {
  1267.                     return false;
  1268.                 }
  1269.             }
  1270.             return true;
  1271.         }
  1272.        
  1273.         private bool IsSequenceFromChoice(XmlSchemaSequence derivedSequence, XmlSchemaChoice baseChoice)
  1274.         {
  1275.             decimal minOccurs;
  1276.             decimal maxOccurs;
  1277.             CalculateSequenceRange(derivedSequence, out minOccurs, out maxOccurs);
  1278.             if (!IsValidOccurrenceRangeRestriction(minOccurs, maxOccurs, baseChoice.MinOccurs, baseChoice.MaxOccurs) || derivedSequence.Items.Count > baseChoice.Items.Count) {
  1279.                 return false;
  1280.             }
  1281.             foreach (XmlSchemaParticle particle in derivedSequence.Items) {
  1282.                 if (GetMappingParticle(particle, baseChoice.Items) < 0)
  1283.                     return false;
  1284.             }
  1285.             return true;
  1286.         }
  1287.        
  1288.         private void CalculateSequenceRange(XmlSchemaSequence sequence, out decimal minOccurs, out decimal maxOccurs)
  1289.         {
  1290.             minOccurs = decimal.Zero;
  1291.             maxOccurs = decimal.Zero;
  1292.             foreach (XmlSchemaParticle p in sequence.Items) {
  1293.                 minOccurs += p.MinOccurs;
  1294.                 if (p.MaxOccurs == decimal.MaxValue)
  1295.                     maxOccurs = decimal.MaxValue;
  1296.                 else if (maxOccurs != decimal.MaxValue)
  1297.                     maxOccurs += p.MaxOccurs;
  1298.             }
  1299.             minOccurs *= sequence.MinOccurs;
  1300.             if (sequence.MaxOccurs == decimal.MaxValue) {
  1301.                 maxOccurs = decimal.MaxValue;
  1302.             }
  1303.             else if (maxOccurs != decimal.MaxValue) {
  1304.                 maxOccurs *= sequence.MaxOccurs;
  1305.             }
  1306.         }
  1307.        
  1308.         private bool IsValidOccurrenceRangeRestriction(XmlSchemaParticle derivedParticle, XmlSchemaParticle baseParticle)
  1309.         {
  1310.             return IsValidOccurrenceRangeRestriction(derivedParticle.MinOccurs, derivedParticle.MaxOccurs, baseParticle.MinOccurs, baseParticle.MaxOccurs);
  1311.         }
  1312.        
  1313.         private bool IsValidOccurrenceRangeRestriction(decimal minOccurs, decimal maxOccurs, decimal baseMinOccurs, decimal baseMaxOccurs)
  1314.         {
  1315.             return (baseMinOccurs <= minOccurs) && (maxOccurs <= baseMaxOccurs);
  1316.         }
  1317.        
  1318.         private int GetMappingParticle(XmlSchemaParticle particle, XmlSchemaObjectCollection collection)
  1319.         {
  1320.             for (int i = 0; i < collection.Count; i++) {
  1321.                 if (IsValidRestriction(particle, (XmlSchemaParticle)collection[i]))
  1322.                     return i;
  1323.             }
  1324.             return -1;
  1325.         }
  1326.        
  1327.         private bool IsParticleEmptiable(XmlSchemaParticle particle)
  1328.         {
  1329.             decimal minOccurs;
  1330.             decimal maxOccurs;
  1331.             CalculateEffectiveTotalRange(particle, out minOccurs, out maxOccurs);
  1332.             return minOccurs == decimal.Zero;
  1333.         }
  1334.        
  1335.         private void CalculateEffectiveTotalRange(XmlSchemaParticle particle, out decimal minOccurs, out decimal maxOccurs)
  1336.         {
  1337.             if (particle is XmlSchemaElement || particle is XmlSchemaAny) {
  1338.                 minOccurs = particle.MinOccurs;
  1339.                 maxOccurs = particle.MaxOccurs;
  1340.             }
  1341.             else if (particle is XmlSchemaChoice) {
  1342.                 if (((XmlSchemaChoice)particle).Items.Count == 0) {
  1343.                     minOccurs = maxOccurs = decimal.Zero;
  1344.                 }
  1345.                 else {
  1346.                     minOccurs = decimal.MaxValue;
  1347.                     maxOccurs = decimal.Zero;
  1348.                     foreach (XmlSchemaParticle p in ((XmlSchemaChoice)particle).Items) {
  1349.                         decimal min;
  1350.                         decimal max;
  1351.                         CalculateEffectiveTotalRange(p, out min, out max);
  1352.                         if (min < minOccurs) {
  1353.                             minOccurs = min;
  1354.                         }
  1355.                         if (max > maxOccurs) {
  1356.                             maxOccurs = max;
  1357.                         }
  1358.                     }
  1359.                     minOccurs *= particle.MinOccurs;
  1360.                     if (maxOccurs != decimal.MaxValue) {
  1361.                         if (particle.MaxOccurs == decimal.MaxValue)
  1362.                             maxOccurs = decimal.MaxValue;
  1363.                         else
  1364.                             maxOccurs *= particle.MaxOccurs;
  1365.                     }
  1366.                 }
  1367.             }
  1368.             else {
  1369.                 XmlSchemaObjectCollection collection = ((XmlSchemaGroupBase)particle).Items;
  1370.                 if (collection.Count == 0) {
  1371.                     minOccurs = maxOccurs = decimal.Zero;
  1372.                 }
  1373.                 else {
  1374.                     minOccurs = 0;
  1375.                     maxOccurs = 0;
  1376.                     foreach (XmlSchemaParticle p in collection) {
  1377.                         decimal min;
  1378.                         decimal max;
  1379.                         CalculateEffectiveTotalRange(p, out min, out max);
  1380.                         minOccurs += min;
  1381.                         if (maxOccurs != decimal.MaxValue) {
  1382.                             if (max == decimal.MaxValue)
  1383.                                 maxOccurs = decimal.MaxValue;
  1384.                             else
  1385.                                 maxOccurs += max;
  1386.                         }
  1387.                     }
  1388.                     minOccurs *= particle.MinOccurs;
  1389.                     if (maxOccurs != decimal.MaxValue) {
  1390.                         if (particle.MaxOccurs == decimal.MaxValue)
  1391.                             maxOccurs = decimal.MaxValue;
  1392.                         else
  1393.                             maxOccurs *= particle.MaxOccurs;
  1394.                     }
  1395.                 }
  1396.             }
  1397.         }
  1398.        
  1399.         private void PushComplexType(XmlSchemaComplexType complexType)
  1400.         {
  1401.             this.complexTypeStack.Push(complexType);
  1402.         }
  1403.        
  1404.         private XmlSchemaContentType GetSchemaContentType(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaParticle particle)
  1405.         {
  1406.             if ((complexContent != null && complexContent.IsMixed) || (complexContent == null && complexType.IsMixed)) {
  1407.                 return XmlSchemaContentType.Mixed;
  1408.             }
  1409.             else if (particle != null && !particle.IsEmpty) {
  1410.                 return XmlSchemaContentType.ElementOnly;
  1411.             }
  1412.             else {
  1413.                 return XmlSchemaContentType.Empty;
  1414.             }
  1415.         }
  1416.        
  1417.         private void CompileAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  1418.         {
  1419.             if (attributeGroup.IsProcessing) {
  1420.                 SendValidationEvent(Res.Sch_AttributeGroupCircularRef, attributeGroup);
  1421.                 return;
  1422.             }
  1423.             if (attributeGroup.AttributeUses.Count > 0) {
  1424.                 // already checked
  1425.                 return;
  1426.             }
  1427.             attributeGroup.IsProcessing = true;
  1428.             XmlSchemaAnyAttribute anyAttribute = attributeGroup.AnyAttribute;
  1429.             foreach (XmlSchemaObject obj in attributeGroup.Attributes) {
  1430.                 if (obj is XmlSchemaAttribute) {
  1431.                     XmlSchemaAttribute attribute = (XmlSchemaAttribute)obj;
  1432.                     if (attribute.Use != XmlSchemaUse.Prohibited) {
  1433.                         CompileAttribute(attribute);
  1434.                     }
  1435.                     if (attributeGroup.AttributeUses[attribute.QualifiedName] == null) {
  1436.                         attributeGroup.AttributeUses.Add(attribute.QualifiedName, attribute);
  1437.                     }
  1438.                     else {
  1439.                         SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1440.                     }
  1441.                 }
  1442.                 else {
  1443.                     // XmlSchemaAttributeGroupRef
  1444.                     XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  1445.                     XmlSchemaAttributeGroup attributeGroupResolved;
  1446.                     if (attributeGroup.Redefined != null && attributeGroupRef.RefName == attributeGroup.Redefined.QualifiedName) {
  1447.                         attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroup.Redefined;
  1448.                     }
  1449.                     else {
  1450.                         attributeGroupResolved = (XmlSchemaAttributeGroup)this.schema.AttributeGroups[attributeGroupRef.RefName];
  1451.                     }
  1452.                     if (attributeGroupResolved != null) {
  1453.                         CompileAttributeGroup(attributeGroupResolved);
  1454.                         foreach (XmlSchemaAttribute attribute in attributeGroupResolved.AttributeUses.Values) {
  1455.                             if (attributeGroup.AttributeUses[attribute.QualifiedName] == null) {
  1456.                                 attributeGroup.AttributeUses.Add(attribute.QualifiedName, attribute);
  1457.                             }
  1458.                             else {
  1459.                                 SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1460.                             }
  1461.                         }
  1462.                         anyAttribute = CompileAnyAttributeIntersection(anyAttribute, attributeGroupResolved.AttributeWildcard);
  1463.                     }
  1464.                     else {
  1465.                         SendValidationEvent(Res.Sch_UndefAttributeGroupRef, attributeGroupRef.RefName.ToString(), attributeGroupRef);
  1466.                     }
  1467.                 }
  1468.             }
  1469.             attributeGroup.AttributeWildcard = anyAttribute;
  1470.             attributeGroup.IsProcessing = false;
  1471.            
  1472.         }
  1473.        
  1474.         private void CompileLocalAttributes(XmlSchemaComplexType baseType, XmlSchemaComplexType derivedType, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlSchemaDerivationMethod derivedBy)
  1475.         {
  1476.             XmlSchemaAnyAttribute baseAttributeWildcard = baseType != null ? baseType.AttributeWildcard : null;
  1477.             foreach (XmlSchemaObject obj in attributes) {
  1478.                 if (obj is XmlSchemaAttribute) {
  1479.                     XmlSchemaAttribute attribute = (XmlSchemaAttribute)obj;
  1480.                     if (attribute.Use != XmlSchemaUse.Prohibited) {
  1481.                         CompileAttribute(attribute);
  1482.                     }
  1483.                     if (attribute.Use != XmlSchemaUse.Prohibited || (attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
  1484.                        
  1485.                         if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
  1486.                             derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
  1487.                         }
  1488.                         else {
  1489.                             SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1490.                         }
  1491.                     }
  1492.                     else {
  1493.                         SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
  1494.                     }
  1495.                    
  1496.                 }
  1497.                 else {
  1498.                     // is XmlSchemaAttributeGroupRef
  1499.                     XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  1500.                     XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)this.schema.AttributeGroups[attributeGroupRef.RefName];
  1501.                     if (attributeGroup != null) {
  1502.                         CompileAttributeGroup(attributeGroup);
  1503.                         foreach (XmlSchemaAttribute attribute in attributeGroup.AttributeUses.Values) {
  1504.                             if (attribute.Use != XmlSchemaUse.Prohibited || (attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
  1505.                                 if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
  1506.                                     derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
  1507.                                 }
  1508.                                 else {
  1509.                                     SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attributeGroupRef);
  1510.                                 }
  1511.                             }
  1512.                             else {
  1513.                                 SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
  1514.                             }
  1515.                            
  1516.                         }
  1517.                         anyAttribute = CompileAnyAttributeIntersection(anyAttribute, attributeGroup.AttributeWildcard);
  1518.                     }
  1519.                     else {
  1520.                         SendValidationEvent(Res.Sch_UndefAttributeGroupRef, attributeGroupRef.RefName.ToString(), attributeGroupRef);
  1521.                     }
  1522.                 }
  1523.             }
  1524.            
  1525.             // check derivation rules
  1526.             if (baseType != null) {
  1527.                 if (derivedBy == XmlSchemaDerivationMethod.Extension) {
  1528.                     derivedType.SetAttributeWildcard(CompileAnyAttributeUnion(anyAttribute, baseAttributeWildcard));
  1529.                     foreach (XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
  1530.                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
  1531.                         if (attribute != null) {
  1532.                             Debug.Assert(attribute.Use != XmlSchemaUse.Prohibited);
  1533.                             if (attribute.AttributeSchemaType != attributeBase.AttributeSchemaType || attributeBase.Use == XmlSchemaUse.Prohibited) {
  1534.                                 SendValidationEvent(Res.Sch_InvalidAttributeExtension, attribute);
  1535.                             }
  1536.                         }
  1537.                         else {
  1538.                             derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
  1539.                         }
  1540.                     }
  1541.                 }
  1542.                 else {
  1543.                     // derivedBy == XmlSchemaDerivationMethod.Restriction
  1544.                     // Schema Component Constraint: Derivation Valid (Restriction, Complex)
  1545.                     if ((anyAttribute != null) && (baseAttributeWildcard == null || !XmlSchemaAnyAttribute.IsSubset(anyAttribute, baseAttributeWildcard))) {
  1546.                         SendValidationEvent(Res.Sch_InvalidAnyAttributeRestriction, derivedType);
  1547.                     }
  1548.                     else {
  1549.                         derivedType.SetAttributeWildcard(anyAttribute);
  1550.                         //complete wildcard
  1551.                     }
  1552.                    
  1553.                     // Add form the base
  1554.                     foreach (XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
  1555.                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
  1556.                         if (attribute == null) {
  1557.                             derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
  1558.                         }
  1559.                         else {
  1560.                             if (attributeBase.Use == XmlSchemaUse.Prohibited && attribute.Use != XmlSchemaUse.Prohibited) {
  1561.                                 #if DEBUG
  1562.                                 string position = string.Empty;
  1563.                                 if (derivedType.SourceUri != null) {
  1564.                                     position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
  1565.                                 }
  1566.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
  1567.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
  1568.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
  1569.                                 #endif
  1570.                                 SendValidationEvent(Res.Sch_AttributeRestrictionProhibited, attribute);
  1571.                             }
  1572.                             else if (attribute.Use == XmlSchemaUse.Prohibited) {
  1573.                                 continue;
  1574.                             }
  1575.                             else if (attributeBase.AttributeSchemaType == null || attribute.AttributeSchemaType == null || !XmlSchemaType.IsDerivedFrom(attribute.AttributeSchemaType, attributeBase.AttributeSchemaType, XmlSchemaDerivationMethod.Empty)) {
  1576.                                 SendValidationEvent(Res.Sch_AttributeRestrictionInvalid, attribute);
  1577.                             }
  1578.                         }
  1579.                     }
  1580.                    
  1581.                     // Check additional ones are valid restriction of base's wildcard
  1582.                     foreach (XmlSchemaAttribute attribute in derivedType.AttributeUses.Values) {
  1583.                         XmlSchemaAttribute attributeBase = (XmlSchemaAttribute)baseType.AttributeUses[attribute.QualifiedName];
  1584.                         if (attributeBase != null) {
  1585.                             continue;
  1586.                         }
  1587.                         if (baseAttributeWildcard == null || !baseAttributeWildcard.Allows(attribute.QualifiedName)) {
  1588.                             #if DEBUG
  1589.                             string position = string.Empty;
  1590.                             if (derivedType.SourceUri != null) {
  1591.                                 position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
  1592.                             }
  1593.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
  1594.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
  1595.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
  1596.                             #endif
  1597.                             SendValidationEvent(Res.Sch_AttributeRestrictionInvalidFromWildcard, attribute);
  1598.                         }
  1599.                     }
  1600.                 }
  1601.             }
  1602.             else {
  1603.                 derivedType.SetAttributeWildcard(anyAttribute);
  1604.             }
  1605.         }
  1606.        
  1607.        
  1608.         #if DEBUG
  1609.         private string DumpAttributes(XmlSchemaObjectTable attributeUses, XmlSchemaAnyAttribute attributeWildcard)
  1610.         {
  1611.             StringBuilder sb = new StringBuilder();
  1612.             sb.Append("[");
  1613.             bool first = true;
  1614.             foreach (XmlSchemaAttribute attribute in attributeUses.Values) {
  1615.                 if (attribute.Use != XmlSchemaUse.Prohibited) {
  1616.                     if (first) {
  1617.                         first = false;
  1618.                     }
  1619.                     else {
  1620.                         sb.Append(" ");
  1621.                     }
  1622.                     sb.Append(attribute.QualifiedName.Name);
  1623.                     if (attribute.Use == XmlSchemaUse.Optional) {
  1624.                         sb.Append("?");
  1625.                     }
  1626.                 }
  1627.             }
  1628.             if (attributeWildcard != null) {
  1629.                 if (attributeUses.Count != 0) {
  1630.                     sb.Append(" ");
  1631.                 }
  1632.                 sb.Append("<");
  1633.                 sb.Append(attributeWildcard.NamespaceList.ToString());
  1634.                 sb.Append(">");
  1635.             }
  1636.             sb.Append("] - [");
  1637.             first = true;
  1638.             foreach (XmlSchemaAttribute attribute in attributeUses.Values) {
  1639.                 if (attribute.Use == XmlSchemaUse.Prohibited) {
  1640.                     if (first) {
  1641.                         first = false;
  1642.                     }
  1643.                     else {
  1644.                         sb.Append(" ");
  1645.                     }
  1646.                     sb.Append(attribute.QualifiedName.Name);
  1647.                 }
  1648.             }
  1649.             sb.Append("]");
  1650.             return sb.ToString();
  1651.         }
  1652.         #endif
  1653.        
  1654.         private XmlSchemaAnyAttribute CompileAnyAttributeUnion(XmlSchemaAnyAttribute a, XmlSchemaAnyAttribute b)
  1655.         {
  1656.             if (a == null) {
  1657.                 return b;
  1658.             }
  1659.             else if (b == null) {
  1660.                 return a;
  1661.             }
  1662.             else {
  1663.                 XmlSchemaAnyAttribute attribute = XmlSchemaAnyAttribute.Union(a, b, true);
  1664.                 //true for v1Compat
  1665.                 if (attribute == null) {
  1666.                     SendValidationEvent(Res.Sch_UnexpressibleAnyAttribute, a);
  1667.                 }
  1668.                 return attribute;
  1669.             }
  1670.            
  1671.         }
  1672.        
  1673.         private XmlSchemaAnyAttribute CompileAnyAttributeIntersection(XmlSchemaAnyAttribute a, XmlSchemaAnyAttribute b)
  1674.         {
  1675.             if (a == null) {
  1676.                 return b;
  1677.             }
  1678.             else if (b == null) {
  1679.                 return a;
  1680.             }
  1681.             else {
  1682.                 XmlSchemaAnyAttribute attribute = XmlSchemaAnyAttribute.Intersection(a, b, true);
  1683.                 //true for v1Compat
  1684.                 if (attribute == null) {
  1685.                     SendValidationEvent(Res.Sch_UnexpressibleAnyAttribute, a);
  1686.                 }
  1687.                 return attribute;
  1688.             }
  1689.         }
  1690.        
  1691.         private void CompileAttribute(XmlSchemaAttribute xa)
  1692.         {
  1693.             if (xa.IsProcessing) {
  1694.                 SendValidationEvent(Res.Sch_AttributeCircularRef, xa);
  1695.                 return;
  1696.             }
  1697.             if (xa.AttDef != null) {
  1698.                 //already compiled?
  1699.                 return;
  1700.             }
  1701.             xa.IsProcessing = true;
  1702.             SchemaAttDef decl = null;
  1703.             try {
  1704.                 if (!xa.RefName.IsEmpty) {
  1705.                     XmlSchemaAttribute a = (XmlSchemaAttribute)this.schema.Attributes[xa.RefName];
  1706.                     if (a == null) {
  1707.                         throw new XmlSchemaException(Res.Sch_UndeclaredAttribute, xa.RefName.ToString(), xa);
  1708.                     }
  1709.                     CompileAttribute(a);
  1710.                     if (a.AttDef == null) {
  1711.                         throw new XmlSchemaException(Res.Sch_RefInvalidAttribute, xa.RefName.ToString(), xa);
  1712.                     }
  1713.                     decl = a.AttDef.Clone();
  1714.                     if (decl.Datatype != null) {
  1715.                         if (a.FixedValue != null) {
  1716.                             if (xa.DefaultValue != null) {
  1717.                                 throw new XmlSchemaException(Res.Sch_FixedDefaultInRef, xa.RefName.ToString(), xa);
  1718.                             }
  1719.                             else if (xa.FixedValue != null) {
  1720.                                 if (xa.FixedValue != a.FixedValue) {
  1721.                                     throw new XmlSchemaException(Res.Sch_FixedInRef, xa.RefName.ToString(), xa);
  1722.                                 }
  1723.                             }
  1724.                             else {
  1725.                                 decl.Presence = SchemaDeclBase.Use.Fixed;
  1726.                                 decl.DefaultValueRaw = decl.DefaultValueExpanded = a.FixedValue;
  1727.                                 decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xa), true);
  1728.                             }
  1729.                         }
  1730.                         else if (a.DefaultValue != null) {
  1731.                             if (xa.DefaultValue == null && xa.FixedValue == null) {
  1732.                                 decl.Presence = SchemaDeclBase.Use.Default;
  1733.                                 decl.DefaultValueRaw = decl.DefaultValueExpanded = a.DefaultValue;
  1734.                                 decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xa), true);
  1735.                             }
  1736.                         }
  1737.                     }
  1738.                     xa.SetAttributeType(a.AttributeSchemaType);
  1739.                 }
  1740.                 else {
  1741.                     decl = new SchemaAttDef(xa.QualifiedName, xa.Prefix);
  1742.                     if (xa.SchemaType != null) {
  1743.                         CompileSimpleType(xa.SchemaType);
  1744.                         xa.SetAttributeType(xa.SchemaType);
  1745.                         decl.SchemaType = xa.SchemaType;
  1746.                         decl.Datatype = xa.SchemaType.Datatype;
  1747.                     }
  1748.                     else if (!xa.SchemaTypeName.IsEmpty) {
  1749.                         XmlSchemaSimpleType simpleType = GetSimpleType(xa.SchemaTypeName);
  1750.                         if (simpleType != null) {
  1751.                             xa.SetAttributeType(simpleType);
  1752.                             decl.Datatype = simpleType.Datatype;
  1753.                             decl.SchemaType = simpleType;
  1754.                         }
  1755.                         else {
  1756.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, xa.SchemaTypeName.ToString(), xa);
  1757.                         }
  1758.                     }
  1759.                     else {
  1760.                         decl.SchemaType = DatatypeImplementation.AnySimpleType;
  1761.                         decl.Datatype = DatatypeImplementation.AnySimpleType.Datatype;
  1762.                         xa.SetAttributeType(DatatypeImplementation.AnySimpleType);
  1763.                     }
  1764.                 }
  1765.                 if (decl.Datatype != null) {
  1766.                     decl.Datatype.VerifySchemaValid(this.schema.Notations, xa);
  1767.                 }
  1768.                 if (xa.DefaultValue != null || xa.FixedValue != null) {
  1769.                     if (xa.DefaultValue != null) {
  1770.                         decl.Presence = SchemaDeclBase.Use.Default;
  1771.                         decl.DefaultValueRaw = decl.DefaultValueExpanded = xa.DefaultValue;
  1772.                     }
  1773.                     else {
  1774.                         decl.Presence = SchemaDeclBase.Use.Fixed;
  1775.                         decl.DefaultValueRaw = decl.DefaultValueExpanded = xa.FixedValue;
  1776.                     }
  1777.                     if (decl.Datatype != null) {
  1778.                         decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xa), true);
  1779.                     }
  1780.                 }
  1781.                 else {
  1782.                     switch (xa.Use) {
  1783.                         case XmlSchemaUse.None:
  1784.                         case XmlSchemaUse.Optional:
  1785.                             decl.Presence = SchemaDeclBase.Use.Implied;
  1786.                             break;
  1787.                         case XmlSchemaUse.Required:
  1788.                             decl.Presence = SchemaDeclBase.Use.Required;
  1789.                             break;
  1790.                         case XmlSchemaUse.Prohibited:
  1791.                             break;
  1792.                     }
  1793.                 }
  1794.                 decl.SchemaAttribute = xa;
  1795.                 //So this is available for PSVI
  1796.                 xa.AttDef = decl;
  1797.             }
  1798.             catch (XmlSchemaException e) {
  1799.                 if (e.SourceSchemaObject == null) {
  1800.                     e.SetSource(xa);
  1801.                 }
  1802.                 SendValidationEvent(e);
  1803.                 xa.AttDef = SchemaAttDef.Empty;
  1804.             }
  1805.             finally {
  1806.                 xa.IsProcessing = false;
  1807.             }
  1808.         }
  1809.        
  1810.         private void CompileIdentityConstraint(XmlSchemaIdentityConstraint xi)
  1811.         {
  1812.             if (xi.IsProcessing) {
  1813.                 xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
  1814.                 SendValidationEvent(Res.Sch_IdentityConstraintCircularRef, xi);
  1815.                 return;
  1816.             }
  1817.            
  1818.             if (xi.CompiledConstraint != null) {
  1819.                 return;
  1820.             }
  1821.            
  1822.             xi.IsProcessing = true;
  1823.             CompiledIdentityConstraint compic = null;
  1824.             try {
  1825.                 SchemaNamespaceManager xnmgr = new SchemaNamespaceManager(xi);
  1826.                 compic = new CompiledIdentityConstraint(xi, xnmgr);
  1827.                 if (xi is XmlSchemaKeyref) {
  1828.                     XmlSchemaIdentityConstraint ic = (XmlSchemaIdentityConstraint)this.schema.IdentityConstraints[((XmlSchemaKeyref)xi).Refer];
  1829.                     if (ic == null) {
  1830.                         throw new XmlSchemaException(Res.Sch_UndeclaredIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
  1831.                     }
  1832.                     CompileIdentityConstraint(ic);
  1833.                     if (ic.CompiledConstraint == null) {
  1834.                         throw new XmlSchemaException(Res.Sch_RefInvalidIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
  1835.                     }
  1836.                     // keyref has the different cardinality with the key it referred
  1837.                     if (ic.Fields.Count != xi.Fields.Count) {
  1838.                         throw new XmlSchemaException(Res.Sch_RefInvalidCardin, xi.QualifiedName.ToString(), xi);
  1839.                     }
  1840.                     // keyref can only refer to key/unique
  1841.                     if (ic.CompiledConstraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) {
  1842.                         throw new XmlSchemaException(Res.Sch_ReftoKeyref, xi.QualifiedName.ToString(), xi);
  1843.                     }
  1844.                 }
  1845.                 xi.CompiledConstraint = compic;
  1846.             }
  1847.             catch (XmlSchemaException e) {
  1848.                 if (e.SourceSchemaObject == null) {
  1849.                     e.SetSource(xi);
  1850.                 }
  1851.                 SendValidationEvent(e);
  1852.                 xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
  1853.                 // empty is better than null here, stop quickly when circle referencing
  1854.             }
  1855.             finally {
  1856.                 xi.IsProcessing = false;
  1857.             }
  1858.            
  1859.         }
  1860.        
  1861.         private void CompileElement(XmlSchemaElement xe)
  1862.         {
  1863.             if (xe.IsProcessing) {
  1864.                 SendValidationEvent(Res.Sch_ElementCircularRef, xe);
  1865.                 return;
  1866.             }
  1867.             if (xe.ElementDecl != null) {
  1868.                 return;
  1869.             }
  1870.             xe.IsProcessing = true;
  1871.             SchemaElementDecl decl = null;
  1872.             try {
  1873.                 if (!xe.RefName.IsEmpty) {
  1874.                     XmlSchemaElement e = (XmlSchemaElement)this.schema.Elements[xe.RefName];
  1875.                     if (e == null) {
  1876.                         throw new XmlSchemaException(Res.Sch_UndeclaredElement, xe.RefName.ToString(), xe);
  1877.                     }
  1878.                     CompileElement(e);
  1879.                     if (e.ElementDecl == null) {
  1880.                         throw new XmlSchemaException(Res.Sch_RefInvalidElement, xe.RefName.ToString(), xe);
  1881.                     }
  1882.                     xe.SetElementType(e.ElementSchemaType);
  1883.                     decl = e.ElementDecl.Clone();
  1884.                 }
  1885.                 else {
  1886.                     if (xe.SchemaType != null) {
  1887.                         xe.SetElementType(xe.SchemaType);
  1888.                     }
  1889.                     else if (!xe.SchemaTypeName.IsEmpty) {
  1890.                         xe.SetElementType(GetAnySchemaType(xe.SchemaTypeName));
  1891.                         if (xe.ElementSchemaType == null) {
  1892.                             throw new XmlSchemaException(Res.Sch_UndeclaredType, xe.SchemaTypeName.ToString(), xe);
  1893.                         }
  1894.                     }
  1895.                     else if (!xe.SubstitutionGroup.IsEmpty) {
  1896.                         XmlSchemaElement examplar = (XmlSchemaElement)this.schema.Elements[xe.SubstitutionGroup];
  1897.                         if (examplar == null) {
  1898.                             throw new XmlSchemaException(Res.Sch_UndeclaredEquivClass, xe.SubstitutionGroup.Name.ToString(CultureInfo.InvariantCulture), xe);
  1899.                         }
  1900.                         if (examplar.IsProcessing) {
  1901.                             //Circular subst group; already detected by now
  1902.                             return;
  1903.                         }
  1904.                         CompileElement(examplar);
  1905.                         if (examplar.ElementDecl == null) {
  1906.                             //If head is invalid, fall back to AnyType
  1907.                             xe.SetElementType(XmlSchemaComplexType.AnyType);
  1908.                             decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
  1909.                         }
  1910.                         else {
  1911.                             xe.SetElementType(examplar.ElementSchemaType);
  1912.                             decl = examplar.ElementDecl.Clone();
  1913.                         }
  1914.                     }
  1915.                     else {
  1916.                         xe.SetElementType(XmlSchemaComplexType.AnyType);
  1917.                         decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
  1918.                     }
  1919.                    
  1920.                     if (decl == null) {
  1921.                         Debug.Assert(xe.ElementSchemaType != null);
  1922.                         if (xe.ElementSchemaType is XmlSchemaComplexType) {
  1923.                             XmlSchemaComplexType complexType = (XmlSchemaComplexType)xe.ElementSchemaType;
  1924.                             CompileComplexType(complexType);
  1925.                             if (complexType.ElementDecl != null) {
  1926.                                 decl = complexType.ElementDecl.Clone();
  1927.                                 // decl.LocalElements = complexType.LocalElementDecls;
  1928.                             }
  1929.                         }
  1930.                         else if (xe.ElementSchemaType is XmlSchemaSimpleType) {
  1931.                             XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)xe.ElementSchemaType;
  1932.                             CompileSimpleType(simpleType);
  1933.                             if (simpleType.ElementDecl != null) {
  1934.                                 decl = simpleType.ElementDecl.Clone();
  1935.                             }
  1936.                         }
  1937.                     }
  1938.                     decl.Name = xe.QualifiedName;
  1939.                     decl.IsAbstract = xe.IsAbstract;
  1940.                     XmlSchemaComplexType ct = xe.ElementSchemaType as XmlSchemaComplexType;
  1941.                     if (ct != null) {
  1942.                         decl.IsAbstract |= ct.IsAbstract;
  1943.                     }
  1944.                     decl.IsNillable = xe.IsNillable;
  1945.                     decl.Block |= xe.BlockResolved;
  1946.                 }
  1947.                 if (decl.Datatype != null) {
  1948.                     decl.Datatype.VerifySchemaValid(this.schema.Notations, xe);
  1949.                 }
  1950.                
  1951.                 if (xe.DefaultValue != null || xe.FixedValue != null) {
  1952.                     if (decl.ContentValidator != null) {
  1953.                         if (decl.ContentValidator.ContentType == XmlSchemaContentType.TextOnly) {
  1954.                             if (xe.DefaultValue != null) {
  1955.                                 decl.Presence = SchemaDeclBase.Use.Default;
  1956.                                 decl.DefaultValueRaw = xe.DefaultValue;
  1957.                             }
  1958.                             else {
  1959.                                 decl.Presence = SchemaDeclBase.Use.Fixed;
  1960.                                 decl.DefaultValueRaw = xe.FixedValue;
  1961.                             }
  1962.                             if (decl.Datatype != null) {
  1963.                                 decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xe), true);
  1964.                             }
  1965.                         }
  1966.                         else if (decl.ContentValidator.ContentType != XmlSchemaContentType.Mixed || !decl.ContentValidator.IsEmptiable) {
  1967.                             throw new XmlSchemaException(Res.Sch_ElementCannotHaveValue, xe);
  1968.                         }
  1969.                     }
  1970.                 }
  1971.                 if (xe.HasConstraints) {
  1972.                     XmlSchemaObjectCollection constraints = xe.Constraints;
  1973.                     CompiledIdentityConstraint[] compiledConstraints = new CompiledIdentityConstraint[constraints.Count];
  1974.                     int idx = 0;
  1975.                     foreach (XmlSchemaIdentityConstraint constraint in constraints) {
  1976.                         CompileIdentityConstraint(constraint);
  1977.                         compiledConstraints[idx++] = constraint.CompiledConstraint;
  1978.                     }
  1979.                     decl.Constraints = compiledConstraints;
  1980.                 }
  1981.                 decl.SchemaElement = xe;
  1982.                 //So this is available for PSVI
  1983.                 xe.ElementDecl = decl;
  1984.             }
  1985.             catch (XmlSchemaException e) {
  1986.                 if (e.SourceSchemaObject == null) {
  1987.                     e.SetSource(xe);
  1988.                 }
  1989.                 SendValidationEvent(e);
  1990.                 xe.ElementDecl = SchemaElementDecl.Empty;
  1991.             }
  1992.             finally {
  1993.                 xe.IsProcessing = false;
  1994.             }
  1995.         }
  1996.        
  1997.         private ContentValidator CompileComplexContent(XmlSchemaComplexType complexType)
  1998.         {
  1999.             if (complexType.ContentType == XmlSchemaContentType.Empty) {
  2000.                 return ContentValidator.Empty;
  2001.             }
  2002.             else if (complexType.ContentType == XmlSchemaContentType.TextOnly) {
  2003.                 return ContentValidator.TextOnly;
  2004.             }
  2005.             XmlSchemaParticle particle = complexType.ContentTypeParticle;
  2006.             if (particle == null || particle == XmlSchemaParticle.Empty) {
  2007.                 if (complexType.ContentType == XmlSchemaContentType.ElementOnly) {
  2008.                     return ContentValidator.Empty;
  2009.                 }
  2010.                 else {
  2011.                     return ContentValidator.Mixed;
  2012.                 }
  2013.             }
  2014.             PushComplexType(complexType);
  2015.             if (particle is XmlSchemaAll) {
  2016.                 XmlSchemaAll all = (XmlSchemaAll)particle;
  2017.                 AllElementsContentValidator contentValidator = new AllElementsContentValidator(complexType.ContentType, all.Items.Count, all.MinOccurs == decimal.Zero);
  2018.                 foreach (XmlSchemaElement localElement in all.Items) {
  2019.                     if (!contentValidator.AddElement(localElement.QualifiedName, localElement, localElement.MinOccurs == decimal.Zero)) {
  2020.                         SendValidationEvent(Res.Sch_DupElement, localElement.QualifiedName.ToString(), localElement);
  2021.                     }
  2022.                 }
  2023.                 return contentValidator;
  2024.             }
  2025.             else {
  2026.                 ParticleContentValidator contentValidator = new ParticleContentValidator(complexType.ContentType);
  2027.                 #if DEBUG
  2028.                 string name = complexType.Name != null ? complexType.Name : string.Empty;
  2029.                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceVerbose, "CompileComplexContent: " + name + DumpContentModel(particle));
  2030.                 #endif
  2031.                 try {
  2032.                     contentValidator.Start();
  2033.                     BuildParticleContentModel(contentValidator, particle);
  2034.                     return contentValidator.Finish(compileContentModel);
  2035.                 }
  2036.                 catch (UpaException e) {
  2037.                     if (e.Particle1 is XmlSchemaElement) {
  2038.                         if (e.Particle2 is XmlSchemaElement) {
  2039.                             SendValidationEvent(Res.Sch_NonDeterministic, ((XmlSchemaElement)e.Particle1).QualifiedName.ToString(), (XmlSchemaElement)e.Particle2);
  2040.                         }
  2041.                         else {
  2042.                             SendValidationEvent(Res.Sch_NonDeterministicAnyEx, ((XmlSchemaAny)e.Particle2).NamespaceList.ToString(), ((XmlSchemaElement)e.Particle1).QualifiedName.ToString(), (XmlSchemaAny)e.Particle2);
  2043.                         }
  2044.                     }
  2045.                     else {
  2046.                         if (e.Particle2 is XmlSchemaElement) {
  2047.                             SendValidationEvent(Res.Sch_NonDeterministicAnyEx, ((XmlSchemaAny)e.Particle1).NamespaceList.ToString(), ((XmlSchemaElement)e.Particle2).QualifiedName.ToString(), (XmlSchemaAny)e.Particle1);
  2048.                         }
  2049.                         else {
  2050.                             SendValidationEvent(Res.Sch_NonDeterministicAnyAny, ((XmlSchemaAny)e.Particle1).NamespaceList.ToString(), ((XmlSchemaAny)e.Particle2).NamespaceList.ToString(), (XmlSchemaAny)e.Particle1);
  2051.                         }
  2052.                     }
  2053.                     return XmlSchemaComplexType.AnyTypeContentValidator;
  2054.                 }
  2055.                 catch (NotSupportedException) {
  2056.                     SendValidationEvent(Res.Sch_ComplexContentModel, complexType, XmlSeverityType.Warning);
  2057.                     return XmlSchemaComplexType.AnyTypeContentValidator;
  2058.                 }
  2059.             }
  2060.         }
  2061.        
  2062.         #if DEBUG
  2063.         private string DumpContentModel(XmlSchemaParticle particle)
  2064.         {
  2065.             StringBuilder sb = new StringBuilder();
  2066.             DumpContentModelTo(sb, particle);
  2067.             return sb.ToString();
  2068.         }
  2069.        
  2070.         private void DumpContentModelTo(StringBuilder sb, XmlSchemaParticle particle)
  2071.         {
  2072.             if (particle is XmlSchemaElement) {
  2073.                 sb.Append(((XmlSchemaElement)particle).QualifiedName);
  2074.             }
  2075.             else if (particle is XmlSchemaAny) {
  2076.                 sb.Append("<");
  2077.                 sb.Append(((XmlSchemaAny)particle).NamespaceList.ToString());
  2078.                 sb.Append(">");
  2079.             }
  2080.             else if (particle is XmlSchemaAll) {
  2081.                 XmlSchemaAll all = (XmlSchemaAll)particle;
  2082.                 sb.Append("[");
  2083.                 bool first = true;
  2084.                 foreach (XmlSchemaElement localElement in all.Items) {
  2085.                     if (first) {
  2086.                         first = false;
  2087.                     }
  2088.                     else {
  2089.                         sb.Append(", ");
  2090.                     }
  2091.                     sb.Append(localElement.QualifiedName.Name);
  2092.                     if (localElement.MinOccurs == decimal.Zero) {
  2093.                         sb.Append("?");
  2094.                     }
  2095.                 }
  2096.                 sb.Append("]");
  2097.             }
  2098.             else if (particle is XmlSchemaGroupBase) {
  2099.                 XmlSchemaGroupBase gb = (XmlSchemaGroupBase)particle;
  2100.                 sb.Append("(");
  2101.                 string delimeter = (particle is XmlSchemaChoice) ? " | " : ", ";
  2102.                 bool first = true;
  2103.                 foreach (XmlSchemaParticle p in gb.Items) {
  2104.                     if (first) {
  2105.                         first = false;
  2106.                     }
  2107.                     else {
  2108.                         sb.Append(delimeter);
  2109.                     }
  2110.                     DumpContentModelTo(sb, p);
  2111.                 }
  2112.                 sb.Append(")");
  2113.             }
  2114.             else {
  2115.                 Debug.Assert(particle == XmlSchemaParticle.Empty);
  2116.                 sb.Append("<>");
  2117.             }
  2118.             if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.One) {
  2119.                 // nothing
  2120.             }
  2121.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.One) {
  2122.                 sb.Append("?");
  2123.             }
  2124.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.MaxValue) {
  2125.                 sb.Append("*");
  2126.             }
  2127.             else if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.MaxValue) {
  2128.                 sb.Append("+");
  2129.             }
  2130.             else {
  2131.                 sb.Append("{" + particle.MinOccurs.ToString(NumberFormatInfo.InvariantInfo) + ", " + particle.MaxOccurs.ToString(NumberFormatInfo.InvariantInfo) + "}");
  2132.             }
  2133.         }
  2134.         #endif
  2135.        
  2136.         private void BuildParticleContentModel(ParticleContentValidator contentValidator, XmlSchemaParticle particle)
  2137.         {
  2138.             if (particle is XmlSchemaElement) {
  2139.                 XmlSchemaElement element = (XmlSchemaElement)particle;
  2140.                 contentValidator.AddName(element.QualifiedName, element);
  2141.             }
  2142.             else if (particle is XmlSchemaAny) {
  2143.                 XmlSchemaAny any = (XmlSchemaAny)particle;
  2144.                 contentValidator.AddNamespaceList(any.NamespaceList, any);
  2145.             }
  2146.             else if (particle is XmlSchemaGroupBase) {
  2147.                 XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items;
  2148.                 bool isChoice = particle is XmlSchemaChoice;
  2149.                 contentValidator.OpenGroup();
  2150.                 bool first = true;
  2151.                 foreach (XmlSchemaParticle p in particles) {
  2152.                     Debug.Assert(!p.IsEmpty);
  2153.                     if (first) {
  2154.                         first = false;
  2155.                     }
  2156.                     else if (isChoice) {
  2157.                         contentValidator.AddChoice();
  2158.                     }
  2159.                     else {
  2160.                         contentValidator.AddSequence();
  2161.                     }
  2162.                     BuildParticleContentModel(contentValidator, p);
  2163.                 }
  2164.                 contentValidator.CloseGroup();
  2165.             }
  2166.             else {
  2167.                 Debug.Assert(false);
  2168.             }
  2169.             if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.One) {
  2170.                 // nothing
  2171.             }
  2172.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.One) {
  2173.                 contentValidator.AddQMark();
  2174.             }
  2175.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.MaxValue) {
  2176.                 contentValidator.AddStar();
  2177.             }
  2178.             else if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.MaxValue) {
  2179.                 contentValidator.AddPlus();
  2180.             }
  2181.             else {
  2182.                 contentValidator.AddLeafRange(particle.MinOccurs, particle.MaxOccurs);
  2183.             }
  2184.         }
  2185.        
  2186.         private void CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle)
  2187.         {
  2188.             if (particle is XmlSchemaElement) {
  2189.                 XmlSchemaElement localElement = (XmlSchemaElement)particle;
  2190.                 CompileElement(localElement);
  2191.                 if (complexType.LocalElements[localElement.QualifiedName] == null) {
  2192.                     complexType.LocalElements.Add(localElement.QualifiedName, localElement);
  2193.                 }
  2194.                 else {
  2195.                     XmlSchemaElement element = (XmlSchemaElement)complexType.LocalElements[localElement.QualifiedName];
  2196.                     if (element.ElementSchemaType != localElement.ElementSchemaType) {
  2197.                         SendValidationEvent(Res.Sch_ElementTypeCollision, particle);
  2198.                     }
  2199.                 }
  2200.             }
  2201.             else if (particle is XmlSchemaGroupBase) {
  2202.                 XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items;
  2203.                 foreach (XmlSchemaParticle p in particles) {
  2204.                     CompileParticleElements(complexType, p);
  2205.                 }
  2206.             }
  2207.         }
  2208.        
  2209.         private void CompileCompexTypeElements(XmlSchemaComplexType complexType)
  2210.         {
  2211.             if (complexType.IsProcessing) {
  2212.                 SendValidationEvent(Res.Sch_TypeCircularRef, complexType);
  2213.                 return;
  2214.             }
  2215.             complexType.IsProcessing = true;
  2216.             if (complexType.ContentTypeParticle != XmlSchemaParticle.Empty) {
  2217.                 CompileParticleElements(complexType, complexType.ContentTypeParticle);
  2218.             }
  2219.             complexType.IsProcessing = false;
  2220.         }
  2221.        
  2222.         private XmlSchemaSimpleType GetSimpleType(XmlQualifiedName name)
  2223.         {
  2224.             XmlSchemaSimpleType type = this.schema.SchemaTypes[name] as XmlSchemaSimpleType;
  2225.             if (type != null) {
  2226.                 CompileSimpleType(type);
  2227.             }
  2228.             else {
  2229.                 type = DatatypeImplementation.GetSimpleTypeFromXsdType(name);
  2230.                 //Re-assign datatype impl for V1Compat
  2231.                 if (type != null) {
  2232.                     if (type.TypeCode == XmlTypeCode.NormalizedString) {
  2233.                         type = DatatypeImplementation.GetNormalizedStringTypeV1Compat();
  2234.                     }
  2235.                     else if (type.TypeCode == XmlTypeCode.Token) {
  2236.                         type = DatatypeImplementation.GetTokenTypeV1Compat();
  2237.                     }
  2238.                 }
  2239.             }
  2240.             return type;
  2241.         }
  2242.        
  2243.         private XmlSchemaComplexType GetComplexType(XmlQualifiedName name)
  2244.         {
  2245.             XmlSchemaComplexType type = this.schema.SchemaTypes[name] as XmlSchemaComplexType;
  2246.             if (type != null) {
  2247.                 CompileComplexType(type);
  2248.             }
  2249.             return type;
  2250.         }
  2251.        
  2252.         private XmlSchemaType GetAnySchemaType(XmlQualifiedName name)
  2253.         {
  2254.             XmlSchemaType type = (XmlSchemaType)this.schema.SchemaTypes[name];
  2255.             if (type != null) {
  2256.                 if (type is XmlSchemaComplexType) {
  2257.                     CompileComplexType((XmlSchemaComplexType)type);
  2258.                 }
  2259.                 else {
  2260.                     CompileSimpleType((XmlSchemaSimpleType)type);
  2261.                 }
  2262.                 return type;
  2263.             }
  2264.             else {
  2265.                 //Its is a built-in simpleType
  2266.                 XmlSchemaSimpleType simpleType = DatatypeImplementation.GetSimpleTypeFromXsdType(name);
  2267.                 return simpleType;
  2268.             }
  2269.         }
  2270.     }
  2271.    
  2272. }
  2273. // namespace System.Xml

Developer Fusion