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