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