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
67 && ((XmlElement) node).IsEmpty;
71 public override string LocalName {
73 XPathNodeType nodeType = NodeType;
75 nodeType == XPathNodeType.Element ||
76 nodeType == XPathNodeType.Attribute ||
77 nodeType == XPathNodeType.ProcessingInstruction ||
78 nodeType == XPathNodeType.Namespace;
79 return canHaveName ? node.LocalName : String.Empty;
83 public override string Name {
85 XPathNodeType nodeType = NodeType;
87 nodeType == XPathNodeType.Element ||
88 nodeType == XPathNodeType.Attribute ||
89 nodeType == XPathNodeType.ProcessingInstruction ||
90 nodeType == XPathNodeType.Namespace;
91 return canHaveName ? node.Name : String.Empty;
95 public override string NamespaceURI {
97 return node.NamespaceURI;
101 public override XmlNameTable NameTable {
103 return document.NameTable;
107 public override XPathNodeType NodeType {
109 return node.XPathNodeType;
113 public override string Prefix {
119 public override string Value {
122 case XPathNodeType.Attribute:
123 case XPathNodeType.Comment:
124 case XPathNodeType.ProcessingInstruction:
125 case XPathNodeType.Text:
126 case XPathNodeType.Whitespace:
127 case XPathNodeType.SignificantWhitespace:
129 case XPathNodeType.Element:
130 case XPathNodeType.Root:
131 return node.InnerText;
137 public override string XmlLang {
147 public override XPathNavigator Clone ()
149 return new XmlDocumentNavigator (node);
152 public override string GetAttribute (string localName, string namespaceURI)
154 XmlElement el = Node as XmlElement;
155 return el != null ? el.GetAttribute (localName, namespaceURI) : String.Empty;
158 public override string GetNamespace (string name)
160 // MSDN says "String.Empty if a matching namespace
161 // node is not found or if the navigator is not
162 // positioned on an element node", but in fact it
163 // returns actual namespace for the other nodes.
164 return Node.GetNamespaceOfPrefix (name);
167 public override bool IsSamePosition (XPathNavigator other)
169 XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
170 if (otherDocumentNavigator != null)
171 return node == otherDocumentNavigator.node;
175 public override bool MoveTo (XPathNavigator other)
177 XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
178 if (otherDocumentNavigator != null) {
179 if (document == otherDocumentNavigator.document) {
180 node = otherDocumentNavigator.node;
187 public override bool MoveToAttribute (string localName, string namespaceURI)
189 attributesEnumerator = node.Attributes.GetEnumerator ();
190 while (attributesEnumerator.MoveNext ()) {
191 XmlAttribute attr = attributesEnumerator.Current as XmlAttribute;
192 if (attr.LocalName == localName && attr.NamespaceURI == namespaceURI) {
200 public override bool MoveToFirst ()
202 if (node.NodeType != XmlNodeType.Attribute && node.ParentNode != null) {
204 // Follow these 2 steps so that we can skip
205 // some types of nodes .
212 public override bool MoveToFirstAttribute ()
214 if (NodeType == XPathNodeType.Element) {
215 attributesEnumerator = node.Attributes.GetEnumerator ();
216 return MoveToNextAttribute ();
221 public override bool MoveToFirstChild ()
224 if (node == document) {
225 XmlNode n = node.FirstChild;
230 switch (n.NodeType) {
231 case XmlNodeType.XmlDeclaration:
232 case XmlNodeType.DocumentType:
245 node = node.FirstChild;
252 public override bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope)
254 throw new NotImplementedException ();
257 public override bool MoveToId (string id)
259 XmlElement eltNew = document.GetElementById (id);
268 public override bool MoveToNamespace (string name)
270 throw new NotImplementedException ();
273 public override bool MoveToNext ()
275 if (node.NextSibling != null) {
276 if (node.ParentNode != null && node.ParentNode.NodeType == XmlNodeType.Document) {
277 XmlNode n = node.NextSibling;
279 switch (n.NodeType) {
280 case XmlNodeType.DocumentType:
281 case XmlNodeType.XmlDeclaration:
293 node = node.NextSibling;
300 public override bool MoveToNextAttribute ()
302 if (attributesEnumerator != null && attributesEnumerator.MoveNext ()) {
303 node = attributesEnumerator.Current as XmlAttribute;
310 public override bool MoveToNextNamespace (XPathNamespaceScope namespaceScope)
312 throw new NotImplementedException ();
315 public override bool MoveToParent ()
317 if (node.NodeType == XmlNodeType.Attribute) {
318 XmlElement ownerElement = ((XmlAttribute)node).OwnerElement;
319 if (ownerElement != null) {
323 } else if (node.ParentNode != null) {
324 node = node.ParentNode;
330 public override bool MoveToPrevious ()
332 if (node.PreviousSibling != null) {
333 node = node.PreviousSibling;
339 public override void MoveToRoot ()
344 internal XmlNode Node { get { return node; } }
346 XmlNode IHasXmlNode.GetNode ()