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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Preprocessor.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.Collections;
  20.     using System.Collections.Generic;
  21.     using System.IO;
  22.     using System.Diagnostics;
  23.    
  24.     #pragma warning disable 618
  25.     internal sealed class SchemaCollectionPreprocessor : BaseProcessor
  26.     {
  27.         enum Compositor
  28.         {
  29.             Root,
  30.             Include,
  31.             Import
  32.         }
  33.        
  34.         XmlSchema schema;
  35.         string targetNamespace;
  36.         bool buildinIncluded = false;
  37.         XmlSchemaForm elementFormDefault;
  38.         XmlSchemaForm attributeFormDefault;
  39.         XmlSchemaDerivationMethod blockDefault;
  40.         XmlSchemaDerivationMethod finalDefault;
  41.         //Dictionary<Uri, Uri> schemaLocations;
  42.         Hashtable schemaLocations;
  43.         Hashtable referenceNamespaces;
  44.        
  45.         string Xmlns;
  46.         const XmlSchemaDerivationMethod schemaBlockDefaultAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Substitution;
  47.         const XmlSchemaDerivationMethod schemaFinalDefaultAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.List | XmlSchemaDerivationMethod.Union;
  48.         const XmlSchemaDerivationMethod elementBlockAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Substitution;
  49.         const XmlSchemaDerivationMethod elementFinalAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension;
  50.         const XmlSchemaDerivationMethod simpleTypeFinalAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.List | XmlSchemaDerivationMethod.Union;
  51.         const XmlSchemaDerivationMethod complexTypeBlockAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension;
  52.         const XmlSchemaDerivationMethod complexTypeFinalAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension;
  53.        
  54.         private XmlResolver xmlResolver = null;
  55.        
  56.         public SchemaCollectionPreprocessor(XmlNameTable nameTable, SchemaNames schemaNames, ValidationEventHandler eventHandler) : base(nameTable, schemaNames, eventHandler)
  57.         {
  58.         }
  59.        
  60.         public bool Execute(XmlSchema schema, string targetNamespace, bool loadExternals, XmlSchemaCollection xsc)
  61.         {
  62.             this.schema = schema;
  63.             Xmlns = NameTable.Add("xmlns");
  64.            
  65.             Cleanup(schema);
  66.             if (loadExternals && xmlResolver != null) {
  67.                 schemaLocations = new Hashtable();
  68.                 //new Dictionary<Uri, Uri>();
  69.                 if (schema.BaseUri != null) {
  70.                     schemaLocations.Add(schema.BaseUri, schema.BaseUri);
  71.                 }
  72.                 LoadExternals(schema, xsc);
  73.             }
  74.             ValidateIdAttribute(schema);
  75.             Preprocess(schema, targetNamespace, Compositor.Root);
  76.             if (!HasErrors) {
  77.                 schema.IsPreprocessed = true;
  78.                 foreach (XmlSchemaExternal include in schema.Includes) {
  79.                     if (include.Schema != null) {
  80.                         include.Schema.IsPreprocessed = true;
  81.                     }
  82.                 }
  83.             }
  84.             return !HasErrors;
  85.         }
  86.        
  87.         private void Cleanup(XmlSchema schema)
  88.         {
  89.             if (schema.IsProcessing) {
  90.                 return;
  91.             }
  92.             schema.IsProcessing = true;
  93.            
  94.             foreach (XmlSchemaExternal include in schema.Includes) {
  95.                 if (include.Schema != null) {
  96.                     Cleanup(include.Schema);
  97.                 }
  98.                
  99.                 if (include is XmlSchemaRedefine) {
  100.                     XmlSchemaRedefine rdef = include as XmlSchemaRedefine;
  101.                     rdef.AttributeGroups.Clear();
  102.                     rdef.Groups.Clear();
  103.                     rdef.SchemaTypes.Clear();
  104.                 }
  105.                
  106.             }
  107.            
  108.             schema.Attributes.Clear();
  109.             schema.AttributeGroups.Clear();
  110.             schema.SchemaTypes.Clear();
  111.             schema.Elements.Clear();
  112.             schema.Groups.Clear();
  113.             schema.Notations.Clear();
  114.             schema.Ids.Clear();
  115.             schema.IdentityConstraints.Clear();
  116.            
  117.             schema.IsProcessing = false;
  118.         }
  119.        
  120.         internal XmlResolver XmlResolver {
  121.             set { xmlResolver = value; }
  122.         }
  123.        
  124.         private void LoadExternals(XmlSchema schema, XmlSchemaCollection xsc)
  125.         {
  126.             if (schema.IsProcessing) {
  127.                 return;
  128.             }
  129.             schema.IsProcessing = true;
  130.             foreach (XmlSchemaExternal include in schema.Includes) {
  131.                 Uri includeLocation = null;
  132.                 //CASE 1: If the Schema object of the include has been set
  133.                 if (include.Schema != null) {
  134.                     // already loaded
  135.                     if (include is XmlSchemaImport && ((XmlSchemaImport)include).Namespace == XmlReservedNs.NsXml) {
  136.                         buildinIncluded = true;
  137.                     }
  138.                     else {
  139.                         includeLocation = include.BaseUri;
  140.                         if (includeLocation != null && schemaLocations[includeLocation] == null) {
  141.                             schemaLocations.Add(includeLocation, includeLocation);
  142.                         }
  143.                         LoadExternals(include.Schema, xsc);
  144.                     }
  145.                     continue;
  146.                 }
  147.                
  148.                 //CASE 2: If the include has been already added to the schema collection directly
  149.                 if (xsc != null && include is XmlSchemaImport) {
  150.                     //Added for SchemaCollection compatibility
  151.                     XmlSchemaImport import = (XmlSchemaImport)include;
  152.                     string importNS = import.Namespace != null ? import.Namespace : string.Empty;
  153.                     include.Schema = xsc[importNS];
  154.                     //Fetch it from the collection
  155.                     if (include.Schema != null) {
  156.                         include.Schema = include.Schema.Clone();
  157.                         if (include.Schema.BaseUri != null && schemaLocations[include.Schema.BaseUri] == null) {
  158.                             schemaLocations.Add(include.Schema.BaseUri, include.Schema.BaseUri);
  159.                         }
  160.                         //To avoid re-including components that were already included through a different path
  161.                         Uri subUri = null;
  162.                         foreach (XmlSchemaExternal subInc in include.Schema.Includes) {
  163.                             if (subInc is XmlSchemaImport) {
  164.                                 XmlSchemaImport subImp = (XmlSchemaImport)subInc;
  165.                                 subUri = subImp.BaseUri != null ? subImp.BaseUri : (subImp.Schema != null && subImp.Schema.BaseUri != null ? subImp.Schema.BaseUri : null);
  166.                                 if (subUri != null) {
  167.                                     if (schemaLocations[subUri] != null) {
  168.                                         subImp.Schema = null;
  169.                                         //So that the components are not included again
  170.                                     }
  171.                                     else {
  172.                                         //if its not there already, add it
  173.                                         schemaLocations.Add(subUri, subUri);
  174.                                         //The schema for that location is available
  175.                                     }
  176.                                 }
  177.                             }
  178.                         }
  179.                         continue;
  180.                     }
  181.                 }
  182.                
  183.                 //CASE 3: If the imported namespace is the XML namespace, load built-in schema
  184.                 if (include is XmlSchemaImport && ((XmlSchemaImport)include).Namespace == XmlReservedNs.NsXml) {
  185.                     if (!buildinIncluded) {
  186.                         buildinIncluded = true;
  187.                         include.Schema = Preprocessor.GetBuildInSchema();
  188.                     }
  189.                     continue;
  190.                 }
  191.                
  192.                 //CASE4: Parse schema from the provided location
  193.                 string schemaLocation = include.SchemaLocation;
  194.                 if (schemaLocation == null) {
  195.                     continue;
  196.                 }
  197.                
  198.                 Uri ruri = ResolveSchemaLocationUri(schema, schemaLocation);
  199.                
  200.                 if (ruri != null && schemaLocations[ruri] == null) {
  201.                     Stream stream = GetSchemaEntity(ruri);
  202.                     if (stream != null) {
  203.                         include.BaseUri = ruri;
  204.                         schemaLocations.Add(ruri, ruri);
  205.                         XmlTextReader reader = new XmlTextReader(ruri.ToString(), stream, NameTable);
  206.                         reader.XmlResolver = xmlResolver;
  207.                         try {
  208.                             Parser parser = new Parser(SchemaType.XSD, NameTable, SchemaNames, EventHandler);
  209.                             parser.Parse(reader, null);
  210.                             while (reader.Read())
  211.                                 ;
  212.                             // wellformness check
  213.                             include.Schema = parser.XmlSchema;
  214.                             LoadExternals(include.Schema, xsc);
  215.                         }
  216.                         catch (XmlSchemaException e) {
  217.                             SendValidationEventNoThrow(new XmlSchemaException(Res.Sch_CannotLoadSchema, new string[] {schemaLocation, e.Message}, e.SourceUri, e.LineNumber, e.LinePosition), XmlSeverityType.Error);
  218.                         }
  219.                         catch (Exception) {
  220.                             SendValidationEvent(Res.Sch_InvalidIncludeLocation, include, XmlSeverityType.Warning);
  221.                         }
  222.                         finally {
  223.                             reader.Close();
  224.                         }
  225.                        
  226.                     }
  227.                     else {
  228.                         SendValidationEvent(Res.Sch_InvalidIncludeLocation, include, XmlSeverityType.Warning);
  229.                     }
  230.                 }
  231.                
  232.             }
  233.             schema.IsProcessing = false;
  234.         }
  235.        
  236.        
  237.         private void BuildRefNamespaces(XmlSchema schema)
  238.         {
  239.             referenceNamespaces = new Hashtable();
  240.             XmlSchemaImport import;
  241.             string ns;
  242.            
  243.             //Add XSD namespace
  244.             referenceNamespaces.Add(XmlReservedNs.NsXs, XmlReservedNs.NsXs);
  245.             referenceNamespaces.Add(string.Empty, string.Empty);
  246.            
  247.             foreach (XmlSchemaExternal include in schema.Includes) {
  248.                 if (include is XmlSchemaImport) {
  249.                     import = include as XmlSchemaImport;
  250.                     ns = import.Namespace;
  251.                     if (ns != null && referenceNamespaces[ns] == null)
  252.                         referenceNamespaces.Add(ns, ns);
  253.                 }
  254.             }
  255.            
  256.             //Add the schema's targetnamespace
  257.             if (schema.TargetNamespace != null && referenceNamespaces[schema.TargetNamespace] == null)
  258.                 referenceNamespaces.Add(schema.TargetNamespace, schema.TargetNamespace);
  259.            
  260.         }
  261.        
  262.         private void Preprocess(XmlSchema schema, string targetNamespace, Compositor compositor)
  263.         {
  264.             if (schema.IsProcessing) {
  265.                 return;
  266.             }
  267.             schema.IsProcessing = true;
  268.             string tns = schema.TargetNamespace;
  269.             if (tns != null) {
  270.                 schema.TargetNamespace = tns = NameTable.Add(tns);
  271.                 if (tns.Length == 0) {
  272.                     SendValidationEvent(Res.Sch_InvalidTargetNamespaceAttribute, schema);
  273.                 }
  274.                 else {
  275.                     try {
  276.                         XmlConvert.ToUri(tns);
  277.                         // can throw
  278.                     }
  279.                     catch {
  280.                         SendValidationEvent(Res.Sch_InvalidNamespace, schema.TargetNamespace, schema);
  281.                     }
  282.                 }
  283.             }
  284.            
  285.             if (schema.Version != null) {
  286.                 try {
  287.                     XmlConvert.VerifyTOKEN(schema.Version);
  288.                     // can throw
  289.                 }
  290.                 catch (Exception) {
  291.                     SendValidationEvent(Res.Sch_AttributeValueDataType, "version", schema);
  292.                 }
  293.             }
  294.             switch (compositor) {
  295.                 case Compositor.Root:
  296.                     if (targetNamespace == null && schema.TargetNamespace != null) {
  297.                         // not specified
  298.                         targetNamespace = schema.TargetNamespace;
  299.                     }
  300.                     else if (schema.TargetNamespace == null && targetNamespace != null && targetNamespace.Length == 0) {
  301.                         // no namespace schema
  302.                         targetNamespace = null;
  303.                     }
  304.                     if (targetNamespace != schema.TargetNamespace) {
  305.                         SendValidationEvent(Res.Sch_MismatchTargetNamespaceEx, targetNamespace, schema.TargetNamespace, schema);
  306.                     }
  307.                     break;
  308.                 case Compositor.Import:
  309.                     if (targetNamespace != schema.TargetNamespace) {
  310.                         SendValidationEvent(Res.Sch_MismatchTargetNamespaceImport, targetNamespace, schema.TargetNamespace, schema);
  311.                     }
  312.                     break;
  313.                 case Compositor.Include:
  314.                     if (schema.TargetNamespace != null) {
  315.                         if (targetNamespace != schema.TargetNamespace) {
  316.                             SendValidationEvent(Res.Sch_MismatchTargetNamespaceInclude, targetNamespace, schema.TargetNamespace, schema);
  317.                         }
  318.                     }
  319.                     break;
  320.             }
  321.            
  322.             foreach (XmlSchemaExternal include in schema.Includes) {
  323.                 SetParent(include, schema);
  324.                 PreprocessAnnotation(include);
  325.                
  326.                 string loc = include.SchemaLocation;
  327.                 if (loc != null) {
  328.                     try {
  329.                         XmlConvert.ToUri(loc);
  330.                         // can throw
  331.                     }
  332.                     catch {
  333.                         SendValidationEvent(Res.Sch_InvalidSchemaLocation, loc, include);
  334.                     }
  335.                 }
  336.                 else if ((include is XmlSchemaRedefine || include is XmlSchemaInclude) && include.Schema == null) {
  337.                     SendValidationEvent(Res.Sch_MissRequiredAttribute, "schemaLocation", include);
  338.                 }
  339.                 if (include.Schema != null) {
  340.                     if (include is XmlSchemaRedefine) {
  341.                         Preprocess(include.Schema, schema.TargetNamespace, Compositor.Include);
  342.                     }
  343.                     else if (include is XmlSchemaImport) {
  344.                         if (((XmlSchemaImport)include).Namespace == null && schema.TargetNamespace == null) {
  345.                             SendValidationEvent(Res.Sch_ImportTargetNamespaceNull, include);
  346.                         }
  347.                         else if (((XmlSchemaImport)include).Namespace == schema.TargetNamespace) {
  348.                             SendValidationEvent(Res.Sch_ImportTargetNamespace, include);
  349.                         }
  350.                         Preprocess(include.Schema, ((XmlSchemaImport)include).Namespace, Compositor.Import);
  351.                     }
  352.                     else {
  353.                         Preprocess(include.Schema, schema.TargetNamespace, Compositor.Include);
  354.                     }
  355.                 }
  356.                 else if (include is XmlSchemaImport) {
  357.                     string ns = ((XmlSchemaImport)include).Namespace;
  358.                     if (ns != null) {
  359.                         if (ns.Length == 0) {
  360.                             SendValidationEvent(Res.Sch_InvalidNamespaceAttribute, ns, include);
  361.                         }
  362.                         else {
  363.                             try {
  364.                                 XmlConvert.ToUri(ns);
  365.                                 //can throw
  366.                             }
  367.                             catch (FormatException) {
  368.                                 SendValidationEvent(Res.Sch_InvalidNamespace, ns, include);
  369.                             }
  370.                         }
  371.                     }
  372.                 }
  373.             }
  374.            
  375.             //Begin processing the current schema passed to preprocess
  376.             //Build the namespaces that can be referenced in the current schema
  377.             BuildRefNamespaces(schema);
  378.            
  379.             this.targetNamespace = targetNamespace == null ? string.Empty : targetNamespace;
  380.            
  381.             if (schema.BlockDefault == XmlSchemaDerivationMethod.All) {
  382.                 this.blockDefault = XmlSchemaDerivationMethod.All;
  383.             }
  384.             else if (schema.BlockDefault == XmlSchemaDerivationMethod.None) {
  385.                 this.blockDefault = XmlSchemaDerivationMethod.Empty;
  386.             }
  387.             else {
  388.                 if ((schema.BlockDefault & ~schemaBlockDefaultAllowed) != 0) {
  389.                     SendValidationEvent(Res.Sch_InvalidBlockDefaultValue, schema);
  390.                 }
  391.                 this.blockDefault = schema.BlockDefault & schemaBlockDefaultAllowed;
  392.             }
  393.             if (schema.FinalDefault == XmlSchemaDerivationMethod.All) {
  394.                 this.finalDefault = XmlSchemaDerivationMethod.All;
  395.             }
  396.             else if (schema.FinalDefault == XmlSchemaDerivationMethod.None) {
  397.                 this.finalDefault = XmlSchemaDerivationMethod.Empty;
  398.             }
  399.             else {
  400.                 if ((schema.FinalDefault & ~schemaFinalDefaultAllowed) != 0) {
  401.                     SendValidationEvent(Res.Sch_InvalidFinalDefaultValue, schema);
  402.                 }
  403.                 this.finalDefault = schema.FinalDefault & schemaFinalDefaultAllowed;
  404.             }
  405.             this.elementFormDefault = schema.ElementFormDefault;
  406.             if (this.elementFormDefault == XmlSchemaForm.None) {
  407.                 this.elementFormDefault = XmlSchemaForm.Unqualified;
  408.             }
  409.             this.attributeFormDefault = schema.AttributeFormDefault;
  410.             if (this.attributeFormDefault == XmlSchemaForm.None) {
  411.                 this.attributeFormDefault = XmlSchemaForm.Unqualified;
  412.             }
  413.            
  414.             foreach (XmlSchemaExternal include in schema.Includes) {
  415.                 if (include is XmlSchemaRedefine) {
  416.                     XmlSchemaRedefine redefine = (XmlSchemaRedefine)include;
  417.                     if (include.Schema != null) {
  418.                         PreprocessRedefine(redefine);
  419.                     }
  420.                     else {
  421.                         foreach (XmlSchemaObject item in redefine.Items) {
  422.                             if (!(item is XmlSchemaAnnotation)) {
  423.                                 SendValidationEvent(Res.Sch_RedefineNoSchema, redefine);
  424.                                 break;
  425.                             }
  426.                         }
  427.                        
  428.                     }
  429.                 }
  430.                 XmlSchema includedSchema = include.Schema;
  431.                 if (includedSchema != null) {
  432.                     foreach (XmlSchemaElement element in includedSchema.Elements.Values) {
  433.                         AddToTable(schema.Elements, element.QualifiedName, element);
  434.                     }
  435.                     foreach (XmlSchemaAttribute attribute in includedSchema.Attributes.Values) {
  436.                         AddToTable(schema.Attributes, attribute.QualifiedName, attribute);
  437.                     }
  438.                     foreach (XmlSchemaGroup group in includedSchema.Groups.Values) {
  439.                         AddToTable(schema.Groups, group.QualifiedName, group);
  440.                     }
  441.                     foreach (XmlSchemaAttributeGroup attributeGroup in includedSchema.AttributeGroups.Values) {
  442.                         AddToTable(schema.AttributeGroups, attributeGroup.QualifiedName, attributeGroup);
  443.                     }
  444.                     foreach (XmlSchemaType type in includedSchema.SchemaTypes.Values) {
  445.                         AddToTable(schema.SchemaTypes, type.QualifiedName, type);
  446.                     }
  447.                     foreach (XmlSchemaNotation notation in includedSchema.Notations.Values) {
  448.                         AddToTable(schema.Notations, notation.QualifiedName, notation);
  449.                     }
  450.                 }
  451.                 ValidateIdAttribute(include);
  452.             }
  453.            
  454.             ArrayList removeItemsList = new ArrayList();
  455.             foreach (XmlSchemaObject item in schema.Items) {
  456.                 SetParent(item, schema);
  457.                 if (item is XmlSchemaAttribute) {
  458.                     XmlSchemaAttribute attribute = (XmlSchemaAttribute)item;
  459.                     PreprocessAttribute(attribute);
  460.                     AddToTable(schema.Attributes, attribute.QualifiedName, attribute);
  461.                 }
  462.                 else if (item is XmlSchemaAttributeGroup) {
  463.                     XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)item;
  464.                     PreprocessAttributeGroup(attributeGroup);
  465.                     AddToTable(schema.AttributeGroups, attributeGroup.QualifiedName, attributeGroup);
  466.                 }
  467.                 else if (item is XmlSchemaComplexType) {
  468.                     XmlSchemaComplexType complexType = (XmlSchemaComplexType)item;
  469.                     PreprocessComplexType(complexType, false);
  470.                     AddToTable(schema.SchemaTypes, complexType.QualifiedName, complexType);
  471.                 }
  472.                 else if (item is XmlSchemaSimpleType) {
  473.                     XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)item;
  474.                     PreprocessSimpleType(simpleType, false);
  475.                     AddToTable(schema.SchemaTypes, simpleType.QualifiedName, simpleType);
  476.                 }
  477.                 else if (item is XmlSchemaElement) {
  478.                     XmlSchemaElement element = (XmlSchemaElement)item;
  479.                     PreprocessElement(element);
  480.                     AddToTable(schema.Elements, element.QualifiedName, element);
  481.                 }
  482.                 else if (item is XmlSchemaGroup) {
  483.                     XmlSchemaGroup group = (XmlSchemaGroup)item;
  484.                     PreprocessGroup(group);
  485.                     AddToTable(schema.Groups, group.QualifiedName, group);
  486.                 }
  487.                 else if (item is XmlSchemaNotation) {
  488.                     XmlSchemaNotation notation = (XmlSchemaNotation)item;
  489.                     PreprocessNotation(notation);
  490.                     AddToTable(schema.Notations, notation.QualifiedName, notation);
  491.                 }
  492.                 else if (!(item is XmlSchemaAnnotation)) {
  493.                     SendValidationEvent(Res.Sch_InvalidCollection, (XmlSchemaObject)item);
  494.                     removeItemsList.Add(item);
  495.                 }
  496.             }
  497.             foreach (XmlSchemaObject item in removeItemsList) {
  498.                 schema.Items.Remove(item);
  499.             }
  500.            
  501.             schema.IsProcessing = false;
  502.         }
  503.        
  504.         private void PreprocessRedefine(XmlSchemaRedefine redefine)
  505.         {
  506.             foreach (XmlSchemaObject item in redefine.Items) {
  507.                 SetParent(item, redefine);
  508.                 if (item is XmlSchemaGroup) {
  509.                     XmlSchemaGroup group = (XmlSchemaGroup)item;
  510.                     PreprocessGroup(group);
  511.                     if (redefine.Groups[group.QualifiedName] != null) {
  512.                         SendValidationEvent(Res.Sch_GroupDoubleRedefine, group);
  513.                     }
  514.                     else {
  515.                         AddToTable(redefine.Groups, group.QualifiedName, group);
  516.                         group.Redefined = (XmlSchemaGroup)redefine.Schema.Groups[group.QualifiedName];
  517.                         if (group.Redefined != null) {
  518.                             CheckRefinedGroup(group);
  519.                         }
  520.                         else {
  521.                             SendValidationEvent(Res.Sch_GroupRedefineNotFound, group);
  522.                         }
  523.                     }
  524.                 }
  525.                 else if (item is XmlSchemaAttributeGroup) {
  526.                     XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)item;
  527.                     PreprocessAttributeGroup(attributeGroup);
  528.                     if (redefine.AttributeGroups[attributeGroup.QualifiedName] != null) {
  529.                         SendValidationEvent(Res.Sch_AttrGroupDoubleRedefine, attributeGroup);
  530.                     }
  531.                     else {
  532.                         AddToTable(redefine.AttributeGroups, attributeGroup.QualifiedName, attributeGroup);
  533.                         attributeGroup.Redefined = (XmlSchemaAttributeGroup)redefine.Schema.AttributeGroups[attributeGroup.QualifiedName];
  534.                         if (attributeGroup.Redefined != null) {
  535.                             CheckRefinedAttributeGroup(attributeGroup);
  536.                         }
  537.                         else {
  538.                             SendValidationEvent(Res.Sch_AttrGroupRedefineNotFound, attributeGroup);
  539.                         }
  540.                     }
  541.                 }
  542.                 else if (item is XmlSchemaComplexType) {
  543.                     XmlSchemaComplexType complexType = (XmlSchemaComplexType)item;
  544.                     PreprocessComplexType(complexType, false);
  545.                     if (redefine.SchemaTypes[complexType.QualifiedName] != null) {
  546.                         SendValidationEvent(Res.Sch_ComplexTypeDoubleRedefine, complexType);
  547.                     }
  548.                     else {
  549.                         AddToTable(redefine.SchemaTypes, complexType.QualifiedName, complexType);
  550.                         XmlSchemaType type = (XmlSchemaType)redefine.Schema.SchemaTypes[complexType.QualifiedName];
  551.                         if (type != null) {
  552.                             if (type is XmlSchemaComplexType) {
  553.                                 complexType.Redefined = type;
  554.                                 CheckRefinedComplexType(complexType);
  555.                             }
  556.                             else {
  557.                                 SendValidationEvent(Res.Sch_SimpleToComplexTypeRedefine, complexType);
  558.                             }
  559.                         }
  560.                         else {
  561.                             SendValidationEvent(Res.Sch_ComplexTypeRedefineNotFound, complexType);
  562.                         }
  563.                     }
  564.                 }
  565.                 else if (item is XmlSchemaSimpleType) {
  566.                     XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)item;
  567.                     PreprocessSimpleType(simpleType, false);
  568.                     if (redefine.SchemaTypes[simpleType.QualifiedName] != null) {
  569.                         SendValidationEvent(Res.Sch_SimpleTypeDoubleRedefine, simpleType);
  570.                     }
  571.                     else {
  572.                         AddToTable(redefine.SchemaTypes, simpleType.QualifiedName, simpleType);
  573.                         XmlSchemaType type = (XmlSchemaType)redefine.Schema.SchemaTypes[simpleType.QualifiedName];
  574.                         if (type != null) {
  575.                             if (type is XmlSchemaSimpleType) {
  576.                                 simpleType.Redefined = type;
  577.                                 CheckRefinedSimpleType(simpleType);
  578.                             }
  579.                             else {
  580.                                 SendValidationEvent(Res.Sch_ComplexToSimpleTypeRedefine, simpleType);
  581.                             }
  582.                         }
  583.                         else {
  584.                             SendValidationEvent(Res.Sch_SimpleTypeRedefineNotFound, simpleType);
  585.                         }
  586.                     }
  587.                 }
  588.             }
  589.            
  590.             foreach (DictionaryEntry entry in redefine.Groups) {
  591.                 redefine.Schema.Groups.Insert((XmlQualifiedName)entry.Key, (XmlSchemaObject)entry.Value);
  592.             }
  593.             foreach (DictionaryEntry entry in redefine.AttributeGroups) {
  594.                 redefine.Schema.AttributeGroups.Insert((XmlQualifiedName)entry.Key, (XmlSchemaObject)entry.Value);
  595.             }
  596.             foreach (DictionaryEntry entry in redefine.SchemaTypes) {
  597.                 redefine.Schema.SchemaTypes.Insert((XmlQualifiedName)entry.Key, (XmlSchemaObject)entry.Value);
  598.             }
  599.         }
  600.        
  601.        
  602.         private int CountGroupSelfReference(XmlSchemaObjectCollection items, XmlQualifiedName name)
  603.         {
  604.             int count = 0;
  605.             foreach (XmlSchemaParticle particle in items) {
  606.                 if (particle is XmlSchemaGroupRef) {
  607.                     XmlSchemaGroupRef groupRef = (XmlSchemaGroupRef)particle;
  608.                     if (groupRef.RefName == name) {
  609.                         if (groupRef.MinOccurs != decimal.One || groupRef.MaxOccurs != decimal.One) {
  610.                             SendValidationEvent(Res.Sch_MinMaxGroupRedefine, groupRef);
  611.                         }
  612.                         count++;
  613.                     }
  614.                 }
  615.                 else if (particle is XmlSchemaGroupBase) {
  616.                     count += CountGroupSelfReference(((XmlSchemaGroupBase)particle).Items, name);
  617.                 }
  618.                 if (count > 1) {
  619.                     break;
  620.                 }
  621.             }
  622.             return count;
  623.            
  624.         }
  625.        
  626.         private void CheckRefinedGroup(XmlSchemaGroup group)
  627.         {
  628.             int count = 0;
  629.             if (group.Particle != null) {
  630.                 count = CountGroupSelfReference(group.Particle.Items, group.QualifiedName);
  631.             }
  632.             if (count > 1) {
  633.                 SendValidationEvent(Res.Sch_MultipleGroupSelfRef, group);
  634.             }
  635.         }
  636.        
  637.         private void CheckRefinedAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  638.         {
  639.             int count = 0;
  640.             foreach (object obj in attributeGroup.Attributes) {
  641.                 if (obj is XmlSchemaAttributeGroupRef && ((XmlSchemaAttributeGroupRef)obj).RefName == attributeGroup.QualifiedName) {
  642.                     count++;
  643.                 }
  644.             }
  645.             if (count > 1) {
  646.                 SendValidationEvent(Res.Sch_MultipleAttrGroupSelfRef, attributeGroup);
  647.             }
  648.         }
  649.        
  650.         private void CheckRefinedSimpleType(XmlSchemaSimpleType stype)
  651.         {
  652.             if (stype.Content != null && stype.Content is XmlSchemaSimpleTypeRestriction) {
  653.                 XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)stype.Content;
  654.                 if (restriction.BaseTypeName == stype.QualifiedName) {
  655.                     return;
  656.                 }
  657.             }
  658.             SendValidationEvent(Res.Sch_InvalidTypeRedefine, stype);
  659.         }
  660.        
  661.         private void CheckRefinedComplexType(XmlSchemaComplexType ctype)
  662.         {
  663.             if (ctype.ContentModel != null) {
  664.                 XmlQualifiedName baseName;
  665.                 if (ctype.ContentModel is XmlSchemaComplexContent) {
  666.                     XmlSchemaComplexContent content = (XmlSchemaComplexContent)ctype.ContentModel;
  667.                     if (content.Content is XmlSchemaComplexContentRestriction) {
  668.                         baseName = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;
  669.                     }
  670.                     else {
  671.                         baseName = ((XmlSchemaComplexContentExtension)content.Content).BaseTypeName;
  672.                     }
  673.                 }
  674.                 else {
  675.                     XmlSchemaSimpleContent content = (XmlSchemaSimpleContent)ctype.ContentModel;
  676.                     if (content.Content is XmlSchemaSimpleContentRestriction) {
  677.                         baseName = ((XmlSchemaSimpleContentRestriction)content.Content).BaseTypeName;
  678.                     }
  679.                     else {
  680.                         baseName = ((XmlSchemaSimpleContentExtension)content.Content).BaseTypeName;
  681.                     }
  682.                 }
  683.                 if (baseName == ctype.QualifiedName) {
  684.                     return;
  685.                 }
  686.             }
  687.             SendValidationEvent(Res.Sch_InvalidTypeRedefine, ctype);
  688.         }
  689.        
  690.         private void PreprocessAttribute(XmlSchemaAttribute attribute)
  691.         {
  692.             if (attribute.Name != null) {
  693.                 ValidateNameAttribute(attribute);
  694.                 attribute.SetQualifiedName(new XmlQualifiedName(attribute.Name, this.targetNamespace));
  695.             }
  696.             else {
  697.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", attribute);
  698.             }
  699.             if (attribute.Use != XmlSchemaUse.None) {
  700.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "use", attribute);
  701.             }
  702.             if (attribute.Form != XmlSchemaForm.None) {
  703.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "form", attribute);
  704.             }
  705.             PreprocessAttributeContent(attribute);
  706.             ValidateIdAttribute(attribute);
  707.         }
  708.        
  709.         private void PreprocessLocalAttribute(XmlSchemaAttribute attribute)
  710.         {
  711.             if (attribute.Name != null) {
  712.                 // name
  713.                 ValidateNameAttribute(attribute);
  714.                 PreprocessAttributeContent(attribute);
  715.                 attribute.SetQualifiedName(new XmlQualifiedName(attribute.Name, (attribute.Form == XmlSchemaForm.Qualified || (attribute.Form == XmlSchemaForm.None && this.attributeFormDefault == XmlSchemaForm.Qualified)) ? this.targetNamespace : null));
  716.             }
  717.             else {
  718.                 // ref
  719.                 PreprocessAnnotation(attribute);
  720.                 //set parent of annotation child of ref
  721.                 if (attribute.RefName.IsEmpty) {
  722.                     SendValidationEvent(Res.Sch_AttributeNameRef, "???", attribute);
  723.                 }
  724.                 else {
  725.                     ValidateQNameAttribute(attribute, "ref", attribute.RefName);
  726.                 }
  727.                 if (!attribute.SchemaTypeName.IsEmpty || attribute.SchemaType != null || attribute.Form != XmlSchemaForm.None)/*||
  728.                     attribute.DefaultValue != null ||
  729.                     attribute.FixedValue != null*/ {
  730.                     SendValidationEvent(Res.Sch_InvalidAttributeRef, attribute);
  731.                 }
  732.                 attribute.SetQualifiedName(attribute.RefName);
  733.             }
  734.             ValidateIdAttribute(attribute);
  735.         }
  736.        
  737.         private void PreprocessAttributeContent(XmlSchemaAttribute attribute)
  738.         {
  739.             PreprocessAnnotation(attribute);
  740.             if (schema.TargetNamespace == XmlReservedNs.NsXsi) {
  741.                 SendValidationEvent(Res.Sch_TargetNamespaceXsi, attribute);
  742.             }
  743.             if (!attribute.RefName.IsEmpty) {
  744.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "ref", attribute);
  745.             }
  746.             if (attribute.DefaultValue != null && attribute.FixedValue != null) {
  747.                 SendValidationEvent(Res.Sch_DefaultFixedAttributes, attribute);
  748.             }
  749.             if (attribute.DefaultValue != null && attribute.Use != XmlSchemaUse.Optional && attribute.Use != XmlSchemaUse.None) {
  750.                 SendValidationEvent(Res.Sch_OptionalDefaultAttribute, attribute);
  751.             }
  752.             if (attribute.Name == Xmlns) {
  753.                 SendValidationEvent(Res.Sch_XmlNsAttribute, attribute);
  754.             }
  755.             if (attribute.SchemaType != null) {
  756.                 SetParent(attribute.SchemaType, attribute);
  757.                 if (!attribute.SchemaTypeName.IsEmpty) {
  758.                     SendValidationEvent(Res.Sch_TypeMutualExclusive, attribute);
  759.                 }
  760.                 PreprocessSimpleType(attribute.SchemaType, true);
  761.             }
  762.             if (!attribute.SchemaTypeName.IsEmpty) {
  763.                 ValidateQNameAttribute(attribute, "type", attribute.SchemaTypeName);
  764.             }
  765.         }
  766.        
  767.         private void PreprocessAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  768.         {
  769.             if (attributeGroup.Name != null) {
  770.                 ValidateNameAttribute(attributeGroup);
  771.                 attributeGroup.SetQualifiedName(new XmlQualifiedName(attributeGroup.Name, this.targetNamespace));
  772.             }
  773.             else {
  774.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", attributeGroup);
  775.             }
  776.             PreprocessAttributes(attributeGroup.Attributes, attributeGroup.AnyAttribute, attributeGroup);
  777.             PreprocessAnnotation(attributeGroup);
  778.             ValidateIdAttribute(attributeGroup);
  779.         }
  780.        
  781.         private void PreprocessElement(XmlSchemaElement element)
  782.         {
  783.             if (element.Name != null) {
  784.                 ValidateNameAttribute(element);
  785.                 element.SetQualifiedName(new XmlQualifiedName(element.Name, this.targetNamespace));
  786.             }
  787.             else {
  788.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", element);
  789.             }
  790.             PreprocessElementContent(element);
  791.            
  792.             if (element.Final == XmlSchemaDerivationMethod.All) {
  793.                 element.SetFinalResolved(XmlSchemaDerivationMethod.All);
  794.             }
  795.             else if (element.Final == XmlSchemaDerivationMethod.None) {
  796.                 if (this.finalDefault == XmlSchemaDerivationMethod.All) {
  797.                     element.SetFinalResolved(XmlSchemaDerivationMethod.All);
  798.                 }
  799.                 else {
  800.                     element.SetFinalResolved(this.finalDefault & elementFinalAllowed);
  801.                 }
  802.             }
  803.             else {
  804.                 if ((element.Final & ~elementFinalAllowed) != 0) {
  805.                     SendValidationEvent(Res.Sch_InvalidElementFinalValue, element);
  806.                 }
  807.                 element.SetFinalResolved(element.Final & elementFinalAllowed);
  808.             }
  809.             if (element.Form != XmlSchemaForm.None) {
  810.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "form", element);
  811.             }
  812.             if (element.MinOccursString != null) {
  813.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "minOccurs", element);
  814.             }
  815.             if (element.MaxOccursString != null) {
  816.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "maxOccurs", element);
  817.             }
  818.             if (!element.SubstitutionGroup.IsEmpty) {
  819.                 ValidateQNameAttribute(element, "type", element.SubstitutionGroup);
  820.             }
  821.             ValidateIdAttribute(element);
  822.         }
  823.        
  824.         private void PreprocessLocalElement(XmlSchemaElement element)
  825.         {
  826.             if (element.Name != null) {
  827.                 // name
  828.                 ValidateNameAttribute(element);
  829.                 PreprocessElementContent(element);
  830.                 element.SetQualifiedName(new XmlQualifiedName(element.Name, (element.Form == XmlSchemaForm.Qualified || (element.Form == XmlSchemaForm.None && this.elementFormDefault == XmlSchemaForm.Qualified)) ? this.targetNamespace : null));
  831.             }
  832.             else {
  833.                 // ref
  834.                 PreprocessAnnotation(element);
  835.                 //Check annotation child for ref and set parent
  836.                 if (element.RefName.IsEmpty) {
  837.                     SendValidationEvent(Res.Sch_ElementNameRef, element);
  838.                 }
  839.                 else {
  840.                     ValidateQNameAttribute(element, "ref", element.RefName);
  841.                 }
  842.                 if (!element.SchemaTypeName.IsEmpty || element.IsAbstract || element.Block != XmlSchemaDerivationMethod.None || element.SchemaType != null || element.HasConstraints || element.DefaultValue != null || element.Form != XmlSchemaForm.None || element.FixedValue != null || element.HasNillableAttribute) {
  843.                     SendValidationEvent(Res.Sch_InvalidElementRef, element);
  844.                 }
  845.                 if (element.DefaultValue != null && element.FixedValue != null) {
  846.                     SendValidationEvent(Res.Sch_DefaultFixedAttributes, element);
  847.                 }
  848.                 element.SetQualifiedName(element.RefName);
  849.             }
  850.             if (element.MinOccurs > element.MaxOccurs) {
  851.                 element.MinOccurs = decimal.Zero;
  852.                 SendValidationEvent(Res.Sch_MinGtMax, element);
  853.             }
  854.             if (element.IsAbstract) {
  855.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "abstract", element);
  856.             }
  857.             if (element.Final != XmlSchemaDerivationMethod.None) {
  858.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "final", element);
  859.             }
  860.             if (!element.SubstitutionGroup.IsEmpty) {
  861.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "substitutionGroup", element);
  862.             }
  863.             ValidateIdAttribute(element);
  864.         }
  865.        
  866.         private void PreprocessElementContent(XmlSchemaElement element)
  867.         {
  868.             PreprocessAnnotation(element);
  869.             //Set parent for Annotation child of element
  870.             if (!element.RefName.IsEmpty) {
  871.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "ref", element);
  872.             }
  873.             if (element.Block == XmlSchemaDerivationMethod.All) {
  874.                 element.SetBlockResolved(XmlSchemaDerivationMethod.All);
  875.             }
  876.             else if (element.Block == XmlSchemaDerivationMethod.None) {
  877.                 if (this.blockDefault == XmlSchemaDerivationMethod.All) {
  878.                     element.SetBlockResolved(XmlSchemaDerivationMethod.All);
  879.                 }
  880.                 else {
  881.                     element.SetBlockResolved(this.blockDefault & elementBlockAllowed);
  882.                 }
  883.             }
  884.             else {
  885.                 if ((element.Block & ~elementBlockAllowed) != 0) {
  886.                     SendValidationEvent(Res.Sch_InvalidElementBlockValue, element);
  887.                 }
  888.                 element.SetBlockResolved(element.Block & elementBlockAllowed);
  889.             }
  890.             if (element.SchemaType != null) {
  891.                 SetParent(element.SchemaType, element);
  892.                 //Set parent for simple / complex type child of element
  893.                 if (!element.SchemaTypeName.IsEmpty) {
  894.                     SendValidationEvent(Res.Sch_TypeMutualExclusive, element);
  895.                 }
  896.                 if (element.SchemaType is XmlSchemaComplexType) {
  897.                     PreprocessComplexType((XmlSchemaComplexType)element.SchemaType, true);
  898.                 }
  899.                 else {
  900.                     PreprocessSimpleType((XmlSchemaSimpleType)element.SchemaType, true);
  901.                 }
  902.             }
  903.             if (!element.SchemaTypeName.IsEmpty) {
  904.                 ValidateQNameAttribute(element, "type", element.SchemaTypeName);
  905.             }
  906.             if (element.DefaultValue != null && element.FixedValue != null) {
  907.                 SendValidationEvent(Res.Sch_DefaultFixedAttributes, element);
  908.             }
  909.             foreach (XmlSchemaIdentityConstraint identityConstraint in element.Constraints) {
  910.                 SetParent(identityConstraint, element);
  911.                 PreprocessIdentityConstraint(identityConstraint);
  912.             }
  913.         }
  914.        
  915.         private void PreprocessIdentityConstraint(XmlSchemaIdentityConstraint constraint)
  916.         {
  917.             bool valid = true;
  918.             PreprocessAnnotation(constraint);
  919.             //Set parent of annotation child of key/keyref/unique
  920.             if (constraint.Name != null) {
  921.                 ValidateNameAttribute(constraint);
  922.                 constraint.SetQualifiedName(new XmlQualifiedName(constraint.Name, this.targetNamespace));
  923.             }
  924.             else {
  925.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", constraint);
  926.                 valid = false;
  927.             }
  928.            
  929.             if (this.schema.IdentityConstraints[constraint.QualifiedName] != null) {
  930.                 SendValidationEvent(Res.Sch_DupIdentityConstraint, constraint.QualifiedName.ToString(), constraint);
  931.                 valid = false;
  932.             }
  933.             else {
  934.                 this.schema.IdentityConstraints.Add(constraint.QualifiedName, constraint);
  935.             }
  936.            
  937.             if (constraint.Selector == null) {
  938.                 SendValidationEvent(Res.Sch_IdConstraintNoSelector, constraint);
  939.                 valid = false;
  940.             }
  941.             if (constraint.Fields.Count == 0) {
  942.                 SendValidationEvent(Res.Sch_IdConstraintNoFields, constraint);
  943.                 valid = false;
  944.             }
  945.             if (constraint is XmlSchemaKeyref) {
  946.                 XmlSchemaKeyref keyref = (XmlSchemaKeyref)constraint;
  947.                 if (keyref.Refer.IsEmpty) {
  948.                     SendValidationEvent(Res.Sch_IdConstraintNoRefer, constraint);
  949.                     valid = false;
  950.                 }
  951.                 else {
  952.                     ValidateQNameAttribute(keyref, "refer", keyref.Refer);
  953.                 }
  954.             }
  955.             if (valid) {
  956.                 ValidateIdAttribute(constraint);
  957.                 ValidateIdAttribute(constraint.Selector);
  958.                 SetParent(constraint.Selector, constraint);
  959.                 foreach (XmlSchemaXPath field in constraint.Fields) {
  960.                     SetParent(field, constraint);
  961.                     ValidateIdAttribute(field);
  962.                 }
  963.             }
  964.         }
  965.        
  966.         private void PreprocessSimpleType(XmlSchemaSimpleType simpleType, bool local)
  967.         {
  968.             if (local) {
  969.                 if (simpleType.Name != null) {
  970.                     SendValidationEvent(Res.Sch_ForbiddenAttribute, "name", simpleType);
  971.                 }
  972.             }
  973.             else {
  974.                 if (simpleType.Name != null) {
  975.                     ValidateNameAttribute(simpleType);
  976.                     simpleType.SetQualifiedName(new XmlQualifiedName(simpleType.Name, this.targetNamespace));
  977.                 }
  978.                 else {
  979.                     SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", simpleType);
  980.                 }
  981.                
  982.                 if (simpleType.Final == XmlSchemaDerivationMethod.All) {
  983.                     simpleType.SetFinalResolved(XmlSchemaDerivationMethod.All);
  984.                 }
  985.                 else if (simpleType.Final == XmlSchemaDerivationMethod.None) {
  986.                     if (this.finalDefault == XmlSchemaDerivationMethod.All) {
  987.                         simpleType.SetFinalResolved(XmlSchemaDerivationMethod.All);
  988.                     }
  989.                     else {
  990.                         simpleType.SetFinalResolved(this.finalDefault & simpleTypeFinalAllowed);
  991.                     }
  992.                 }
  993.                 else {
  994.                     if ((simpleType.Final & ~simpleTypeFinalAllowed) != 0) {
  995.                         SendValidationEvent(Res.Sch_InvalidSimpleTypeFinalValue, simpleType);
  996.                     }
  997.                     simpleType.SetFinalResolved(simpleType.Final & simpleTypeFinalAllowed);
  998.                 }
  999.             }
  1000.            
  1001.             if (simpleType.Content == null) {
  1002.                 SendValidationEvent(Res.Sch_NoSimpleTypeContent, simpleType);
  1003.             }
  1004.             else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) {
  1005.                 XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content;
  1006.                 //SetParent
  1007.                 SetParent(restriction, simpleType);
  1008.                 foreach (XmlSchemaObject facetObj in restriction.Facets) {
  1009.                     SetParent(facetObj, restriction);
  1010.                 }
  1011.                
  1012.                 if (restriction.BaseType != null) {
  1013.                     if (!restriction.BaseTypeName.IsEmpty) {
  1014.                         SendValidationEvent(Res.Sch_SimpleTypeRestRefBase, restriction);
  1015.                     }
  1016.                     PreprocessSimpleType(restriction.BaseType, true);
  1017.                 }
  1018.                 else {
  1019.                     if (restriction.BaseTypeName.IsEmpty) {
  1020.                         SendValidationEvent(Res.Sch_SimpleTypeRestRefBaseNone, restriction);
  1021.                     }
  1022.                     else {
  1023.                         ValidateQNameAttribute(restriction, "base", restriction.BaseTypeName);
  1024.                     }
  1025.                 }
  1026.                 PreprocessAnnotation(restriction);
  1027.                 //set parent of annotation child of simple type restriction
  1028.                 ValidateIdAttribute(restriction);
  1029.             }
  1030.             else if (simpleType.Content is XmlSchemaSimpleTypeList) {
  1031.                 XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content;
  1032.                 SetParent(list, simpleType);
  1033.                
  1034.                 if (list.ItemType != null) {
  1035.                     if (!list.ItemTypeName.IsEmpty) {
  1036.                         SendValidationEvent(Res.Sch_SimpleTypeListRefBase, list);
  1037.                     }
  1038.                     SetParent(list.ItemType, list);
  1039.                     PreprocessSimpleType(list.ItemType, true);
  1040.                 }
  1041.                 else {
  1042.                     if (list.ItemTypeName.IsEmpty) {
  1043.                         SendValidationEvent(Res.Sch_SimpleTypeListRefBaseNone, list);
  1044.                     }
  1045.                     else {
  1046.                         ValidateQNameAttribute(list, "itemType", list.ItemTypeName);
  1047.                     }
  1048.                 }
  1049.                 PreprocessAnnotation(list);
  1050.                 //set parent of annotation child of simple type list
  1051.                 ValidateIdAttribute(list);
  1052.             }
  1053.             else {
  1054.                 // union
  1055.                 XmlSchemaSimpleTypeUnion union1 = (XmlSchemaSimpleTypeUnion)simpleType.Content;
  1056.                 SetParent(union1, simpleType);
  1057.                
  1058.                 int baseTypeCount = union1.BaseTypes.Count;
  1059.                 if (union1.MemberTypes != null) {
  1060.                     baseTypeCount += union1.MemberTypes.Length;
  1061.                     foreach (XmlQualifiedName qname in union1.MemberTypes) {
  1062.                         ValidateQNameAttribute(union1, "memberTypes", qname);
  1063.                     }
  1064.                 }
  1065.                 if (baseTypeCount == 0) {
  1066.                     SendValidationEvent(Res.Sch_SimpleTypeUnionNoBase, union1);
  1067.                 }
  1068.                 foreach (XmlSchemaSimpleType type in union1.BaseTypes) {
  1069.                     SetParent(type, union1);
  1070.                     PreprocessSimpleType(type, true);
  1071.                 }
  1072.                 PreprocessAnnotation(union1);
  1073.                 //set parent of annotation child of simple type union
  1074.                 ValidateIdAttribute(union1);
  1075.             }
  1076.             ValidateIdAttribute(simpleType);
  1077.         }
  1078.        
  1079.         private void PreprocessComplexType(XmlSchemaComplexType complexType, bool local)
  1080.         {
  1081.             if (local) {
  1082.                 if (complexType.Name != null) {
  1083.                     SendValidationEvent(Res.Sch_ForbiddenAttribute, "name", complexType);
  1084.                 }
  1085.             }
  1086.             else {
  1087.                 if (complexType.Name != null) {
  1088.                     ValidateNameAttribute(complexType);
  1089.                     complexType.SetQualifiedName(new XmlQualifiedName(complexType.Name, this.targetNamespace));
  1090.                 }
  1091.                 else {
  1092.                     SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", complexType);
  1093.                 }
  1094.                 if (complexType.Block == XmlSchemaDerivationMethod.All) {
  1095.                     complexType.SetBlockResolved(XmlSchemaDerivationMethod.All);
  1096.                 }
  1097.                 else if (complexType.Block == XmlSchemaDerivationMethod.None) {
  1098.                     complexType.SetBlockResolved(this.blockDefault & complexTypeBlockAllowed);
  1099.                 }
  1100.                 else {
  1101.                     if ((complexType.Block & ~complexTypeBlockAllowed) != 0) {
  1102.                         SendValidationEvent(Res.Sch_InvalidComplexTypeBlockValue, complexType);
  1103.                     }
  1104.                     complexType.SetBlockResolved(complexType.Block & complexTypeBlockAllowed);
  1105.                 }
  1106.                 if (complexType.Final == XmlSchemaDerivationMethod.All) {
  1107.                     complexType.SetFinalResolved(XmlSchemaDerivationMethod.All);
  1108.                 }
  1109.                 else if (complexType.Final == XmlSchemaDerivationMethod.None) {
  1110.                     if (this.finalDefault == XmlSchemaDerivationMethod.All) {
  1111.                         complexType.SetFinalResolved(XmlSchemaDerivationMethod.All);
  1112.                     }
  1113.                     else {
  1114.                         complexType.SetFinalResolved(this.finalDefault & complexTypeFinalAllowed);
  1115.                     }
  1116.                 }
  1117.                 else {
  1118.                     if ((complexType.Final & ~complexTypeFinalAllowed) != 0) {
  1119.                         SendValidationEvent(Res.Sch_InvalidComplexTypeFinalValue, complexType);
  1120.                     }
  1121.                     complexType.SetFinalResolved(complexType.Final & complexTypeFinalAllowed);
  1122.                 }
  1123.                
  1124.             }
  1125.            
  1126.             if (complexType.ContentModel != null) {
  1127.                 SetParent(complexType.ContentModel, complexType);
  1128.                 //SimpleContent / complexCotent
  1129.                 PreprocessAnnotation(complexType.ContentModel);
  1130.                
  1131.                 if (complexType.Particle != null || complexType.Attributes != null) {
  1132.                     // this is illigal
  1133.                 }
  1134.                 if (complexType.ContentModel is XmlSchemaSimpleContent) {
  1135.                     XmlSchemaSimpleContent content = (XmlSchemaSimpleContent)complexType.ContentModel;
  1136.                     if (content.Content == null) {
  1137.                         if (complexType.QualifiedName == XmlQualifiedName.Empty) {
  1138.                             SendValidationEvent(Res.Sch_NoRestOrExt, complexType);
  1139.                         }
  1140.                         else {
  1141.                             SendValidationEvent(Res.Sch_NoRestOrExtQName, complexType.QualifiedName.Name, complexType.QualifiedName.Namespace, complexType);
  1142.                         }
  1143.                     }
  1144.                     else {
  1145.                         SetParent(content.Content, content);
  1146.                         //simplecontent extension / restriction
  1147.                         PreprocessAnnotation(content.Content);
  1148.                         //annotation child of simple extension / restriction
  1149.                         if (content.Content is XmlSchemaSimpleContentExtension) {
  1150.                             XmlSchemaSimpleContentExtension contentExtension = (XmlSchemaSimpleContentExtension)content.Content;
  1151.                             if (contentExtension.BaseTypeName.IsEmpty) {
  1152.                                 SendValidationEvent(Res.Sch_MissAttribute, "base", contentExtension);
  1153.                             }
  1154.                             else {
  1155.                                 ValidateQNameAttribute(contentExtension, "base", contentExtension.BaseTypeName);
  1156.                             }
  1157.                             PreprocessAttributes(contentExtension.Attributes, contentExtension.AnyAttribute, contentExtension);
  1158.                             ValidateIdAttribute(contentExtension);
  1159.                         }
  1160.                         else {
  1161.                             //XmlSchemaSimpleContentRestriction
  1162.                             XmlSchemaSimpleContentRestriction contentRestriction = (XmlSchemaSimpleContentRestriction)content.Content;
  1163.                             if (contentRestriction.BaseTypeName.IsEmpty) {
  1164.                                 SendValidationEvent(Res.Sch_MissAttribute, "base", contentRestriction);
  1165.                             }
  1166.                             else {
  1167.                                 ValidateQNameAttribute(contentRestriction, "base", contentRestriction.BaseTypeName);
  1168.                             }
  1169.                             if (contentRestriction.BaseType != null) {
  1170.                                 SetParent(contentRestriction.BaseType, contentRestriction);
  1171.                                 PreprocessSimpleType(contentRestriction.BaseType, true);
  1172.                             }
  1173.                             PreprocessAttributes(contentRestriction.Attributes, contentRestriction.AnyAttribute, contentRestriction);
  1174.                             ValidateIdAttribute(contentRestriction);
  1175.                         }
  1176.                     }
  1177.                     ValidateIdAttribute(content);
  1178.                 }
  1179.                 else {
  1180.                     // XmlSchemaComplexContent
  1181.                     XmlSchemaComplexContent content = (XmlSchemaComplexContent)complexType.ContentModel;
  1182.                     if (content.Content == null) {
  1183.                         if (complexType.QualifiedName == XmlQualifiedName.Empty) {
  1184.                             SendValidationEvent(Res.Sch_NoRestOrExt, complexType);
  1185.                         }
  1186.                         else {
  1187.                             SendValidationEvent(Res.Sch_NoRestOrExtQName, complexType.QualifiedName.Name, complexType.QualifiedName.Namespace, complexType);
  1188.                         }
  1189.                     }
  1190.                     else {
  1191.                         if (!content.HasMixedAttribute && complexType.IsMixed) {
  1192.                             content.IsMixed = true;
  1193.                             // fixup
  1194.                         }
  1195.                         SetParent(content.Content, content);
  1196.                         //complexcontent extension / restriction
  1197.                         PreprocessAnnotation(content.Content);
  1198.                         //Annotation child of extension / restriction
  1199.                         if (content.Content is XmlSchemaComplexContentExtension) {
  1200.                             XmlSchemaComplexContentExtension contentExtension = (XmlSchemaComplexContentExtension)content.Content;
  1201.                             if (contentExtension.BaseTypeName.IsEmpty) {
  1202.                                 SendValidationEvent(Res.Sch_MissAttribute, "base", contentExtension);
  1203.                             }
  1204.                             else {
  1205.                                 ValidateQNameAttribute(contentExtension, "base", contentExtension.BaseTypeName);
  1206.                             }
  1207.                             if (contentExtension.Particle != null) {
  1208.                                 SetParent(contentExtension.Particle, contentExtension);
  1209.                                 //Group / all / choice / sequence
  1210.                                 PreprocessParticle(contentExtension.Particle);
  1211.                             }
  1212.                             PreprocessAttributes(contentExtension.Attributes, contentExtension.AnyAttribute, contentExtension);
  1213.                             ValidateIdAttribute(contentExtension);
  1214.                         }
  1215.                         else {
  1216.                             // XmlSchemaComplexContentRestriction
  1217.                             XmlSchemaComplexContentRestriction contentRestriction = (XmlSchemaComplexContentRestriction)content.Content;
  1218.                             if (contentRestriction.BaseTypeName.IsEmpty) {
  1219.                                 SendValidationEvent(Res.Sch_MissAttribute, "base", contentRestriction);
  1220.                             }
  1221.                             else {
  1222.                                 ValidateQNameAttribute(contentRestriction, "base", contentRestriction.BaseTypeName);
  1223.                             }
  1224.                             if (contentRestriction.Particle != null) {
  1225.                                 SetParent(contentRestriction.Particle, contentRestriction);
  1226.                                 //Group / all / choice / sequence
  1227.                                 PreprocessParticle(contentRestriction.Particle);
  1228.                             }
  1229.                             PreprocessAttributes(contentRestriction.Attributes, contentRestriction.AnyAttribute, contentRestriction);
  1230.                             ValidateIdAttribute(contentRestriction);
  1231.                         }
  1232.                         ValidateIdAttribute(content);
  1233.                     }
  1234.                 }
  1235.             }
  1236.             else {
  1237.                 if (complexType.Particle != null) {
  1238.                     SetParent(complexType.Particle, complexType);
  1239.                     PreprocessParticle(complexType.Particle);
  1240.                 }
  1241.                 PreprocessAttributes(complexType.Attributes, complexType.AnyAttribute, complexType);
  1242.             }
  1243.             ValidateIdAttribute(complexType);
  1244.         }
  1245.        
  1246.         private void PreprocessGroup(XmlSchemaGroup group)
  1247.         {
  1248.             if (group.Name != null) {
  1249.                 ValidateNameAttribute(group);
  1250.                 group.SetQualifiedName(new XmlQualifiedName(group.Name, this.targetNamespace));
  1251.             }
  1252.             else {
  1253.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", group);
  1254.             }
  1255.             if (group.Particle == null) {
  1256.                 SendValidationEvent(Res.Sch_NoGroupParticle, group);
  1257.                 return;
  1258.             }
  1259.             if (group.Particle.MinOccursString != null) {
  1260.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "minOccurs", group.Particle);
  1261.             }
  1262.             if (group.Particle.MaxOccursString != null) {
  1263.                 SendValidationEvent(Res.Sch_ForbiddenAttribute, "maxOccurs", group.Particle);
  1264.             }
  1265.            
  1266.             PreprocessParticle(group.Particle);
  1267.             PreprocessAnnotation(group);
  1268.             //Set parent of annotation child of group
  1269.             ValidateIdAttribute(group);
  1270.         }
  1271.        
  1272.         private void PreprocessNotation(XmlSchemaNotation notation)
  1273.         {
  1274.             if (notation.Name != null) {
  1275.                 ValidateNameAttribute(notation);
  1276.                 notation.QualifiedName = new XmlQualifiedName(notation.Name, this.targetNamespace);
  1277.             }
  1278.             else {
  1279.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "name", notation);
  1280.             }
  1281.             if (notation.Public != null) {
  1282.                 try {
  1283.                     XmlConvert.ToUri(notation.Public);
  1284.                     // can throw
  1285.                 }
  1286.                 catch {
  1287.                     SendValidationEvent(Res.Sch_InvalidPublicAttribute, notation.Public, notation);
  1288.                 }
  1289.             }
  1290.             else {
  1291.                 SendValidationEvent(Res.Sch_MissRequiredAttribute, "public", notation);
  1292.             }
  1293.             if (notation.System != null) {
  1294.                 try {
  1295.                     XmlConvert.ToUri(notation.System);
  1296.                     // can throw
  1297.                 }
  1298.                 catch {
  1299.                     SendValidationEvent(Res.Sch_InvalidSystemAttribute, notation.System, notation);
  1300.                 }
  1301.             }
  1302.             PreprocessAnnotation(notation);
  1303.             //Set parent of annotation child of notation
  1304.             ValidateIdAttribute(notation);
  1305.         }
  1306.        
  1307.        
  1308.         private void PreprocessParticle(XmlSchemaParticle particle)
  1309.         {
  1310.             if (particle is XmlSchemaAll) {
  1311.                 if (particle.MinOccurs != decimal.Zero && particle.MinOccurs != decimal.One) {
  1312.                     particle.MinOccurs = decimal.One;
  1313.                     SendValidationEvent(Res.Sch_InvalidAllMin, particle);
  1314.                 }
  1315.                 if (particle.MaxOccurs != decimal.One) {
  1316.                     particle.MaxOccurs = decimal.One;
  1317.                     SendValidationEvent(Res.Sch_InvalidAllMax, particle);
  1318.                 }
  1319.                 foreach (XmlSchemaElement element in ((XmlSchemaAll)particle).Items) {
  1320.                     if (element.MaxOccurs != decimal.Zero && element.MaxOccurs != decimal.One) {
  1321.                         element.MaxOccurs = decimal.One;
  1322.                         SendValidationEvent(Res.Sch_InvalidAllElementMax, element);
  1323.                     }
  1324.                     SetParent(element, particle);
  1325.                     PreprocessLocalElement(element);
  1326.                 }
  1327.             }
  1328.             else {
  1329.                 if (particle.MinOccurs > particle.MaxOccurs) {
  1330.                     particle.MinOccurs = particle.MaxOccurs;
  1331.                     SendValidationEvent(Res.Sch_MinGtMax, particle);
  1332.                 }
  1333.                 if (particle is XmlSchemaChoice) {
  1334.                     foreach (XmlSchemaObject item in ((XmlSchemaChoice)particle).Items) {
  1335.                         SetParent(item, particle);
  1336.                         if (item is XmlSchemaElement) {
  1337.                             PreprocessLocalElement((XmlSchemaElement)item);
  1338.                         }
  1339.                         else {
  1340.                             PreprocessParticle((XmlSchemaParticle)item);
  1341.                         }
  1342.                     }
  1343.                 }
  1344.                 else if (particle is XmlSchemaSequence) {
  1345.                     foreach (XmlSchemaObject item in ((XmlSchemaSequence)particle).Items) {
  1346.                         SetParent(item, particle);
  1347.                         if (item is XmlSchemaElement) {
  1348.                             PreprocessLocalElement((XmlSchemaElement)item);
  1349.                         }
  1350.                         else {
  1351.                             PreprocessParticle((XmlSchemaParticle)item);
  1352.                         }
  1353.                     }
  1354.                 }
  1355.                 else if (particle is XmlSchemaGroupRef) {
  1356.                     XmlSchemaGroupRef groupRef = (XmlSchemaGroupRef)particle;
  1357.                     if (groupRef.RefName.IsEmpty) {
  1358.                         SendValidationEvent(Res.Sch_MissAttribute, "ref", groupRef);
  1359.                     }
  1360.                     else {
  1361.                         ValidateQNameAttribute(groupRef, "ref", groupRef.RefName);
  1362.                     }
  1363.                 }
  1364.                 else if (particle is XmlSchemaAny) {
  1365.                     try {
  1366.                         ((XmlSchemaAny)particle).BuildNamespaceListV1Compat(this.targetNamespace);
  1367.                     }
  1368.                     catch {
  1369.                         SendValidationEvent(Res.Sch_InvalidAny, particle);
  1370.                     }
  1371.                 }
  1372.             }
  1373.             PreprocessAnnotation(particle);
  1374.             //set parent of annotation child of group / all/ choice / sequence
  1375.             ValidateIdAttribute(particle);
  1376.         }
  1377.        
  1378.         private void PreprocessAttributes(XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlSchemaObject parent)
  1379.         {
  1380.             foreach (XmlSchemaAnnotated obj in attributes) {
  1381.                 SetParent(obj, parent);
  1382.                 if (obj is XmlSchemaAttribute) {
  1383.                     PreprocessLocalAttribute((XmlSchemaAttribute)obj);
  1384.                 }
  1385.                 else {
  1386.                     // XmlSchemaAttributeGroupRef
  1387.                     XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  1388.                     if (attributeGroupRef.RefName.IsEmpty) {
  1389.                         SendValidationEvent(Res.Sch_MissAttribute, "ref", attributeGroupRef);
  1390.                     }
  1391.                     else {
  1392.                         ValidateQNameAttribute(attributeGroupRef, "ref", attributeGroupRef.RefName);
  1393.                     }
  1394.                     PreprocessAnnotation(obj);
  1395.                     //set parent of annotation child of attributeGroupRef
  1396.                     ValidateIdAttribute(obj);
  1397.                 }
  1398.             }
  1399.             if (anyAttribute != null) {
  1400.                 try {
  1401.                     SetParent(anyAttribute, parent);
  1402.                     PreprocessAnnotation(anyAttribute);
  1403.                     //set parent of annotation child of any attribute
  1404.                     anyAttribute.BuildNamespaceListV1Compat(this.targetNamespace);
  1405.                 }
  1406.                 catch {
  1407.                     SendValidationEvent(Res.Sch_InvalidAnyAttribute, anyAttribute);
  1408.                 }
  1409.                 ValidateIdAttribute(anyAttribute);
  1410.             }
  1411.         }
  1412.        
  1413.         private void ValidateIdAttribute(XmlSchemaObject xso)
  1414.         {
  1415.             if (xso.IdAttribute != null) {
  1416.                 try {
  1417.                     xso.IdAttribute = NameTable.Add(XmlConvert.VerifyNCName(xso.IdAttribute));
  1418.                     if (this.schema.Ids[xso.IdAttribute] != null) {
  1419.                         SendValidationEvent(Res.Sch_DupIdAttribute, xso);
  1420.                     }
  1421.                     else {
  1422.                         this.schema.Ids.Add(xso.IdAttribute, xso);
  1423.                     }
  1424.                 }
  1425.                 catch (Exception ex) {
  1426.                     SendValidationEvent(Res.Sch_InvalidIdAttribute, ex.Message, xso);
  1427.                 }
  1428.             }
  1429.         }
  1430.        
  1431.         private void ValidateNameAttribute(XmlSchemaObject xso)
  1432.         {
  1433.             string name = xso.NameAttribute;
  1434.             if (name == null || name.Length == 0) {
  1435.                 SendValidationEvent(Res.Sch_InvalidNameAttributeEx, null, Res.GetString(Res.Sch_NullValue), xso);
  1436.             }
  1437.             //Normalize whitespace since NCName has whitespace facet="collapse"
  1438.             name = XmlComplianceUtil.NonCDataNormalize(name);
  1439.             int len = ValidateNames.ParseNCName(name, 0);
  1440.             if (len != name.Length) {
  1441.                 // If the string is not a valid NCName, then throw or return false
  1442.                 string innerStr = Res.GetString(Res.Xml_BadNameCharWithPos, XmlException.BuildCharExceptionStr(name[len])[0], XmlException.BuildCharExceptionStr(name[len])[1], len);
  1443.                 SendValidationEvent(Res.Sch_InvalidNameAttributeEx, name, innerStr, xso);
  1444.             }
  1445.             else {
  1446.                 xso.NameAttribute = NameTable.Add(name);
  1447.             }
  1448.         }
  1449.        
  1450.         private void ValidateQNameAttribute(XmlSchemaObject xso, string attributeName, XmlQualifiedName value)
  1451.         {
  1452.             try {
  1453.                 value.Verify();
  1454.                 value.Atomize(NameTable);
  1455.                 if (referenceNamespaces[value.Namespace] == null) {
  1456.                     SendValidationEvent(Res.Sch_UnrefNS, value.Namespace, xso, XmlSeverityType.Warning);
  1457.                 }
  1458.             }
  1459.             catch (Exception ex) {
  1460.                 SendValidationEvent(Res.Sch_InvalidAttribute, attributeName, ex.Message, xso);
  1461.             }
  1462.         }
  1463.        
  1464.         private void SetParent(XmlSchemaObject child, XmlSchemaObject parent)
  1465.         {
  1466.             child.Parent = parent;
  1467.         }
  1468.        
  1469.         private void PreprocessAnnotation(XmlSchemaObject schemaObject)
  1470.         {
  1471.             if (schemaObject is XmlSchemaAnnotated) {
  1472.                 XmlSchemaAnnotated annotated = schemaObject as XmlSchemaAnnotated;
  1473.                 if (annotated.Annotation != null) {
  1474.                     annotated.Annotation.Parent = schemaObject;
  1475.                     foreach (XmlSchemaObject obj in annotated.Annotation.Items) {
  1476.                         obj.Parent = annotated.Annotation;
  1477.                         //Can be documentation or appInfo
  1478.                     }
  1479.                 }
  1480.                
  1481.             }
  1482.         }
  1483.        
  1484.         private Uri ResolveSchemaLocationUri(XmlSchema enclosingSchema, string location)
  1485.         {
  1486.             try {
  1487.                 return xmlResolver.ResolveUri(enclosingSchema.BaseUri, location);
  1488.             }
  1489.             catch {
  1490.                 return null;
  1491.             }
  1492.         }
  1493.        
  1494.         private Stream GetSchemaEntity(Uri ruri)
  1495.         {
  1496.             try {
  1497.                 return (Stream)xmlResolver.GetEntity(ruri, null, null);
  1498.             }
  1499.             catch {
  1500.                 return null;
  1501.             }
  1502.         }
  1503.        
  1504.     }
  1505.     #pragma warning restore 618
  1506.    
  1507. }
  1508. // namespace System.Xml

Developer Fusion