Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / schema / xdrvalidator.cs / 1 / xdrvalidator.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Schema { using System.IO; using System.Text; using System.Collections; using System.Diagnostics; using System.Globalization; #pragma warning disable 618 internal sealed class XdrValidator : BaseValidator { private const int STACK_INCREMENT = 10; private HWStack validationStack; // validaton contexts private Hashtable attPresence; private XmlQualifiedName name = XmlQualifiedName.Empty; private XmlNamespaceManager nsManager; private bool isProcessContents = false; private Hashtable IDs; private IdRefNode idRefListHead; private Parser inlineSchemaParser = null; private const string x_schema = "x-schema:"; internal XdrValidator(BaseValidator validator) : base(validator) { Init(); } internal XdrValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, ValidationEventHandler eventHandler) : base(reader, schemaCollection, eventHandler) { Init(); } private void Init() { nsManager = reader.NamespaceManager; if (nsManager == null) { nsManager = new XmlNamespaceManager(NameTable); isProcessContents = true; } validationStack = new HWStack(STACK_INCREMENT); textValue = new StringBuilder(); name = XmlQualifiedName.Empty; attPresence = new Hashtable(); Push(XmlQualifiedName.Empty); schemaInfo = new SchemaInfo(); checkDatatype = false; } 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; } } } private void ValidateElement() { elementName.Init(reader.LocalName, XmlSchemaDatatype.XdrCanonizeUri(reader.NamespaceURI, NameTable, SchemaNames)); ValidateChildElement(); if (SchemaNames.IsXDRRoot(elementName.Name, elementName.Namespace) && reader.Depth > 0) { inlineSchemaParser = new Parser(SchemaType.XDR, NameTable, SchemaNames, EventHandler); inlineSchemaParser.StartParsing(reader, null); inlineSchemaParser.ParseReaderNode(); } else { ProcessElement(); } } private void ValidateChildElement() { if (context.NeedValidateChildren) { int errorCode = 0; context.ElementDecl.ContentValidator.ValidateElement(elementName, context, out errorCode); if (errorCode < 0) { XmlSchemaValidator.ElementValidationError(elementName, context, EventHandler, reader, reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition, false); } } } private bool IsInlineSchemaStarted { get { return inlineSchemaParser != null; } } private void ProcessInlineSchema() { if (!inlineSchemaParser.ParseReaderNode()) { // Done inlineSchemaParser.FinishParsing(); SchemaInfo xdrSchema = inlineSchemaParser.XdrSchema; if (xdrSchema != null && xdrSchema.ErrorCount == 0) { foreach(string inlineNS in xdrSchema.TargetNamespaces.Keys) { if (!SchemaInfo.HasSchema(inlineNS)) { schemaInfo.Add(xdrSchema, EventHandler); SchemaCollection.Add(inlineNS, xdrSchema, null, false); break; } } } inlineSchemaParser = null; } } private void ProcessElement() { Push(elementName); if (isProcessContents) { nsManager.PopScope(); } context.ElementDecl = ThoroughGetElementDecl(); if (context.ElementDecl != null) { ValidateStartElement(); ValidateEndStartElement(); context.NeedValidateChildren = true; context.ElementDecl.ContentValidator.InitValidation(context); } } private void ValidateEndElement() { if (isProcessContents) { nsManager.PopScope(); } if (context.ElementDecl != null) { if (context.NeedValidateChildren) { if(!context.ElementDecl.ContentValidator.CompleteValidation(context)) { XmlSchemaValidator.CompleteValidationError(context, EventHandler, reader, reader.BaseURI, PositionInfo.LineNumber, PositionInfo.LinePosition, false); } } if (checkDatatype) { string stringValue = !hasSibling ? textString : textValue.ToString(); // only for identity-constraint exception reporting CheckValue(stringValue, null); checkDatatype = false; textValue.Length = 0; // cleanup textString = string.Empty; } } Pop(); } private SchemaElementDecl ThoroughGetElementDecl() { if (reader.Depth == 0) { LoadSchema(string.Empty); } if (reader.MoveToFirstAttribute()) { do { string objectNs = reader.NamespaceURI; string objectName = reader.LocalName; if (Ref.Equal(objectNs, SchemaNames.NsXmlNs)) { LoadSchema(reader.Value); if (isProcessContents) { nsManager.AddNamespace(reader.Prefix.Length == 0 ? string.Empty : reader.LocalName, reader.Value); } } if ( Ref.Equal(objectNs, SchemaNames.QnDtDt.Namespace) && Ref.Equal(objectName, SchemaNames.QnDtDt.Name) ) { reader.SchemaTypeObject = XmlSchemaDatatype.FromXdrName(reader.Value); } } while(reader.MoveToNextAttribute()); reader.MoveToElement(); } SchemaElementDecl elementDecl = schemaInfo.GetElementDecl(elementName); if(elementDecl == null) { if(schemaInfo.TargetNamespaces.Contains(context.Namespace)) { SendValidationEvent(Res.Sch_UndeclaredElement, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } return elementDecl; } private void ValidateStartElement() { if (context.ElementDecl != null) { if (context.ElementDecl.SchemaType != null) { reader.SchemaTypeObject = context.ElementDecl.SchemaType; } else { reader.SchemaTypeObject = context.ElementDecl.Datatype; } if (reader.IsEmptyElement && !context.IsNill && context.ElementDecl.DefaultValueTyped != null) { reader.TypedValueObject = context.ElementDecl.DefaultValueTyped; context.IsNill = true; // reusing IsNill } if (this.context.ElementDecl.HasRequiredAttribute) { attPresence.Clear(); } } if (reader.MoveToFirstAttribute()) { do { if ((object)reader.NamespaceURI == (object)SchemaNames.NsXmlNs) { continue; } try { reader.SchemaTypeObject = null; SchemaAttDef attnDef = schemaInfo.GetAttributeXdr(context.ElementDecl, QualifiedName(reader.LocalName, reader.NamespaceURI)); if (attnDef != null) { if (context.ElementDecl != null && context.ElementDecl.HasRequiredAttribute) { attPresence.Add(attnDef.Name, attnDef); } reader.SchemaTypeObject = (attnDef.SchemaType != null) ? (object)attnDef.SchemaType : (object)attnDef.Datatype; if (attnDef.Datatype != null) { string attributeValue = reader.Value; // need to check the contents of this attribute to make sure // it is valid according to the specified attribute type. CheckValue(attributeValue, attnDef); } } } 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); } } 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) { // is x-schema if (!XdrBuilder.IsXdrSchema(uri)) { return; } string url = uri.Substring(x_schema.Length); XmlReader reader = null; SchemaInfo xdrSchema = 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); ((XmlTextReader)reader).XmlResolver = this.XmlResolver; Parser parser = new Parser(SchemaType.XDR, NameTable, SchemaNames, EventHandler); parser.XmlResolver = this.XmlResolver; parser.Parse(reader, uri); while(reader.Read());// wellformness check xdrSchema = parser.XdrSchema; } catch(XmlSchemaException e) { SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, XmlSeverityType.Error); } catch(Exception e) { SendValidationEvent(Res.Sch_CannotLoadSchema, new string[] {uri, e.Message}, XmlSeverityType.Warning); } finally { if (reader != null) { reader.Close(); } } if (xdrSchema != null && xdrSchema.ErrorCount == 0) { schemaInfo.Add(xdrSchema, EventHandler); SchemaCollection.Add(uri, xdrSchema, null, false); } } private void LoadSchema(string uri) { if (SchemaInfo.TargetNamespaces.Contains(uri)) { return; } if (this.XmlResolver == null) { return; } SchemaInfo schemaInfo = null; if (SchemaCollection != null) schemaInfo = SchemaCollection.GetSchemaInfo(uri); if (schemaInfo != null) { if(schemaInfo.SchemaType != SchemaType.XDR) { throw new XmlException(Res.Xml_MultipleValidaitonTypes, string.Empty, this.PositionInfo.LineNumber, this.PositionInfo.LinePosition); } SchemaInfo.Add(schemaInfo, EventHandler); return; } LoadSchemaFromLocation(uri); } 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; } } public override void CompleteValidation() { if (HasSchema) { CheckForwardRefs(); } else { SendValidationEvent(new XmlSchemaException(Res.Xml_NoValidation, string.Empty), XmlSeverityType.Warning); } } 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 } if (dtype.TokenizedType != XmlTokenizedType.CDATA) { value = value.Trim(); } if (value.Length == 0) { return; // don't need to check } object typedValue = dtype.ParseValue(value, NameTable, nsManager); reader.TypedValueObject = typedValue; // 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.MaxLength != uint.MaxValue) { if(value.Length > decl.MaxLength) { SendValidationEvent(Res.Sch_MaxLengthConstraintFailed, value); } } if (decl.MinLength != uint.MaxValue) { if(value.Length < decl.MinLength) { SendValidationEvent(Res.Sch_MinLengthConstraintFailed, value); } } if (decl.Values != null && !decl.CheckEnumeration(typedValue)) { if (dtype.TokenizedType == XmlTokenizedType.NOTATION) { SendValidationEvent(Res.Sch_NotationValue, typedValue.ToString()); } else { SendValidationEvent(Res.Sch_EnumerationValue, typedValue.ToString()); } } if (!decl.CheckValue(typedValue)) { if (isAttn) { SendValidationEvent(Res.Sch_FixedAttributeValue, attdef.Name.ToString()); } else { SendValidationEvent(Res.Sch_FixedElementValue, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } } catch (XmlSchemaException) { if (attdef != null) { SendValidationEvent(Res.Sch_AttributeValueDataType, attdef.Name.ToString()); } else { SendValidationEvent(Res.Sch_ElementValueDataType, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } } } public static void CheckDefaultValue( string value, SchemaAttDef attdef, SchemaInfo sinfo, XmlNamespaceManager nsManager, XmlNameTable NameTable, object sender, ValidationEventHandler eventhandler, string baseUri, int lineNo, int linePos ) { try { XmlSchemaDatatype dtype = attdef.Datatype; if (dtype == null) { return; // no reason to check } if (dtype.TokenizedType != XmlTokenizedType.CDATA) { value = value.Trim(); } if (value.Length == 0) { return; // don't need to check } object typedValue = dtype.ParseValue(value, NameTable, nsManager); // Check special types XmlTokenizedType ttype = dtype.TokenizedType; if (ttype == XmlTokenizedType.ENTITY) { if (dtype.Variety == XmlSchemaDatatypeVariety.List) { string[] ss = (string[])typedValue; foreach(string s in ss) { ProcessEntity(sinfo, s, sender, eventhandler, baseUri, lineNo, linePos); } } else { ProcessEntity(sinfo, (string)typedValue, sender, eventhandler, baseUri, lineNo, linePos); } } else if (ttype == XmlTokenizedType.ENUMERATION) { if (!attdef.CheckEnumeration(typedValue)) { XmlSchemaException e = new XmlSchemaException(Res.Sch_EnumerationValue, typedValue.ToString(), baseUri, lineNo, linePos); if (eventhandler != null) { eventhandler(sender, new ValidationEventArgs(e)); } else { throw e; } } } attdef.DefaultValueTyped = typedValue; } #if DEBUG catch (XmlSchemaException ex) { Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, ex.Message); #else catch { #endif XmlSchemaException e = new XmlSchemaException(Res.Sch_AttributeDefaultDataType, attdef.Name.ToString(), baseUri, lineNo, linePos); if (eventhandler != null) { eventhandler(sender, new ValidationEventArgs(e)); } else { throw e; } } } 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]; } 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.NeedValidateChildren = false; } private void Pop() { if (validationStack.Length > 1) { validationStack.Pop(); context = (ValidationState)validationStack.Peek(); } } 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 XmlQualifiedName QualifiedName(string name, string ns) { return new XmlQualifiedName(name, XmlSchemaDatatype.XdrCanonizeUri(ns, NameTable, SchemaNames)); } }; #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
- StringUtil.cs
- _AcceptOverlappedAsyncResult.cs
- CounterSampleCalculator.cs
- ViewBox.cs
- ByteViewer.cs
- DataObjectEventArgs.cs
- DecimalConverter.cs
- EventHandlerList.cs
- NativeMethods.cs
- DrawingImage.cs
- GestureRecognizer.cs
- XXXInfos.cs
- ReadOnlyDataSourceView.cs
- ButtonFieldBase.cs
- GridViewSortEventArgs.cs
- FixedSOMElement.cs
- MasterPage.cs
- DesignerVerb.cs
- AnnotationAuthorChangedEventArgs.cs
- StylusPlugin.cs
- WorkingDirectoryEditor.cs
- StylusLogic.cs
- NetCodeGroup.cs
- InternalBase.cs
- ComponentEditorForm.cs
- ProxyFragment.cs
- Label.cs
- Section.cs
- SystemIcmpV6Statistics.cs
- FontUnitConverter.cs
- ContourSegment.cs
- CodeExporter.cs
- ExcludePathInfo.cs
- ExpressionBindings.cs
- M3DUtil.cs
- SharedPersonalizationStateInfo.cs
- CriticalFinalizerObject.cs
- ProtocolsConfigurationHandler.cs
- SignerInfo.cs
- SecurityAlgorithmSuiteConverter.cs
- BindValidator.cs
- DateTimeFormatInfo.cs
- ByteStorage.cs
- RequestCache.cs
- IResourceProvider.cs
- FocusChangedEventArgs.cs
- BrowserCapabilitiesCompiler.cs
- IsolationInterop.cs
- IFormattable.cs
- GridItemProviderWrapper.cs
- DocumentPageView.cs
- BitmapEffectGeneralTransform.cs
- DataGridViewRowCancelEventArgs.cs
- HierarchicalDataBoundControl.cs
- StateRuntime.cs
- Dictionary.cs
- KeyGestureValueSerializer.cs
- TableRowGroup.cs
- DataTableTypeConverter.cs
- TableLayoutRowStyleCollection.cs
- DBCSCodePageEncoding.cs
- UnsignedPublishLicense.cs
- FormatException.cs
- SymLanguageType.cs
- RuntimeConfig.cs
- SecurityDocument.cs
- DbProviderFactories.cs
- DataGridRowHeaderAutomationPeer.cs
- StringCollection.cs
- WebHeaderCollection.cs
- DataGridViewImageCell.cs
- AccessibilityHelperForVista.cs
- Viewport3DAutomationPeer.cs
- Codec.cs
- DiagnosticTrace.cs
- FileCodeGroup.cs
- GeneratedCodeAttribute.cs
- ReferentialConstraint.cs
- MDIControlStrip.cs
- StringBuilder.cs
- CodeArgumentReferenceExpression.cs
- ClientRoleProvider.cs
- XmlnsDictionary.cs
- QueryPageSettingsEventArgs.cs
- ButtonChrome.cs
- RuntimeVariableList.cs
- TextBoxAutomationPeer.cs
- ContextMenuStrip.cs
- Queue.cs
- Rotation3D.cs
- XmlSchemaDatatype.cs
- SvcMapFile.cs
- TextParaLineResult.cs
- WebPartDisplayModeEventArgs.cs
- HTMLTextWriter.cs
- SqlUDTStorage.cs
- SessionParameter.cs
- HwndSource.cs
- SynchronizationFilter.cs
- TemplateContent.cs