1 //------------------------------------------------------------------------------ 2 // <copyright file="DataDocumentXPathNavigator.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // <owner current="true" primary="true">Microsoft</owner> 6 // <owner current="true" primary="false">Microsoft</owner> 7 //------------------------------------------------------------------------------ 8 #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument 9 namespace System.Xml { 10 using System; 11 using System.Xml.XPath; 12 13 internal sealed class DataDocumentXPathNavigator: XPathNavigator, IHasXmlNode { 14 private XPathNodePointer _curNode; //pointer to remember the current node position 15 private XmlDataDocument _doc; //pointer to remember the root -- can only be XmlDataDocument for DataDocumentXPathNavigator 16 private XPathNodePointer _temp; 17 DataDocumentXPathNavigator( XmlDataDocument doc, XmlNode node )18 internal DataDocumentXPathNavigator( XmlDataDocument doc, XmlNode node ) { 19 _curNode = new XPathNodePointer( this, doc, node ); 20 _temp = new XPathNodePointer( this, doc, node ); 21 _doc = doc; 22 } 23 DataDocumentXPathNavigator( DataDocumentXPathNavigator other )24 private DataDocumentXPathNavigator( DataDocumentXPathNavigator other ) { 25 this._curNode = other._curNode.Clone( this ); 26 this._temp = other._temp.Clone( this ); 27 this._doc = other._doc; 28 } Clone()29 public override XPathNavigator Clone(){ 30 return new DataDocumentXPathNavigator( this ); 31 } 32 33 internal XPathNodePointer CurNode { get { return _curNode; } } 34 internal XmlDataDocument Document { get { return _doc; } } 35 36 //Convert will deal with nodeType as Attribute or Namespace nodes 37 public override XPathNodeType NodeType { get { return _curNode.NodeType; } } 38 39 public override string LocalName { get { return _curNode.LocalName; } } 40 41 public override string NamespaceURI { get { return _curNode.NamespaceURI; } } 42 43 public override string Name { get { return _curNode.Name; } } 44 45 public override string Prefix { get { return _curNode.Prefix; } } 46 47 public override string Value { 48 get { 49 XPathNodeType xnt = _curNode.NodeType; 50 if ( xnt == XPathNodeType.Element || xnt == XPathNodeType.Root ) 51 return _curNode.InnerText; 52 return _curNode.Value; 53 } 54 } 55 56 public override String BaseURI { get { return _curNode.BaseURI; } } 57 58 public override String XmlLang { get { return _curNode.XmlLang; } } 59 60 public override bool IsEmptyElement { get { return _curNode.IsEmptyElement; } } 61 62 public override XmlNameTable NameTable { get { return _doc.NameTable; } } 63 64 // Attributes 65 public override bool HasAttributes { get { return _curNode.AttributeCount > 0; } } 66 GetAttribute( string localName, string namespaceURI )67 public override string GetAttribute( string localName, string namespaceURI ) { 68 if ( _curNode.NodeType != XPathNodeType.Element ) 69 return string.Empty; //other type of nodes can't have attributes 70 _temp.MoveTo( _curNode ); 71 if ( _temp.MoveToAttribute( localName, namespaceURI ) ) 72 return _temp.Value; 73 return string.Empty; 74 } 75 76 //#if SupportNamespaces 77 GetNamespace(string name)78 public override string GetNamespace(string name) { 79 return _curNode.GetNamespace( name ); 80 } 81 MoveToNamespace(string name)82 public override bool MoveToNamespace(string name) { 83 if ( _curNode.NodeType != XPathNodeType.Element ) 84 return false; 85 return _curNode.MoveToNamespace( name ); 86 } 87 MoveToFirstNamespace(XPathNamespaceScope namespaceScope)88 public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) { 89 if ( _curNode.NodeType != XPathNodeType.Element ) 90 return false; 91 return _curNode.MoveToFirstNamespace(namespaceScope); 92 } 93 MoveToNextNamespace(XPathNamespaceScope namespaceScope)94 public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) { 95 if ( _curNode.NodeType != XPathNodeType.Namespace ) 96 return false; 97 return _curNode.MoveToNextNamespace(namespaceScope); 98 } 99 //#endif 100 MoveToAttribute( string localName, string namespaceURI )101 public override bool MoveToAttribute( string localName, string namespaceURI ) { 102 if ( _curNode.NodeType != XPathNodeType.Element ) 103 return false; //other type of nodes can't have attributes 104 return _curNode.MoveToAttribute( localName, namespaceURI ); 105 } 106 MoveToFirstAttribute()107 public override bool MoveToFirstAttribute() { 108 if ( _curNode.NodeType != XPathNodeType.Element ) 109 return false; //other type of nodes can't have attributes 110 return _curNode.MoveToNextAttribute(true); 111 } 112 MoveToNextAttribute()113 public override bool MoveToNextAttribute() { 114 if ( _curNode.NodeType != XPathNodeType.Attribute ) 115 return false; 116 return _curNode.MoveToNextAttribute(false); 117 } 118 119 120 // Tree MoveToNext()121 public override bool MoveToNext() { 122 if ( _curNode.NodeType == XPathNodeType.Attribute ) 123 return false; 124 return _curNode.MoveToNextSibling(); 125 } 126 MoveToPrevious()127 public override bool MoveToPrevious() { 128 if ( _curNode.NodeType == XPathNodeType.Attribute ) 129 return false; 130 return _curNode.MoveToPreviousSibling(); 131 } 132 MoveToFirst()133 public override bool MoveToFirst() { 134 if ( _curNode.NodeType == XPathNodeType.Attribute ) 135 return false; 136 return _curNode.MoveToFirst(); 137 } 138 139 public override bool HasChildren { get { return _curNode.HasChildren; } } 140 MoveToFirstChild()141 public override bool MoveToFirstChild() { 142 return _curNode.MoveToFirstChild(); 143 } 144 MoveToParent()145 public override bool MoveToParent() { 146 return _curNode.MoveToParent(); 147 } 148 MoveToRoot()149 public override void MoveToRoot() { 150 _curNode.MoveToRoot(); 151 } 152 MoveTo( XPathNavigator other )153 public override bool MoveTo( XPathNavigator other ) { 154 if ( other == null ) 155 return false; 156 DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator; 157 if ( otherDataDocXPathNav != null ) { 158 if ( _curNode.MoveTo( otherDataDocXPathNav.CurNode ) ) { 159 _doc = _curNode.Document; 160 return true; 161 } 162 else 163 return false; 164 } 165 return false; 166 } 167 168 //doesn't support MoveToId MoveToId( string id )169 public override bool MoveToId( string id ) { 170 return false; 171 } 172 IsSamePosition( XPathNavigator other )173 public override bool IsSamePosition( XPathNavigator other ) { 174 if ( other == null ) 175 return false; 176 DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator; 177 if ( otherDataDocXPathNav != null ) { 178 if ( this._doc == otherDataDocXPathNav.Document && this._curNode.IsSamePosition(otherDataDocXPathNav.CurNode) ) 179 return true; 180 } 181 return false; 182 } 183 184 //the function is only called for XPathNodeList enumerate nodes and 185 // shouldn't be promoted to frequently use because it will cause foliation IHasXmlNode.GetNode()186 XmlNode IHasXmlNode.GetNode() { return _curNode.Node; } 187 ComparePosition( XPathNavigator other )188 public override XmlNodeOrder ComparePosition( XPathNavigator other ) { 189 if ( other == null ) 190 return XmlNodeOrder.Unknown; // this is what XPathDocument does. // WebData 103403 191 192 DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator; 193 194 if ( otherDataDocXPathNav == null || otherDataDocXPathNav.Document != this._doc ) 195 return XmlNodeOrder.Unknown; 196 197 return this._curNode.ComparePosition( otherDataDocXPathNav.CurNode ); 198 } 199 200 } 201 202 } 203