2002-08-17 Jason Diamond <jason@injektilo.org>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / XPathNavigator.cs
1 //
2 // System.Xml.XPath.XPathNavigator
3 //
4 // Author:
5 //   Jason Diamond (jason@injektilo.org)
6 //
7 // (C) 2002 Jason Diamond  http://injektilo.org/
8 //
9
10 using System;
11 using Mono.Xml.XPath;
12
13 namespace System.Xml.XPath
14 {
15         public abstract class XPathNavigator : ICloneable
16         {
17                 #region Constructor
18
19                 protected XPathNavigator ()
20                 {
21                 }
22
23                 #endregion
24
25                 #region Properties
26
27                 public abstract string BaseURI { get; }
28
29                 public abstract bool HasAttributes { get; }
30
31                 public abstract bool HasChildren { get; }
32
33                 public abstract bool IsEmptyElement { get; }
34
35                 public abstract string LocalName { get; }
36
37                 public abstract string Name { get; }
38
39                 public abstract string NamespaceURI { get; }
40
41                 public abstract XmlNameTable NameTable { get; }
42
43                 public abstract XPathNodeType NodeType { get; }
44
45                 public abstract string Prefix { get; }
46
47                 public abstract string Value { get; }
48
49                 public abstract string XmlLang { get; }
50
51                 #endregion
52
53                 #region Methods
54
55                 public abstract XPathNavigator Clone ();
56
57                 [MonoTODO]
58                 public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
59                 {
60                         throw new NotImplementedException ();
61                 }
62
63                 public virtual XPathExpression Compile (string xpath)
64                 {
65                         Tokenizer tokenizer = new Tokenizer (xpath);
66                         XPathParser parser = new XPathParser ();
67                         Expression expr = (Expression) parser.yyparse (tokenizer);
68 //                      Expression expr = (Expression) parser.yyparseDebug (tokenizer);
69                         return new CompiledExpression (expr);
70                 }
71
72                 public virtual object Evaluate (string xpath)
73                 {
74                         return Evaluate (Compile (xpath));
75                 }
76
77                 public virtual object Evaluate (XPathExpression expr)
78                 {
79                         return Evaluate (expr, null);
80                 }
81
82                 public virtual object Evaluate (XPathExpression expr, XPathNodeIterator context)
83                 {
84                         if (context == null)
85                                 context = new SelfIterator (this, new DefaultContext ());
86                         return ((CompiledExpression) expr).Evaluate ((BaseIterator) context);
87                 }
88
89                 public abstract string GetAttribute (string localName, string namespaceURI);
90
91                 public abstract string GetNamespace (string name);
92                 
93                 object ICloneable.Clone ()
94                 {
95                         return Clone ();
96                 }
97
98                 public virtual bool IsDescendant (XPathNavigator nav)
99                 {
100                         if (nav != null)
101                         {
102                                 nav = nav.Clone ();
103                                 while (nav.MoveToParent ())
104                                 {
105                                         if (IsSamePosition (nav))
106                                                 return true;
107                                 }
108                         }
109                         return false;
110                 }
111
112                 public abstract bool IsSamePosition (XPathNavigator other);
113
114                 public virtual bool Matches (string xpath)
115                 {
116                         return Matches (Compile (xpath));
117                 }
118
119                 public virtual bool Matches (XPathExpression expr)
120                 {
121                         if (expr.Expression.StartsWith ("/")) {
122                                 XPathNodeIterator nodes = Select (expr);
123                                 while (nodes.MoveNext ()) {
124                                         if (IsSamePosition (nodes.Current))
125                                                 return true;
126                                 }
127                         } else {
128                                 XPathNavigator navigator = Clone ();
129
130                                 while (navigator.MoveToParent ()) {
131                                         XPathNodeIterator nodes = navigator.Select (expr);
132                                         while (nodes.MoveNext ()) {
133                                                 if (IsSamePosition (nodes.Current))
134                                                         return true;
135                                         }
136                                 }
137                         }
138
139                         return false;
140                 }
141
142                 public abstract bool MoveTo (XPathNavigator other);
143
144                 public abstract bool MoveToAttribute (string localName, string namespaceURI);
145
146                 public abstract bool MoveToFirst ();
147
148                 public abstract bool MoveToFirstAttribute ();
149
150                 public abstract bool MoveToFirstChild ();
151
152                 public bool MoveToFirstNamespace ()
153                 {
154                         return MoveToFirstNamespace (XPathNamespaceScope.All);
155                 }
156
157                 public abstract bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope);
158
159                 public abstract bool MoveToId (string id);
160
161                 public abstract bool MoveToNamespace (string name);
162
163                 public abstract bool MoveToNext ();
164
165                 public abstract bool MoveToNextAttribute ();
166
167                 public bool MoveToNextNamespace ()
168                 {
169                         return MoveToNextNamespace (XPathNamespaceScope.All);
170                 }
171
172                 public abstract bool MoveToNextNamespace (XPathNamespaceScope namespaceScope);
173
174                 public abstract bool MoveToParent ();
175
176                 public abstract bool MoveToPrevious ();
177
178                 public abstract void MoveToRoot ();
179
180                 public virtual XPathNodeIterator Select (string xpath)
181                 {
182                         return Select (Compile (xpath));
183                 }
184
185                 public virtual XPathNodeIterator Select (XPathExpression expr)
186                 {
187                         BaseIterator iter = new SelfIterator (this, new DefaultContext ());
188                         return ((CompiledExpression) expr).EvaluateNodeSet (iter);
189                 }
190
191                 public virtual XPathNodeIterator SelectAncestors (XPathNodeType type, bool matchSelf)
192                 {
193                         Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
194                         NodeTest test = new NodeTypeTest (axis, type);
195                         return SelectTest (test);
196                 }
197
198                 [MonoTODO]
199                 public virtual XPathNodeIterator SelectAncestors (string name, string namespaceURI, bool matchSelf)
200                 {
201                         if (namespaceURI != null && namespaceURI != "")
202                                 throw new NotImplementedException ();
203
204                         Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
205                         QName qname = new QName ("", name);
206                         NodeTest test = new NodeNameTest (axis, qname);
207                         return SelectTest (test);
208                 }
209
210                 public virtual XPathNodeIterator SelectChildren (XPathNodeType type)
211                 {
212                         NodeTest test = new NodeTypeTest (Axes.Child, type);
213                         return SelectTest (test);
214                 }
215
216                 [MonoTODO]
217                 public virtual XPathNodeIterator SelectChildren (string name, string namespaceURI)
218                 {
219                         if (namespaceURI != null && namespaceURI != "")
220                                 throw new NotImplementedException ();
221
222                         Axes axis = Axes.Child;
223                         QName qname = new QName ("", name);
224                         NodeTest test = new NodeNameTest (axis, qname);
225                         return SelectTest (test);
226                 }
227
228                 public virtual XPathNodeIterator SelectDescendants (XPathNodeType type, bool matchSelf)
229                 {
230                         Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
231                         NodeTest test = new NodeTypeTest (axis, type);
232                         return SelectTest (test);
233                 }
234
235                 [MonoTODO]
236                 public virtual XPathNodeIterator SelectDescendants (string name, string namespaceURI, bool matchSelf)
237                 {
238                         if (namespaceURI != null && namespaceURI != "")
239                                 throw new NotImplementedException ();
240
241                         Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
242                         QName qname = new QName ("", name);
243                         NodeTest test = new NodeNameTest (axis, qname);
244                         return SelectTest (test);
245                 }
246
247                 internal XPathNodeIterator SelectTest (NodeTest test)
248                 {
249                         Expression expr = new ExprStep (test, null);
250                         BaseIterator iter = new SelfIterator (this, new DefaultContext ());
251                         return expr.EvaluateNodeSet (iter);
252                 }
253
254                 public override string ToString ()
255                 {
256                         return Value;
257                 }
258
259                 #endregion
260         }
261 }