2 // Mono.Xml.XPath.XPathDocument2Navigator.cs
\r
5 // Atsushi Enomoto <atsushi@ximian.com>
\r
7 // (C)2004 Novell Inc.
\r
9 // read-only XPathNavigator for editable XPathDocument.
\r
13 // Permission is hereby granted, free of charge, to any person obtaining
\r
14 // a copy of this software and associated documentation files (the
\r
15 // "Software"), to deal in the Software without restriction, including
\r
16 // without limitation the rights to use, copy, modify, merge, publish,
\r
17 // distribute, sublicense, and/or sell copies of the Software, and to
\r
18 // permit persons to whom the Software is furnished to do so, subject to
\r
19 // the following conditions:
\r
21 // The above copyright notice and this permission notice shall be
\r
22 // included in all copies or substantial portions of the Software.
\r
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 using System.Collections;
\r
35 using System.Collections.Specialized;
\r
39 using System.Xml.XPath;
\r
41 namespace Mono.Xml.XPath
\r
43 public class XomNavigator : XPathNavigator, IHasXomNode
\r
47 XomNamespace currentNS;
\r
49 public XomNavigator (XomRoot root)
\r
55 public override string BaseURI {
\r
56 get { return current.BaseURI; }
\r
59 public override bool IsEmptyElement {
\r
60 get { return currentNS == null && current.IsEmptyElement; }
\r
63 public override bool HasChildren {
\r
64 get { return currentNS == null && current.ChildCount != 0; }
\r
67 public override bool HasAttributes {
\r
69 if (currentNS != null || current.NodeType != XPathNodeType.Element)
\r
71 XomElement el = current as XomElement;
\r
72 return el.AttributeCount != 0;
\r
76 XomNode IHasXomNode.GetNode ()
\r
78 return currentNS != null ? currentNS : current;
\r
81 public override string GetAttribute (string name, string ns)
\r
83 if (currentNS != null || current.NodeType != XPathNodeType.Element)
\r
84 return String.Empty;
\r
85 XomElement el = current as XomElement;
\r
86 XomAttribute attr = el.GetAttribute (name, ns);
\r
87 return attr != null ? attr.Value : String.Empty;
\r
90 public override XmlNameTable NameTable {
\r
91 get { return current.Root.NameTable; }
\r
94 public override string LocalName {
\r
95 get { return current.LocalName; }
\r
98 public override string Name {
\r
99 get { return current.PrefixedName; }
\r
102 public override string NamespaceURI {
\r
103 get { return current.Namespace; }
\r
106 public override string Prefix {
\r
107 get { return current.Prefix; }
\r
110 public override string Value {
\r
112 switch (NodeType) {
\r
113 case XPathNodeType.Attribute:
\r
114 case XPathNodeType.Comment:
\r
115 case XPathNodeType.ProcessingInstruction:
\r
116 return current.Value;
\r
117 case XPathNodeType.Text:
\r
118 case XPathNodeType.Whitespace:
\r
119 case XPathNodeType.SignificantWhitespace:
\r
120 string value = current.Value;
\r
121 for (XomNode n = current.NextSibling; n != null; n = n.NextSibling) {
\r
122 switch (n.NodeType) {
\r
123 case XPathNodeType.Text:
\r
124 case XPathNodeType.Whitespace:
\r
125 case XPathNodeType.SignificantWhitespace:
\r
132 case XPathNodeType.Element:
\r
133 case XPathNodeType.Root:
\r
134 return current.Value;
\r
135 case XPathNodeType.Namespace:
\r
136 return currentNS.Value;
\r
138 return String.Empty;
\r
142 public override string XmlLang {
\r
143 get { return current.XmlLang; }
\r
146 public override XPathNodeType NodeType {
\r
147 get { return current.NodeType; }
\r
150 public override XPathNavigator Clone ()
\r
152 XomNavigator n = new XomNavigator (root);
\r
153 n.current = current;
\r
154 n.currentNS = currentNS;
\r
158 public override void MoveToRoot ()
\r
164 public override bool MoveToParent ()
\r
166 if (currentNS != null) {
\r
170 XomParentNode parent = current.Parent;
\r
171 if (parent == null)
\r
177 public override bool MoveToFirstChild ()
\r
179 if (currentNS != null || current.NodeType == XPathNodeType.Attribute || current.ChildCount == 0)
\r
181 current = current.FirstChild;
\r
185 public override bool MoveToFirst ()
\r
187 if (currentNS != null || current.NodeType == XPathNodeType.Attribute)
\r
189 XomParentNode pn = current.Parent;
\r
192 XomNode n = pn.FirstChild;
\r
199 public override bool MoveToFirstAttribute ()
\r
201 if (currentNS != null)
\r
203 XomElement el = current as XomElement;
\r
206 if (el.AttributeCount == 0)
\r
208 current = el.GetAttribute (0);
\r
212 public override bool MoveToNextAttribute ()
\r
214 XomAttribute attr = current as XomAttribute;
\r
217 XomElement owner = attr.Parent as XomElement;
\r
220 XomAttribute next = owner.GetNextAttribute (attr);
\r
227 public override bool MoveToAttribute (string name, string ns)
\r
229 if (currentNS != null || current.NodeType != XPathNodeType.Element)
\r
231 XomElement el = current as XomElement;
\r
232 XomAttribute attr = el.GetAttribute (name, ns);
\r
239 public override string GetNamespace (string prefix)
\r
241 if (currentNS != null)
\r
242 return String.Empty;
\r
243 XomNamespace n = GetXomNamespace (prefix);
\r
245 return String.Empty;
\r
247 return n.Namespace;
\r
250 private XomNamespace GetXomNamespace (string prefix)
\r
252 if (current.NodeType != XPathNodeType.Element)
\r
254 if (prefix == "xml")
\r
255 return XomNamespace.Xml;
\r
256 XomElement el = current as XomElement;
\r
258 XomNamespace n = el.GetLocalNamespace (prefix);
\r
261 el = el.Parent as XomElement;
\r
262 } while (el != null);
\r
266 public override bool MoveToNamespace (string prefix)
\r
268 if (currentNS != null)
\r
270 XomNamespace n = GetXomNamespace (prefix);
\r
277 public override bool MoveToFirstNamespace (XPathNamespaceScope scope)
\r
279 if (currentNS != null || current.NodeType != XPathNodeType.Element)
\r
281 XomElement el = current as XomElement;
\r
282 XomNamespace n = null;
\r
284 case XPathNamespaceScope.Local:
\r
285 if (el.NamespaceCount > 0)
\r
286 n = el.GetLocalNamespace (0);
\r
290 if (el.NamespaceCount > 0) {
\r
291 n = el.GetLocalNamespace (0);
\r
294 el = el.Parent as XomElement;
\r
295 } while (el != null);
\r
302 else if (scope == XPathNamespaceScope.All) {
\r
303 currentNS = XomNamespace.Xml;
\r
309 public override bool MoveToNextNamespace (XPathNamespaceScope scope)
\r
311 if (currentNS == null || currentNS == XomNamespace.Xml)
\r
313 XomElement el = currentNS.Parent as XomElement;
\r
314 XomNamespace n = el.GetNextLocalNamespace (currentNS);
\r
320 case XPathNamespaceScope.Local:
\r
323 el = el.Parent as XomElement;
\r
324 while (el != null) {
\r
325 if (el.NamespaceCount > 0) {
\r
326 n = el.GetLocalNamespace (0);
\r
329 el = el.Parent as XomElement;
\r
337 else if (scope == XPathNamespaceScope.All) {
\r
338 currentNS = XomNamespace.Xml;
\r
344 public override bool MoveToNext ()
\r
346 if (currentNS != null)
\r
348 switch (NodeType) {
\r
349 case XPathNodeType.Text:
\r
350 case XPathNodeType.SignificantWhitespace:
\r
351 case XPathNodeType.Whitespace:
\r
352 for (XomNode t = current.NextSibling; t != null; t = t.NextSibling) {
\r
353 switch (t.NodeType) {
\r
354 case XPathNodeType.Text:
\r
355 case XPathNodeType.SignificantWhitespace:
\r
356 case XPathNodeType.Whitespace:
\r
364 XomNode n = current.NextSibling;
\r
372 public override bool MoveToPrevious ()
\r
374 if (currentNS != null)
\r
376 XomNode n = current.PreviousSibling;
\r
381 switch (NodeType) {
\r
382 case XPathNodeType.Text:
\r
383 case XPathNodeType.SignificantWhitespace:
\r
384 case XPathNodeType.Whitespace:
\r
385 for (XomNode t = current.PreviousSibling; t != null; t = t.NextSibling) {
\r
386 switch (t.NodeType) {
\r
387 case XPathNodeType.Text:
\r
388 case XPathNodeType.SignificantWhitespace:
\r
389 case XPathNodeType.Whitespace:
\r
401 public override bool IsSamePosition (XPathNavigator other)
\r
403 XomNavigator xom = other as XomNavigator;
\r
404 if (xom == null || root != xom.root)
\r
406 return current == xom.current && currentNS == xom.currentNS;
\r
409 public override bool MoveTo (XPathNavigator other)
\r
411 XomNavigator xom = other as XomNavigator;
\r
414 current = xom.current;
\r
415 currentNS = xom.currentNS;
\r
419 public override bool MoveToId (string id)
\r
421 XomElement el = root.GetIdenticalNode (id);
\r