2 //------------------------------------------------------------------------------
3 // <copyright file="XmlValidatingReaderImpl.cs" company="Microsoft">
4 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <owner current="true" primary="true">Microsoft</owner>
7 //------------------------------------------------------------------------------
12 using System
.Xml
.Schema
;
13 using System
.Collections
;
14 using System
.Diagnostics
;
15 using System
.Globalization
;
16 using System
.Security
.Policy
;
17 using System
.Collections
.Generic
;
18 using System
.Security
.Permissions
;
19 using System
.Runtime
.Versioning
;
23 internal sealed partial class XmlValidatingReaderImpl
: XmlReader
, IXmlLineInfo
, IXmlNamespaceResolver
{
26 // Private helper types
28 // ParsingFunction = what should the reader do when the next Read() is called
29 enum ParsingFunction
{
33 ResolveEntityInternally
,
40 internal class ValidationEventHandling
: IValidationEventHandling
{
42 XmlValidatingReaderImpl reader
;
43 ValidationEventHandler eventHandler
;
46 internal ValidationEventHandling(XmlValidatingReaderImpl reader
) {
50 // IValidationEventHandling interface
51 #region IValidationEventHandling interface
52 object IValidationEventHandling
.EventHandler
{
53 get { return eventHandler; }
56 void IValidationEventHandling
.SendEvent(Exception
/*XmlSchemaException*/ exception
, XmlSeverityType severity
) {
57 if (eventHandler
!= null) {
58 eventHandler(reader
, new ValidationEventArgs((XmlSchemaException
)exception
, severity
));
60 else if (reader
.ValidationType
!= ValidationType
.None
&& severity
== XmlSeverityType
.Error
) {
66 // XmlValidatingReaderImpl helper methods
67 internal void AddHandler(ValidationEventHandler handler
) {
68 eventHandler
+= handler
;
71 internal void RemoveHandler(ValidationEventHandler handler
) {
72 eventHandler
-= handler
;
81 XmlTextReaderImpl coreReaderImpl
;
82 IXmlNamespaceResolver coreReaderNSResolver
;
85 ValidationType validationType
;
86 BaseValidator validator
;
88 #pragma warning disable 618
89 XmlSchemaCollection schemaCollection
;
90 #pragma warning restore 618
91 bool processIdentityConstraints
;
93 // parsing function (state)
94 ParsingFunction parsingFunction
= ParsingFunction
.Init
;
97 ValidationEventHandling eventHandling
;
100 XmlParserContext parserContext
;
102 // helper for Read[Element]ContentAs{Base64,BinHex} methods
103 ReadContentAsBinaryHelper readBinaryHelper
;
105 // Outer XmlReader exposed to the user - either XmlValidatingReader or XmlValidatingReaderImpl (when created via XmlReader.Create).
106 // Virtual methods called from within XmlValidatingReaderImpl must be called on the outer reader so in case the user overrides
107 // some of the XmlValidatingReader methods we will call the overriden version.
108 XmlReader outerReader
;
113 // Initializes a new instance of XmlValidatingReaderImpl class with the specified XmlReader.
114 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
115 internal XmlValidatingReaderImpl( XmlReader reader
) {
116 XmlAsyncCheckReader asyncCheckReader
= reader
as XmlAsyncCheckReader
;
117 if (asyncCheckReader
!= null) {
118 reader
= asyncCheckReader
.CoreReader
;
122 coreReaderNSResolver
= reader
as IXmlNamespaceResolver
;
123 coreReaderImpl
= reader
as XmlTextReaderImpl
;
124 if ( coreReaderImpl
== null ) {
125 XmlTextReader tr
= reader
as XmlTextReader
;
127 coreReaderImpl
= tr
.Impl
;
130 if ( coreReaderImpl
== null ) {
131 throw new ArgumentException( Res
.GetString( Res
.Arg_ExpectingXmlTextReader
), "reader" );
133 coreReaderImpl
.EntityHandling
= EntityHandling
.ExpandEntities
;
134 coreReaderImpl
.XmlValidatingReaderCompatibilityMode
= true;
135 this.processIdentityConstraints
= true;
137 #pragma warning disable 618
138 schemaCollection
= new XmlSchemaCollection( coreReader
.NameTable
);
139 schemaCollection
.XmlResolver
= GetResolver();
141 eventHandling
= new ValidationEventHandling(this);
142 coreReaderImpl
.ValidationEventHandling
= eventHandling
;
143 coreReaderImpl
.OnDefaultAttributeUse
= new XmlTextReaderImpl
.OnDefaultAttributeUseDelegate(ValidateDefaultAttributeOnUse
);
145 validationType
= ValidationType
.Auto
;
146 SetupValidation( ValidationType
.Auto
);
147 #pragma warning restore 618
151 // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified string, fragment type and parser context
152 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
153 // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning.
154 [ResourceConsumption(ResourceScope
.Machine
, ResourceScope
.Machine
)]
155 [ResourceExposure(ResourceScope
.None
)]
156 internal XmlValidatingReaderImpl( string xmlFragment
, XmlNodeType fragType
, XmlParserContext context
)
157 : this( new XmlTextReader( xmlFragment
, fragType
, context
) )
159 if ( coreReader
.BaseURI
.Length
> 0 ) {
160 validator
.BaseUri
= GetResolver().ResolveUri( null, coreReader
.BaseURI
);
163 if ( context
!= null ) {
164 parsingFunction
= ParsingFunction
.ParseDtdFromContext
;
165 parserContext
= context
;
169 // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified stream, fragment type and parser context
170 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
171 // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning.
172 [ResourceConsumption(ResourceScope
.Machine
, ResourceScope
.Machine
)]
173 [ResourceExposure(ResourceScope
.None
)]
174 internal XmlValidatingReaderImpl( Stream xmlFragment
, XmlNodeType fragType
, XmlParserContext context
)
175 : this( new XmlTextReader( xmlFragment
, fragType
, context
) )
177 if ( coreReader
.BaseURI
.Length
> 0 ) {
178 validator
.BaseUri
= GetResolver().ResolveUri( null, coreReader
.BaseURI
);
181 if ( context
!= null ) {
182 parsingFunction
= ParsingFunction
.ParseDtdFromContext
;
183 parserContext
= context
;
187 // Initializes a new instance of XmlValidatingReaderImpl class with the specified arguments.
188 // This constructor is used when creating XmlValidatingReaderImpl reader via "XmlReader.Create(..)"
189 internal XmlValidatingReaderImpl( XmlReader reader
, ValidationEventHandler settingsEventHandler
, bool processIdentityConstraints
) {
190 XmlAsyncCheckReader asyncCheckReader
= reader
as XmlAsyncCheckReader
;
191 if (asyncCheckReader
!= null) {
192 reader
= asyncCheckReader
.CoreReader
;
196 coreReaderImpl
= reader
as XmlTextReaderImpl
;
197 if ( coreReaderImpl
== null ) {
198 XmlTextReader tr
= reader
as XmlTextReader
;
200 coreReaderImpl
= tr
.Impl
;
203 if ( coreReaderImpl
== null ) {
204 throw new ArgumentException( Res
.GetString( Res
.Arg_ExpectingXmlTextReader
), "reader" );
206 coreReaderImpl
.XmlValidatingReaderCompatibilityMode
= true;
207 coreReaderNSResolver
= reader
as IXmlNamespaceResolver
;
208 this.processIdentityConstraints
= processIdentityConstraints
;
210 #pragma warning disable 618
212 schemaCollection
= new XmlSchemaCollection( coreReader
.NameTable
);
214 #pragma warning restore 618
216 schemaCollection
.XmlResolver
= GetResolver();
218 eventHandling
= new ValidationEventHandling(this);
219 if (settingsEventHandler
!= null) {
220 eventHandling
.AddHandler(settingsEventHandler
);
222 coreReaderImpl
.ValidationEventHandling
= eventHandling
;
223 coreReaderImpl
.OnDefaultAttributeUse
= new XmlTextReaderImpl
.OnDefaultAttributeUseDelegate(ValidateDefaultAttributeOnUse
);
225 validationType
= ValidationType
.DTD
;
226 SetupValidation( ValidationType
.DTD
);
232 // Returns the current settings of the reader
233 public override XmlReaderSettings Settings
{
235 XmlReaderSettings settings
;
236 if (coreReaderImpl
.V1Compat
) {
240 settings
= coreReader
.Settings
;
242 if (settings
!= null) {
243 settings
= settings
.Clone();
246 settings
= new XmlReaderSettings();
248 settings
.ValidationType
= ValidationType
.DTD
;
249 if (!processIdentityConstraints
) {
250 settings
.ValidationFlags
&= ~XmlSchemaValidationFlags
.ProcessIdentityConstraints
;
252 settings
.ReadOnly
= true;
257 // Returns the type of the current node.
258 public override XmlNodeType NodeType
{
260 return coreReader
.NodeType
;
264 // Returns the name of the current node, including prefix.
265 public override string Name
{
267 return coreReader
.Name
;
271 // Returns local name of the current node (without prefix)
272 public override string LocalName
{
274 return coreReader
.LocalName
;
278 // Returns namespace name of the current node.
279 public override string NamespaceURI
{
281 return coreReader
.NamespaceURI
;
285 // Returns prefix associated with the current node.
286 public override string Prefix
{
288 return coreReader
.Prefix
;
292 // Returns true if the current node can have Value property != string.Empty.
293 public override bool HasValue
{
295 return coreReader
.HasValue
;
299 // Returns the text value of the current node.
300 public override string Value
{
302 return coreReader
.Value
;
306 // Returns the depth of the current node in the XML element stack
307 public override int Depth
{
309 return coreReader
.Depth
;
313 // Returns the base URI of the current node.
314 public override string BaseURI
{
316 return coreReader
.BaseURI
;
320 // Returns true if the current node is an empty element (for example, <MyElement/>).
321 public override bool IsEmptyElement
{
323 return coreReader
.IsEmptyElement
;
327 // Returns true of the current node is a default attribute declared in DTD.
328 public override bool IsDefault
{
330 return coreReader
.IsDefault
;
334 // Returns the quote character used in the current attribute declaration
335 public override char QuoteChar
{
337 return coreReader
.QuoteChar
;
341 // Returns the current xml:space scope.
342 public override XmlSpace XmlSpace
{
344 return coreReader
.XmlSpace
;
348 // Returns the current xml:lang scope.</para>
349 public override string XmlLang
{
351 return coreReader
.XmlLang
;
355 // Returns the current read state of the reader
356 public override ReadState ReadState
{
358 return ( parsingFunction
== ParsingFunction
.Init
) ? ReadState
.Initial
: coreReader
.ReadState
;
362 // Returns true if the reader reached end of the input data
363 public override bool EOF
{
365 return coreReader
.EOF
;
369 // Returns the XmlNameTable associated with this XmlReader
370 public override XmlNameTable NameTable
{
372 return coreReader
.NameTable
;
376 // Returns encoding of the XML document
377 internal Encoding Encoding
{
379 return coreReaderImpl
.Encoding
;
383 // Returns the number of attributes on the current node.
384 public override int AttributeCount
{
386 return coreReader
.AttributeCount
;
390 // Returns value of an attribute with the specified Name
391 public override string GetAttribute( string name
) {
392 return coreReader
.GetAttribute( name
);
395 // Returns value of an attribute with the specified LocalName and NamespaceURI
396 public override string GetAttribute( string localName
, string namespaceURI
) {
397 return coreReader
.GetAttribute( localName
, namespaceURI
);
400 // Returns value of an attribute at the specified index (position)
401 public override string GetAttribute( int i
) {
402 return coreReader
.GetAttribute( i
);
405 // Moves to an attribute with the specified Name
406 public override bool MoveToAttribute( string name
) {
407 if ( !coreReader
.MoveToAttribute( name
) ) {
410 parsingFunction
= ParsingFunction
.Read
;
414 // Moves to an attribute with the specified LocalName and NamespceURI
415 public override bool MoveToAttribute( string localName
, string namespaceURI
) {
416 if ( !coreReader
.MoveToAttribute( localName
, namespaceURI
) ) {
419 parsingFunction
= ParsingFunction
.Read
;
423 // Moves to an attribute at the specified index (position)
424 public override void MoveToAttribute( int i
) {
425 coreReader
.MoveToAttribute( i
);
426 parsingFunction
= ParsingFunction
.Read
;
429 // Moves to the first attribute of the current node
430 public override bool MoveToFirstAttribute() {
431 if ( !coreReader
.MoveToFirstAttribute() ) {
434 parsingFunction
= ParsingFunction
.Read
;
438 // Moves to the next attribute of the current node
439 public override bool MoveToNextAttribute() {
440 if ( !coreReader
.MoveToNextAttribute() ) {
443 parsingFunction
= ParsingFunction
.Read
;
447 // If on attribute, moves to the element that contains the attribute node
448 public override bool MoveToElement() {
449 if ( !coreReader
.MoveToElement() ) {
452 parsingFunction
= ParsingFunction
.Read
;
456 // Reads and validated next node from the input data
457 public override bool Read() {
458 switch ( parsingFunction
) {
459 case ParsingFunction
.Read
:
460 if ( coreReader
.Read() ) {
461 ProcessCoreReaderEvent();
465 validator
.CompleteValidation();
468 case ParsingFunction
.ParseDtdFromContext
:
469 parsingFunction
= ParsingFunction
.Read
;
470 ParseDtdFromParserContext();
471 goto case ParsingFunction
.Read
;
472 case ParsingFunction
.Error
:
473 case ParsingFunction
.ReaderClosed
:
475 case ParsingFunction
.Init
:
476 parsingFunction
= ParsingFunction
.Read
; // this changes the value returned by ReadState
477 if ( coreReader
.ReadState
== ReadState
.Interactive
) {
478 ProcessCoreReaderEvent();
482 goto case ParsingFunction
.Read
;
484 case ParsingFunction
.ResolveEntityInternally
:
485 parsingFunction
= ParsingFunction
.Read
;
486 ResolveEntityInternally();
487 goto case ParsingFunction
.Read
;
488 case ParsingFunction
.InReadBinaryContent
:
489 parsingFunction
= ParsingFunction
.Read
;
490 readBinaryHelper
.Finish();
491 goto case ParsingFunction
.Read
;
493 Debug
.Assert( false );
498 // Closes the input stream ot TextReader, changes the ReadState to Closed and sets all properties to zero/string.Empty
499 public override void Close() {
501 parsingFunction
= ParsingFunction
.ReaderClosed
;
504 // Returns NamespaceURI associated with the specified prefix in the current namespace scope.
505 public override String
LookupNamespace( String prefix
) {
506 return coreReaderImpl
.LookupNamespace( prefix
);
509 // Iterates through the current attribute value's text and entity references chunks.
510 public override bool ReadAttributeValue() {
511 if ( parsingFunction
== ParsingFunction
.InReadBinaryContent
) {
512 parsingFunction
= ParsingFunction
.Read
;
513 readBinaryHelper
.Finish();
515 if (!coreReader
.ReadAttributeValue()) {
518 parsingFunction
= ParsingFunction
.Read
;
522 public override bool CanReadBinaryContent
{
528 public override int ReadContentAsBase64( byte[] buffer
, int index
, int count
) {
529 if ( ReadState
!= ReadState
.Interactive
) {
533 // init ReadChunkHelper if called the first time
534 if ( parsingFunction
!= ParsingFunction
.InReadBinaryContent
) {
535 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, outerReader
);
538 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
539 parsingFunction
= ParsingFunction
.Read
;
541 // call to the helper
542 int readCount
= readBinaryHelper
.ReadContentAsBase64( buffer
, index
, count
);
544 // setup parsingFunction
545 parsingFunction
= ParsingFunction
.InReadBinaryContent
;
549 public override int ReadContentAsBinHex( byte[] buffer
, int index
, int count
) {
550 if ( ReadState
!= ReadState
.Interactive
) {
554 // init ReadChunkHelper when called first time
555 if ( parsingFunction
!= ParsingFunction
.InReadBinaryContent
) {
556 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, outerReader
);
559 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
560 parsingFunction
= ParsingFunction
.Read
;
562 // call to the helper
563 int readCount
= readBinaryHelper
.ReadContentAsBinHex( buffer
, index
, count
);
565 // setup parsingFunction
566 parsingFunction
= ParsingFunction
.InReadBinaryContent
;
570 public override int ReadElementContentAsBase64( byte[] buffer
, int index
, int count
) {
571 if ( ReadState
!= ReadState
.Interactive
) {
575 // init ReadChunkHelper if called the first time
576 if ( parsingFunction
!= ParsingFunction
.InReadBinaryContent
) {
577 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, outerReader
);
580 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
581 parsingFunction
= ParsingFunction
.Read
;
583 // call to the helper
584 int readCount
= readBinaryHelper
.ReadElementContentAsBase64( buffer
, index
, count
);
586 // setup parsingFunction
587 parsingFunction
= ParsingFunction
.InReadBinaryContent
;
591 public override int ReadElementContentAsBinHex( byte[] buffer
, int index
, int count
) {
592 if ( ReadState
!= ReadState
.Interactive
) {
596 // init ReadChunkHelper when called first time
597 if ( parsingFunction
!= ParsingFunction
.InReadBinaryContent
) {
598 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, outerReader
);
601 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
602 parsingFunction
= ParsingFunction
.Read
;
604 // call to the helper
605 int readCount
= readBinaryHelper
.ReadElementContentAsBinHex( buffer
, index
, count
);
607 // setup parsingFunction
608 parsingFunction
= ParsingFunction
.InReadBinaryContent
;
612 // Returns true if the XmlReader knows how to resolve general entities
613 public override bool CanResolveEntity
{
619 // Resolves the current entity reference node
620 public override void ResolveEntity() {
621 if ( parsingFunction
== ParsingFunction
.ResolveEntityInternally
) {
622 parsingFunction
= ParsingFunction
.Read
;
624 coreReader
.ResolveEntity();
627 internal XmlReader OuterReader
{
632 #pragma warning disable 618
633 Debug
.Assert( value is XmlValidatingReader
);
634 #pragma warning restore 618
639 internal void MoveOffEntityReference() {
640 if ( outerReader
.NodeType
== XmlNodeType
.EntityReference
&& parsingFunction
!= ParsingFunction
.ResolveEntityInternally
) {
641 if ( !outerReader
.Read() ) {
642 throw new InvalidOperationException( Res
.GetString(Res
.Xml_InvalidOperation
) );
647 public override string ReadString() {
648 MoveOffEntityReference();
649 return base.ReadString();
653 // IXmlLineInfo members
655 public bool HasLineInfo() {
659 // Returns the line number of the current node
660 public int LineNumber
{
662 return ((IXmlLineInfo
)coreReader
).LineNumber
;
666 // Returns the line number of the current node
667 public int LinePosition
{
669 return ((IXmlLineInfo
)coreReader
).LinePosition
;
674 // IXmlNamespaceResolver members
676 IDictionary
<string,string> IXmlNamespaceResolver
.GetNamespacesInScope( XmlNamespaceScope scope
) {
677 return this.GetNamespacesInScope( scope
);
680 string IXmlNamespaceResolver
.LookupNamespace(string prefix
) {
681 return this.LookupNamespace( prefix
);
684 string IXmlNamespaceResolver
.LookupPrefix( string namespaceName
) {
685 return this.LookupPrefix( namespaceName
);
688 // Internal IXmlNamespaceResolver methods
689 internal IDictionary
<string,string> GetNamespacesInScope( XmlNamespaceScope scope
) {
690 return coreReaderNSResolver
.GetNamespacesInScope( scope
);
693 internal string LookupPrefix( string namespaceName
) {
694 return coreReaderNSResolver
.LookupPrefix( namespaceName
);
698 // XmlValidatingReader members
700 // Specufies the validation event handler that wil get warnings and errors related to validation
701 internal event ValidationEventHandler ValidationEventHandler
{
703 eventHandling
.AddHandler(value);
706 eventHandling
.RemoveHandler(value); ;
710 // returns the schema type of the current node
711 internal object SchemaType
{
713 if ( validationType
!= ValidationType
.None
) {
714 XmlSchemaType schemaTypeObj
= coreReaderImpl
.InternalSchemaType
as XmlSchemaType
;
715 if ( schemaTypeObj
!= null && schemaTypeObj
.QualifiedName
.Namespace
== XmlReservedNs
.NsXs
) {
716 return schemaTypeObj
.Datatype
;
718 return coreReaderImpl
.InternalSchemaType
;
725 // returns the underlying XmlTextReader or XmlTextReaderImpl
726 internal XmlReader Reader
{
728 return (XmlReader
) coreReader
;
732 // returns the underlying XmlTextReaderImpl
733 internal XmlTextReaderImpl ReaderImpl
{
735 return coreReaderImpl
;
739 // specifies the validation type (None, DDT, XSD, XDR, Auto)
740 internal ValidationType ValidationType
{
742 return validationType
;
745 if ( ReadState
!= ReadState
.Initial
) {
746 throw new InvalidOperationException( Res
.GetString( Res
.Xml_InvalidOperation
) );
748 validationType
= value;
749 SetupValidation( value );
753 // current schema collection used for validationg
754 #pragma warning disable 618
755 internal XmlSchemaCollection Schemas
{
757 return schemaCollection
;
760 #pragma warning restore 618
762 // Spefifies whether general entities should be automatically expanded or not
763 internal EntityHandling EntityHandling
{
765 return coreReaderImpl
.EntityHandling
;
768 coreReaderImpl
.EntityHandling
= value;
772 // Specifies XmlResolver used for opening the XML document and other external references
773 internal XmlResolver XmlResolver
{
775 coreReaderImpl
.XmlResolver
= value;
776 validator
.XmlResolver
= value;
777 schemaCollection
.XmlResolver
= value;
781 // Disables or enables support of W3C XML 1.0 Namespaces
782 internal bool Namespaces
{
784 return coreReaderImpl
.Namespaces
;
787 coreReaderImpl
.Namespaces
= value;
791 // Returns typed value of the current node (based on the type specified by schema)
792 public object ReadTypedValue() {
793 if ( validationType
== ValidationType
.None
) {
797 switch ( outerReader
.NodeType
) {
798 case XmlNodeType
.Attribute
:
799 return coreReaderImpl
.InternalTypedValue
;
800 case XmlNodeType
.Element
:
801 if ( SchemaType
== null ) {
804 XmlSchemaDatatype dtype
= ( SchemaType
is XmlSchemaDatatype
) ? (XmlSchemaDatatype
)SchemaType
: ((XmlSchemaType
)SchemaType
).Datatype
;
805 if ( dtype
!= null ) {
806 if ( !outerReader
.IsEmptyElement
) {
808 if ( !outerReader
.Read() ) {
809 throw new InvalidOperationException( Res
.GetString( Res
.Xml_InvalidOperation
) );
811 XmlNodeType type
= outerReader
.NodeType
;
812 if ( type
!= XmlNodeType
.CDATA
&& type
!= XmlNodeType
.Text
&&
813 type
!= XmlNodeType
.Whitespace
&& type
!= XmlNodeType
.SignificantWhitespace
&&
814 type
!= XmlNodeType
.Comment
&& type
!= XmlNodeType
.ProcessingInstruction
) {
818 if ( outerReader
.NodeType
!= XmlNodeType
.EndElement
) {
819 throw new XmlException( Res
.Xml_InvalidNodeType
, outerReader
.NodeType
.ToString());
822 return coreReaderImpl
.InternalTypedValue
;
826 case XmlNodeType
.EndElement
:
830 if ( coreReaderImpl
.V1Compat
) { //If v1 XmlValidatingReader return null
840 // Private implementation methods
843 private void ParseDtdFromParserContext()
845 Debug
.Assert( parserContext
!= null );
846 Debug
.Assert( coreReaderImpl
.DtdInfo
== null );
848 if ( parserContext
.DocTypeName
== null || parserContext
.DocTypeName
.Length
== 0 ) {
852 IDtdParser dtdParser
= DtdParser
.Create();
853 XmlTextReaderImpl
.DtdParserProxy proxy
= new XmlTextReaderImpl
.DtdParserProxy(coreReaderImpl
);
854 IDtdInfo dtdInfo
= dtdParser
.ParseFreeFloatingDtd( parserContext
.BaseURI
, parserContext
.DocTypeName
, parserContext
.PublicId
,
855 parserContext
.SystemId
, parserContext
.InternalSubset
, proxy
);
856 coreReaderImpl
.SetDtdInfo( dtdInfo
);
861 private void ValidateDtd() {
862 IDtdInfo dtdInfo
= coreReaderImpl
.DtdInfo
;
863 if (dtdInfo
!= null) {
864 switch ( validationType
) {
865 #pragma warning disable 618
866 case ValidationType
.Auto
:
867 SetupValidation( ValidationType
.DTD
);
868 goto case ValidationType
.DTD
;
869 #pragma warning restore 618
870 case ValidationType
.DTD
:
871 case ValidationType
.None
:
872 validator
.DtdInfo
= dtdInfo
;
878 private void ResolveEntityInternally() {
879 Debug
.Assert( coreReader
.NodeType
== XmlNodeType
.EntityReference
);
880 int initialDepth
= coreReader
.Depth
;
881 outerReader
.ResolveEntity();
882 while ( outerReader
.Read() && coreReader
.Depth
> initialDepth
);
885 // SxS: This method resolves an Uri but does not expose it to caller. It's OK to suppress the SxS warning.
886 [ResourceConsumption(ResourceScope
.Machine
, ResourceScope
.Machine
)]
887 [ResourceExposure(ResourceScope
.None
)]
888 private void SetupValidation( ValidationType valType
) {
889 validator
= BaseValidator
.CreateInstance( valType
, this, schemaCollection
, eventHandling
, processIdentityConstraints
);
891 XmlResolver resolver
= GetResolver();
892 validator
.XmlResolver
= resolver
;
894 if ( outerReader
.BaseURI
.Length
> 0 ) {
895 validator
.BaseUri
= ( resolver
== null ) ? new Uri( outerReader
.BaseURI
, UriKind
.RelativeOrAbsolute
) : resolver
.ResolveUri( null, outerReader
.BaseURI
);
897 coreReaderImpl
.ValidationEventHandling
= (validationType
== ValidationType
.None
) ? null : eventHandling
;
900 static XmlResolver s_tempResolver
;
902 // This is needed because we can't have the setter for XmlResolver public and with internal getter.
903 private XmlResolver
GetResolver() {
904 XmlResolver tempResolver
= coreReaderImpl
.GetResolver();
906 if (tempResolver
== null && !coreReaderImpl
.IsResolverSet
&&
907 !System
.Xml
.XmlReaderSettings
.EnableLegacyXmlSettings())
909 // it is safe to return valid resolver as it'll be used in the schema validation
910 if (s_tempResolver
== null)
911 s_tempResolver
= new XmlUrlResolver();
912 return s_tempResolver
;
919 // Internal methods for validators, DOM, XPathDocument etc.
921 private void ProcessCoreReaderEvent() {
922 switch ( coreReader
.NodeType
) {
923 case XmlNodeType
.Whitespace
:
924 if ( coreReader
.Depth
> 0 || coreReaderImpl
.FragmentType
!= XmlNodeType
.Document
) {
925 if ( validator
.PreserveWhitespace
) {
926 coreReaderImpl
.ChangeCurrentNodeType( XmlNodeType
.SignificantWhitespace
);
930 case XmlNodeType
.DocumentType
:
933 case XmlNodeType
.EntityReference
:
934 parsingFunction
= ParsingFunction
.ResolveEntityInternally
;
937 coreReaderImpl
.InternalSchemaType
= null;
938 coreReaderImpl
.InternalTypedValue
= null;
939 validator
.Validate();
944 internal void Close( bool closeStream
) {
945 coreReaderImpl
.Close( closeStream
);
946 parsingFunction
= ParsingFunction
.ReaderClosed
;
949 internal BaseValidator Validator
{
958 internal override XmlNamespaceManager NamespaceManager
{
960 return coreReaderImpl
.NamespaceManager
;
964 internal bool StandAlone
{
966 return coreReaderImpl
.StandAlone
;
970 internal object SchemaTypeObject
{
972 coreReaderImpl
.InternalSchemaType
= value;
976 internal object TypedValueObject
{
978 return coreReaderImpl
.InternalTypedValue
;
981 coreReaderImpl
.InternalTypedValue
= value;
985 internal bool Normalization
{
987 return coreReaderImpl
.Normalization
;
991 internal bool AddDefaultAttribute( SchemaAttDef attdef
) {
992 return coreReaderImpl
.AddDefaultAttributeNonDtd( attdef
);
995 internal override IDtdInfo DtdInfo
{
996 get { return coreReaderImpl.DtdInfo; }
999 internal void ValidateDefaultAttributeOnUse(IDtdDefaultAttributeInfo defaultAttribute
, XmlTextReaderImpl coreReader
) {
1000 SchemaAttDef attdef
= defaultAttribute
as SchemaAttDef
;
1001 if (attdef
== null) {
1005 if (!attdef
.DefaultValueChecked
) {
1006 SchemaInfo schemaInfo
= coreReader
.DtdInfo
as SchemaInfo
;
1007 if (schemaInfo
== null) {
1010 DtdValidator
.CheckDefaultValue(attdef
, schemaInfo
, eventHandling
, coreReader
.BaseURI
);