2 // System.Xml.XmlDocumentNavigator
5 // Jason Diamond <jason@injektilo.org>
7 // (C) 2002 Jason Diamond
11 using System.Collections;
\r
13 using System.Xml.XPath;
\r
15 namespace System.Xml
\r
17 internal class XmlDocumentNavigator : XPathNavigator, IHasXmlNode
\r
19 #region Constructors
\r
21 internal XmlDocumentNavigator(XmlNode node)
\r
24 this.document = node.NodeType == XmlNodeType.Document ?
\r
25 node as XmlDocument : node.OwnerDocument;
\r
32 private XmlNode node;
\r
33 private XmlDocument document;
\r
34 private IEnumerator attributesEnumerator;
\r
40 public override string BaseURI {
46 public override bool HasAttributes {
48 if (node.Attributes != null)
49 foreach (XmlAttribute attribute in node.Attributes)
50 if (attribute.NamespaceURI != "http://www.w3.org/2000/xmlns/")
56 public override bool HasChildren {
58 XPathNodeType nodeType = NodeType;
59 bool canHaveChildren = nodeType == XPathNodeType.Root || nodeType == XPathNodeType.Element;
60 return canHaveChildren && node.FirstChild != null;
64 public override bool IsEmptyElement {
66 return node.NodeType == XmlNodeType.Element && !HasChildren;
70 public override string LocalName {
72 XPathNodeType nodeType = NodeType;
74 nodeType == XPathNodeType.Element ||
75 nodeType == XPathNodeType.Attribute ||
76 nodeType == XPathNodeType.ProcessingInstruction ||
77 nodeType == XPathNodeType.Namespace;
78 return canHaveName ? node.LocalName : String.Empty;
82 public override string Name {
84 XPathNodeType nodeType = NodeType;
86 nodeType == XPathNodeType.Element ||
87 nodeType == XPathNodeType.Attribute ||
88 nodeType == XPathNodeType.ProcessingInstruction ||
89 nodeType == XPathNodeType.Namespace;
90 return canHaveName ? node.Name : String.Empty;
94 public override string NamespaceURI {
96 return node.NamespaceURI;
100 public override XmlNameTable NameTable {
102 return document.NameTable;
106 public override XPathNodeType NodeType {
108 return node.XPathNodeType;
112 public override string Prefix {
118 public override string Value {
121 case XPathNodeType.Attribute:
122 case XPathNodeType.Comment:
123 case XPathNodeType.ProcessingInstruction:
124 case XPathNodeType.Text:
125 case XPathNodeType.Whitespace:
126 case XPathNodeType.SignificantWhitespace:
128 case XPathNodeType.Element:
129 case XPathNodeType.Root:
130 return node.InnerText;
136 public override string XmlLang {
146 public override XPathNavigator Clone ()
148 return new XmlDocumentNavigator (node);
151 public override string GetAttribute (string localName, string namespaceURI)
153 XmlElement el = Node as XmlElement;
154 return (el != null) ? el.GetAttribute (localName, namespaceURI) : String.Empty;
157 public override string GetNamespace (string name)
159 // MSDN says "String.Empty if a matching namespace
160 // node is not found or if the navigator is not
161 // positioned on an element node", but in fact it
162 // returns actual namespace for the other nodes.
163 return Node.GetNamespaceOfPrefix (name);
166 public override bool IsSamePosition (XPathNavigator other)
168 XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
169 if (otherDocumentNavigator != null)
170 return node == otherDocumentNavigator.node;
174 public override bool MoveTo (XPathNavigator other)
176 XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
177 if (otherDocumentNavigator != null) {
178 if (document == otherDocumentNavigator.document) {
179 node = otherDocumentNavigator.node;
186 public override bool MoveToAttribute (string localName, string namespaceURI)
188 attributesEnumerator = node.Attributes.GetEnumerator ();
189 while (attributesEnumerator.MoveNext ()) {
190 XmlAttribute attr = attributesEnumerator.Current as XmlAttribute;
191 if (attr.LocalName == localName && attr.NamespaceURI == namespaceURI) {
199 public override bool MoveToFirst ()
201 if (node.NodeType != XmlNodeType.Attribute && node.ParentNode != null) {
202 node = node.ParentNode.FirstChild;
208 public override bool MoveToFirstAttribute ()
210 if (NodeType == XPathNodeType.Element) {
211 attributesEnumerator = node.Attributes.GetEnumerator ();
212 return MoveToNextAttribute ();
217 public override bool MoveToFirstChild ()
220 if (node == document) {
221 XmlNode n = node.FirstChild;
226 switch (n.NodeType) {
227 case XmlNodeType.XmlDeclaration:
228 case XmlNodeType.DocumentType:
241 node = node.FirstChild;
248 public override bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope)
250 throw new NotImplementedException ();
253 public override bool MoveToId (string id)
255 XmlElement eltNew = document.GetElementById (id);
264 public override bool MoveToNamespace (string name)
266 throw new NotImplementedException ();
269 public override bool MoveToNext ()
271 if (node.NextSibling != null) {
272 node = node.NextSibling;
278 public override bool MoveToNextAttribute ()
280 if (attributesEnumerator != null && attributesEnumerator.MoveNext ()) {
281 node = attributesEnumerator.Current as XmlAttribute;
288 public override bool MoveToNextNamespace (XPathNamespaceScope namespaceScope)
290 throw new NotImplementedException ();
293 public override bool MoveToParent ()
295 if (node.NodeType == XmlNodeType.Attribute) {
296 XmlElement ownerElement = ((XmlAttribute)node).OwnerElement;
297 if (ownerElement != null) {
301 } else if (node.ParentNode != null) {
302 node = node.ParentNode;
308 public override bool MoveToPrevious ()
310 if (node.PreviousSibling != null) {
311 node = node.PreviousSibling;
317 public override void MoveToRoot ()
322 internal XmlNode Node { get { return node; } }
324 XmlNode IHasXmlNode.GetNode ()