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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSchemaValidator.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. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Text;
  19. using System.IO;
  20. using System.Diagnostics;
  21. using System.Xml;
  22. using System.Xml.Schema;
  23. using System.Xml.XPath;
  24. using System.Threading;
  25. namespace System.Xml.Schema
  26. {
  27.    
  28.     public delegate object XmlValueGetter();
  29.    
  30.     [Flags()]
  31.     public enum XmlSchemaValidationFlags
  32.     {
  33.         None = 0,
  34.         ProcessInlineSchema = 1,
  35.         ProcessSchemaLocation = 2,
  36.         ReportValidationWarnings = 4,
  37.         ProcessIdentityConstraints = 8,
  38.         AllowXmlAttributes = 16
  39.     }
  40.    
  41.     internal enum ValidatorState
  42.     {
  43.         None,
  44.         Start,
  45.         TopLevelAttribute,
  46.         TopLevelTextOrWS,
  47.         Element,
  48.         Attribute,
  49.         EndOfAttributes,
  50.         Text,
  51.         Whitespace,
  52.         EndElement,
  53.         SkipToEndElement,
  54.         Finish
  55.     }
  56.     internal class IdRefNode
  57.     {
  58.         internal string Id;
  59.         internal int LineNo;
  60.         internal int LinePos;
  61.         internal IdRefNode Next;
  62.        
  63.         internal IdRefNode(IdRefNode next, string id, int lineNo, int linePos)
  64.         {
  65.             this.Id = id;
  66.             this.LineNo = lineNo;
  67.             this.LinePos = linePos;
  68.             this.Next = next;
  69.         }
  70.     }
  71.    
  72.     public sealed class XmlSchemaValidator
  73.     {
  74.        
  75.         //Schema Set
  76.         private XmlSchemaSet schemaSet;
  77.        
  78.         //Validation Settings
  79.         private XmlSchemaValidationFlags validationFlags;
  80.        
  81.         //Validation
  82.         private int startIDConstraint = -1;
  83.         private const int STACK_INCREMENT = 10;
  84.         private bool isRoot;
  85.         private bool rootHasSchema;
  86.        
  87.         //PSVI
  88.         private bool attrValid;
  89.         private bool checkEntity;
  90.        
  91.         private SchemaInfo compiledSchemaInfo;
  92.         private SchemaInfo dtdSchemaInfo;
  93.         private Hashtable validatedNamespaces;
  94.        
  95.         private HWStack validationStack;
  96.         // validaton contexts
  97.         private ValidationState context;
  98.         // current context
  99.         private ValidatorState currentState;
  100.        
  101.         //Attributes & IDS
  102.         private Hashtable attPresence;
  103.         //(AttName Vs AttIndex)
  104.         private SchemaAttDef wildID;
  105.        
  106.         private Hashtable IDs;
  107.         private IdRefNode idRefListHead;
  108.        
  109.         //Parsing
  110.         XmlQualifiedName contextQName;
  111.        
  112.         //Avoid SchemaNames creation
  113.         private string NsXs;
  114.         private string NsXsi;
  115.         private string NsXmlNs;
  116.         private string NsXml;
  117.        
  118.         //PartialValidation
  119.         private XmlSchemaObject partialValidationType;
  120.        
  121.         //text to typedValue
  122.         private StringBuilder textValue;
  123.        
  124.         //Other state
  125.         private ValidationEventHandler eventHandler;
  126.         private object validationEventSender;
  127.         private XmlNameTable nameTable;
  128.         private IXmlLineInfo positionInfo;
  129.         private IXmlLineInfo dummyPositionInfo;
  130.        
  131.         private XmlResolver xmlResolver;
  132.         private Uri sourceUri;
  133.         private string sourceUriString;
  134.         private IXmlNamespaceResolver nsResolver;
  135.        
  136.         private XmlSchemaContentProcessing processContents = XmlSchemaContentProcessing.Strict;
  137.        
  138.         private static XmlSchemaAttribute xsiTypeSO;
  139.         private static XmlSchemaAttribute xsiNilSO;
  140.         private static XmlSchemaAttribute xsiSLSO;
  141.         private static XmlSchemaAttribute xsiNoNsSLSO;
  142.        
  143.         //Xsi Attributes that are atomized
  144.         private string xsiTypeString;
  145.         private string xsiNilString;
  146.         private string xsiSchemaLocationString;
  147.         private string xsiNoNamespaceSchemaLocationString;
  148.        
  149.         //Xsi Attributes parsing
  150.         private static readonly XmlSchemaDatatype dtQName = XmlSchemaDatatype.FromXmlTokenizedTypeXsd(XmlTokenizedType.QName);
  151.         private static readonly XmlSchemaDatatype dtCDATA = XmlSchemaDatatype.FromXmlTokenizedType(XmlTokenizedType.CDATA);
  152.         private static readonly XmlSchemaDatatype dtStringArray = dtCDATA.DeriveByList(null);
  153.        
  154.         //Error message constants
  155.         private const string Quote = "'";
  156.        
  157.         //Empty arrays
  158.         private static XmlSchemaParticle[] EmptyParticleArray = new XmlSchemaParticle[0];
  159.         private static XmlSchemaAttribute[] EmptyAttributeArray = new XmlSchemaAttribute[0];
  160.        
  161.         static internal bool[,] ValidStates = new bool[12, 12] {{true, true, false, false, false, false, false, false, false, false,
  162.         false, false}, {false, true, true, true, true, false, false, false, false, false,
  163.         false, true}, {false, false, false, false, false, false, false, false, false, false,
  164.         false, true}, {false, false, false, true, true, false, false, false, false, false,
  165.         false, true}, {false, false, false, true, false, true, true, false, false, true,
  166.         true, false}, {false, false, false, false, false, true, true, false, false, true,
  167.         true, false}, {false, false, false, false, true, false, false, true, true, true,
  168.         true, false}, {false, false, false, false, true, false, false, true, true, true,
  169.         true, false}, {false, false, false, false, true, false, false, true, true, true,
  170.         true, false}, {false, false, false, true, true, false, false, true, true, true,
  171.         true, true},
  172.         {false, false, false, true, true, false, false, true, true, true,
  173.         true, true}, {false, true, false, false, false, false, false, false, false, false,
  174.             /*ValidatorState.None*/            /*ValidatorState.Start  /*ValidatorState.TopLevelAttribute*/            /*ValidatorState.TopLevelTOrWS*/            /*ValidatorState.Element*/            /*ValidatorState.Attribute*/            /*ValidatorState.EndAttributes*/            /*ValidatorState.Text/      /*ValidatorState.WS/*      /*ValidatorState.EndElement*/            /*ValidatorState.SkipToEndElement*/            /*ValidatorState.Finish*/           
  175.             /*ValidatorState.None*/            /*ValidatorState.Start*/            /*ValidatorState.TopLevelAttribute*/            /*ValidatorState.TopLevelTextOrWS*/            /*ValidatorState.Element*/            /*ValidatorState.Attribute*/            /*ValidatorState.EndAttributes*/            /*ValidatorState.Text*/            /*ValidatorState.Whitespace*/            /*ValidatorState.EndElement*/            /*?*/            /*ValidatorState.SkipToEndElement*/            /*ValidatorState.Finish*/        false, false}};
  176.        
  177.         private static string[] MethodNames = new string[12] {"None", "Initialize", "top-level ValidateAttribute", "top-level ValidateText or ValidateWhitespace", "ValidateElement", "ValidateAttribute", "ValidateEndOfAttributes", "ValidateText", "ValidateWhitespace", "ValidateEndElement",
  178.         "SkipToEndElement", "EndValidation"};
  179.        
  180.         public XmlSchemaValidator(XmlNameTable nameTable, XmlSchemaSet schemas, IXmlNamespaceResolver namespaceResolver, XmlSchemaValidationFlags validationFlags)
  181.         {
  182.             if (nameTable == null) {
  183.                 throw new ArgumentNullException("nameTable");
  184.             }
  185.             if (schemas == null) {
  186.                 throw new ArgumentNullException("schemas");
  187.             }
  188.             if (namespaceResolver == null) {
  189.                 throw new ArgumentNullException("namespaceResolver");
  190.             }
  191.             this.nameTable = nameTable;
  192.             this.nsResolver = namespaceResolver;
  193.             this.validationFlags = validationFlags;
  194.            
  195.            
  196.             if (((validationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0) || ((validationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)) {
  197.                 //Process schema hints in xml document, hence user's set might change
  198.                 this.schemaSet = new XmlSchemaSet(nameTable);
  199.                 this.schemaSet.ValidationEventHandler += schemas.GetEventHandler();
  200.                 this.schemaSet.CompilationSettings = schemas.CompilationSettings;
  201.                 this.schemaSet.XmlResolver = schemas.GetResolver();
  202.                 this.schemaSet.Add(schemas);
  203.                 validatedNamespaces = new Hashtable();
  204.             }
  205.             else {
  206.                 //Use the same set from the user
  207.                 this.schemaSet = schemas;
  208.             }
  209.             Init();
  210.         }
  211.        
  212.         private void Init()
  213.         {
  214.             validationStack = new HWStack(STACK_INCREMENT);
  215.             attPresence = new Hashtable();
  216.             Push(XmlQualifiedName.Empty);
  217.            
  218.             dummyPositionInfo = new PositionInfo();
  219.             //Dummy position info, will return (0,0) if user does not set the LineInfoProvider property
  220.             positionInfo = dummyPositionInfo;
  221.             validationEventSender = this;
  222.             currentState = ValidatorState.None;
  223.             textValue = new StringBuilder(100);
  224.             xmlResolver = new XmlUrlResolver();
  225.             contextQName = new XmlQualifiedName();
  226.             //Re-use qname
  227.             Reset();
  228.            
  229.             RecompileSchemaSet();
  230.             //Gets compiled info from set as well
  231.             //Get already Atomized strings
  232.             NsXs = nameTable.Add(XmlReservedNs.NsXs);
  233.             NsXsi = nameTable.Add(XmlReservedNs.NsXsi);
  234.             NsXmlNs = nameTable.Add(XmlReservedNs.NsXmlNs);
  235.             NsXml = nameTable.Add(XmlReservedNs.NsXml);
  236.             xsiTypeString = nameTable.Add("type");
  237.             xsiNilString = nameTable.Add("nil");
  238.             xsiSchemaLocationString = nameTable.Add("schemaLocation");
  239.             xsiNoNamespaceSchemaLocationString = nameTable.Add("noNamespaceSchemaLocation");
  240.         }
  241.        
  242.         private void Reset()
  243.         {
  244.             isRoot = true;
  245.             rootHasSchema = true;
  246.             while (validationStack.Length > 1) {
  247.                 //Clear all other context from stack
  248.                 validationStack.Pop();
  249.             }
  250.             startIDConstraint = -1;
  251.             partialValidationType = null;
  252.            
  253.             //Clear previous tables
  254.             if (IDs != null) {
  255.                 IDs.Clear();
  256.             }
  257.             if (ProcessSchemaHints) {
  258.                 validatedNamespaces.Clear();
  259.             }
  260.         }
  261.        
  262.         //Properties
  263.         public XmlResolver XmlResolver {
  264.             set { xmlResolver = value; }
  265.         }
  266.        
  267.         public IXmlLineInfo LineInfoProvider {
  268.             get { return positionInfo; }
  269.             set {
  270.                 if (value == null) {
  271.                     //If value is null, retain the default dummy line info
  272.                     this.positionInfo = dummyPositionInfo;
  273.                 }
  274.                 else {
  275.                     this.positionInfo = value;
  276.                 }
  277.             }
  278.         }
  279.        
  280.         public Uri SourceUri {
  281.             get { return sourceUri; }
  282.             set {
  283.                 sourceUri = value;
  284.                 sourceUriString = sourceUri.ToString();
  285.             }
  286.         }
  287.        
  288.         public object ValidationEventSender {
  289.             get { return validationEventSender; }
  290.             set { validationEventSender = value; }
  291.         }
  292.        
  293.         public event ValidationEventHandler ValidationEventHandler {
  294.             add { eventHandler += value; }
  295.             remove { eventHandler -= value; }
  296.         }
  297.        
  298.         //Methods
  299.        
  300.         public void AddSchema(XmlSchema schema)
  301.         {
  302.             if (schema == null) {
  303.                 throw new ArgumentNullException("schema");
  304.             }
  305.             if ((validationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) == 0) {
  306.                 //Do not process schema if processInlineSchema is not set
  307.                 return;
  308.             }
  309.             string tns = schema.TargetNamespace;
  310.             if (tns == null) {
  311.                 tns = string.Empty;
  312.             }
  313.             //Store the previous locations
  314.             Hashtable schemaLocations = schemaSet.SchemaLocations;
  315.             DictionaryEntry[] oldLocations = new DictionaryEntry[schemaLocations.Count];
  316.             schemaLocations.CopyTo(oldLocations, 0);
  317.            
  318.             //TODO should i not error if SOM reference same as one in the set or should i assume that inline schema will always be a new SOM ref
  319.             Debug.Assert(validatedNamespaces != null);
  320.             if (validatedNamespaces[tns] != null && schemaSet.FindSchemaByNSAndUrl(schema.BaseUri, tns, oldLocations) == null) {
  321.                 SendValidationEvent(Res.Sch_ComponentAlreadySeenForNS, tns, XmlSeverityType.Error);
  322.             }
  323.             if (schema.ErrorCount == 0) {
  324.                 try {
  325.                     schemaSet.Add(schema);
  326.                     RecompileSchemaSet();
  327.                 }
  328.                 catch (XmlSchemaException e) {
  329.                     SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {schema.BaseUri.ToString(), e.Message}, e);
  330.                 }
  331.                 foreach (XmlSchema impSchema in schema.ImportedSchemas) {
  332.                     //Check for its imports
  333.                     tns = impSchema.TargetNamespace;
  334.                     if (tns == null) {
  335.                         tns = string.Empty;
  336.                     }
  337.                     if (validatedNamespaces[tns] != null && schemaSet.FindSchemaByNSAndUrl(impSchema.BaseUri, tns, oldLocations) == null) {
  338.                         SendValidationEvent(Res.Sch_ComponentAlreadySeenForNS, tns, XmlSeverityType.Error);
  339.                         schemaSet.RemoveRecursive(schema);
  340.                         break;
  341.                     }
  342.                 }
  343.             }
  344.         }
  345.        
  346.         public void Initialize()
  347.         {
  348.             if (currentState != ValidatorState.None && currentState != ValidatorState.Finish) {
  349.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidStateTransition, new string[] {MethodNames[(int)currentState], MethodNames[(int)ValidatorState.Start]}));
  350.             }
  351.             currentState = ValidatorState.Start;
  352.             Reset();
  353.         }
  354.        
  355.         public void Initialize(XmlSchemaObject partialValidationType)
  356.         {
  357.             if (currentState != ValidatorState.None && currentState != ValidatorState.Finish) {
  358.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidStateTransition, new string[] {MethodNames[(int)currentState], MethodNames[(int)ValidatorState.Start]}));
  359.             }
  360.             if (partialValidationType == null) {
  361.                 throw new ArgumentNullException("partialValidationType");
  362.             }
  363.             if (!(partialValidationType is XmlSchemaElement || partialValidationType is XmlSchemaAttribute || partialValidationType is XmlSchemaType)) {
  364.                 throw new ArgumentException(Res.GetString(Res.Sch_InvalidPartialValidationType));
  365.             }
  366.             currentState = ValidatorState.Start;
  367.             Reset();
  368.             this.partialValidationType = partialValidationType;
  369.         }
  370.        
  371.         public void ValidateElement(string localName, string namespaceUri, XmlSchemaInfo schemaInfo)
  372.         {
  373.             ValidateElement(localName, namespaceUri, schemaInfo, null, null, null, null);
  374.         }
  375.        
  376.         public void ValidateElement(string localName, string namespaceUri, XmlSchemaInfo schemaInfo, string xsiType, string xsiNil, string xsiSchemaLocation, string xsiNoNamespaceSchemaLocation)
  377.         {
  378.             if (localName == null) {
  379.                 throw new ArgumentNullException("localName");
  380.             }
  381.             if (namespaceUri == null) {
  382.                 throw new ArgumentNullException("namespaceUri");
  383.             }
  384.            
  385.             CheckStateTransition(ValidatorState.Element, MethodNames[(int)ValidatorState.Element]);
  386.            
  387.             ClearPSVI();
  388.             contextQName.Init(localName, namespaceUri);
  389.             XmlQualifiedName elementName = contextQName;
  390.            
  391.             bool invalidElementInContext;
  392.             object particle = ValidateElementContext(elementName, out invalidElementInContext);
  393.             //Check element name is allowed in current position
  394.             SchemaElementDecl elementDecl = FastGetElementDecl(elementName, particle);
  395.            
  396.             //Change context to current element and update element decl
  397.             Push(elementName);
  398.            
  399.             //Change current context's error state depending on whether this element was validated in its context correctly
  400.             if (invalidElementInContext) {
  401.                 context.Validity = XmlSchemaValidity.Invalid;
  402.             }
  403.            
  404.             //Check if there are Xsi attributes
  405.             if ((validationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0 && xmlResolver != null) {
  406.                 //we should process schema location
  407.                 ProcessSchemaLocations(xsiSchemaLocation, xsiNoNamespaceSchemaLocation);
  408.             }
  409.            
  410.             if (processContents != XmlSchemaContentProcessing.Skip) {
  411.                 if (elementDecl == null && partialValidationType == null) {
  412.                     //Since new schemaLocations might have been added, try for decl from the set again only if no PVType is set
  413.                     elementDecl = compiledSchemaInfo.GetElementDecl(elementName);
  414.                 }
  415.                 bool declFound = elementDecl != null;
  416.                 if (xsiType != null || xsiNil != null) {
  417.                     elementDecl = CheckXsiTypeAndNil(elementDecl, xsiType, xsiNil, ref declFound);
  418.                 }
  419.                 if (elementDecl == null) {
  420.                     ThrowDeclNotFoundWarningOrError(declFound);
  421.                     //This updates processContents
  422.                 }
  423.             }
  424.            
  425.             context.ElementDecl = elementDecl;
  426.             XmlSchemaElement localSchemaElement = null;
  427.             XmlSchemaType localSchemaType = null;
  428.             if (elementDecl != null) {
  429.                 CheckElementProperties();
  430.                 attPresence.Clear();
  431.                 //Clear attributes hashtable for every element
  432.                 context.NeedValidateChildren = processContents != XmlSchemaContentProcessing.Skip;
  433.                 ValidateStartElementIdentityConstraints();
  434.                 //Need attr collection validated here
  435.                 elementDecl.ContentValidator.InitValidation(context);
  436.                
  437.                 localSchemaType = elementDecl.SchemaType;
  438.                 localSchemaElement = GetSchemaElement();
  439.             }
  440.            
  441.             if (schemaInfo != null) {
  442.                 schemaInfo.SchemaType = localSchemaType;
  443.                 schemaInfo.SchemaElement = localSchemaElement;
  444.                 schemaInfo.IsNil = context.IsNill;
  445.                 schemaInfo.Validity = context.Validity;
  446.             }
  447.             if (ProcessSchemaHints) {
  448.                 if (validatedNamespaces[namespaceUri] == null) {
  449.                     validatedNamespaces.Add(namespaceUri, namespaceUri);
  450.                 }
  451.             }
  452.            
  453.             if (isRoot) {
  454.                 isRoot = false;
  455.             }
  456.         }
  457.        
  458.         public object ValidateAttribute(string localName, string namespaceUri, string attributeValue, XmlSchemaInfo schemaInfo)
  459.         {
  460.             if (attributeValue == null) {
  461.                 throw new ArgumentNullException("attributeValue");
  462.             }
  463.             return ValidateAttribute(localName, namespaceUri, null, attributeValue, schemaInfo);
  464.         }
  465.        
  466.         public object ValidateAttribute(string localName, string namespaceUri, XmlValueGetter attributeValue, XmlSchemaInfo schemaInfo)
  467.         {
  468.             if (attributeValue == null) {
  469.                 throw new ArgumentNullException("attributeValue");
  470.             }
  471.             return ValidateAttribute(localName, namespaceUri, attributeValue, null, schemaInfo);
  472.         }
  473.        
  474.         private object ValidateAttribute(string lName, string ns, XmlValueGetter attributeValueGetter, string attributeStringValue, XmlSchemaInfo schemaInfo)
  475.         {
  476.             if (lName == null) {
  477.                 throw new ArgumentNullException("localName");
  478.             }
  479.             if (ns == null) {
  480.                 throw new ArgumentNullException("namespaceUri");
  481.             }
  482.            
  483.             ValidatorState toState = validationStack.Length > 1 ? ValidatorState.Attribute : ValidatorState.TopLevelAttribute;
  484.             CheckStateTransition(toState, MethodNames[(int)toState]);
  485.            
  486.             object typedVal = null;
  487.             attrValid = true;
  488.             XmlSchemaValidity localValidity = XmlSchemaValidity.NotKnown;
  489.             XmlSchemaAttribute localAttribute = null;
  490.             XmlSchemaSimpleType localMemberType = null;
  491.            
  492.             ns = nameTable.Add(ns);
  493.             if (Ref.Equal(ns, NsXmlNs)) {
  494.                 return null;
  495.             }
  496.            
  497.             SchemaAttDef attributeDef = null;
  498.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  499.             XmlQualifiedName attQName = new XmlQualifiedName(lName, ns);
  500.             if (attPresence[attQName] != null) {
  501.                 //this attribute already checked as it is duplicate;
  502.                 SendValidationEvent(Res.Sch_DuplicateAttribute, attQName.ToString());
  503.                 if (schemaInfo != null) {
  504.                     schemaInfo.Clear();
  505.                 }
  506.                 return null;
  507.             }
  508.            
  509.             if (!Ref.Equal(ns, NsXsi)) {
  510.                 //TODO add xmlns check here
  511.                 XmlSchemaObject pvtAttribute = currentState == ValidatorState.TopLevelAttribute ? partialValidationType : null;
  512.                 AttributeMatchState attributeMatchState;
  513.                 attributeDef = compiledSchemaInfo.GetAttributeXsd(currentElementDecl, attQName, pvtAttribute, out attributeMatchState);
  514.                
  515.                 switch (attributeMatchState) {
  516.                     case AttributeMatchState.UndeclaredElementAndAttribute:
  517.                         if ((attributeDef = CheckIsXmlAttribute(attQName)) != null) {
  518.                             //Try for xml attribute
  519.                             goto case AttributeMatchState.AttributeFound;
  520.                         }
  521.                         if (currentElementDecl == null && processContents == XmlSchemaContentProcessing.Strict && attQName.Namespace.Length != 0 && compiledSchemaInfo.Contains(attQName.Namespace)) {
  522.                             attrValid = false;
  523.                             SendValidationEvent(Res.Sch_UndeclaredAttribute, attQName.ToString());
  524.                         }
  525.                         else if (processContents != XmlSchemaContentProcessing.Skip) {
  526.                             SendValidationEvent(Res.Sch_NoAttributeSchemaFound, attQName.ToString(), XmlSeverityType.Warning);
  527.                         }
  528.                         break;
  529.                     case AttributeMatchState.UndeclaredAttribute:
  530.                        
  531.                         if ((attributeDef = CheckIsXmlAttribute(attQName)) != null) {
  532.                             goto case AttributeMatchState.AttributeFound;
  533.                         }
  534.                         else {
  535.                             attrValid = false;
  536.                             SendValidationEvent(Res.Sch_UndeclaredAttribute, attQName.ToString());
  537.                         }
  538.                         break;
  539.                     case AttributeMatchState.ProhibitedAnyAttribute:
  540.                        
  541.                         if ((attributeDef = CheckIsXmlAttribute(attQName)) != null) {
  542.                             goto case AttributeMatchState.AttributeFound;
  543.                         }
  544.                         else {
  545.                             attrValid = false;
  546.                             SendValidationEvent(Res.Sch_ProhibitedAttribute, attQName.ToString());
  547.                         }
  548.                         break;
  549.                     case AttributeMatchState.ProhibitedAttribute:
  550.                        
  551.                         attrValid = false;
  552.                         SendValidationEvent(Res.Sch_ProhibitedAttribute, attQName.ToString());
  553.                         break;
  554.                     case AttributeMatchState.AttributeNameMismatch:
  555.                        
  556.                         attrValid = false;
  557.                         SendValidationEvent(Res.Sch_SchemaAttributeNameMismatch, new string[] {attQName.ToString(), ((XmlSchemaAttribute)pvtAttribute).QualifiedName.ToString()});
  558.                         break;
  559.                     case AttributeMatchState.ValidateAttributeInvalidCall:
  560.                        
  561.                         Debug.Assert(currentState == ValidatorState.TopLevelAttribute);
  562.                         //Re-set state back to start on error with partial validation type
  563.                         currentState = ValidatorState.Start;
  564.                         attrValid = false;
  565.                         SendValidationEvent(Res.Sch_ValidateAttributeInvalidCall, string.Empty);
  566.                         break;
  567.                     case AttributeMatchState.AnyIdAttributeFound:
  568.                        
  569.                         if (wildID == null) {
  570.                             wildID = attributeDef;
  571.                             Debug.Assert(currentElementDecl != null);
  572.                             XmlSchemaComplexType ct = currentElementDecl.SchemaType as XmlSchemaComplexType;
  573.                             Debug.Assert(ct != null);
  574.                             if (ct.ContainsIdAttribute(false)) {
  575.                                 SendValidationEvent(Res.Sch_AttrUseAndWildId, string.Empty);
  576.                             }
  577.                             else {
  578.                                 goto case AttributeMatchState.AttributeFound;
  579.                             }
  580.                         }
  581.                         else {
  582.                             //More than one attribute per element cannot match wildcard if both their types are derived from ID
  583.                             SendValidationEvent(Res.Sch_MoreThanOneWildId, string.Empty);
  584.                         }
  585.                         break;
  586.                     case AttributeMatchState.AttributeFound:
  587.                        
  588.                         Debug.Assert(attributeDef != null);
  589.                         localAttribute = attributeDef.SchemaAttribute;
  590.                         if (currentElementDecl != null) {
  591.                             //Have to add to hashtable to check whether to add default attributes
  592.                             attPresence.Add(attQName, attributeDef);
  593.                         }
  594.                         object attValue;
  595.                         if (attributeValueGetter != null) {
  596.                             attValue = attributeValueGetter();
  597.                         }
  598.                         else {
  599.                             attValue = attributeStringValue;
  600.                         }
  601.                         typedVal = CheckAttributeValue(attValue, attributeDef);
  602.                         XmlSchemaDatatype datatype = attributeDef.Datatype;
  603.                         if (datatype.Variety == XmlSchemaDatatypeVariety.Union && typedVal != null) {
  604.                             //Unpack the union
  605.                             XsdSimpleValue simpleValue = typedVal as XsdSimpleValue;
  606.                             Debug.Assert(simpleValue != null);
  607.                            
  608.                             localMemberType = simpleValue.XmlType;
  609.                             datatype = simpleValue.XmlType.Datatype;
  610.                             typedVal = simpleValue.TypedValue;
  611.                         }
  612.                         CheckTokenizedTypes(datatype, typedVal, true);
  613.                         if (HasIdentityConstraints) {
  614.                             AttributeIdentityConstraints(attQName.Name, attQName.Namespace, typedVal, attValue.ToString(), datatype);
  615.                         }
  616.                         break;
  617.                     case AttributeMatchState.AnyAttributeLax:
  618.                        
  619.                         SendValidationEvent(Res.Sch_NoAttributeSchemaFound, attQName.ToString(), XmlSeverityType.Warning);
  620.                         break;
  621.                     case AttributeMatchState.AnyAttributeSkip:
  622.                        
  623.                         break;
  624.                     default:
  625.                        
  626.                         break;
  627.                 }
  628.             }
  629.             else {
  630.                 //Attribute from xsi namespace
  631.                 lName = nameTable.Add(lName);
  632.                 if (Ref.Equal(lName, xsiTypeString) || Ref.Equal(lName, xsiNilString) || Ref.Equal(lName, xsiSchemaLocationString) || Ref.Equal(lName, xsiNoNamespaceSchemaLocationString)) {
  633.                     attPresence.Add(attQName, SchemaAttDef.Empty);
  634.                 }
  635.                 else {
  636.                     attrValid = false;
  637.                     SendValidationEvent(Res.Sch_NotXsiAttribute, attQName.ToString());
  638.                 }
  639.             }
  640.            
  641.             if (!attrValid) {
  642.                 localValidity = XmlSchemaValidity.Invalid;
  643.             }
  644.             else if (attributeDef != null) {
  645.                 localValidity = XmlSchemaValidity.Valid;
  646.             }
  647.             if (schemaInfo != null) {
  648.                 schemaInfo.SchemaAttribute = localAttribute;
  649.                 schemaInfo.SchemaType = localAttribute == null ? null : localAttribute.AttributeSchemaType;
  650.                 schemaInfo.MemberType = localMemberType;
  651.                 schemaInfo.IsDefault = false;
  652.                 schemaInfo.Validity = localValidity;
  653.             }
  654.             if (ProcessSchemaHints) {
  655.                 if (validatedNamespaces[ns] == null) {
  656.                     validatedNamespaces.Add(ns, ns);
  657.                 }
  658.             }
  659.             return typedVal;
  660.         }
  661.        
  662.         public void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes)
  663.         {
  664.             if (defaultAttributes == null) {
  665.                 throw new ArgumentNullException("defaultAttributes");
  666.             }
  667.             CheckStateTransition(ValidatorState.Attribute, "GetUnspecifiedDefaultAttributes");
  668.             GetUnspecifiedDefaultAttributes(defaultAttributes, false);
  669.         }
  670.        
  671.         public void ValidateEndOfAttributes(XmlSchemaInfo schemaInfo)
  672.         {
  673.             CheckStateTransition(ValidatorState.EndOfAttributes, MethodNames[(int)ValidatorState.EndOfAttributes]);
  674.             //Check required attributes
  675.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  676.             if (currentElementDecl != null && currentElementDecl.HasRequiredAttribute) {
  677.                 context.CheckRequiredAttribute = false;
  678.                 CheckRequiredAttributes(currentElementDecl);
  679.             }
  680.             if (schemaInfo != null) {
  681.                 //set validity depending on whether all required attributes were validated successfully
  682.                 schemaInfo.Validity = context.Validity;
  683.             }
  684.         }
  685.        
  686.         public void ValidateText(string elementValue)
  687.         {
  688.             if (elementValue == null) {
  689.                 throw new ArgumentNullException("elementValue");
  690.             }
  691.             ValidateText(elementValue, null);
  692.         }
  693.        
  694.         public void ValidateText(XmlValueGetter elementValue)
  695.         {
  696.             if (elementValue == null) {
  697.                 throw new ArgumentNullException("elementValue");
  698.             }
  699.             ValidateText(null, elementValue);
  700.         }
  701.        
  702.         private void ValidateText(string elementStringValue, XmlValueGetter elementValueGetter)
  703.         {
  704.             ValidatorState toState = validationStack.Length > 1 ? ValidatorState.Text : ValidatorState.TopLevelTextOrWS;
  705.             CheckStateTransition(toState, MethodNames[(int)toState]);
  706.            
  707.             if (context.NeedValidateChildren) {
  708.                 if (context.IsNill) {
  709.                     SendValidationEvent(Res.Sch_ContentInNill, QNameString(context.LocalName, context.Namespace));
  710.                     return;
  711.                 }
  712.                 XmlSchemaContentType contentType = context.ElementDecl.ContentValidator.ContentType;
  713.                 switch (contentType) {
  714.                     case XmlSchemaContentType.Empty:
  715.                         SendValidationEvent(Res.Sch_InvalidTextInEmpty, string.Empty);
  716.                         break;
  717.                     case XmlSchemaContentType.TextOnly:
  718.                        
  719.                         if (elementValueGetter != null) {
  720.                             SaveTextValue(elementValueGetter());
  721.                         }
  722.                         else {
  723.                             SaveTextValue(elementStringValue);
  724.                         }
  725.                         break;
  726.                     case XmlSchemaContentType.ElementOnly:
  727.                        
  728.                         ArrayList names = context.ElementDecl.ContentValidator.ExpectedParticles(context, false);
  729.                         if (names == null || names.Count == 0) {
  730.                             SendValidationEvent(Res.Sch_InvalidTextInElement, BuildElementName(context.LocalName, context.Namespace));
  731.                         }
  732.                         else {
  733.                             Debug.Assert(names.Count > 0);
  734.                             SendValidationEvent(Res.Sch_InvalidTextInElementExpecting, new string[] {BuildElementName(context.LocalName, context.Namespace), PrintExpectedElements(names, true)});
  735.                         }
  736.                         break;
  737.                     case XmlSchemaContentType.Mixed:
  738.                        
  739.                         if (context.ElementDecl.DefaultValueTyped != null) {
  740.                             if (elementValueGetter != null) {
  741.                                 SaveTextValue(elementValueGetter());
  742.                             }
  743.                             else {
  744.                                 SaveTextValue(elementStringValue);
  745.                             }
  746.                         }
  747.                         break;
  748.                 }
  749.             }
  750.         }
  751.        
  752.         public void ValidateWhitespace(string elementValue)
  753.         {
  754.             if (elementValue == null) {
  755.                 throw new ArgumentNullException("elementValue");
  756.             }
  757.             ValidateWhitespace(elementValue, null);
  758.         }
  759.        
  760.         public void ValidateWhitespace(XmlValueGetter elementValue)
  761.         {
  762.             if (elementValue == null) {
  763.                 throw new ArgumentNullException("elementValue");
  764.             }
  765.             ValidateWhitespace(null, elementValue);
  766.         }
  767.        
  768.         private void ValidateWhitespace(string elementStringValue, XmlValueGetter elementValueGetter)
  769.         {
  770.             ValidatorState toState = validationStack.Length > 1 ? ValidatorState.Whitespace : ValidatorState.TopLevelTextOrWS;
  771.             CheckStateTransition(toState, MethodNames[(int)toState]);
  772.            
  773.             if (context.NeedValidateChildren) {
  774.                 if (context.IsNill) {
  775.                     SendValidationEvent(Res.Sch_ContentInNill, QNameString(context.LocalName, context.Namespace));
  776.                 }
  777.                 XmlSchemaContentType contentType = context.ElementDecl.ContentValidator.ContentType;
  778.                 switch (contentType) {
  779.                     case XmlSchemaContentType.Empty:
  780.                         SendValidationEvent(Res.Sch_InvalidWhitespaceInEmpty, string.Empty);
  781.                         break;
  782.                     case XmlSchemaContentType.TextOnly:
  783.                        
  784.                         if (elementValueGetter != null) {
  785.                             SaveTextValue(elementValueGetter());
  786.                         }
  787.                         else {
  788.                             SaveTextValue(elementStringValue);
  789.                         }
  790.                         break;
  791.                     case XmlSchemaContentType.Mixed:
  792.                        
  793.                         if (context.ElementDecl.DefaultValueTyped != null) {
  794.                             if (elementValueGetter != null) {
  795.                                 SaveTextValue(elementValueGetter());
  796.                             }
  797.                             else {
  798.                                 SaveTextValue(elementStringValue);
  799.                             }
  800.                         }
  801.                         break;
  802.                     default:
  803.                        
  804.                         break;
  805.                 }
  806.             }
  807.         }
  808.        
  809.        
  810.         public object ValidateEndElement(XmlSchemaInfo schemaInfo)
  811.         {
  812.             return InternalValidateEndElement(schemaInfo, null);
  813.         }
  814.        
  815.         public object ValidateEndElement(XmlSchemaInfo schemaInfo, object typedValue)
  816.         {
  817.             if (typedValue == null) {
  818.                 throw new ArgumentNullException("typedValue");
  819.             }
  820.             if (textValue.Length > 0) {
  821.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidEndElementCall));
  822.             }
  823.             return InternalValidateEndElement(schemaInfo, typedValue);
  824.         }
  825.        
  826.         public void SkipToEndElement(XmlSchemaInfo schemaInfo)
  827.         {
  828.             if (validationStack.Length <= 1) {
  829.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidEndElementMultiple, MethodNames[(int)ValidatorState.SkipToEndElement]));
  830.             }
  831.             CheckStateTransition(ValidatorState.SkipToEndElement, MethodNames[(int)ValidatorState.SkipToEndElement]);
  832.            
  833.             if (schemaInfo != null) {
  834.                 SchemaElementDecl currentElementDecl = context.ElementDecl;
  835.                 if (currentElementDecl != null) {
  836.                     schemaInfo.SchemaType = currentElementDecl.SchemaType;
  837.                     schemaInfo.SchemaElement = GetSchemaElement();
  838.                 }
  839.                 else {
  840.                     schemaInfo.SchemaType = null;
  841.                     schemaInfo.SchemaElement = null;
  842.                 }
  843.                 schemaInfo.MemberType = null;
  844.                 schemaInfo.IsNil = context.IsNill;
  845.                 schemaInfo.IsDefault = context.IsDefault;
  846.                 Debug.Assert(context.Validity != XmlSchemaValidity.Valid);
  847.                 schemaInfo.Validity = context.Validity;
  848.             }
  849.             context.ValidationSkipped = true;
  850.             currentState = ValidatorState.SkipToEndElement;
  851.             Pop();
  852.         }
  853.        
  854.         public void EndValidation()
  855.         {
  856.             if (validationStack.Length > 1) {
  857.                 //We have pending elements in the stack to call ValidateEndElement
  858.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidEndValidation));
  859.             }
  860.             CheckStateTransition(ValidatorState.Finish, MethodNames[(int)ValidatorState.Finish]);
  861.             CheckForwardRefs();
  862.         }
  863.        
  864.         public XmlSchemaParticle[] GetExpectedParticles()
  865.         {
  866.             if (currentState == ValidatorState.Start || currentState == ValidatorState.TopLevelTextOrWS) {
  867.                 //Right after initialize
  868.                 if (partialValidationType != null) {
  869.                     XmlSchemaElement element = partialValidationType as XmlSchemaElement;
  870.                     if (element != null) {
  871.                         return new XmlSchemaParticle[1] {element};
  872.                     }
  873.                     return EmptyParticleArray;
  874.                 }
  875.                 else {
  876.                     //Should return all global elements
  877.                     ICollection elements = schemaSet.GlobalElements.Values;
  878.                     XmlSchemaParticle[] expectedElements = new XmlSchemaParticle[elements.Count];
  879.                     elements.CopyTo(expectedElements, 0);
  880.                     return expectedElements;
  881.                 }
  882.             }
  883.             if (context.ElementDecl != null) {
  884.                 ArrayList expected = context.ElementDecl.ContentValidator.ExpectedParticles(context, false);
  885.                 if (expected != null) {
  886.                     return expected.ToArray(typeof(XmlSchemaParticle)) as XmlSchemaParticle[];
  887.                 }
  888.             }
  889.             return EmptyParticleArray;
  890.         }
  891.        
  892.         public XmlSchemaAttribute[] GetExpectedAttributes()
  893.         {
  894.             if (currentState == ValidatorState.Element || currentState == ValidatorState.Attribute) {
  895.                 SchemaElementDecl elementDecl = context.ElementDecl;
  896.                 ArrayList attList = new ArrayList();
  897.                 if (elementDecl != null) {
  898.                     foreach (SchemaAttDef attDef in elementDecl.AttDefs.Values) {
  899.                         if (attPresence[attDef.Name] == null) {
  900.                             attList.Add(attDef.SchemaAttribute);
  901.                         }
  902.                     }
  903.                 }
  904.                 if (nsResolver.LookupPrefix(NsXsi) != null) {
  905.                     //Xsi namespace defined
  906.                     AddXsiAttributes(attList);
  907.                 }
  908.                 return attList.ToArray(typeof(XmlSchemaAttribute)) as XmlSchemaAttribute[];
  909.             }
  910.             else if (currentState == ValidatorState.Start) {
  911.                 if (partialValidationType != null) {
  912.                     XmlSchemaAttribute attribute = partialValidationType as XmlSchemaAttribute;
  913.                     if (attribute != null) {
  914.                         return new XmlSchemaAttribute[1] {attribute};
  915.                     }
  916.                 }
  917.             }
  918.             return EmptyAttributeArray;
  919.         }
  920.        
  921.         internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool createNodeData)
  922.         {
  923.             currentState = ValidatorState.Attribute;
  924.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  925.            
  926.             if (currentElementDecl != null && currentElementDecl.HasDefaultAttribute) {
  927.                 foreach (SchemaAttDef attdef in currentElementDecl.DefaultAttDefs) {
  928.                     if (!attPresence.Contains(attdef.Name)) {
  929.                         if (attdef.DefaultValueTyped == null) {
  930.                             //Invalid attribute default in the schema
  931.                             continue;
  932.                         }
  933.                        
  934.                         //Check to see default attributes WILL be qualified if attributeFormDefault = qualified in schema
  935.                         string attributeNS = nameTable.Add(attdef.Name.Namespace);
  936.                         string defaultPrefix = string.Empty;
  937.                         if (attributeNS.Length > 0) {
  938.                             defaultPrefix = GetDefaultAttributePrefix(attributeNS);
  939.                             if (defaultPrefix == null || defaultPrefix.Length == 0) {
  940.                                 SendValidationEvent(Res.Sch_DefaultAttributeNotApplied, new string[2] {attdef.Name.ToString(), QNameString(context.LocalName, context.Namespace)});
  941.                                 continue;
  942.                             }
  943.                         }
  944.                         XmlSchemaDatatype datatype = attdef.Datatype;
  945.                         if (createNodeData) {
  946.                             ValidatingReaderNodeData attrData = new ValidatingReaderNodeData();
  947.                             attrData.LocalName = nameTable.Add(attdef.Name.Name);
  948.                             attrData.Namespace = attributeNS;
  949.                             attrData.Prefix = nameTable.Add(defaultPrefix);
  950.                             attrData.NodeType = XmlNodeType.Attribute;
  951.                            
  952.                             //set PSVI properties
  953.                             AttributePSVIInfo attrValidInfo = new AttributePSVIInfo();
  954.                             XmlSchemaInfo attSchemaInfo = attrValidInfo.attributeSchemaInfo;
  955.                             Debug.Assert(attSchemaInfo != null);
  956.                             if (attdef.Datatype.Variety == XmlSchemaDatatypeVariety.Union) {
  957.                                 XsdSimpleValue simpleValue = attdef.DefaultValueTyped as XsdSimpleValue;
  958.                                 attSchemaInfo.MemberType = simpleValue.XmlType;
  959.                                 datatype = simpleValue.XmlType.Datatype;
  960.                                 attrValidInfo.typedAttributeValue = simpleValue.TypedValue;
  961.                             }
  962.                             else {
  963.                                 attrValidInfo.typedAttributeValue = attdef.DefaultValueTyped;
  964.                             }
  965.                             attSchemaInfo.IsDefault = true;
  966.                             attSchemaInfo.Validity = XmlSchemaValidity.Valid;
  967.                             attSchemaInfo.SchemaType = attdef.SchemaType;
  968.                             attSchemaInfo.SchemaAttribute = attdef.SchemaAttribute;
  969.                             attrData.RawValue = attSchemaInfo.XmlType.ValueConverter.ToString(attrValidInfo.typedAttributeValue);
  970.                            
  971.                             attrData.AttInfo = attrValidInfo;
  972.                             defaultAttributes.Add(attrData);
  973.                         }
  974.                         else {
  975.                             defaultAttributes.Add(attdef.SchemaAttribute);
  976.                         }
  977.                         CheckTokenizedTypes(datatype, attdef.DefaultValueTyped, true);
  978.                         if (HasIdentityConstraints) {
  979.                             AttributeIdentityConstraints(attdef.Name.Name, attdef.Name.Namespace, attdef.DefaultValueTyped, attdef.DefaultValueRaw, datatype);
  980.                         }
  981.                     }
  982.                 }
  983.             }
  984.             return;
  985.         }
  986.        
  987.         internal XmlSchemaSet SchemaSet {
  988.             get { return schemaSet; }
  989.         }
  990.        
  991.         internal XmlSchemaValidationFlags ValidationFlags {
  992.             get { return validationFlags; }
  993.         }
  994.        
  995.         internal XmlSchemaContentType CurrentContentType {
  996.             get {
  997.                 if (context.ElementDecl == null) {
  998.                     return XmlSchemaContentType.Empty;
  999.                 }
  1000.                 return context.ElementDecl.ContentValidator.ContentType;
  1001.             }
  1002.         }
  1003.        
  1004.         internal XmlSchemaContentProcessing CurrentProcessContents {
  1005.             get { return processContents; }
  1006.         }
  1007.        
  1008.         internal void SetDtdSchemaInfo(SchemaInfo dtdSchemaInfo)
  1009.         {
  1010.             this.dtdSchemaInfo = dtdSchemaInfo;
  1011.             this.checkEntity = true;
  1012.         }
  1013.        
  1014.         private bool StrictlyAssessed {
  1015.             get { return (processContents == XmlSchemaContentProcessing.Strict || processContents == XmlSchemaContentProcessing.Lax) && context.ElementDecl != null && !context.ValidationSkipped; }
  1016.         }
  1017.        
  1018.         private bool HasSchema {
  1019.             get {
  1020.                 if (isRoot) {
  1021.                     isRoot = false;
  1022.                     if (!compiledSchemaInfo.Contains(context.Namespace)) {
  1023.                         rootHasSchema = false;
  1024.                     }
  1025.                 }
  1026.                 return rootHasSchema;
  1027.             }
  1028.         }
  1029.        
  1030.         internal string GetConcatenatedValue()
  1031.         {
  1032.             return textValue.ToString();
  1033.         }
  1034.        
  1035.         private object InternalValidateEndElement(XmlSchemaInfo schemaInfo, object typedValue)
  1036.         {
  1037.             if (validationStack.Length <= 1) {
  1038.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidEndElementMultiple, MethodNames[(int)ValidatorState.EndElement]));
  1039.             }
  1040.             CheckStateTransition(ValidatorState.EndElement, MethodNames[(int)ValidatorState.EndElement]);
  1041.            
  1042.             SchemaElementDecl contextElementDecl = context.ElementDecl;
  1043.             XmlSchemaSimpleType memberType = null;
  1044.             XmlSchemaType localSchemaType = null;
  1045.             XmlSchemaElement localSchemaElement = null;
  1046.            
  1047.             string stringValue = string.Empty;
  1048.            
  1049.             if (contextElementDecl != null) {
  1050.                 if (context.CheckRequiredAttribute && contextElementDecl.HasRequiredAttribute) {
  1051.                     CheckRequiredAttributes(contextElementDecl);
  1052.                 }
  1053.                 if (!context.IsNill) {
  1054.                     if (context.NeedValidateChildren) {
  1055.                         XmlSchemaContentType contentType = contextElementDecl.ContentValidator.ContentType;
  1056.                         switch (contentType) {
  1057.                             case XmlSchemaContentType.TextOnly:
  1058.                                 if (typedValue == null) {
  1059.                                     stringValue = textValue.ToString();
  1060.                                     typedValue = ValidateAtomicValue(stringValue, out memberType);
  1061.                                 }
  1062.                                 else {
  1063.                                     //Parsed object passed in, need to verify only facets
  1064.                                     typedValue = ValidateAtomicValue(typedValue, out memberType);
  1065.                                 }
  1066.                                 break;
  1067.                             case XmlSchemaContentType.Mixed:
  1068.                                
  1069.                                 if (contextElementDecl.DefaultValueTyped != null) {
  1070.                                     if (typedValue == null) {
  1071.                                         stringValue = textValue.ToString();
  1072.                                         typedValue = CheckMixedValueConstraint(stringValue);
  1073.                                     }
  1074.                                 }
  1075.                                 break;
  1076.                             case XmlSchemaContentType.ElementOnly:
  1077.                                
  1078.                                 if (typedValue != null) {
  1079.                                     //Cannot pass in typedValue for complex content
  1080.                                     throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidEndElementCallTyped));
  1081.                                 }
  1082.                                 break;
  1083.                             default:
  1084.                                
  1085.                                 break;
  1086.                         }
  1087.                         if (!contextElementDecl.ContentValidator.CompleteValidation(context)) {
  1088.                             CompleteValidationError(context, eventHandler, nsResolver, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition, true);
  1089.                             context.Validity = XmlSchemaValidity.Invalid;
  1090.                         }
  1091.                     }
  1092.                 }
  1093.                 // for each level in the stack, endchildren and fill value from element
  1094.                 if (HasIdentityConstraints) {
  1095.                     XmlSchemaType xmlType = memberType == null ? contextElementDecl.SchemaType : memberType;
  1096.                     EndElementIdentityConstraints(typedValue, stringValue, xmlType.Datatype);
  1097.                 }
  1098.                 localSchemaType = contextElementDecl.SchemaType;
  1099.                 localSchemaElement = GetSchemaElement();
  1100.             }
  1101.             if (schemaInfo != null) {
  1102.                 //SET SchemaInfo
  1103.                 schemaInfo.SchemaType = localSchemaType;
  1104.                 schemaInfo.SchemaElement = localSchemaElement;
  1105.                 schemaInfo.MemberType = memberType;
  1106.                 schemaInfo.IsNil = context.IsNill;
  1107.                 schemaInfo.IsDefault = context.IsDefault;
  1108.                 if (context.Validity == XmlSchemaValidity.NotKnown && StrictlyAssessed) {
  1109.                     context.Validity = XmlSchemaValidity.Valid;
  1110.                 }
  1111.                 schemaInfo.Validity = context.Validity;
  1112.             }
  1113.             Pop();
  1114.             return typedValue;
  1115.         }
  1116.        
  1117.         private void ProcessSchemaLocations(string xsiSchemaLocation, string xsiNoNamespaceSchemaLocation)
  1118.         {
  1119.             bool compile = false;
  1120.             if (xsiNoNamespaceSchemaLocation != null) {
  1121.                 compile = true;
  1122.                 LoadSchema(string.Empty, xsiNoNamespaceSchemaLocation);
  1123.             }
  1124.             if (xsiSchemaLocation != null) {
  1125.                
  1126.                 object typedValue;
  1127.                 Exception exception = dtStringArray.TryParseValue(xsiSchemaLocation, nameTable, nsResolver, out typedValue);
  1128.                 if (exception != null) {
  1129.                     SendValidationEvent(new XmlSchemaException(Res.Sch_InvalidValueDetailed, new string[] {xsiSchemaLocation, dtStringArray.TypeCodeString, exception.Message}, exception, null, 0, 0, null));
  1130.                     return;
  1131.                 }
  1132.                 string[] locations = (string[])typedValue;
  1133.                 compile = true;
  1134.                 try {
  1135.                     for (int j = 0; j < locations.Length - 1; j += 2) {
  1136.                         LoadSchema((string)locations[j], (string)locations[j + 1]);
  1137.                     }
  1138.                 }
  1139.                 catch (XmlSchemaException schemaException) {
  1140.                     SendValidationEvent(schemaException);
  1141.                 }
  1142.             }
  1143.             if (compile) {
  1144.                 RecompileSchemaSet();
  1145.             }
  1146.         }
  1147.        
  1148.        
  1149.         private object ValidateElementContext(XmlQualifiedName elementName, out bool invalidElementInContext)
  1150.         {
  1151.             object particle = null;
  1152.             int errorCode = 0;
  1153.             XmlQualifiedName head;
  1154.             XmlSchemaElement headElement = null;
  1155.             invalidElementInContext = false;
  1156.            
  1157.             if (context.NeedValidateChildren) {
  1158.                 if (context.IsNill) {
  1159.                     SendValidationEvent(Res.Sch_ContentInNill, QNameString(context.LocalName, context.Namespace));
  1160.                     return null;
  1161.                 }
  1162.                 ContentValidator contentValidator = context.ElementDecl.ContentValidator;
  1163.                 if (contentValidator.ContentType == XmlSchemaContentType.Mixed && context.ElementDecl.Presence == SchemaDeclBase.Use.Fixed) {
  1164.                     //Mixed with default or fixed
  1165.                     SendValidationEvent(Res.Sch_ElementInMixedWithFixed, QNameString(context.LocalName, context.Namespace));
  1166.                     return null;
  1167.                 }
  1168.                
  1169.                 head = elementName;
  1170.                 bool substitution = false;
  1171.                
  1172.                 while (true) {
  1173.                     particle = context.ElementDecl.ContentValidator.ValidateElement(head, context, out errorCode);
  1174.                     if (particle != null) {
  1175.                         //Match found
  1176.                         break;
  1177.                     }
  1178.                     if (errorCode == -2) {
  1179.                         //ContentModel all group error
  1180.                         SendValidationEvent(Res.Sch_AllElement, elementName.ToString());
  1181.                         invalidElementInContext = true;
  1182.                         processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip;
  1183.                         return null;
  1184.                     }
  1185.                     //Match not found; check for substitutionGroup
  1186.                     substitution = true;
  1187.                     headElement = GetSubstitutionGroupHead(head);
  1188.                     if (headElement == null) {
  1189.                         break;
  1190.                     }
  1191.                     else {
  1192.                         head = headElement.QualifiedName;
  1193.                     }
  1194.                 }
  1195.                
  1196.                 if (substitution) {
  1197.                     XmlSchemaElement matchedElem = particle as XmlSchemaElement;
  1198.                     if (matchedElem == null) {
  1199.                         //It matched an xs:any in that position
  1200.                         particle = null;
  1201.                     }
  1202.                     else if (matchedElem.RefName.IsEmpty) {
  1203.                         //It is not element ref but a local element
  1204.                         //If the head and matched particle are not hte same, then this is not substitutable, duped by a localElement with same QName
  1205.                         SendValidationEvent(Res.Sch_InvalidElementSubstitution, BuildElementName(elementName), BuildElementName(matchedElem.QualifiedName));
  1206.                         invalidElementInContext = true;
  1207.                         processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip;
  1208.                     }
  1209.                     else {
  1210.                         //Correct substitution head found
  1211.                         particle = compiledSchemaInfo.GetElement(elementName);
  1212.                         //Re-assign correct particle
  1213.                         context.NeedValidateChildren = true;
  1214.                         //This will be reset to false once member match is not found
  1215.                     }
  1216.                 }
  1217.                 if (particle == null) {
  1218.                     ElementValidationError(elementName, context, eventHandler, nsResolver, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition, true);
  1219.                     invalidElementInContext = true;
  1220.                     processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip;
  1221.                 }
  1222.             }
  1223.             return particle;
  1224.         }
  1225.        
  1226.        
  1227.         private XmlSchemaElement GetSubstitutionGroupHead(XmlQualifiedName member)
  1228.         {
  1229.             XmlSchemaElement memberElem = compiledSchemaInfo.GetElement(member);
  1230.             if (memberElem != null) {
  1231.                 XmlQualifiedName head = memberElem.SubstitutionGroup;
  1232.                 if (!head.IsEmpty) {
  1233.                     XmlSchemaElement headElem = compiledSchemaInfo.GetElement(head);
  1234.                     if (headElem != null) {
  1235.                         if ((headElem.BlockResolved & XmlSchemaDerivationMethod.Substitution) != 0) {
  1236.                             SendValidationEvent(Res.Sch_SubstitutionNotAllowed, new string[] {member.ToString(), head.ToString()});
  1237.                             return null;
  1238.                         }
  1239.                         if (!XmlSchemaType.IsDerivedFrom(memberElem.ElementSchemaType, headElem.ElementSchemaType, headElem.BlockResolved)) {
  1240.                             SendValidationEvent(Res.Sch_SubstitutionBlocked, new string[] {member.ToString(), head.ToString()});
  1241.                             return null;
  1242.                         }
  1243.                         return headElem;
  1244.                     }
  1245.                 }
  1246.             }
  1247.             return null;
  1248.         }
  1249.        
  1250.         private object ValidateAtomicValue(string stringValue, out XmlSchemaSimpleType memberType)
  1251.         {
  1252.             object typedVal = null;
  1253.             memberType = null;
  1254.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  1255.             if (!context.IsNill) {
  1256.                 if (stringValue.Length == 0 && currentElementDecl.DefaultValueTyped != null) {
  1257.                     //default value maybe present
  1258.                     SchemaElementDecl declBeforeXsi = context.ElementDeclBeforeXsi;
  1259.                     if (declBeforeXsi != null && declBeforeXsi != currentElementDecl) {
  1260.                         //There was xsi:type
  1261.                         Debug.Assert(currentElementDecl.Datatype != null);
  1262.                         Exception exception = currentElementDecl.Datatype.TryParseValue(currentElementDecl.DefaultValueRaw, nameTable, nsResolver, out typedVal);
  1263.                         if (exception != null) {
  1264.                             SendValidationEvent(Res.Sch_InvalidElementDefaultValue, new string[] {currentElementDecl.DefaultValueRaw, QNameString(context.LocalName, context.Namespace)});
  1265.                         }
  1266.                         else {
  1267.                             context.IsDefault = true;
  1268.                         }
  1269.                     }
  1270.                     else {
  1271.                         context.IsDefault = true;
  1272.                         typedVal = currentElementDecl.DefaultValueTyped;
  1273.                     }
  1274.                 }
  1275.                 else {
  1276.                     typedVal = CheckElementValue(stringValue);
  1277.                 }
  1278.                 XsdSimpleValue simpleValue = typedVal as XsdSimpleValue;
  1279.                 XmlSchemaDatatype dtype = currentElementDecl.Datatype;
  1280.                 if (simpleValue != null) {
  1281.                     memberType = simpleValue.XmlType;
  1282.                     typedVal = simpleValue.TypedValue;
  1283.                     dtype = memberType.Datatype;
  1284.                 }
  1285.                 CheckTokenizedTypes(dtype, typedVal, false);
  1286.             }
  1287.             return typedVal;
  1288.         }
  1289.        
  1290.         private object ValidateAtomicValue(object parsedValue, out XmlSchemaSimpleType memberType)
  1291.         {
  1292.             memberType = null;
  1293.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  1294.             object typedValue = null;
  1295.             if (!context.IsNill) {
  1296.                 SchemaDeclBase decl = currentElementDecl as SchemaDeclBase;
  1297.                 XmlSchemaDatatype dtype = currentElementDecl.Datatype;
  1298.                 Exception exception = dtype.TryParseValue(parsedValue, nameTable, nsResolver, out typedValue);
  1299.                 if (exception != null) {
  1300.                     string stringValue = parsedValue as string;
  1301.                     if (stringValue == null) {
  1302.                         stringValue = XmlSchemaDatatype.ConcatenatedToString(parsedValue);
  1303.                     }
  1304.                     SendValidationEvent(Res.Sch_ElementValueDataTypeDetailed, new string[] {QNameString(context.LocalName, context.Namespace), stringValue, GetTypeName(decl), exception.Message}, exception);
  1305.                     return null;
  1306.                 }
  1307.                 if (!decl.CheckValue(typedValue)) {
  1308.                     SendValidationEvent(Res.Sch_FixedElementValue, QNameString(context.LocalName, context.Namespace));
  1309.                 }
  1310.                 if (dtype.Variety == XmlSchemaDatatypeVariety.Union) {
  1311.                     XsdSimpleValue simpleValue = typedValue as XsdSimpleValue;
  1312.                     Debug.Assert(simpleValue != null);
  1313.                     memberType = simpleValue.XmlType;
  1314.                     typedValue = simpleValue.TypedValue;
  1315.                     dtype = memberType.Datatype;
  1316.                 }
  1317.                 CheckTokenizedTypes(dtype, typedValue, false);
  1318.             }
  1319.             return typedValue;
  1320.         }
  1321.        
  1322.         private string GetTypeName(SchemaDeclBase decl)
  1323.         {
  1324.             Debug.Assert(decl != null && decl.SchemaType != null);
  1325.             string typeName = decl.SchemaType.QualifiedName.ToString();
  1326.             if (typeName.Length == 0) {
  1327.                 typeName = decl.Datatype.TypeCodeString;
  1328.             }
  1329.             return typeName;
  1330.         }
  1331.        
  1332.         private void SaveTextValue(object value)
  1333.         {
  1334.             string s = value.ToString();
  1335.             //For strings, which will mostly be the case, ToString() will return this. For other typedValues, need to go through value converter (eg: TimeSpan, DateTime etc)
  1336.             textValue.Append(s);
  1337.         }
  1338.        
  1339.         private void Push(XmlQualifiedName elementName)
  1340.         {
  1341.             context = (ValidationState)validationStack.Push();
  1342.             if (context == null) {
  1343.                 context = new ValidationState();
  1344.                 validationStack.AddToTop(context);
  1345.             }
  1346.             context.LocalName = elementName.Name;
  1347.             context.Namespace = elementName.Namespace;
  1348.             context.HasMatched = false;
  1349.             context.IsNill = false;
  1350.             context.IsDefault = false;
  1351.             context.CheckRequiredAttribute = true;
  1352.             context.ValidationSkipped = false;
  1353.             context.Validity = XmlSchemaValidity.NotKnown;
  1354.             context.NeedValidateChildren = false;
  1355.             context.ProcessContents = processContents;
  1356.             context.ElementDeclBeforeXsi = null;
  1357.             context.Constr = null;
  1358.             //resetting the constraints to be null incase context != null
  1359.             // when pushing onto stack;
  1360.         }
  1361.        
  1362.         private void Pop()
  1363.         {
  1364.             Debug.Assert(validationStack.Length > 1);
  1365.             ValidationState previousContext = (ValidationState)validationStack.Pop();
  1366.            
  1367.             if (startIDConstraint == validationStack.Length) {
  1368.                 startIDConstraint = -1;
  1369.             }
  1370.             context = (ValidationState)validationStack.Peek();
  1371.             if (previousContext.Validity == XmlSchemaValidity.Invalid) {
  1372.                 //Should set current context's validity to that of what was popped now in case of Invalid
  1373.                 context.Validity = XmlSchemaValidity.Invalid;
  1374.             }
  1375.             if (previousContext.ValidationSkipped) {
  1376.                 context.ValidationSkipped = true;
  1377.             }
  1378.             processContents = context.ProcessContents;
  1379.         }
  1380.        
  1381.         private void AddXsiAttributes(ArrayList attList)
  1382.         {
  1383.             BuildXsiAttributes();
  1384.             if (attPresence[xsiTypeSO.QualifiedName] == null) {
  1385.                 attList.Add(xsiTypeSO);
  1386.             }
  1387.             if (attPresence[xsiNilSO.QualifiedName] == null) {
  1388.                 attList.Add(xsiNilSO);
  1389.             }
  1390.             if (attPresence[xsiSLSO.QualifiedName] == null) {
  1391.                 attList.Add(xsiSLSO);
  1392.             }
  1393.             if (attPresence[xsiNoNsSLSO.QualifiedName] == null) {
  1394.                 attList.Add(xsiNoNsSLSO);
  1395.             }
  1396.         }
  1397.        
  1398.         private SchemaElementDecl FastGetElementDecl(XmlQualifiedName elementName, object particle)
  1399.         {
  1400.             SchemaElementDecl elementDecl = null;
  1401.             if (particle != null) {
  1402.                 XmlSchemaElement element = particle as XmlSchemaElement;
  1403.                 if (element != null) {
  1404.                     elementDecl = element.ElementDecl;
  1405.                 }
  1406.                 else {
  1407.                     XmlSchemaAny any = (XmlSchemaAny)particle;
  1408.                     processContents = any.ProcessContentsCorrect;
  1409.                 }
  1410.             }
  1411.             if (elementDecl == null && processContents != XmlSchemaContentProcessing.Skip) {
  1412.                 if (isRoot && partialValidationType != null) {
  1413.                     if (partialValidationType is XmlSchemaElement) {
  1414.                         XmlSchemaElement element = (XmlSchemaElement)partialValidationType;
  1415.                         if (elementName.Equals(element.QualifiedName)) {
  1416.                             elementDecl = element.ElementDecl;
  1417.                         }
  1418.                         else {
  1419.                             SendValidationEvent(Res.Sch_SchemaElementNameMismatch, elementName.ToString(), element.QualifiedName.ToString());
  1420.                         }
  1421.                     }
  1422.                     else if (partialValidationType is XmlSchemaType) {
  1423.                         //Element name is wildcard
  1424.                         XmlSchemaType type = (XmlSchemaType)partialValidationType;
  1425.                         elementDecl = type.ElementDecl;
  1426.                     }
  1427.                     else {
  1428.                         //its XmlSchemaAttribute
  1429.                         Debug.Assert(partialValidationType is XmlSchemaAttribute);
  1430.                         SendValidationEvent(Res.Sch_ValidateElementInvalidCall, string.Empty);
  1431.                     }
  1432.                 }
  1433.                 else {
  1434.                     elementDecl = compiledSchemaInfo.GetElementDecl(elementName);
  1435.                 }
  1436.             }
  1437.             return elementDecl;
  1438.         }
  1439.        
  1440.         private SchemaElementDecl CheckXsiTypeAndNil(SchemaElementDecl elementDecl, string xsiType, string xsiNil, ref bool declFound)
  1441.         {
  1442.             XmlQualifiedName xsiTypeName = XmlQualifiedName.Empty;
  1443.             if (xsiType != null) {
  1444.                 object typedVal = null;
  1445.                 Exception exception = dtQName.TryParseValue(xsiType, nameTable, nsResolver, out typedVal);
  1446.                 if (exception != null) {
  1447.                     SendValidationEvent(new XmlSchemaException(Res.Sch_InvalidValueDetailed, new string[] {xsiType, dtQName.TypeCodeString, exception.Message}, exception, null, 0, 0, null));
  1448.                 }
  1449.                 else {
  1450.                     xsiTypeName = typedVal as XmlQualifiedName;
  1451.                 }
  1452.             }
  1453.             if (elementDecl != null) {
  1454.                 //nillable is not dependent on xsi:type.
  1455.                 if (elementDecl.IsNillable) {
  1456.                     if (xsiNil != null) {
  1457.                         context.IsNill = XmlConvert.ToBoolean(xsiNil);
  1458.                         if (context.IsNill && elementDecl.Presence == SchemaDeclBase.Use.Fixed) {
  1459.                             Debug.Assert(elementDecl.DefaultValueTyped != null);
  1460.                             SendValidationEvent(Res.Sch_XsiNilAndFixed);
  1461.                         }
  1462.                     }
  1463.                 }
  1464.                 else if (xsiNil != null) {
  1465.                     SendValidationEvent(Res.Sch_InvalidXsiNill);
  1466.                 }
  1467.             }
  1468.             if (xsiTypeName.IsEmpty) {
  1469.                 if (elementDecl != null && elementDecl.IsAbstract) {
  1470.                     SendValidationEvent(Res.Sch_AbstractElement, QNameString(context.LocalName, context.Namespace));
  1471.                     elementDecl = null;
  1472.                 }
  1473.             }
  1474.             else {
  1475.                 SchemaElementDecl elementDeclXsi = compiledSchemaInfo.GetTypeDecl(xsiTypeName);
  1476.                 XmlSeverityType severity = XmlSeverityType.Warning;
  1477.                 if (HasSchema && processContents == XmlSchemaContentProcessing.Strict) {
  1478.                     severity = XmlSeverityType.Error;
  1479.                 }
  1480.                 if (elementDeclXsi == null && xsiTypeName.Namespace == NsXs) {
  1481.                     XmlSchemaType schemaType = DatatypeImplementation.GetSimpleTypeFromXsdType(xsiTypeName);
  1482.                     if (schemaType == null) {
  1483.                         //try getting complexType - xs:anyType
  1484.                         schemaType = XmlSchemaType.GetBuiltInComplexType(xsiTypeName);
  1485.                     }
  1486.                     if (schemaType != null) {
  1487.                         elementDeclXsi = schemaType.ElementDecl;
  1488.                     }
  1489.                    
  1490.                 }
  1491.                 if (elementDeclXsi == null) {
  1492.                     SendValidationEvent(Res.Sch_XsiTypeNotFound, xsiTypeName.ToString(), severity);
  1493.                     elementDecl = null;
  1494.                 }
  1495.                 else {
  1496.                     declFound = true;
  1497.                     if (elementDeclXsi.IsAbstract) {
  1498.                         SendValidationEvent(Res.Sch_XsiTypeAbstract, xsiTypeName.ToString(), severity);
  1499.                         elementDecl = null;
  1500.                     }
  1501.                     else if (elementDecl != null && !XmlSchemaType.IsDerivedFrom(elementDeclXsi.SchemaType, elementDecl.SchemaType, elementDecl.Block)) {
  1502.                         SendValidationEvent(Res.Sch_XsiTypeBlockedEx, new string[] {xsiTypeName.ToString(), QNameString(context.LocalName, context.Namespace)});
  1503.                         elementDecl = null;
  1504.                     }
  1505.                     else {
  1506.                         if (elementDecl != null) {
  1507.                             //Get all element decl properties before assigning xsi:type decl; nillable already checked
  1508.                             elementDeclXsi = elementDeclXsi.Clone();
  1509.                             //Before updating properties onto xsi:type decl, clone it
  1510.                             elementDeclXsi.Constraints = elementDecl.Constraints;
  1511.                             elementDeclXsi.DefaultValueRaw = elementDecl.DefaultValueRaw;
  1512.                             elementDeclXsi.DefaultValueTyped = elementDecl.DefaultValueTyped;
  1513.                             elementDeclXsi.Block = elementDecl.Block;
  1514.                         }
  1515.                         context.ElementDeclBeforeXsi = elementDecl;
  1516.                         elementDecl = elementDeclXsi;
  1517.                     }
  1518.                 }
  1519.             }
  1520.             return elementDecl;
  1521.         }
  1522.        
  1523.         private void ThrowDeclNotFoundWarningOrError(bool declFound)
  1524.         {
  1525.             if (declFound) {
  1526.                 //But invalid, so discontinue processing of children
  1527.                 processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip;
  1528.                 context.NeedValidateChildren = false;
  1529.             }
  1530.             else if (HasSchema && processContents == XmlSchemaContentProcessing.Strict) {
  1531.                 //Error and skip validation for children
  1532.                 processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip;
  1533.                 context.NeedValidateChildren = false;
  1534.                 SendValidationEvent(Res.Sch_UndeclaredElement, QNameString(context.LocalName, context.Namespace));
  1535.             }
  1536.             else {
  1537.                 SendValidationEvent(Res.Sch_NoElementSchemaFound, QNameString(context.LocalName, context.Namespace), XmlSeverityType.Warning);
  1538.             }
  1539.         }
  1540.        
  1541.         private void CheckElementProperties()
  1542.         {
  1543.             if (context.ElementDecl.IsAbstract) {
  1544.                 SendValidationEvent(Res.Sch_AbstractElement, QNameString(context.LocalName, context.Namespace));
  1545.             }
  1546.         }
  1547.        
  1548.         private void ValidateStartElementIdentityConstraints()
  1549.         {
  1550.             // added on June 15, set the context here, so the stack can have them
  1551.             if (ProcessIdentityConstraints && context.ElementDecl.Constraints != null) {
  1552.                 AddIdentityConstraints();
  1553.             }
  1554.             //foreach constraint in stack (including the current one)
  1555.             if (HasIdentityConstraints) {
  1556.                 ElementIdentityConstraints();
  1557.             }
  1558.         }
  1559.        
  1560.         private SchemaAttDef CheckIsXmlAttribute(XmlQualifiedName attQName)
  1561.         {
  1562.             SchemaAttDef attdef = null;
  1563.             if (Ref.Equal(attQName.Namespace, NsXml) && (validationFlags & XmlSchemaValidationFlags.AllowXmlAttributes) != 0) {
  1564.                 //Need to check if this attribute is an xml attribute
  1565.                 if (!compiledSchemaInfo.Contains(NsXml)) {
  1566.                     //We dont have a schema for xml namespace
  1567.                     Debug.Assert(!schemaSet.Contains(NsXml));
  1568.                     AddXmlNamespaceSchema();
  1569.                 }
  1570.                 attdef = (SchemaAttDef)compiledSchemaInfo.AttributeDecls[attQName];
  1571.                 //the xml attributes are all global attributes
  1572.             }
  1573.             return attdef;
  1574.         }
  1575.        
  1576.         private void AddXmlNamespaceSchema()
  1577.         {
  1578.             XmlSchemaSet localSet = new XmlSchemaSet();
  1579.             //Avoiding cost of incremental compilation checks by compiling schema in a seperate set and adding compiled set
  1580.             localSet.Add(Preprocessor.GetBuildInSchema());
  1581.             localSet.Compile();
  1582.             schemaSet.Add(localSet);
  1583.             RecompileSchemaSet();
  1584.         }
  1585.        
  1586.         internal object CheckMixedValueConstraint(string elementValue)
  1587.         {
  1588.             SchemaElementDecl elementDecl = context.ElementDecl;
  1589.             Debug.Assert(elementDecl.ContentValidator.ContentType == XmlSchemaContentType.Mixed && elementDecl.DefaultValueTyped != null);
  1590.             if (context.IsNill) {
  1591.                 //Nil and fixed is error; Nil and default is compile time error
  1592.                 return null;
  1593.             }
  1594.             if (elementValue.Length == 0) {
  1595.                 context.IsDefault = true;
  1596.                 return elementDecl.DefaultValueTyped;
  1597.             }
  1598.             else {
  1599.                 SchemaDeclBase decl = elementDecl as SchemaDeclBase;
  1600.                 Debug.Assert(decl != null);
  1601.                 if (decl.Presence == SchemaDeclBase.Use.Fixed && !elementValue.Equals(elementDecl.DefaultValueRaw)) {
  1602.                     //check string equality for mixed as it is untyped.
  1603.                     SendValidationEvent(Res.Sch_FixedElementValue, elementDecl.Name.ToString());
  1604.                 }
  1605.                 return elementValue;
  1606.             }
  1607.         }
  1608.        
  1609.         private void LoadSchema(string uri, string url)
  1610.         {
  1611.             Debug.Assert(xmlResolver != null);
  1612.             XmlReader Reader = null;
  1613.             try {
  1614.                 Uri ruri = xmlResolver.ResolveUri(sourceUri, url);
  1615.                 Stream stm = (Stream)xmlResolver.GetEntity(ruri, null, null);
  1616.                 XmlReaderSettings readerSettings = schemaSet.ReaderSettings;
  1617.                 readerSettings.CloseInput = true;
  1618.                 readerSettings.XmlResolver = xmlResolver;
  1619.                 Reader = XmlReader.Create(stm, readerSettings, ruri.ToString());
  1620.                 schemaSet.Add(uri, Reader, validatedNamespaces);
  1621.                 while (Reader.Read())
  1622.                     ;
  1623.                 // wellformness check
  1624.             }
  1625.             catch (XmlSchemaException e) {
  1626.                 SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, e);
  1627.             }
  1628.             catch (Exception e) {
  1629.                 SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, e, XmlSeverityType.Warning);
  1630.             }
  1631.             finally {
  1632.                 if (Reader != null) {
  1633.                     Reader.Close();
  1634.                 }
  1635.             }
  1636.         }
  1637.        
  1638.        
  1639.         internal void RecompileSchemaSet()
  1640.         {
  1641.             if (!schemaSet.IsCompiled) {
  1642.                 try {
  1643.                     schemaSet.Compile();
  1644.                 }
  1645.                 catch (XmlSchemaException e) {
  1646.                     SendValidationEvent(e);
  1647.                 }
  1648.             }
  1649.             compiledSchemaInfo = schemaSet.CompiledInfo;
  1650.             //Fetch compiled info from set
  1651.         }
  1652.        
  1653.         private void ProcessTokenizedType(XmlTokenizedType ttype, string name, bool attrValue)
  1654.         {
  1655.             switch (ttype) {
  1656.                 case XmlTokenizedType.ID:
  1657.                     if (ProcessIdentityConstraints) {
  1658.                         if (FindId(name) != null) {
  1659.                             if (attrValue) {
  1660.                                 attrValid = false;
  1661.                             }
  1662.                             SendValidationEvent(Res.Sch_DupId, name);
  1663.                         }
  1664.                         else {
  1665.                             if (IDs == null) {
  1666.                                 //ADD ID
  1667.                                 IDs = new Hashtable();
  1668.                             }
  1669.                             IDs.Add(name, context.LocalName);
  1670.                         }
  1671.                     }
  1672.                     break;
  1673.                 case XmlTokenizedType.IDREF:
  1674.                     if (ProcessIdentityConstraints) {
  1675.                         object p = FindId(name);
  1676.                         if (p == null) {
  1677.                             // add it to linked list to check it later
  1678.                             idRefListHead = new IdRefNode(idRefListHead, name, positionInfo.LineNumber, positionInfo.LinePosition);
  1679.                         }
  1680.                     }
  1681.                     break;
  1682.                 case XmlTokenizedType.ENTITY:
  1683.                     ProcessEntity(name);
  1684.                     break;
  1685.                 default:
  1686.                     break;
  1687.             }
  1688.         }
  1689.        
  1690.         private object CheckAttributeValue(object value, SchemaAttDef attdef)
  1691.         {
  1692.             object typedValue = null;
  1693.             SchemaDeclBase decl = attdef as SchemaDeclBase;
  1694.            
  1695.             XmlSchemaDatatype dtype = attdef.Datatype;
  1696.             Debug.Assert(dtype != null);
  1697.             string stringValue = value as string;
  1698.             Exception exception = null;
  1699.            
  1700.             if (stringValue != null) {
  1701.                 //TODO: Combine both ParseValue with same signature in XmlSchemaDatatype
  1702.                 exception = dtype.TryParseValue(stringValue, nameTable, nsResolver, out typedValue);
  1703.                 if (exception != null)
  1704.                     goto Error;
  1705.             }
  1706.             else {
  1707.                 //Calling object ParseValue for checking facets
  1708.                 exception = dtype.TryParseValue(value, nameTable, nsResolver, out typedValue);
  1709.                 if (exception != null)
  1710.                     goto Error;
  1711.             }
  1712.             if (!decl.CheckValue(typedValue)) {
  1713.                 attrValid = false;
  1714.                 SendValidationEvent(Res.Sch_FixedAttributeValue, attdef.Name.ToString());
  1715.             }
  1716.             return typedValue;
  1717.             Error:
  1718.            
  1719.             attrValid = false;
  1720.             if (stringValue == null) {
  1721.                 stringValue = XmlSchemaDatatype.ConcatenatedToString(value);
  1722.             }
  1723.             SendValidationEvent(Res.Sch_AttributeValueDataTypeDetailed, new string[] {attdef.Name.ToString(), stringValue, GetTypeName(decl), exception.Message}, exception);
  1724.             return null;
  1725.         }
  1726.        
  1727.         private object CheckElementValue(string stringValue)
  1728.         {
  1729.             object typedValue = null;
  1730.             SchemaDeclBase decl = context.ElementDecl as SchemaDeclBase;
  1731.            
  1732.             XmlSchemaDatatype dtype = decl.Datatype;
  1733.             Debug.Assert(dtype != null);
  1734.            
  1735.             Exception exception = dtype.TryParseValue(stringValue, nameTable, nsResolver, out typedValue);
  1736.             if (exception != null) {
  1737.                 SendValidationEvent(Res.Sch_ElementValueDataTypeDetailed, new string[] {QNameString(context.LocalName, context.Namespace), stringValue, GetTypeName(decl), exception.Message}, exception);
  1738.                 return null;
  1739.             }
  1740.             if (!decl.CheckValue(typedValue)) {
  1741.                 SendValidationEvent(Res.Sch_FixedElementValue, QNameString(context.LocalName, context.Namespace));
  1742.             }
  1743.             return typedValue;
  1744.         }
  1745.        
  1746.         private void CheckTokenizedTypes(XmlSchemaDatatype dtype, object typedValue, bool attrValue)
  1747.         {
  1748.             // Check special types
  1749.             if (typedValue == null) {
  1750.                 return;
  1751.             }
  1752.             XmlTokenizedType ttype = dtype.TokenizedType;
  1753.             if (ttype == XmlTokenizedType.ENTITY || ttype == XmlTokenizedType.ID || ttype == XmlTokenizedType.IDREF) {
  1754.                 if (dtype.Variety == XmlSchemaDatatypeVariety.List) {
  1755.                     string[] ss = (string[])typedValue;
  1756.                     foreach (string s in ss) {
  1757.                         ProcessTokenizedType(dtype.TokenizedType, s, attrValue);
  1758.                     }
  1759.                 }
  1760.                 else {
  1761.                     ProcessTokenizedType(dtype.TokenizedType, (string)typedValue, attrValue);
  1762.                 }
  1763.             }
  1764.         }
  1765.        
  1766.         private object FindId(string name)
  1767.         {
  1768.             return IDs == null ? null : IDs[name];
  1769.         }
  1770.        
  1771.         private void CheckForwardRefs()
  1772.         {
  1773.             IdRefNode next = idRefListHead;
  1774.             while (next != null) {
  1775.                 if (FindId(next.Id) == null) {
  1776.                     SendValidationEvent(new XmlSchemaValidationException(Res.Sch_UndeclaredId, next.Id, this.sourceUriString, next.LineNo, next.LinePos), XmlSeverityType.Error);
  1777.                 }
  1778.                 IdRefNode ptr = next.Next;
  1779.                 next.Next = null;
  1780.                 // unhook each object so it is cleaned up by Garbage Collector
  1781.                 next = ptr;
  1782.             }
  1783.             // not needed any more.
  1784.             idRefListHead = null;
  1785.         }
  1786.        
  1787.        
  1788.         private bool HasIdentityConstraints {
  1789.             get { return ProcessIdentityConstraints && startIDConstraint != -1; }
  1790.         }
  1791.        
  1792.         internal bool ProcessIdentityConstraints {
  1793.             get { return (validationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) != 0; }
  1794.         }
  1795.        
  1796.         internal bool ReportValidationWarnings {
  1797.             get { return (validationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) != 0; }
  1798.         }
  1799.        
  1800.         internal bool ProcessInlineSchema {
  1801.             get { return (validationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0; }
  1802.         }
  1803.        
  1804.         internal bool ProcessSchemaLocation {
  1805.             get { return (validationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0; }
  1806.         }
  1807.        
  1808.         internal bool ProcessSchemaHints {
  1809.             get { return (validationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0 || (validationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0; }
  1810.         }
  1811.        
  1812.         private void CheckStateTransition(ValidatorState toState, string methodName)
  1813.         {
  1814.             if (!ValidStates[(int)currentState, (int)toState]) {
  1815.                 if (currentState == ValidatorState.None) {
  1816.                     throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidStartTransition, new string[] {methodName, MethodNames[(int)ValidatorState.Start]}));
  1817.                 }
  1818.                 throw new InvalidOperationException(Res.GetString(Res.Sch_InvalidStateTransition, new string[] {MethodNames[(int)currentState], methodName}));
  1819.             }
  1820.             currentState = toState;
  1821.         }
  1822.        
  1823.         private void ClearPSVI()
  1824.         {
  1825.             if (textValue != null) {
  1826.                 textValue.Length = 0;
  1827.             }
  1828.             attPresence.Clear();
  1829.             //Clear attributes hashtable for every element
  1830.             wildID = null;
  1831.             //clear it for every element
  1832.         }
  1833.        
  1834.         private void CheckRequiredAttributes(SchemaElementDecl currentElementDecl)
  1835.         {
  1836.             Debug.Assert(currentElementDecl != null);
  1837.             Hashtable attributeDefs = currentElementDecl.AttDefs;
  1838.             foreach (SchemaAttDef attdef in attributeDefs.Values) {
  1839.                 if (attPresence[attdef.Name] == null) {
  1840.                     if (attdef.Presence == SchemaDeclBase.Use.Required || attdef.Presence == SchemaDeclBase.Use.RequiredFixed) {
  1841.                         SendValidationEvent(Res.Sch_MissRequiredAttribute, attdef.Name.ToString());
  1842.                     }
  1843.                 }
  1844.             }
  1845.         }
  1846.        
  1847.         private XmlSchemaElement GetSchemaElement()
  1848.         {
  1849.             SchemaElementDecl beforeXsiDecl = context.ElementDeclBeforeXsi;
  1850.             SchemaElementDecl currentDecl = context.ElementDecl;
  1851.            
  1852.             if (beforeXsiDecl != null) {
  1853.                 //Have a xsi:type
  1854.                 if (beforeXsiDecl.SchemaElement != null) {
  1855.                     XmlSchemaElement xsiElement = (XmlSchemaElement)beforeXsiDecl.SchemaElement.Clone();
  1856.                     xsiElement.SchemaTypeName = XmlQualifiedName.Empty;
  1857.                     //Reset typeName on element as this might be different
  1858.                     xsiElement.SchemaType = currentDecl.SchemaType;
  1859.                     xsiElement.SetElementType(currentDecl.SchemaType);
  1860.                     xsiElement.ElementDecl = currentDecl;
  1861.                     return xsiElement;
  1862.                 }
  1863.             }
  1864.             return currentDecl.SchemaElement;
  1865.         }
  1866.        
  1867.         internal string GetDefaultAttributePrefix(string attributeNS)
  1868.         {
  1869.             IDictionary<string, string> namespaceDecls = nsResolver.GetNamespacesInScope(XmlNamespaceScope.All);
  1870.             string defaultPrefix = null;
  1871.             string defaultNS;
  1872.            
  1873.             foreach (KeyValuePair<string, string> pair in namespaceDecls) {
  1874.                 defaultNS = nameTable.Add(pair.Value);
  1875.                 if (Ref.Equal(defaultNS, attributeNS)) {
  1876.                     defaultPrefix = pair.Key;
  1877.                     if (defaultPrefix.Length != 0) {
  1878.                         //Locate first non-empty prefix
  1879.                         return defaultPrefix;
  1880.                     }
  1881.                 }
  1882.             }
  1883.             return defaultPrefix;
  1884.         }
  1885.        
  1886.         private void AddIdentityConstraints()
  1887.         {
  1888.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  1889.             context.Constr = new ConstraintStruct[currentElementDecl.Constraints.Length];
  1890.             int id = 0;
  1891.             foreach (CompiledIdentityConstraint constraint in currentElementDecl.Constraints) {
  1892.                 context.Constr[id++] = new ConstraintStruct(constraint);
  1893.             }
  1894.             // foreach constraint /constraintstruct
  1895.             // added on June 19, make connections between new keyref tables with key/unique tables in stack
  1896.             // i can't put it in the above loop, coz there will be key on the same level
  1897.             foreach (ConstraintStruct keyrefconstr in context.Constr) {
  1898.                 if (keyrefconstr.constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) {
  1899.                     bool find = false;
  1900.                     // go upwards checking or only in this level
  1901.                     for (int level = this.validationStack.Length - 1; level >= ((this.startIDConstraint >= 0) ? this.startIDConstraint : this.validationStack.Length - 1); level--) {
  1902.                         // no constraint for this level
  1903.                         if (((ValidationState)(this.validationStack[level])).Constr == null) {
  1904.                             continue;
  1905.                         }
  1906.                         // else
  1907.                         foreach (ConstraintStruct constr in ((ValidationState)(this.validationStack[level])).Constr) {
  1908.                             if (constr.constraint.name == keyrefconstr.constraint.refer) {
  1909.                                 find = true;
  1910.                                 if (constr.keyrefTable == null) {
  1911.                                     constr.keyrefTable = new Hashtable();
  1912.                                 }
  1913.                                 keyrefconstr.qualifiedTable = constr.keyrefTable;
  1914.                                 break;
  1915.                             }
  1916.                         }
  1917.                        
  1918.                         if (find) {
  1919.                             break;
  1920.                         }
  1921.                     }
  1922.                     if (!find) {
  1923.                         // didn't find connections, throw exceptions
  1924.                         SendValidationEvent(Res.Sch_RefNotInScope, QNameString(context.LocalName, context.Namespace));
  1925.                     }
  1926.                 }
  1927.                 // finished dealing with keyref
  1928.             }
  1929.             // end foreach
  1930.             // initial set
  1931.             if (this.startIDConstraint == -1) {
  1932.                 this.startIDConstraint = this.validationStack.Length - 1;
  1933.             }
  1934.         }
  1935.        
  1936.         private void ElementIdentityConstraints()
  1937.         {
  1938.             SchemaElementDecl currentElementDecl = context.ElementDecl;
  1939.             string localName = context.LocalName;
  1940.             string namespaceUri = context.Namespace;
  1941.            
  1942.             for (int i = this.startIDConstraint; i < this.validationStack.Length; i++) {
  1943.                 // no constraint for this level
  1944.                 if (((ValidationState)(this.validationStack[i])).Constr == null) {
  1945.                     continue;
  1946.                 }
  1947.                
  1948.                 // else
  1949.                 foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[i])).Constr) {
  1950.                     // check selector from here
  1951.                     if (conuct.axisSelector.MoveToStartElement(localName, namespaceUri)) {
  1952.                         // selector selects new node, activate a new set of fields
  1953.                         Debug.WriteLine("Selector Match!");
  1954.                         Debug.WriteLine("Name: " + localName + "\t|\tURI: " + namespaceUri + "\n");
  1955.                        
  1956.                         // in which axisFields got updated
  1957.                         conuct.axisSelector.PushKS(positionInfo.LineNumber, positionInfo.LinePosition);
  1958.                     }
  1959.                    
  1960.                     // axisFields is not null, but may be empty
  1961.                     foreach (LocatedActiveAxis laxis in conuct.axisFields) {
  1962.                         // check field from here
  1963.                         if (laxis.MoveToStartElement(localName, namespaceUri)) {
  1964.                             Debug.WriteLine("Element Field Match!");
  1965.                             // checking simpleType / simpleContent
  1966.                             if (currentElementDecl != null) {
  1967.                                 // nextElement can be null when xml/xsd are not valid
  1968.                                 if (currentElementDecl.Datatype == null || currentElementDecl.ContentValidator.ContentType == XmlSchemaContentType.Mixed) {
  1969.                                     SendValidationEvent(Res.Sch_FieldSimpleTypeExpected, localName);
  1970.                                 }
  1971.                                 else {
  1972.                                     // can't fill value here, wait till later....
  1973.                                     // fill type : xsdType
  1974.                                     laxis.isMatched = true;
  1975.                                     // since it's simpletyped element, the endchildren will come consequently... don't worry
  1976.                                 }
  1977.                             }
  1978.                         }
  1979.                     }
  1980.                    
  1981.                 }
  1982.             }
  1983.         }
  1984.        
  1985.         private void AttributeIdentityConstraints(string name, string ns, object obj, string sobj, XmlSchemaDatatype datatype)
  1986.         {
  1987.             for (int ci = this.startIDConstraint; ci < this.validationStack.Length; ci++) {
  1988.                 // no constraint for this level
  1989.                 if (((ValidationState)(this.validationStack[ci])).Constr == null) {
  1990.                     continue;
  1991.                 }
  1992.                
  1993.                 // else
  1994.                 foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[ci])).Constr) {
  1995.                     // axisFields is not null, but may be empty
  1996.                     foreach (LocatedActiveAxis laxis in conuct.axisFields) {
  1997.                         // check field from here
  1998.                         if (laxis.MoveToAttribute(name, ns)) {
  1999.                             Debug.WriteLine("Attribute Field Match!");
  2000.                             //attribute is only simpletype, so needn't checking...
  2001.                             // can fill value here, yeah!!
  2002.                             Debug.WriteLine("Attribute Field Filling Value!");
  2003.                             Debug.WriteLine("Name: " + name + "\t|\tURI: " + ns + "\t|\tValue: " + obj + "\n");
  2004.                             if (laxis.Ks[laxis.Column] != null) {
  2005.                                 // should be evaluated to either an empty node-set or a node-set with exactly one member
  2006.                                 // two matches...
  2007.                                 SendValidationEvent(Res.Sch_FieldSingleValueExpected, name);
  2008.                             }
  2009.                             else {
  2010.                                 Debug.Assert(datatype != null);
  2011.                                 laxis.Ks[laxis.Column] = new TypedObject(obj, sobj, datatype);
  2012.                             }
  2013.                         }
  2014.                     }
  2015.                 }
  2016.             }
  2017.         }
  2018.        
  2019.         private void EndElementIdentityConstraints(object typedValue, string stringValue, XmlSchemaDatatype datatype)
  2020.         {
  2021.             string localName = context.LocalName;
  2022.             string namespaceUri = context.Namespace;
  2023.             for (int ci = this.validationStack.Length - 1; ci >= this.startIDConstraint; ci--) {
  2024.                 // no constraint for this level
  2025.                 if (((ValidationState)(this.validationStack[ci])).Constr == null) {
  2026.                     continue;
  2027.                 }
  2028.                
  2029.                 // else
  2030.                 foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[ci])).Constr) {
  2031.                     // EndChildren
  2032.                     // axisFields is not null, but may be empty
  2033.                     foreach (LocatedActiveAxis laxis in conuct.axisFields) {
  2034.                         // check field from here
  2035.                         // isMatched is false when nextElement is null. so needn't change this part.
  2036.                         if (laxis.isMatched) {
  2037.                             Debug.WriteLine("Element Field Filling Value!");
  2038.                             Debug.WriteLine("Name: " + localName + "\t|\tURI: " + namespaceUri + "\t|\tValue: " + typedValue + "\n");
  2039.                             // fill value
  2040.                             laxis.isMatched = false;
  2041.                             if (laxis.Ks[laxis.Column] != null) {
  2042.                                 // [field...] should be evaluated to either an empty node-set or a node-set with exactly one member
  2043.                                 // two matches... already existing field value in the table.
  2044.                                 SendValidationEvent(Res.Sch_FieldSingleValueExpected, localName);
  2045.                             }
  2046.                             else {
  2047.                                 // for element, Reader.Value = "";
  2048.                                 if (typedValue != null && stringValue.Length != 0) {
  2049.                                     laxis.Ks[laxis.Column] = new TypedObject(typedValue, stringValue, datatype);
  2050.                                 }
  2051.                             }
  2052.                         }
  2053.                         // EndChildren
  2054.                         laxis.EndElement(localName, namespaceUri);
  2055.                     }
  2056.                    
  2057.                     if (conuct.axisSelector.EndElement(localName, namespaceUri)) {
  2058.                         // insert key sequence into hash (+ located active axis tuple leave for later)
  2059.                         KeySequence ks = conuct.axisSelector.PopKS();
  2060.                         // unqualified keysequence are not allowed
  2061.                         switch (conuct.constraint.Role) {
  2062.                             case CompiledIdentityConstraint.ConstraintRole.Key:
  2063.                                 if (!ks.IsQualified()) {
  2064.                                     //Key's fields can't be null... if we can return context node's line info maybe it will be better
  2065.                                     //only keymissing & keyduplicate reporting cases are necessary to be dealt with... 3 places...
  2066.                                     SendValidationEvent(new XmlSchemaValidationException(Res.Sch_MissingKey, conuct.constraint.name.ToString(), sourceUriString, ks.PosLine, ks.PosCol));
  2067.                                 }
  2068.                                 else if (conuct.qualifiedTable.Contains(ks)) {
  2069.                                     SendValidationEvent(new XmlSchemaValidationException(Res.Sch_DuplicateKey, new string[2] {ks.ToString(), conuct.constraint.name.ToString()}, sourceUriString, ks.PosLine, ks.PosCol));
  2070.                                 }
  2071.                                 else {
  2072.                                     conuct.qualifiedTable.Add(ks, ks);
  2073.                                 }
  2074.                                 break;
  2075.                             case CompiledIdentityConstraint.ConstraintRole.Unique:
  2076.                                
  2077.                                 if (!ks.IsQualified()) {
  2078.                                     continue;
  2079.                                 }
  2080.                                 if (conuct.qualifiedTable.Contains(ks)) {
  2081.                                     // unique or key checking confliction
  2082.                                     // KeySequence ks2 = (KeySequence) conuct.qualifiedTable[ks];
  2083.                                     SendValidationEvent(new XmlSchemaValidationException(Res.Sch_DuplicateKey, new string[2] {ks.ToString(), conuct.constraint.name.ToString()}, sourceUriString, ks.PosLine, ks.PosCol));
  2084.                                 }
  2085.                                 else {
  2086.                                     conuct.qualifiedTable.Add(ks, ks);
  2087.                                 }
  2088.                                 break;
  2089.                             case CompiledIdentityConstraint.ConstraintRole.Keyref:
  2090.                                 // is there any possibility:
  2091.                                 // 2 keyrefs: value is equal, type is not
  2092.                                 // both put in the hashtable, 1 reference, 1 not
  2093.                                 if (conuct.qualifiedTable != null) {
  2094.                                     //Will be null in cases when the keyref is outside the scope of the key, that is not allowed by our impl
  2095.                                     if (!ks.IsQualified() || conuct.qualifiedTable.Contains(ks)) {
  2096.                                         continue;
  2097.                                     }
  2098.                                     conuct.qualifiedTable.Add(ks, ks);
  2099.                                 }
  2100.                                 break;
  2101.                         }
  2102.                     }
  2103.                 }
  2104.             }
  2105.            
  2106.            
  2107.             // current level's constraint struct
  2108.             ConstraintStruct[] vcs = ((ValidationState)(this.validationStack[this.validationStack.Length - 1])).Constr;
  2109.             if (vcs != null) {
  2110.                 // validating all referencing tables...
  2111.                
  2112.                 foreach (ConstraintStruct conuct in vcs) {
  2113.                     if ((conuct.constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) || (conuct.keyrefTable == null)) {
  2114.                         continue;
  2115.                     }
  2116.                     foreach (KeySequence ks in conuct.keyrefTable.Keys) {
  2117.                         if (!conuct.qualifiedTable.Contains(ks)) {
  2118.                             SendValidationEvent(new XmlSchemaValidationException(Res.Sch_UnresolvedKeyref, ks.ToString(), sourceUriString, ks.PosLine, ks.PosCol));
  2119.                         }
  2120.                     }
  2121.                 }
  2122.             }
  2123.            
  2124.         }
  2125.         //End of method
  2126.         private static void BuildXsiAttributes()
  2127.         {
  2128.             if (xsiTypeSO == null) {
  2129.                 //xsi:type attribute
  2130.                 XmlSchemaAttribute tempXsiTypeSO = new XmlSchemaAttribute();
  2131.                 tempXsiTypeSO.Name = "type";
  2132.                 tempXsiTypeSO.SetQualifiedName(new XmlQualifiedName("type", XmlReservedNs.NsXsi));
  2133.                 tempXsiTypeSO.SetAttributeType(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.QName));
  2134.                 Interlocked.CompareExchange<XmlSchemaAttribute>(ref xsiTypeSO, tempXsiTypeSO, null);
  2135.             }
  2136.             if (xsiNilSO == null) {
  2137.                 //xsi:nil
  2138.                 XmlSchemaAttribute tempxsiNilSO = new XmlSchemaAttribute();
  2139.                 tempxsiNilSO.Name = "nil";
  2140.                 tempxsiNilSO.SetQualifiedName(new XmlQualifiedName("nil", XmlReservedNs.NsXsi));
  2141.                 tempxsiNilSO.SetAttributeType(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Boolean));
  2142.                 Interlocked.CompareExchange<XmlSchemaAttribute>(ref xsiNilSO, tempxsiNilSO, null);
  2143.             }
  2144.             if (xsiSLSO == null) {
  2145.                 //xsi:schemaLocation
  2146.                 XmlSchemaSimpleType stringType = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String);
  2147.                 XmlSchemaAttribute tempxsiSLSO = new XmlSchemaAttribute();
  2148.                 tempxsiSLSO.Name = "schemaLocation";
  2149.                 tempxsiSLSO.SetQualifiedName(new XmlQualifiedName("schemaLocation", XmlReservedNs.NsXsi));
  2150.                 tempxsiSLSO.SetAttributeType(stringType);
  2151.                 Interlocked.CompareExchange<XmlSchemaAttribute>(ref xsiSLSO, tempxsiSLSO, null);
  2152.             }
  2153.             if (xsiNoNsSLSO == null) {
  2154.                 XmlSchemaSimpleType stringType = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String);
  2155.                 XmlSchemaAttribute tempxsiNoNsSLSO = new XmlSchemaAttribute();
  2156.                 tempxsiNoNsSLSO.Name = "noNamespaceSchemaLocation";
  2157.                 tempxsiNoNsSLSO.SetQualifiedName(new XmlQualifiedName("noNamespaceSchemaLocation", XmlReservedNs.NsXsi));
  2158.                 tempxsiNoNsSLSO.SetAttributeType(stringType);
  2159.                 Interlocked.CompareExchange<XmlSchemaAttribute>(ref xsiNoNsSLSO, tempxsiNoNsSLSO, null);
  2160.             }
  2161.         }
  2162.        
  2163.         static internal void ElementValidationError(XmlQualifiedName name, ValidationState context, ValidationEventHandler eventHandler, object sender, string sourceUri, int lineNo, int linePos, bool getParticles)
  2164.         {
  2165.             ArrayList names = null;
  2166.             if (context.ElementDecl != null) {
  2167.                 ContentValidator contentValidator = context.ElementDecl.ContentValidator;
  2168.                 XmlSchemaContentType contentType = contentValidator.ContentType;
  2169.                 if (contentType == XmlSchemaContentType.ElementOnly || (contentType == XmlSchemaContentType.Mixed && contentValidator != ContentValidator.Mixed && contentValidator != ContentValidator.Any)) {
  2170.                     Debug.Assert(contentValidator is DfaContentValidator || contentValidator is NfaContentValidator || contentValidator is RangeContentValidator || contentValidator is AllElementsContentValidator);
  2171.                     if (getParticles) {
  2172.                         names = contentValidator.ExpectedParticles(context, false);
  2173.                     }
  2174.                     else {
  2175.                         names = contentValidator.ExpectedElements(context, false);
  2176.                     }
  2177.                    
  2178.                     if (names == null || names.Count == 0) {
  2179.                         if (context.TooComplex) {
  2180.                             SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementContentComplex, new string[] {BuildElementName(context.LocalName, context.Namespace), BuildElementName(name), Res.GetString(Res.Sch_ComplexContentModel)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2181.                         }
  2182.                         else {
  2183.                             SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementContent, new string[] {BuildElementName(context.LocalName, context.Namespace), BuildElementName(name)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2184.                         }
  2185.                     }
  2186.                     else {
  2187.                         Debug.Assert(names.Count > 0);
  2188.                         if (context.TooComplex) {
  2189.                             SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementContentExpectingComplex, new string[] {BuildElementName(context.LocalName, context.Namespace), BuildElementName(name), PrintExpectedElements(names, getParticles), Res.GetString(Res.Sch_ComplexContentModel)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2190.                         }
  2191.                         else {
  2192.                             SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementContentExpecting, new string[] {BuildElementName(context.LocalName, context.Namespace), BuildElementName(name), PrintExpectedElements(names, getParticles)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2193.                         }
  2194.                     }
  2195.                 }
  2196.                 else {
  2197.                     //Base ContentValidator: Empty || TextOnly || Mixed || Any
  2198.                     if (contentType == XmlSchemaContentType.Empty) {
  2199.                         SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementInEmptyEx, new string[] {QNameString(context.LocalName, context.Namespace), name.ToString()}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2200.                     }
  2201.                     else if (!contentValidator.IsOpen) {
  2202.                         SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_InvalidElementInTextOnlyEx, new string[] {QNameString(context.LocalName, context.Namespace), name.ToString()}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2203.                     }
  2204.                 }
  2205.             }
  2206.         }
  2207.        
  2208.         static internal void CompleteValidationError(ValidationState context, ValidationEventHandler eventHandler, object sender, string sourceUri, int lineNo, int linePos, bool getParticles)
  2209.         {
  2210.             ArrayList names = null;
  2211.             if (context.ElementDecl != null) {
  2212.                 if (getParticles) {
  2213.                     names = context.ElementDecl.ContentValidator.ExpectedParticles(context, true);
  2214.                 }
  2215.                 else {
  2216.                     names = context.ElementDecl.ContentValidator.ExpectedElements(context, true);
  2217.                 }
  2218.             }
  2219.             if (names == null || names.Count == 0) {
  2220.                 if (context.TooComplex) {
  2221.                     SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_IncompleteContentComplex, new string[] {BuildElementName(context.LocalName, context.Namespace), Res.GetString(Res.Sch_ComplexContentModel)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2222.                 }
  2223.                 SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_IncompleteContent, BuildElementName(context.LocalName, context.Namespace), sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2224.             }
  2225.             else {
  2226.                 Debug.Assert(names.Count > 0);
  2227.                 if (context.TooComplex) {
  2228.                     SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_IncompleteContentExpectingComplex, new string[] {BuildElementName(context.LocalName, context.Namespace), PrintExpectedElements(names, getParticles), Res.GetString(Res.Sch_ComplexContentModel)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2229.                 }
  2230.                 else {
  2231.                     SendValidationEvent(eventHandler, sender, new XmlSchemaValidationException(Res.Sch_IncompleteContentExpecting, new string[] {BuildElementName(context.LocalName, context.Namespace), PrintExpectedElements(names, getParticles)}, sourceUri, lineNo, linePos), XmlSeverityType.Error);
  2232.                 }
  2233.             }
  2234.         }
  2235.        
  2236.         static internal string PrintExpectedElements(ArrayList expected, bool getParticles)
  2237.         {
  2238.             if (getParticles) {
  2239.                 string ContinuationString = Res.GetString(Res.Sch_ContinuationString, new string[] {" "});
  2240.                 XmlSchemaParticle currentParticle = null;
  2241.                 XmlSchemaParticle nextParticle = null;
  2242.                 XmlQualifiedName currentQName;
  2243.                 ArrayList expectedNames = new ArrayList();
  2244.                 StringBuilder builder = new StringBuilder();
  2245.                
  2246.                 if (expected.Count == 1) {
  2247.                     nextParticle = expected[0] as XmlSchemaParticle;
  2248.                 }
  2249.                 else {
  2250.                     for (int i = 1; i < expected.Count; i++) {
  2251.                         currentParticle = expected[i - 1] as XmlSchemaParticle;
  2252.                         nextParticle = expected[i] as XmlSchemaParticle;
  2253.                         currentQName = currentParticle.GetQualifiedName();
  2254.                         if (currentQName.Namespace != nextParticle.GetQualifiedName().Namespace) {
  2255.                             expectedNames.Add(currentQName);
  2256.                             PrintNamesWithNS(expectedNames, builder);
  2257.                             expectedNames.Clear();
  2258.                             Debug.Assert(builder.Length != 0);
  2259.                             builder.Append(ContinuationString);
  2260.                         }
  2261.                         else {
  2262.                             expectedNames.Add(currentQName);
  2263.                         }
  2264.                     }
  2265.                 }
  2266.                 //Add last one.
  2267.                 expectedNames.Add(nextParticle.GetQualifiedName());
  2268.                 PrintNamesWithNS(expectedNames, builder);
  2269.                
  2270.                 return builder.ToString();
  2271.             }
  2272.             else {
  2273.                 return PrintNames(expected);
  2274.             }
  2275.         }
  2276.        
  2277.         private static string PrintNames(ArrayList expected)
  2278.         {
  2279.             StringBuilder builder = new StringBuilder();
  2280.             builder.Append(Quote);
  2281.             builder.Append(expected[0].ToString());
  2282.             for (int i = 1; i < expected.Count; ++i) {
  2283.                 builder.Append(" ");
  2284.                 builder.Append(expected[i].ToString());
  2285.             }
  2286.             builder.Append(Quote);
  2287.             return builder.ToString();
  2288.         }
  2289.        
  2290.         private static void PrintNamesWithNS(ArrayList expected, StringBuilder builder)
  2291.         {
  2292.             XmlQualifiedName name = null;
  2293.             name = expected[0] as XmlQualifiedName;
  2294.             if (expected.Count == 1) {
  2295.                 //In case of one element in a namespace or any
  2296.                 if (name.Name == "*") {
  2297.                     //Any
  2298.                     EnumerateAny(builder, name.Namespace);
  2299.                 }
  2300.                 else {
  2301.                     if (name.Namespace.Length != 0) {
  2302.                         builder.Append(Res.GetString(Res.Sch_ElementNameAndNamespace, name.Name, name.Namespace));
  2303.                     }
  2304.                     else {
  2305.                         builder.Append(Res.GetString(Res.Sch_ElementName, name.Name));
  2306.                     }
  2307.                 }
  2308.             }
  2309.             else {
  2310.                 bool foundAny = false;
  2311.                 bool first = true;
  2312.                 StringBuilder subBuilder = new StringBuilder();
  2313.                 for (int i = 0; i < expected.Count; i++) {
  2314.                     name = expected[i] as XmlQualifiedName;
  2315.                     if (name.Name == "*") {
  2316.                         //rare case where ns of element and that of Any match
  2317.                         foundAny = true;
  2318.                         continue;
  2319.                     }
  2320.                     if (first) {
  2321.                         first = false;
  2322.                     }
  2323.                     else {
  2324.                         subBuilder.Append(", ");
  2325.                     }
  2326.                     subBuilder.Append(name.Name);
  2327.                 }
  2328.                 if (foundAny) {
  2329.                     subBuilder.Append(", ");
  2330.                     subBuilder.Append(Res.GetString(Res.Sch_AnyElement));
  2331.                 }
  2332.                 else {
  2333.                     if (name.Namespace.Length != 0) {
  2334.                         builder.Append(Res.GetString(Res.Sch_ElementNameAndNamespace, subBuilder.ToString(), name.Namespace));
  2335.                     }
  2336.                     else {
  2337.                         builder.Append(Res.GetString(Res.Sch_ElementName, subBuilder.ToString()));
  2338.                     }
  2339.                 }
  2340.             }
  2341.         }
  2342.        
  2343.         private static void EnumerateAny(StringBuilder builder, string namespaces)
  2344.         {
  2345.             StringBuilder subBuilder = new StringBuilder();
  2346.             if (namespaces == "##any" || namespaces == "##other") {
  2347.                 subBuilder.Append(namespaces);
  2348.             }
  2349.             else {
  2350.                 string[] nsList = XmlConvert.SplitString(namespaces);
  2351.                 Debug.Assert(nsList.Length > 0);
  2352.                 subBuilder.Append(nsList[0]);
  2353.                 for (int i = 1; i < nsList.Length; i++) {
  2354.                     subBuilder.Append(", ");
  2355.                     subBuilder.Append(nsList[i]);
  2356.                 }
  2357.             }
  2358.             builder.Append(Res.GetString(Res.Sch_AnyElementNS, subBuilder.ToString()));
  2359.         }
  2360.        
  2361.         static internal string QNameString(string localName, string ns)
  2362.         {
  2363.             return (ns.Length != 0) ? string.Concat(ns, ":", localName) : localName;
  2364.         }
  2365.        
  2366.         static internal string BuildElementName(XmlQualifiedName qname)
  2367.         {
  2368.             return BuildElementName(qname.Name, qname.Namespace);
  2369.         }
  2370.        
  2371.         static internal string BuildElementName(string localName, string ns)
  2372.         {
  2373.             if (ns.Length != 0) {
  2374.                 return Res.GetString(Res.Sch_ElementNameAndNamespace, localName, ns);
  2375.             }
  2376.             else {
  2377.                 return Res.GetString(Res.Sch_ElementName, localName);
  2378.             }
  2379.         }
  2380.        
  2381.         private void ProcessEntity(string name)
  2382.         {
  2383.             if (!this.checkEntity) {
  2384.                 return;
  2385.             }
  2386.             SchemaEntity en = null;
  2387.             if (dtdSchemaInfo != null) {
  2388.                 en = (SchemaEntity)dtdSchemaInfo.GeneralEntities[new XmlQualifiedName(name)];
  2389.             }
  2390.             if (en == null) {
  2391.                 // validation error, see xml spec [68]
  2392.                 SendValidationEvent(Res.Sch_UndeclaredEntity, name);
  2393.             }
  2394.             else if (!en.NData.IsEmpty) {
  2395.                 // validation error, see xml spec [68]
  2396.                 SendValidationEvent(Res.Sch_UnparsedEntityRef, name);
  2397.             }
  2398.         }
  2399.        
  2400.         private void SendValidationEvent(string code)
  2401.         {
  2402.             SendValidationEvent(code, string.Empty);
  2403.         }
  2404.        
  2405.         private void SendValidationEvent(string code, string[] args)
  2406.         {
  2407.             SendValidationEvent(new XmlSchemaValidationException(code, args, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition));
  2408.         }
  2409.        
  2410.         private void SendValidationEvent(string code, string arg)
  2411.         {
  2412.             SendValidationEvent(new XmlSchemaValidationException(code, arg, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition));
  2413.         }
  2414.        
  2415.         private void SendValidationEvent(string code, string arg1, string arg2)
  2416.         {
  2417.             SendValidationEvent(new XmlSchemaValidationException(code, new string[] {arg1, arg2}, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition));
  2418.         }
  2419.        
  2420.         private void SendValidationEvent(string code, string[] args, Exception innerException, XmlSeverityType severity)
  2421.         {
  2422.             if (severity != XmlSeverityType.Warning || ReportValidationWarnings) {
  2423.                 SendValidationEvent(new XmlSchemaValidationException(code, args, innerException, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition), severity);
  2424.             }
  2425.         }
  2426.        
  2427.         private void SendValidationEvent(string code, string[] args, Exception innerException)
  2428.         {
  2429.             SendValidationEvent(new XmlSchemaValidationException(code, args, innerException, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition), XmlSeverityType.Error);
  2430.         }
  2431.        
  2432.         private void SendValidationEvent(XmlSchemaValidationException e)
  2433.         {
  2434.             SendValidationEvent(e, XmlSeverityType.Error);
  2435.         }
  2436.        
  2437.         private void SendValidationEvent(XmlSchemaException e)
  2438.         {
  2439.             SendValidationEvent(new XmlSchemaValidationException(e.GetRes, e.Args, e.SourceUri, e.LineNumber, e.LinePosition), XmlSeverityType.Error);
  2440.         }
  2441.        
  2442.         private void SendValidationEvent(string code, string msg, XmlSeverityType severity)
  2443.         {
  2444.             if (severity != XmlSeverityType.Warning || ReportValidationWarnings) {
  2445.                 SendValidationEvent(new XmlSchemaValidationException(code, msg, sourceUriString, positionInfo.LineNumber, positionInfo.LinePosition), severity);
  2446.             }
  2447.         }
  2448.        
  2449.         private void SendValidationEvent(XmlSchemaValidationException e, XmlSeverityType severity)
  2450.         {
  2451.             bool errorSeverity = false;
  2452.             if (severity == XmlSeverityType.Error) {
  2453.                 errorSeverity = true;
  2454.                 context.Validity = XmlSchemaValidity.Invalid;
  2455.             }
  2456.             if (errorSeverity) {
  2457.                 if (eventHandler != null) {
  2458.                     eventHandler(validationEventSender, new ValidationEventArgs(e, severity));
  2459.                 }
  2460.                 else {
  2461.                     throw e;
  2462.                 }
  2463.             }
  2464.             else if (ReportValidationWarnings && eventHandler != null) {
  2465.                 eventHandler(validationEventSender, new ValidationEventArgs(e, severity));
  2466.             }
  2467.         }
  2468.        
  2469.         static internal void SendValidationEvent(ValidationEventHandler eventHandler, object sender, XmlSchemaValidationException e, XmlSeverityType severity)
  2470.         {
  2471.             if (eventHandler != null) {
  2472.                 eventHandler(sender, new ValidationEventArgs(e, severity));
  2473.             }
  2474.             else if (severity == XmlSeverityType.Error) {
  2475.                 throw e;
  2476.             }
  2477.         }
  2478.     }
  2479.     //End of class
  2480. }
  2481. //End of namespace

Developer Fusion