DataDocumentXPathNavigator.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. internal sealed class DataDocumentXPathNavigator: XPathNavigator, IHasXmlNode {
  13. private XPathNodePointer _curNode; //pointer to remember the current node position
  14. private XmlDataDocument _doc; //pointer to remember the root -- can only be XmlDataDocument for DataDocumentXPathNavigator
  15. private XPathNodePointer _temp;
  16. internal DataDocumentXPathNavigator( XmlDataDocument doc, XmlNode node ) {
  17. _curNode = new XPathNodePointer( this, doc, node );
  18. _temp = new XPathNodePointer( this, doc, node );
  19. _doc = doc;
  20. }
  21. private DataDocumentXPathNavigator( DataDocumentXPathNavigator other ) {
  22. this._curNode = other._curNode.Clone( this );
  23. this._temp = other._temp.Clone( this );
  24. this._doc = other._doc;
  25. }
  26. public override XPathNavigator Clone(){
  27. return new DataDocumentXPathNavigator( this );
  28. }
  29. internal XPathNodePointer CurNode { get { return _curNode; } }
  30. internal XmlDataDocument Document { get { return _doc; } }
  31. //Convert will deal with nodeType as Attribute or Namespace nodes
  32. public override XPathNodeType NodeType { get { return _curNode.NodeType; } }
  33. public override string LocalName { get { return _curNode.LocalName; } }
  34. public override string NamespaceURI { get { return _curNode.NamespaceURI; } }
  35. public override string Name { get { return _curNode.Name; } }
  36. public override string Prefix { get { return _curNode.Prefix; } }
  37. public override string Value {
  38. get {
  39. XPathNodeType xnt = _curNode.NodeType;
  40. if ( xnt == XPathNodeType.Element || xnt == XPathNodeType.Root )
  41. return _curNode.InnerText;
  42. return _curNode.Value;
  43. }
  44. }
  45. public override String BaseURI { get { return _curNode.BaseURI; } }
  46. public override String XmlLang { get { return _curNode.XmlLang; } }
  47. public override bool IsEmptyElement { get { return _curNode.IsEmptyElement; } }
  48. public override XmlNameTable NameTable { get { return _doc.NameTable; } }
  49. // Attributes
  50. public override bool HasAttributes { get { return _curNode.AttributeCount > 0; } }
  51. public override string GetAttribute( string localName, string namespaceURI ) {
  52. if ( _curNode.NodeType != XPathNodeType.Element )
  53. return string.Empty; //other type of nodes can't have attributes
  54. _temp.MoveTo( _curNode );
  55. if ( _temp.MoveToAttribute( localName, namespaceURI ) )
  56. return _temp.Value;
  57. return string.Empty;
  58. }
  59. //#if SupportNamespaces
  60. public override string GetNamespace(string name) {
  61. return _curNode.GetNamespace( name );
  62. }
  63. public override bool MoveToNamespace(string name) {
  64. if ( _curNode.NodeType != XPathNodeType.Element )
  65. return false;
  66. return _curNode.MoveToNamespace( name );
  67. }
  68. public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) {
  69. if ( _curNode.NodeType != XPathNodeType.Element )
  70. return false;
  71. return _curNode.MoveToFirstNamespace(namespaceScope);
  72. }
  73. public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) {
  74. if ( _curNode.NodeType != XPathNodeType.Namespace )
  75. return false;
  76. return _curNode.MoveToNextNamespace(namespaceScope);
  77. }
  78. //#endif
  79. public override bool MoveToAttribute( string localName, string namespaceURI ) {
  80. if ( _curNode.NodeType != XPathNodeType.Element )
  81. return false; //other type of nodes can't have attributes
  82. return _curNode.MoveToAttribute( localName, namespaceURI );
  83. }
  84. public override bool MoveToFirstAttribute() {
  85. if ( _curNode.NodeType != XPathNodeType.Element )
  86. return false; //other type of nodes can't have attributes
  87. return _curNode.MoveToNextAttribute(true);
  88. }
  89. public override bool MoveToNextAttribute() {
  90. if ( _curNode.NodeType != XPathNodeType.Attribute )
  91. return false;
  92. return _curNode.MoveToNextAttribute(false);
  93. }
  94. // Tree
  95. public override bool MoveToNext() {
  96. if ( _curNode.NodeType == XPathNodeType.Attribute )
  97. return false;
  98. return _curNode.MoveToNextSibling();
  99. }
  100. public override bool MoveToPrevious() {
  101. if ( _curNode.NodeType == XPathNodeType.Attribute )
  102. return false;
  103. return _curNode.MoveToPreviousSibling();
  104. }
  105. public override bool MoveToFirst() {
  106. if ( _curNode.NodeType == XPathNodeType.Attribute )
  107. return false;
  108. return _curNode.MoveToFirst();
  109. }
  110. public override bool HasChildren { get { return _curNode.HasChildren; } }
  111. public override bool MoveToFirstChild() {
  112. return _curNode.MoveToFirstChild();
  113. }
  114. public override bool MoveToParent() {
  115. return _curNode.MoveToParent();
  116. }
  117. public override void MoveToRoot() {
  118. _curNode.MoveToRoot();
  119. }
  120. public override bool MoveTo( XPathNavigator other ) {
  121. if ( other == null )
  122. return false;
  123. DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
  124. if ( otherDataDocXPathNav != null ) {
  125. if ( _curNode.MoveTo( otherDataDocXPathNav.CurNode ) ) {
  126. _doc = _curNode.Document;
  127. return true;
  128. }
  129. else
  130. return false;
  131. }
  132. return false;
  133. }
  134. //doesn't support MoveToId
  135. public override bool MoveToId( string id ) {
  136. return false;
  137. }
  138. public override bool IsSamePosition( XPathNavigator other ) {
  139. if ( other == null )
  140. return false;
  141. DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
  142. if ( otherDataDocXPathNav != null ) {
  143. if ( this._doc == otherDataDocXPathNav.Document && this._curNode.IsSamePosition(otherDataDocXPathNav.CurNode) )
  144. return true;
  145. }
  146. return false;
  147. }
  148. //the function is only called for XPathNodeList enumerate nodes and
  149. // shouldn't be promoted to frequently use because it will cause foliation
  150. XmlNode IHasXmlNode.GetNode() { return _curNode.Node; }
  151. public override XmlNodeOrder ComparePosition( XPathNavigator other ) {
  152. if ( other == null )
  153. return XmlNodeOrder.Unknown; // this is what XPathDocument does. // WebData 103403
  154. DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
  155. if ( otherDataDocXPathNav == null || otherDataDocXPathNav.Document != this._doc )
  156. return XmlNodeOrder.Unknown;
  157. return this._curNode.ComparePosition( otherDataDocXPathNav.CurNode );
  158. }
  159. }
  160. }