1 //------------------------------------------------------------------------------
2 // <copyright file="XmlNavigatorReader.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
9 using System
.Xml
.Schema
;
10 using System
.Collections
;
11 using System
.Diagnostics
;
12 using System
.Collections
.Generic
;
15 namespace System
.Xml
.XPath
{
18 /// Reader that traverses the subtree rooted at the current position of the specified navigator.
20 internal class XPathNavigatorReader
: XmlReader
, IXmlNamespaceResolver
{
33 private XPathNavigator nav
;
34 private XPathNavigator navToRead
;
37 private XmlNodeType nodeType
;
38 private int attrCount
;
39 private bool readEntireDocument
;
41 protected IXmlLineInfo lineInfo
;
42 protected IXmlSchemaInfo schemaInfo
;
44 private ReadContentAsBinaryHelper readBinaryHelper
;
45 private State savedState
;
47 internal const string space
= "space";
49 internal static XmlNodeType
[] convertFromXPathNodeType
= {
50 XmlNodeType
.Document
, // XPathNodeType.Root
51 XmlNodeType
.Element
, // XPathNodeType.Element
52 XmlNodeType
.Attribute
, // XPathNodeType.Attribute
53 XmlNodeType
.Attribute
, // XPathNodeType.Namespace
54 XmlNodeType
.Text
, // XPathNodeType.Text
55 XmlNodeType
.SignificantWhitespace
, // XPathNodeType.SignificantWhitespace
56 XmlNodeType
.Whitespace
, // XPathNodeType.Whitespace
57 XmlNodeType
.ProcessingInstruction
, // XPathNodeType.ProcessingInstruction
58 XmlNodeType
.Comment
, // XPathNodeType.Comment
59 XmlNodeType
.None
// XPathNodeType.All
63 /// Translates an XPathNodeType value into the corresponding XmlNodeType value.
64 /// XPathNodeType.Whitespace and XPathNodeType.SignificantWhitespace are mapped into XmlNodeType.Text.
66 internal static XmlNodeType
ToXmlNodeType( XPathNodeType typ
) {
67 return XPathNavigatorReader
.convertFromXPathNodeType
[(int) typ
];
70 internal object UnderlyingObject
{
72 return this.nav
.UnderlyingObject
;
76 static public XPathNavigatorReader
Create(XPathNavigator navToRead
) {
77 XPathNavigator nav
= navToRead
.Clone();
78 IXmlLineInfo xli
= nav
as IXmlLineInfo
;
79 IXmlSchemaInfo xsi
= nav
as IXmlSchemaInfo
;
80 #if NAVREADER_SUPPORTSLINEINFO
83 return new XPathNavigatorReader(nav
, xli
, xsi
);
86 return new XPathNavigatorReaderWithLI(nav
, xli
, xsi
);
91 return new XPathNavigatorReaderWithSI(nav
, xli
, xsi
);
94 return new XPathNavigatorReaderWithLIAndSI(nav
, xli
, xsi
);
99 return new XPathNavigatorReader(nav
, xli
, xsi
);
102 return new XPathNavigatorReaderWithSI(nav
, xli
, xsi
);
107 protected XPathNavigatorReader( XPathNavigator navToRead
, IXmlLineInfo xli
, IXmlSchemaInfo xsi
) {
108 // Need clone that can be moved independently of original navigator
109 this.navToRead
= navToRead
;
111 this.schemaInfo
= xsi
;
112 this.nav
= XmlEmptyNavigator
.Singleton
;
113 this.state
= State
.Initial
;
115 this.nodeType
= XPathNavigatorReader
.ToXmlNodeType( this.nav
.NodeType
);
118 protected bool IsReading
{
119 get { return this.state > State.Initial && this.state < State.EOF; }
122 internal override XmlNamespaceManager NamespaceManager
{
123 get { return XPathNavigator.GetNamespaces( this ); }
127 //-----------------------------------------------
128 // IXmlNamespaceResolver -- pass through to Navigator
129 //-----------------------------------------------
130 public override XmlNameTable NameTable
{
132 return this.navToRead
.NameTable
;
136 IDictionary
<string,string> IXmlNamespaceResolver
.GetNamespacesInScope(XmlNamespaceScope scope
) {
137 return this.nav
.GetNamespacesInScope(scope
);
140 string IXmlNamespaceResolver
.LookupNamespace(string prefix
) {
141 return this.nav
.LookupNamespace(prefix
);
144 string IXmlNamespaceResolver
.LookupPrefix(string namespaceName
) {
145 return this.nav
.LookupPrefix(namespaceName
);
148 //-----------------------------------------------
149 // XmlReader -- pass through to Navigator
150 //-----------------------------------------------
152 public override XmlReaderSettings Settings
{
154 XmlReaderSettings rs
= new XmlReaderSettings();
155 rs
.NameTable
= this.NameTable
;
156 rs
.ConformanceLevel
= ConformanceLevel
.Fragment
;
157 rs
.CheckCharacters
= false;
163 public override IXmlSchemaInfo SchemaInfo
{
165 // Special case attribute text (this.nav points to attribute even though current state is Text)
166 if ( this.nodeType
== XmlNodeType
.Text
)
168 return this.nav
.SchemaInfo
;
172 public override System
.Type ValueType
{
173 get { return this.nav.ValueType; }
176 public override XmlNodeType NodeType
{
177 get { return this.nodeType; }
180 public override string NamespaceURI
{
182 //NamespaceUri for namespace nodes is different in case of XPathNavigator and Reader
183 if (this.nav
.NodeType
== XPathNodeType
.Namespace
)
184 return this.NameTable
.Add(XmlReservedNs
.NsXmlNs
);
185 //Special case attribute text node
186 if (this.NodeType
== XmlNodeType
.Text
)
188 return this.nav
.NamespaceURI
;
192 public override string LocalName
{
194 //Default namespace in case of reader has a local name value of 'xmlns'
195 if (this.nav
.NodeType
== XPathNodeType
.Namespace
&& this.nav
.LocalName
.Length
== 0)
196 return this.NameTable
.Add("xmlns");
197 //Special case attribute text node
198 if (this.NodeType
== XmlNodeType
.Text
)
200 return this.nav
.LocalName
;
204 public override string Prefix
{
206 //Prefix for namespace nodes is different in case of XPathNavigator and Reader
207 if (this.nav
.NodeType
== XPathNodeType
.Namespace
&& this.nav
.LocalName
.Length
!= 0)
208 return this.NameTable
.Add("xmlns");
209 //Special case attribute text node
210 if (this.NodeType
== XmlNodeType
.Text
)
212 return this.nav
.Prefix
;
216 public override string BaseURI
{
218 //reader returns BaseUri even before read method is called.
219 if( this.state
== State
.Initial
)
220 return this.navToRead
.BaseURI
;
221 return this.nav
.BaseURI
;
225 public override bool IsEmptyElement
{
227 return this.nav
.IsEmptyElement
;
231 public override XmlSpace XmlSpace
{
233 XPathNavigator tempNav
= this.nav
.Clone();
235 if (tempNav
.MoveToAttribute(XPathNavigatorReader
.space
, XmlReservedNs
.NsXml
)) {
236 switch (XmlConvert
.TrimString(tempNav
.Value
)) {
238 return XmlSpace
.Default
;
240 return XmlSpace
.Preserve
;
244 tempNav
.MoveToParent();
247 while (tempNav
.MoveToParent());
248 return XmlSpace
.None
;
252 public override string XmlLang
{
254 return this.nav
.XmlLang
;
258 public override bool HasValue
{
260 if( ( this.nodeType
!= XmlNodeType
.Element
)
261 && ( this.nodeType
!=XmlNodeType
.Document
)
262 && ( this.nodeType
!=XmlNodeType
.EndElement
)
263 && ( this.nodeType
!=XmlNodeType
.None
) )
269 public override string Value
{
271 if( ( this.nodeType
!= XmlNodeType
.Element
)
272 && ( this.nodeType
!=XmlNodeType
.Document
)
273 && ( this.nodeType
!=XmlNodeType
.EndElement
)
274 && ( this.nodeType
!=XmlNodeType
.None
) )
275 return this.nav
.Value
;
280 private XPathNavigator
GetElemNav() {
281 XPathNavigator tempNav
;
282 switch (this.state
) {
284 return this.nav
.Clone();
285 case State
.Attribute
:
287 tempNav
= this.nav
.Clone();
288 if (tempNav
.MoveToParent())
291 case State
.InReadBinary
:
293 XPathNavigator nav
= GetElemNav();
294 state
= State
.InReadBinary
;
300 private XPathNavigator
GetElemNav(out int depth
) {
301 XPathNavigator nav
= null;
302 switch (this.state
) {
304 if (this.nodeType
== XmlNodeType
.Element
)
305 nav
= this.nav
.Clone();
308 case State
.Attribute
:
309 nav
= this.nav
.Clone();
311 depth
= this.depth
- 1;
314 nav
= this.nav
.Clone();
316 depth
= this.depth
- 2;
318 case State
.InReadBinary
:
320 nav
= GetElemNav(out depth
);
321 state
= State
.InReadBinary
;
330 private void MoveToAttr(XPathNavigator nav
, int depth
) {
331 this.nav
.MoveTo( nav
);
333 this.nodeType
= XmlNodeType
.Attribute
;
334 this.state
= State
.Attribute
;
337 public override int AttributeCount
{
339 if ( this.attrCount
< 0 ) {
340 // attribute count works for element, regardless of where you are in start tag
341 XPathNavigator tempNav
= GetElemNav();
343 if ( null != tempNav
) {
344 if( tempNav
.MoveToFirstNamespace( XPathNamespaceScope
.Local
) ) {
347 } while( tempNav
.MoveToNextNamespace( ( XPathNamespaceScope
.Local
) ) );
348 tempNav
.MoveToParent();
350 if( tempNav
.MoveToFirstAttribute() ) {
353 } while( tempNav
.MoveToNextAttribute() );
356 this.attrCount
= count
;
358 return this.attrCount
;
362 public override string GetAttribute( string name
) {
363 // reader allows calling GetAttribute, even when positioned inside attributes
364 XPathNavigator nav
= this.nav
;
365 switch (nav
.NodeType
) {
366 case XPathNodeType
.Element
:
368 case XPathNodeType
.Attribute
:
370 if (!nav
.MoveToParent())
376 string prefix
, localname
;
377 ValidateNames
.SplitQName( name
, out prefix
, out localname
);
378 if ( 0 == prefix
.Length
) {
379 if( localname
== "xmlns" )
380 return nav
.GetNamespace( string.Empty
);
381 if ( (object)nav
== (object)this.nav
)
383 if ( nav
.MoveToAttribute( localname
, string.Empty
) )
387 if( prefix
== "xmlns" )
388 return nav
.GetNamespace( localname
);
389 if ((object)nav
== (object)this.nav
)
391 if (nav
.MoveToFirstAttribute()) {
393 if (nav
.LocalName
== localname
&& nav
.Prefix
== prefix
)
395 } while (nav
.MoveToNextAttribute());
401 public override string GetAttribute( string localName
, string namespaceURI
) {
402 if ( null == localName
)
403 throw new ArgumentNullException("localName");
404 // reader allows calling GetAttribute, even when positioned inside attributes
405 XPathNavigator nav
= this.nav
;
406 switch (nav
.NodeType
) {
407 case XPathNodeType
.Element
:
409 case XPathNodeType
.Attribute
:
411 if (!nav
.MoveToParent())
417 // are they really looking for a namespace-decl?
418 if( namespaceURI
== XmlReservedNs
.NsXmlNs
) {
419 if (localName
== "xmlns")
420 localName
= string.Empty
;
421 return nav
.GetNamespace( localName
);
423 if ( null == namespaceURI
)
424 namespaceURI
= string.Empty
;
425 // We need to clone the navigator and move the clone to the attribute to see whether the attribute exists,
426 // because XPathNavigator.GetAttribute return string.Empty for both when the the attribute is not there or when
427 // it has an empty value. XmlReader.GetAttribute must return null if the attribute does not exist.
428 if ((object)nav
== (object)this.nav
)
430 if ( nav
.MoveToAttribute( localName
, namespaceURI
) ) {
438 private static string GetNamespaceByIndex( XPathNavigator nav
, int index
, out int count
) {
439 string thisValue
= nav
.Value
;
441 if ( nav
.MoveToNextNamespace( XPathNamespaceScope
.Local
) ) {
442 value = GetNamespaceByIndex( nav
, index
, out count
);
447 if ( count
== index
) {
448 Debug
.Assert( value == null );
455 public override string GetAttribute( int index
) {
458 XPathNavigator nav
= GetElemNav();
461 if ( nav
.MoveToFirstNamespace( XPathNamespaceScope
.Local
) ) {
462 // namespaces are returned in reverse order,
463 // but we want to return them in the correct order,
464 // so first count the namespaces
466 string value = GetNamespaceByIndex( nav
, index
, out nsCount
);
467 if ( null != value ) {
473 if ( nav
.MoveToFirstAttribute() ) {
478 } while ( nav
.MoveToNextAttribute() );
480 // can't find it... error
482 throw new ArgumentOutOfRangeException("index");
486 public override bool MoveToAttribute( string localName
, string namespaceName
) {
487 if ( null == localName
)
488 throw new ArgumentNullException("localName");
489 int depth
= this.depth
;
490 XPathNavigator nav
= GetElemNav(out depth
);
492 if ( namespaceName
== XmlReservedNs
.NsXmlNs
) {
493 if (localName
== "xmlns")
494 localName
= string.Empty
;
495 if( nav
.MoveToFirstNamespace( XPathNamespaceScope
.Local
) ) {
497 if ( nav
.LocalName
== localName
)
499 } while( nav
.MoveToNextNamespace( XPathNamespaceScope
.Local
) );
503 if (null == namespaceName
)
504 namespaceName
= string.Empty
;
505 if ( nav
.MoveToAttribute( localName
, namespaceName
) )
512 if ( state
== State
.InReadBinary
) {
513 readBinaryHelper
.Finish();
516 MoveToAttr(nav
, depth
+1);
520 public override bool MoveToFirstAttribute() {
522 XPathNavigator nav
= GetElemNav(out depth
);
524 if ( nav
.MoveToFirstNamespace( XPathNamespaceScope
.Local
) ) {
525 // attributes are in reverse order
526 while ( nav
.MoveToNextNamespace( XPathNamespaceScope
.Local
) )
530 if ( nav
.MoveToFirstAttribute() ) {
536 if ( state
== State
.InReadBinary
) {
537 readBinaryHelper
.Finish();
540 MoveToAttr(nav
, depth
+1);
544 public override bool MoveToNextAttribute() {
545 switch (this.state
) {
547 return MoveToFirstAttribute();
549 case State
.Attribute
: {
550 if (XPathNodeType
.Attribute
== this.nav
.NodeType
)
551 return this.nav
.MoveToNextAttribute();
553 // otherwise it is on a namespace... namespace are in reverse order
554 Debug
.Assert( XPathNodeType
.Namespace
== this.nav
.NodeType
);
555 XPathNavigator nav
= this.nav
.Clone();
556 if ( !nav
.MoveToParent() )
557 return false; // shouldn't happen
558 if ( !nav
.MoveToFirstNamespace( XPathNamespaceScope
.Local
) )
559 return false; // shouldn't happen
560 if ( nav
.IsSamePosition( this.nav
) ) {
561 // this was the last one... start walking attributes
563 if (!nav
.MoveToFirstAttribute())
565 // otherwise we are there
566 this.nav
.MoveTo(nav
);
570 XPathNavigator prev
= nav
.Clone();
572 if ( !nav
.MoveToNextNamespace( XPathNamespaceScope
.Local
) ) {
573 Debug
.Fail( "Couldn't find Namespace Node! Should not happen!" );
576 if ( nav
.IsSamePosition( this.nav
) ) {
577 this.nav
.MoveTo(prev
);
582 // found previous namespace position
587 this.state
= State
.Attribute
;
588 if (!MoveToNextAttribute()) {
590 this.state
= State
.AttrVal
;
593 this.nodeType
= XmlNodeType
.Attribute
;
596 case State
.InReadBinary
:
598 if (!MoveToNextAttribute()) {
599 state
= State
.InReadBinary
;
602 readBinaryHelper
.Finish();
610 public override bool MoveToAttribute( string name
) {
612 XPathNavigator nav
= GetElemNav(out depth
);
616 string prefix
, localname
;
617 ValidateNames
.SplitQName( name
, out prefix
, out localname
);
619 // watch for a namespace name
620 bool IsXmlnsNoPrefix
= false;
621 if ( ( IsXmlnsNoPrefix
= ( 0 == prefix
.Length
&& localname
== "xmlns" ) )
622 || ( prefix
== "xmlns" ) ) {
623 if ( IsXmlnsNoPrefix
)
624 localname
= string.Empty
;
625 if ( nav
.MoveToFirstNamespace(XPathNamespaceScope
.Local
) ) {
627 if (nav
.LocalName
== localname
)
629 } while ( nav
.MoveToNextNamespace(XPathNamespaceScope
.Local
) );
632 else if ( 0 == prefix
.Length
) {
633 // the empty prefix always means empty namespaceUri for attributes
634 if ( nav
.MoveToAttribute( localname
, string.Empty
) )
638 if ( nav
.MoveToFirstAttribute() ) {
640 if (nav
.LocalName
== localname
&& nav
.Prefix
== prefix
)
642 } while (nav
.MoveToNextAttribute());
648 if ( state
== State
.InReadBinary
) {
649 readBinaryHelper
.Finish();
652 MoveToAttr(nav
, depth
+1);
656 public override bool MoveToElement() {
657 switch (this.state
) {
658 case State
.Attribute
:
660 if (!nav
.MoveToParent())
663 if (this.state
== State
.AttrVal
)
665 this.state
= State
.Content
;
666 this.nodeType
= XmlNodeType
.Element
;
668 case State
.InReadBinary
:
670 if (!MoveToElement()) {
671 state
= State
.InReadBinary
;
674 readBinaryHelper
.Finish();
680 public override bool EOF
{
682 return this.state
== State
.EOF
;
686 public override ReadState ReadState
{
688 switch (this.state
) {
690 return ReadState
.Initial
;
692 case State
.EndElement
:
693 case State
.Attribute
:
695 case State
.InReadBinary
:
696 return ReadState
.Interactive
;
698 return ReadState
.EndOfFile
;
700 return ReadState
.Closed
;
702 return ReadState
.Error
;
707 public override void ResolveEntity() {
708 throw new InvalidOperationException( Res
.GetString( Res
.Xml_InvalidOperation
) );
711 public override bool ReadAttributeValue() {
712 if ( state
== State
.InReadBinary
) {
713 readBinaryHelper
.Finish();
716 if ( this.state
== State
.Attribute
) {
717 this.state
= State
.AttrVal
;
718 this.nodeType
= XmlNodeType
.Text
;
725 public override bool CanReadBinaryContent
{
731 public override int ReadContentAsBase64( byte[] buffer
, int index
, int count
) {
732 if ( ReadState
!= ReadState
.Interactive
) {
736 // init ReadContentAsBinaryHelper when called first time
737 if ( state
!= State
.InReadBinary
) {
738 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, this );
742 // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
745 // call to the helper
746 int readCount
= readBinaryHelper
.ReadContentAsBase64( buffer
, index
, count
);
748 // turn on InReadBinary state again and return
750 state
= State
.InReadBinary
;
754 public override int ReadContentAsBinHex( byte[] buffer
, int index
, int count
) {
755 if ( ReadState
!= ReadState
.Interactive
) {
759 // init ReadContentAsBinaryHelper when called first time
760 if ( state
!= State
.InReadBinary
) {
761 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, this );
765 // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
768 // call to the helper
769 int readCount
= readBinaryHelper
.ReadContentAsBinHex( buffer
, index
, count
);
771 // turn on InReadBinary state again and return
773 state
= State
.InReadBinary
;
777 public override int ReadElementContentAsBase64( byte[] buffer
, int index
, int count
) {
778 if ( ReadState
!= ReadState
.Interactive
) {
782 // init ReadContentAsBinaryHelper when called first time
783 if ( state
!= State
.InReadBinary
) {
784 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, this );
788 // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
791 // call to the helper
792 int readCount
= readBinaryHelper
.ReadElementContentAsBase64( buffer
, index
, count
);
794 // turn on InReadBinary state again and return
796 state
= State
.InReadBinary
;
800 public override int ReadElementContentAsBinHex( byte[] buffer
, int index
, int count
) {
801 if ( ReadState
!= ReadState
.Interactive
) {
805 // init ReadContentAsBinaryHelper when called first time
806 if ( state
!= State
.InReadBinary
) {
807 readBinaryHelper
= ReadContentAsBinaryHelper
.CreateOrReset( readBinaryHelper
, this );
811 // turn off InReadBinary state in order to have a normal Read() behavior when called from readBinaryHelper
814 // call to the helper
815 int readCount
= readBinaryHelper
.ReadElementContentAsBinHex( buffer
, index
, count
);
817 // turn on InReadBinary state again and return
819 state
= State
.InReadBinary
;
823 public override string LookupNamespace( string prefix
) {
824 return this.nav
.LookupNamespace( prefix
);
828 /// Current depth in subtree.
830 public override int Depth
{
831 get { return this.depth; }
835 /// Move to the next reader state. Return false if that is ReaderState.Closed.
837 public override bool Read() {
839 switch (this.state
) {
846 // Starting state depends on the navigator's item type
847 this.nav
= this.navToRead
;
848 this.state
= State
.Content
;
849 if ( XPathNodeType
.Root
== this.nav
.NodeType
) {
850 if( !nav
.MoveToFirstChild() ) {
854 this.readEntireDocument
= true;
856 else if ( XPathNodeType
.Attribute
== this.nav
.NodeType
) {
857 this.state
= State
.Attribute
;
859 this.nodeType
= ToXmlNodeType( this.nav
.NodeType
);
863 if ( this.nav
.MoveToFirstChild() ) {
864 this.nodeType
= ToXmlNodeType( this.nav
.NodeType
);
866 this.state
= State
.Content
;
868 else if ( this.nodeType
== XmlNodeType
.Element
869 && !this.nav
.IsEmptyElement
) {
870 this.nodeType
= XmlNodeType
.EndElement
;
871 this.state
= State
.EndElement
;
874 goto case State
.EndElement
;
877 case State
.EndElement
:
878 if ( 0 == depth
&& !this.readEntireDocument
) {
882 else if ( this.nav
.MoveToNext() ) {
883 this.nodeType
= ToXmlNodeType( this.nav
.NodeType
);
884 this.state
= State
.Content
;
886 else if ( depth
> 0 && this.nav
.MoveToParent() ) {
887 Debug
.Assert( this.nav
.NodeType
== XPathNodeType
.Element
, this.nav
.NodeType
.ToString() + " == XPathNodeType.Element" );
888 this.nodeType
= XmlNodeType
.EndElement
;
889 this.state
= State
.EndElement
;
898 case State
.Attribute
:
900 if ( !this.nav
.MoveToParent() ) {
904 this.nodeType
= ToXmlNodeType( this.nav
.NodeType
);
906 if (state
== State
.AttrVal
)
908 goto case State
.Content
;
909 case State
.InReadBinary
:
911 readBinaryHelper
.Finish();
919 /// End reading by transitioning into the Closed state.
921 public override void Close() {
922 this.nav
= XmlEmptyNavigator
.Singleton
;
923 this.nodeType
= XmlNodeType
.None
;
924 this.state
= State
.Closed
;
929 /// set reader to EOF state
931 private void SetEOF() {
932 this.nav
= XmlEmptyNavigator
.Singleton
;
933 this.nodeType
= XmlNodeType
.None
;
934 this.state
= State
.EOF
;
939 #if NAVREADER_SUPPORTSLINEINFO
940 internal class XPathNavigatorReaderWithLI
: XPathNavigatorReader
, System
.Xml
.IXmlLineInfo
{
941 internal XPathNavigatorReaderWithLI( XPathNavigator navToRead
, IXmlLineInfo xli
, IXmlSchemaInfo xsi
)
942 : base( navToRead
, xli
, xsi
) {
945 //-----------------------------------------------
947 //-----------------------------------------------
949 public virtual bool HasLineInfo() { return IsReading ? this.lineInfo.HasLineInfo() : false; }
950 public virtual int LineNumber { get { return IsReading ? this.lineInfo.LineNumber : 0; }
}
951 public virtual int LinePosition { get { return IsReading ? this.lineInfo.LinePosition : 0; }
}
954 internal class XPathNavigatorReaderWithLIAndSI
: XPathNavigatorReaderWithLI
, System
.Xml
.IXmlLineInfo
, System
.Xml
.Schema
.IXmlSchemaInfo
{
955 internal XPathNavigatorReaderWithLIAndSI( XPathNavigator navToRead
, IXmlLineInfo xli
, IXmlSchemaInfo xsi
)
956 : base( navToRead
, xli
, xsi
) {
959 //-----------------------------------------------
961 //-----------------------------------------------
963 public virtual XmlSchemaValidity Validity { get { return IsReading ? this.schemaInfo.Validity : XmlSchemaValidity.NotKnown; }
}
964 public override bool IsDefault { get { return IsReading ? this.schemaInfo.IsDefault : false; }
}
965 public virtual bool IsNil { get { return IsReading ? this.schemaInfo.IsNil : false; }
}
966 public virtual XmlSchemaSimpleType MemberType { get { return IsReading ? this.schemaInfo.MemberType : null; }
}
967 public virtual XmlSchemaType SchemaType { get { return IsReading ? this.schemaInfo.SchemaType : null; }
}
968 public virtual XmlSchemaElement SchemaElement { get { return IsReading ? this.schemaInfo.SchemaElement : null; }
}
969 public virtual XmlSchemaAttribute SchemaAttribute { get { return IsReading ? this.schemaInfo.SchemaAttribute : null; }
}
973 internal class XPathNavigatorReaderWithSI
: XPathNavigatorReader
, System
.Xml
.Schema
.IXmlSchemaInfo
{
974 internal XPathNavigatorReaderWithSI( XPathNavigator navToRead
, IXmlLineInfo xli
, IXmlSchemaInfo xsi
)
975 : base( navToRead
, xli
, xsi
) {
978 //-----------------------------------------------
980 //-----------------------------------------------
982 public virtual XmlSchemaValidity Validity { get { return IsReading ? this.schemaInfo.Validity : XmlSchemaValidity.NotKnown; }
}
983 public override bool IsDefault { get { return IsReading ? this.schemaInfo.IsDefault : false; }
}
984 public virtual bool IsNil { get { return IsReading ? this.schemaInfo.IsNil : false; }
}
985 public virtual XmlSchemaSimpleType MemberType { get { return IsReading ? this.schemaInfo.MemberType : null; }
}
986 public virtual XmlSchemaType SchemaType { get { return IsReading ? this.schemaInfo.SchemaType : null; }
}
987 public virtual XmlSchemaElement SchemaElement { get { return IsReading ? this.schemaInfo.SchemaElement : null; }
}
988 public virtual XmlSchemaAttribute SchemaAttribute { get { return IsReading ? this.schemaInfo.SchemaAttribute : null; }
}
992 /// The XmlEmptyNavigator exposes a document node with no children.
993 /// Only one XmlEmptyNavigator exists per AppDomain (Singleton). That's why the constructor is private.
994 /// Use the Singleton property to get the EmptyNavigator.
996 internal class XmlEmptyNavigator
: XPathNavigator
{
997 private static volatile XmlEmptyNavigator singleton
;
999 private XmlEmptyNavigator() {
1002 public static XmlEmptyNavigator Singleton
{
1004 if (XmlEmptyNavigator
.singleton
== null)
1005 XmlEmptyNavigator
.singleton
= new XmlEmptyNavigator();
1006 return XmlEmptyNavigator
.singleton
;
1010 //-----------------------------------------------
1012 //-----------------------------------------------
1014 public override XPathNodeType NodeType
{
1015 get { return XPathNodeType.All; }
1018 public override string NamespaceURI
{
1019 get { return string.Empty; }
1022 public override string LocalName
{
1023 get { return string.Empty; }
1026 public override string Name
{
1027 get { return string.Empty; }
1030 public override string Prefix
{
1031 get { return string.Empty; }
1034 public override string BaseURI
{
1035 get { return string.Empty; }
1038 public override string Value
{
1039 get { return string.Empty; }
1042 public override bool IsEmptyElement
{
1043 get { return false; }
1046 public override string XmlLang
{
1047 get { return string.Empty; }
1050 public override bool HasAttributes
{
1051 get { return false; }
1054 public override bool HasChildren
{
1055 get { return false; }
1059 //-----------------------------------------------
1060 // IXmlNamespaceResolver
1061 //-----------------------------------------------
1063 public override XmlNameTable NameTable
{
1064 get { return new NameTable(); }
1067 public override bool MoveToFirstChild() {
1071 public override void MoveToRoot() {
1076 public override bool MoveToNext() {
1080 public override bool MoveToPrevious() {
1084 public override bool MoveToFirst() {
1088 public override bool MoveToFirstAttribute() {
1092 public override bool MoveToNextAttribute() {
1096 public override bool MoveToId(string id
) {
1100 public override string GetAttribute(string localName
, string namespaceName
) {
1104 public override bool MoveToAttribute(string localName
, string namespaceName
) {
1108 public override string GetNamespace( string name
) {
1112 public override bool MoveToNamespace( string prefix
) {
1117 public override bool MoveToFirstNamespace(XPathNamespaceScope scope
) {
1121 public override bool MoveToNextNamespace(XPathNamespaceScope scope
) {
1125 public override bool MoveToParent() {
1129 public override bool MoveTo(XPathNavigator other
) {
1130 // Only one instance of XmlEmptyNavigator exists on the system
1131 return (object) this == (object) other
;
1134 public override XmlNodeOrder
ComparePosition(XPathNavigator other
) {
1135 // Only one instance of XmlEmptyNavigator exists on the system
1136 return ((object) this == (object) other
) ? XmlNodeOrder
.Same
: XmlNodeOrder
.Unknown
;
1139 public override bool IsSamePosition(XPathNavigator other
) {
1140 // Only one instance of XmlEmptyNavigator exists on the system
1141 return (object) this == (object) other
;
1145 //-----------------------------------------------
1147 //-----------------------------------------------
1148 public override XPathNavigator
Clone() {
1149 // Singleton, so clone just returns this