Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / schema / xsdvalidator.cs / 1 / xsdvalidator.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Schema { using System.Collections; using System.Collections.Specialized; using System.Text; using System.IO; using System.Diagnostics; using System.Xml.Schema; using System.Xml.XPath; #pragma warning disable 618 internal sealed class XsdValidator : BaseValidator { private int startIDConstraint = -1; private const int STACK_INCREMENT = 10; private HWStack validationStack; // validaton contexts private Hashtable attPresence; private XmlNamespaceManager nsManager; private bool bManageNamespaces = false; private Hashtable IDs; private IdRefNode idRefListHead; private Parser inlineSchemaParser = null; private XmlSchemaContentProcessing processContents; private static readonly XmlSchemaDatatype dtCDATA = XmlSchemaDatatype.FromXmlTokenizedType(XmlTokenizedType.CDATA); private static readonly XmlSchemaDatatype dtQName = XmlSchemaDatatype.FromXmlTokenizedTypeXsd(XmlTokenizedType.QName); private static readonly XmlSchemaDatatype dtStringArray = dtCDATA.DeriveByList(null); //To avoid SchemaNames creation private string NsXmlNs; private string NsXs; private string NsXsi; private string XsiType; private string XsiNil; private string XsiSchemaLocation; private string XsiNoNamespaceSchemaLocation; private string XsdSchema; internal XsdValidator(BaseValidator validator) : base(validator) { Init(); } internal XsdValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, ValidationEventHandler eventHandler) : base(reader, schemaCollection, eventHandler) { Init(); } private void Init() { nsManager = reader.NamespaceManager; if (nsManager == null) { nsManager = new XmlNamespaceManager(NameTable); bManageNamespaces = true; } validationStack = new HWStack(STACK_INCREMENT); textValue = new StringBuilder(); attPresence = new Hashtable(); schemaInfo = new SchemaInfo (); checkDatatype = false; processContents = XmlSchemaContentProcessing.Strict; Push (XmlQualifiedName.Empty); //Add common strings to be compared to NameTable NsXmlNs = NameTable.Add(XmlReservedNs.NsXmlNs); NsXs = NameTable.Add(XmlReservedNs.NsXs); NsXsi = NameTable.Add(XmlReservedNs.NsXsi); XsiType = NameTable.Add("type"); XsiNil = NameTable.Add("nil"); XsiSchemaLocation = NameTable.Add("schemaLocation"); XsiNoNamespaceSchemaLocation = NameTable.Add("noNamespaceSchemaLocation"); XsdSchema = NameTable.Add("schema"); } public override void Validate() { if (IsInlineSchemaStarted) { ProcessInlineSchema(); } else { switch (reader.NodeType) { case XmlNodeType.Element: ValidateElement(); if (reader.IsEmptyElement) { goto case XmlNodeType.EndElement; } break; case XmlNodeType.Whitespace: ValidateWhitespace(); break; case XmlNodeType.Text: // text inside a node case XmlNodeType.CDATA: // case XmlNodeType.SignificantWhitespace: ValidateText(); break; case XmlNodeType.EndElement: ValidateEndElement(); break; } } } public override void CompleteValidation() { CheckForwardRefs(); } //for frag validation public ValidationState Context{ set { context = value; } } //share for frag validation public static XmlSchemaDatatype DtQName { get { return dtQName; } } private bool IsInlineSchemaStarted { get { return inlineSchemaParser != null; } } private void ProcessInlineSchema() { if (!inlineSchemaParser.ParseReaderNode()) { // Done inlineSchemaParser.FinishParsing(); XmlSchema schema = inlineSchemaParser.XmlSchema; string inlineNS = null; if (schema != null && schema.ErrorCount == 0) { try { SchemaInfo inlineSchemaInfo = new SchemaInfo(); inlineSchemaInfo.SchemaType = SchemaType.XSD; inlineNS = schema.TargetNamespace == null? string.Empty : schema.TargetNamespace; if (!SchemaInfo.TargetNamespaces.Contains(inlineNS)) { if (SchemaCollection.Add(inlineNS, inlineSchemaInfo, schema, true) != null) { //If no errors on compile //Add to validator's SchemaInfo SchemaInfo.Add(inlineSchemaInfo, EventHandler); } } } catch(XmlSchemaException e) { SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {BaseUri.AbsoluteUri, e.Message}, XmlSeverityType.Error); } } inlineSchemaParser = null; } } private void ValidateElement() { elementName.Init(reader.LocalName, reader.NamespaceURI); object particle = ValidateChildElement (); if (IsXSDRoot(elementName.Name, elementName.Namespace) && reader.Depth > 0) { inlineSchemaParser = new Parser(SchemaType.XSD, NameTable, SchemaNames, EventHandler); inlineSchemaParser.StartParsing(reader, null); inlineSchemaParser.ParseReaderNode(); } else { ProcessElement(particle); } } private object ValidateChildElement() { object particle = null; int errorCode = 0; if (context.NeedValidateChildren) { if (context.IsNill) { SendValidationEvent(Res.Sch_ContentInNill, elementName.ToString()); return null; } particle = context.ElementDecl.ContentValidator.ValidateElement(elementName, context, out errorCode); if (particle == null) { processContents = context.ProcessContents = XmlSchemaContentProcessing.Skip; if (errorCode == -2) { //ContentModel all group error SendValidationEvent(Res.Sch_AllElement, elementName.ToString()); } XmlSchemaValidator.ElementValidationError(elementName, context, EventHandler, reader, reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition, false); } } return particle; } private void ProcessElement(object particle) { XmlQualifiedName xsiType; string xsiNil; SchemaElementDecl elementDecl = FastGetElementDecl (particle); Push(elementName); if (bManageNamespaces) { nsManager.PushScope(); } ProcessXsiAttributes(out xsiType, out xsiNil); if (processContents != XmlSchemaContentProcessing.Skip) { if (elementDecl == null || !xsiType.IsEmpty || xsiNil != null) { elementDecl = ThoroughGetElementDecl(elementDecl, xsiType, xsiNil); } if (elementDecl == null) { if (HasSchema && processContents == XmlSchemaContentProcessing.Strict) { SendValidationEvent(Res.Sch_UndeclaredElement, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } else { SendValidationEvent(Res.Sch_NoElementSchemaFound, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace), XmlSeverityType.Warning); } } } context.ElementDecl = elementDecl; ValidateStartElementIdentityConstraints(); ValidateStartElement(); if (context.ElementDecl != null) { ValidateEndStartElement(); context.NeedValidateChildren = processContents != XmlSchemaContentProcessing.Skip; context.ElementDecl.ContentValidator.InitValidation(context); } } private void ProcessXsiAttributes(out XmlQualifiedName xsiType, out string xsiNil) { string[] xsiSchemaLocation = null; string xsiNoNamespaceSchemaLocation = null; xsiType = XmlQualifiedName.Empty; xsiNil = null; if (reader.Depth == 0) { //Load schema for empty namespace LoadSchema(string.Empty, null); //Should load schemas for namespaces already added to nsManager foreach(string ns in nsManager.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml).Values) { LoadSchema(ns, null); } } if (reader.MoveToFirstAttribute()) { do { string objectNs = reader.NamespaceURI; string objectName = reader.LocalName; if (Ref.Equal(objectNs, NsXmlNs)) { LoadSchema(reader.Value, null); if (bManageNamespaces) { nsManager.AddNamespace(reader.Prefix.Length == 0 ? string.Empty : reader.LocalName, reader.Value); } } else if (Ref.Equal(objectNs, NsXsi)) { if (Ref.Equal(objectName, XsiSchemaLocation)) { xsiSchemaLocation = (string[])dtStringArray.ParseValue(reader.Value, NameTable, nsManager); } else if (Ref.Equal(objectName, XsiNoNamespaceSchemaLocation)) { xsiNoNamespaceSchemaLocation = reader.Value; } else if (Ref.Equal(objectName, XsiType)) { xsiType = (XmlQualifiedName)dtQName.ParseValue(reader.Value, NameTable, nsManager); } else if (Ref.Equal(objectName, XsiNil)) { xsiNil = reader.Value; } } } while(reader.MoveToNextAttribute()); reader.MoveToElement(); } if (xsiNoNamespaceSchemaLocation != null) { LoadSchema(string.Empty, xsiNoNamespaceSchemaLocation); } if (xsiSchemaLocation != null) { for (int i = 0; i < xsiSchemaLocation.Length - 1; i += 2) { LoadSchema((string)xsiSchemaLocation[i], (string)xsiSchemaLocation[i + 1]); } } } private void ValidateEndElement() { if (bManageNamespaces) { nsManager.PopScope(); } if (context.ElementDecl != null) { if (!context.IsNill) { if (context.NeedValidateChildren) { if(!context.ElementDecl.ContentValidator.CompleteValidation(context)) { XmlSchemaValidator.CompleteValidationError(context, EventHandler, reader, reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition, false); } } if (checkDatatype && !context.IsNill) { string stringValue = !hasSibling ? textString : textValue.ToString(); // only for identity-constraint exception reporting if(!(stringValue.Length == 0 && context.ElementDecl.DefaultValueTyped != null)) { CheckValue(stringValue, null); checkDatatype = false; } } } // for each level in the stack, endchildren and fill value from element if (HasIdentityConstraints) { EndElementIdentityConstraints(); } } Pop(); } private SchemaElementDecl FastGetElementDecl(object particle) { SchemaElementDecl elementDecl = null; if (particle != null) { XmlSchemaElement element = particle as XmlSchemaElement; if (element != null) { elementDecl = element.ElementDecl; } else { XmlSchemaAny any = (XmlSchemaAny)particle; processContents = any.ProcessContentsCorrect; } } return elementDecl; } private SchemaElementDecl ThoroughGetElementDecl(SchemaElementDecl elementDecl, XmlQualifiedName xsiType, string xsiNil) { if (elementDecl == null) { elementDecl = schemaInfo.GetElementDecl(elementName); } if (elementDecl != null) { if (xsiType.IsEmpty) { if (elementDecl.IsAbstract) { SendValidationEvent(Res.Sch_AbstractElement, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); elementDecl = null; } } else if(xsiNil != null && xsiNil.Equals("true")) { SendValidationEvent(Res.Sch_XsiNilAndType); } else { SchemaElementDecl elementDeclXsi = (SchemaElementDecl)schemaInfo.ElementDeclsByType[xsiType]; if (elementDeclXsi == null && xsiType.Namespace == NsXs) { XmlSchemaSimpleType simpleType = DatatypeImplementation.GetSimpleTypeFromXsdType(new XmlQualifiedName(xsiType.Name,NsXs)); if (simpleType != null) { elementDeclXsi = simpleType.ElementDecl; } } if (elementDeclXsi == null) { SendValidationEvent(Res.Sch_XsiTypeNotFound, xsiType.ToString()); elementDecl = null; } else if (!XmlSchemaType.IsDerivedFrom(elementDeclXsi.SchemaType,elementDecl.SchemaType,elementDecl.Block)) { SendValidationEvent(Res.Sch_XsiTypeBlockedEx, new string[] { xsiType.ToString(), XmlSchemaValidator.QNameString(context.LocalName, context.Namespace) }); elementDecl = null; } else { elementDecl = elementDeclXsi; } } if (elementDecl != null && elementDecl.IsNillable) { if (xsiNil != null) { context.IsNill = XmlConvert.ToBoolean(xsiNil); if (context.IsNill && elementDecl.DefaultValueTyped != null) { SendValidationEvent(Res.Sch_XsiNilAndFixed); } } } else if (xsiNil != null) { SendValidationEvent(Res.Sch_InvalidXsiNill); } } return elementDecl; } private void ValidateStartElement() { if (context.ElementDecl != null) { if (context.ElementDecl.IsAbstract) { SendValidationEvent(Res.Sch_AbstractElement, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } reader.SchemaTypeObject = context.ElementDecl.SchemaType; if (reader.IsEmptyElement && !context.IsNill && context.ElementDecl.DefaultValueTyped != null) { reader.TypedValueObject = UnWrapUnion(context.ElementDecl.DefaultValueTyped); context.IsNill = true; // reusing IsNill } else { reader.TypedValueObject = null; //Typed value cleanup } if (this.context.ElementDecl.HasRequiredAttribute || HasIdentityConstraints) { attPresence.Clear(); } } if (reader.MoveToFirstAttribute()) { do { if ((object)reader.NamespaceURI == (object)NsXmlNs) { continue; } if ((object)reader.NamespaceURI == (object)NsXsi) { continue; } try { reader.SchemaTypeObject = null; XmlQualifiedName attQName = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI); bool skipContents = (processContents == XmlSchemaContentProcessing.Skip); SchemaAttDef attnDef = schemaInfo.GetAttributeXsd(context.ElementDecl, attQName, ref skipContents); if (attnDef != null) { if (context.ElementDecl != null && (context.ElementDecl.HasRequiredAttribute || this.startIDConstraint != -1)) { attPresence.Add(attnDef.Name, attnDef); } Debug.Assert(attnDef.SchemaType != null); reader.SchemaTypeObject = attnDef.SchemaType; if (attnDef.Datatype != null) { // need to check the contents of this attribute to make sure // it is valid according to the specified attribute type. CheckValue(reader.Value, attnDef); } if (HasIdentityConstraints) { AttributeIdentityConstraints(reader.LocalName, reader.NamespaceURI, reader.TypedValueObject, reader.Value, attnDef); } } else if (!skipContents) { if (context.ElementDecl == null && processContents == XmlSchemaContentProcessing.Strict && attQName.Namespace.Length != 0 && schemaInfo.Contains(attQName.Namespace) ) { SendValidationEvent(Res.Sch_UndeclaredAttribute, attQName.ToString()); } else { SendValidationEvent(Res.Sch_NoAttributeSchemaFound, attQName.ToString(), XmlSeverityType.Warning); } } } catch (XmlSchemaException e) { e.SetSource(reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition); SendValidationEvent(e); } } while(reader.MoveToNextAttribute()); reader.MoveToElement(); } } private void ValidateEndStartElement() { if (context.ElementDecl.HasDefaultAttribute) { foreach (SchemaAttDef attdef in context.ElementDecl.DefaultAttDefs) { reader.AddDefaultAttribute(attdef); // even default attribute i have to move to... but can't exist if (HasIdentityConstraints && !attPresence.Contains(attdef.Name)) { AttributeIdentityConstraints(attdef.Name.Name, attdef.Name.Namespace, UnWrapUnion(attdef.DefaultValueTyped), attdef.DefaultValueRaw, attdef); } } } if (context.ElementDecl.HasRequiredAttribute) { try { context.ElementDecl.CheckAttributes(attPresence, reader.StandAlone); } catch (XmlSchemaException e) { e.SetSource(reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition); SendValidationEvent(e); } } if (context.ElementDecl.Datatype != null) { checkDatatype = true; hasSibling = false; textString = string.Empty; textValue.Length = 0; } } private void LoadSchemaFromLocation(string uri, string url) { XmlReader reader = null; SchemaInfo schemaInfo = null; try { Uri ruri = this.XmlResolver.ResolveUri(BaseUri, url); Stream stm = (Stream)this.XmlResolver.GetEntity(ruri,null,null); reader = new XmlTextReader(ruri.ToString(), stm, NameTable); //XmlSchema schema = SchemaCollection.Add(uri, reader, this.XmlResolver); Parser parser = new Parser(SchemaType.XSD, NameTable, SchemaNames, EventHandler); parser.XmlResolver = this.XmlResolver; SchemaType schemaType = parser.Parse(reader, uri); schemaInfo = new SchemaInfo(); schemaInfo.SchemaType = schemaType; if (schemaType == SchemaType.XSD) { if (SchemaCollection.EventHandler == null) { SchemaCollection.EventHandler = this.EventHandler; } SchemaCollection.Add(uri, schemaInfo, parser.XmlSchema, true); } //Add to validator's SchemaInfo SchemaInfo.Add(schemaInfo, EventHandler); while(reader.Read());// wellformness check } catch(XmlSchemaException e) { schemaInfo = null; SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, XmlSeverityType.Error); } catch(Exception e) { schemaInfo = null; SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, XmlSeverityType.Warning); } finally { if (reader != null) { reader.Close(); } } } private void LoadSchema(string uri, string url) { if (this.XmlResolver == null) { return; } if (SchemaInfo.TargetNamespaces.Contains(uri) && nsManager.LookupPrefix(uri) != null) { return; } SchemaInfo schemaInfo = null; if (SchemaCollection != null) schemaInfo = SchemaCollection.GetSchemaInfo(uri); if (schemaInfo != null) { if(schemaInfo.SchemaType != SchemaType.XSD) { throw new XmlException(Res.Xml_MultipleValidaitonTypes, string.Empty, this.PositionInfo.LineNumber, this.PositionInfo.LinePosition); } SchemaInfo.Add(schemaInfo, EventHandler); return; } if (url != null) { LoadSchemaFromLocation(uri, url); } } private bool HasSchema { get { return schemaInfo.SchemaType != SchemaType.None;}} public override bool PreserveWhitespace { get { return context.ElementDecl != null ? context.ElementDecl.ContentValidator.PreserveWhitespace : false; } } void ProcessTokenizedType( XmlTokenizedType ttype, string name ) { switch(ttype) { case XmlTokenizedType.ID: if (FindId(name) != null) { SendValidationEvent(Res.Sch_DupId, name); } else { AddID(name, context.LocalName); } break; case XmlTokenizedType.IDREF: object p = FindId(name); if (p == null) { // add it to linked list to check it later idRefListHead = new IdRefNode(idRefListHead, name, this.PositionInfo.LineNumber, this.PositionInfo.LinePosition); } break; case XmlTokenizedType.ENTITY: ProcessEntity(schemaInfo, name, this, EventHandler, reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition); break; default: break; } } private void CheckValue( string value, SchemaAttDef attdef ) { try { reader.TypedValueObject = null; bool isAttn = attdef != null; XmlSchemaDatatype dtype = isAttn ? attdef.Datatype : context.ElementDecl.Datatype; if (dtype == null) { return; // no reason to check } object typedValue = dtype.ParseValue(value, NameTable, nsManager, true); // Check special types XmlTokenizedType ttype = dtype.TokenizedType; if (ttype == XmlTokenizedType.ENTITY || ttype == XmlTokenizedType.ID || ttype == XmlTokenizedType.IDREF) { if (dtype.Variety == XmlSchemaDatatypeVariety.List) { string[] ss = (string[])typedValue; foreach(string s in ss) { ProcessTokenizedType(dtype.TokenizedType, s); } } else { ProcessTokenizedType(dtype.TokenizedType, (string)typedValue); } } SchemaDeclBase decl = isAttn ? (SchemaDeclBase)attdef : (SchemaDeclBase)context.ElementDecl; if (!decl.CheckValue(typedValue)) { if (isAttn) { SendValidationEvent(Res.Sch_FixedAttributeValue, attdef.Name.ToString()); } else { SendValidationEvent(Res.Sch_FixedElementValue, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } if (dtype.Variety == XmlSchemaDatatypeVariety.Union) { typedValue = UnWrapUnion(typedValue); } reader.TypedValueObject = typedValue; } catch (XmlSchemaException) { if (attdef != null) { SendValidationEvent(Res.Sch_AttributeValueDataType, attdef.Name.ToString()); } else { SendValidationEvent(Res.Sch_ElementValueDataType, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } } internal void AddID(string name, object node) { // Note: It used to be true that we only called this if _fValidate was true, // but due to the fact that you can now dynamically type somethign as an ID // that is no longer true. if (IDs == null) { IDs = new Hashtable(); } IDs.Add(name, node); } public override object FindId(string name) { return IDs == null ? null : IDs[name]; } public bool IsXSDRoot(string localName, string ns) { return Ref.Equal(ns, NsXs) && Ref.Equal(localName, XsdSchema); } private void Push(XmlQualifiedName elementName) { context = (ValidationState)validationStack.Push(); if (context == null) { context = new ValidationState(); validationStack.AddToTop(context); } context.LocalName = elementName.Name; context.Namespace = elementName.Namespace; context.HasMatched = false; context.IsNill = false; context.ProcessContents = processContents; context.NeedValidateChildren = false; context.Constr = null; //resetting the constraints to be null incase context != null // when pushing onto stack; } private void Pop() { if (validationStack.Length > 1) { validationStack.Pop(); if (startIDConstraint == validationStack.Length) { startIDConstraint = -1; } context = (ValidationState)validationStack.Peek(); processContents = context.ProcessContents; } } private void CheckForwardRefs() { IdRefNode next = idRefListHead; while (next != null) { if(FindId(next.Id) == null) { SendValidationEvent(new XmlSchemaException(Res.Sch_UndeclaredId, next.Id, reader.BaseURI, next.LineNo, next.LinePos)); } IdRefNode ptr = next.Next; next.Next = null; // unhook each object so it is cleaned up by Garbage Collector next = ptr; } // not needed any more. idRefListHead = null; } private void ValidateStartElementIdentityConstraints() { // added on June 15, set the context here, so the stack can have them if (context.ElementDecl != null) { if (context.ElementDecl.Constraints != null) { AddIdentityConstraints(); } //foreach constraint in stack (including the current one) if (HasIdentityConstraints) { ElementIdentityConstraints(); } } } private bool HasIdentityConstraints { get { return startIDConstraint != -1; } } private void AddIdentityConstraints() { context.Constr = new ConstraintStruct[context.ElementDecl.Constraints.Length]; int id = 0; foreach (CompiledIdentityConstraint constraint in context.ElementDecl.Constraints) { context.Constr[id++] = new ConstraintStruct (constraint); } // foreach constraint /constraintstruct // added on June 19, make connections between new keyref tables with key/unique tables in stack // i can't put it in the above loop, coz there will be key on the same level foreach (ConstraintStruct keyrefconstr in context.Constr) { if ( keyrefconstr.constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref ) { bool find = false; // go upwards checking or only in this level for (int level = this.validationStack.Length - 1; level >= ((this.startIDConstraint >= 0) ? this.startIDConstraint : this.validationStack.Length - 1); level --) { // no constraint for this level if (((ValidationState)(this.validationStack[level])).Constr == null) { continue; } // else foreach (ConstraintStruct constr in ((ValidationState)(this.validationStack[level])).Constr) { if (constr.constraint.name == keyrefconstr.constraint.refer) { find = true; if (constr.keyrefTable == null) { constr.keyrefTable = new Hashtable(); } keyrefconstr.qualifiedTable = constr.keyrefTable; break; } } if (find) { break; } } if (!find) { // didn't find connections, throw exceptions SendValidationEvent(Res.Sch_RefNotInScope, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } // finished dealing with keyref } // end foreach // initial set if (this.startIDConstraint == -1) { this.startIDConstraint = this.validationStack.Length - 1; } } private void ElementIdentityConstraints () { for (int i = this.startIDConstraint; i < this.validationStack.Length; i ++) { // no constraint for this level if (((ValidationState)(this.validationStack[i])).Constr == null) { continue; } // else foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[i])).Constr) { // check selector from here if (conuct.axisSelector.MoveToStartElement(reader.LocalName, reader.NamespaceURI)) { // selector selects new node, activate a new set of fields Debug.WriteLine("Selector Match!"); Debug.WriteLine("Name: " + reader.LocalName + "\t|\tURI: " + reader.NamespaceURI + "\n"); // in which axisFields got updated conuct.axisSelector.PushKS(PositionInfo.LineNumber, PositionInfo.LinePosition); } // axisFields is not null, but may be empty foreach (LocatedActiveAxis laxis in conuct.axisFields) { // check field from here if (laxis.MoveToStartElement(reader.LocalName, reader.NamespaceURI)) { Debug.WriteLine("Element Field Match!"); // checking simpleType / simpleContent if (context.ElementDecl != null) { // nextElement can be null when xml/xsd are not valid if (context.ElementDecl.Datatype == null) { SendValidationEvent(Res.Sch_FieldSimpleTypeExpected, reader.LocalName); } else { // can't fill value here, wait till later.... // fill type : xsdType laxis.isMatched = true; // since it's simpletyped element, the endchildren will come consequently... don't worry } } } } } } } // facilitate modifying private void AttributeIdentityConstraints(string name, string ns, object obj, string sobj, SchemaAttDef attdef) { for (int ci = this.startIDConstraint; ci < this.validationStack.Length; ci ++) { // no constraint for this level if (((ValidationState)(this.validationStack[ci])).Constr == null) { continue; } // else foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[ci])).Constr) { // axisFields is not null, but may be empty foreach (LocatedActiveAxis laxis in conuct.axisFields) { // check field from here if (laxis.MoveToAttribute(name, ns)) { Debug.WriteLine("Attribute Field Match!"); //attribute is only simpletype, so needn't checking... // can fill value here, yeah!! Debug.WriteLine("Attribute Field Filling Value!"); Debug.WriteLine("Name: " + name + "\t|\tURI: " + ns + "\t|\tValue: " + obj + "\n"); if (laxis.Ks[laxis.Column] != null) { // should be evaluated to either an empty node-set or a node-set with exactly one member // two matches... SendValidationEvent (Res.Sch_FieldSingleValueExpected, name); } else if ((attdef != null) && (attdef.Datatype != null)){ laxis.Ks[laxis.Column] = new TypedObject (obj, sobj, attdef.Datatype); } } } } } } private object UnWrapUnion(object typedValue) { XsdSimpleValue simpleValue = typedValue as XsdSimpleValue; if (simpleValue != null) { typedValue = simpleValue.TypedValue; } return typedValue; } private void EndElementIdentityConstraints() { for (int ci = this.validationStack.Length - 1; ci >= this.startIDConstraint; ci --) { // no constraint for this level if (((ValidationState)(this.validationStack[ci])).Constr == null) { continue; } // else foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[ci])).Constr) { // EndChildren // axisFields is not null, but may be empty foreach (LocatedActiveAxis laxis in conuct.axisFields) { // check field from here // isMatched is false when nextElement is null. so needn't change this part. if (laxis.isMatched) { Debug.WriteLine("Element Field Filling Value!"); Debug.WriteLine("Name: " + reader.LocalName + "\t|\tURI: " + reader.NamespaceURI + "\t|\tValue: " + reader.TypedValueObject + "\n"); // fill value laxis.isMatched = false; if (laxis.Ks[laxis.Column] != null) { // [field...] should be evaluated to either an empty node-set or a node-set with exactly one member // two matches... already existing field value in the table. SendValidationEvent (Res.Sch_FieldSingleValueExpected, reader.LocalName); } else { // for element, reader.Value = ""; string stringValue = !hasSibling ? textString : textValue.ToString(); // only for identity-constraint exception reporting if(reader.TypedValueObject != null && stringValue.Length != 0) { laxis.Ks[laxis.Column] = new TypedObject(reader.TypedValueObject,stringValue,context.ElementDecl.Datatype); } } } // EndChildren laxis.EndElement(reader.LocalName, reader.NamespaceURI); } if (conuct.axisSelector.EndElement(reader.LocalName, reader.NamespaceURI)) { // insert key sequence into hash (+ located active axis tuple leave for later) KeySequence ks = conuct.axisSelector.PopKS(); // unqualified keysequence are not allowed switch (conuct.constraint.Role) { case CompiledIdentityConstraint.ConstraintRole.Key: if (! ks.IsQualified()) { //Key's fields can't be null... if we can return context node's line info maybe it will be better //only keymissing & keyduplicate reporting cases are necessary to be dealt with... 3 places... SendValidationEvent(new XmlSchemaException(Res.Sch_MissingKey, conuct.constraint.name.ToString(), reader.BaseURI, ks.PosLine, ks.PosCol)); } else if (conuct.qualifiedTable.Contains (ks)) { // unique or key checking value confliction // for redundant key, reporting both occurings // doesn't work... how can i retrieve value out?? SendValidationEvent(new XmlSchemaException(Res.Sch_DuplicateKey, new string[2] {ks.ToString(), conuct.constraint.name.ToString()}, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { conuct.qualifiedTable.Add (ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Unique: if (! ks.IsQualified()) { continue; } if (conuct.qualifiedTable.Contains (ks)) { // unique or key checking confliction SendValidationEvent(new XmlSchemaException(Res.Sch_DuplicateKey, new string[2] {ks.ToString(), conuct.constraint.name.ToString()}, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { conuct.qualifiedTable.Add (ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Keyref: // is there any possibility: // 2 keyrefs: value is equal, type is not // both put in the hashtable, 1 reference, 1 not if (conuct.qualifiedTable != null) { //Will be null in cases when the keyref is outside the scope of the key, that is not allowed by our impl if (! ks.IsQualified() || conuct.qualifiedTable.Contains (ks)) { continue; } conuct.qualifiedTable.Add (ks, ks); } break; } } } } // current level's constraint struct ConstraintStruct[] vcs = ((ValidationState)(this.validationStack[this.validationStack.Length - 1])).Constr; if ( vcs != null) { // validating all referencing tables... foreach (ConstraintStruct conuct in vcs) { if (( conuct.constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) || (conuct.keyrefTable == null)) { continue; } foreach (KeySequence ks in conuct.keyrefTable.Keys) { if (! conuct.qualifiedTable.Contains (ks)) { SendValidationEvent(new XmlSchemaException(Res.Sch_UnresolvedKeyref, ks.ToString(), reader.BaseURI, ks.PosLine, ks.PosCol)); } } } } } } #pragma warning restore 618 } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HostProtectionException.cs
- ComponentDispatcher.cs
- ReadOnlyDictionary.cs
- ConnectionPointCookie.cs
- CalendarDayButton.cs
- ItemDragEvent.cs
- TimelineCollection.cs
- CacheHelper.cs
- InvokeMethod.cs
- CollectionChangedEventManager.cs
- ComponentResourceKeyConverter.cs
- XmlTextEncoder.cs
- TextEditorMouse.cs
- XmlElementAttribute.cs
- BaseDataListPage.cs
- NumericUpDown.cs
- TextEmbeddedObject.cs
- CommandField.cs
- QueuedDeliveryRequirementsMode.cs
- SatelliteContractVersionAttribute.cs
- TextTreeNode.cs
- ApplicationFileParser.cs
- XmlTypeMapping.cs
- DragCompletedEventArgs.cs
- IntSecurity.cs
- RegexNode.cs
- CodePropertyReferenceExpression.cs
- SafeRightsManagementQueryHandle.cs
- SByte.cs
- XamlFigureLengthSerializer.cs
- NumericExpr.cs
- SafeRightsManagementHandle.cs
- MimeWriter.cs
- RuntimeUtils.cs
- DecimalStorage.cs
- MailAddressParser.cs
- ScrollPattern.cs
- ScriptingProfileServiceSection.cs
- RadioButtonPopupAdapter.cs
- StagingAreaInputItem.cs
- XmlWellformedWriter.cs
- CellQuery.cs
- BooleanStorage.cs
- Propagator.JoinPropagator.cs
- FunctionImportElement.cs
- ScrollableControlDesigner.cs
- CalendarDay.cs
- StylusPoint.cs
- FileReader.cs
- DataGrid.cs
- ContentDefinition.cs
- _TLSstream.cs
- TypeListConverter.cs
- hresults.cs
- NavigationWindowAutomationPeer.cs
- ApplyImportsAction.cs
- Mouse.cs
- SplitterCancelEvent.cs
- BoundsDrawingContextWalker.cs
- ColorAnimation.cs
- Camera.cs
- Vars.cs
- TiffBitmapDecoder.cs
- filewebrequest.cs
- ComboBoxAutomationPeer.cs
- EncodingTable.cs
- RSACryptoServiceProvider.cs
- CallbackValidator.cs
- ZoomingMessageFilter.cs
- TextEditorCopyPaste.cs
- _AcceptOverlappedAsyncResult.cs
- OdbcConnectionFactory.cs
- XamlInt32CollectionSerializer.cs
- PageTrueTypeFont.cs
- HashLookup.cs
- CapabilitiesAssignment.cs
- RewritingPass.cs
- ColumnWidthChangedEvent.cs
- JsonGlobals.cs
- RepeaterItemCollection.cs
- DecoratedNameAttribute.cs
- ToolboxDataAttribute.cs
- XmlSchemaAnnotation.cs
- URL.cs
- OrderPreservingMergeHelper.cs
- AggregateNode.cs
- DynamicPropertyHolder.cs
- SchemaContext.cs
- MultipartContentParser.cs
- LineServicesCallbacks.cs
- DataServiceClientException.cs
- OleDbParameter.cs
- ConfigsHelper.cs
- PreservationFileWriter.cs
- HtmlGenericControl.cs
- Gdiplus.cs
- DateBoldEvent.cs
- TargetInvocationException.cs
- WindowsServiceElement.cs
- WSTransactionSection.cs