2002-03-15 Duncan Mak <duncan@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlNode.cs
1 //
2 // System.Xml.XmlNode
3 //
4 // Author:
5 //   Kral Ferch <kral_ferch@hotmail.com>
6 //
7 // (C) 2002 Kral Ferch
8 //
9
10 using System;
11 using System.Collections;
12 using System.Xml.XPath;
13
14 namespace System.Xml
15 {
16         public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable
17         {
18                 #region Fields
19
20                 XmlDocument ownerDocument;
21                 XmlNode parentNode;
22
23                 #endregion
24
25                 #region Constructors
26
27                 protected internal XmlNode (XmlDocument ownerDocument)
28                 {
29                         this.ownerDocument = ownerDocument;
30                 }
31
32                 #endregion
33
34                 #region Properties
35
36                 public virtual XmlAttributeCollection Attributes
37                 {
38                         get { return null; }
39                 }
40
41                 [MonoTODO]
42                 public virtual string BaseURI
43                 {
44                         get { throw new NotImplementedException (); }
45                 }
46
47                 public virtual XmlNodeList ChildNodes {
48                         get {
49                                 return new XmlNodeListChildren(this);
50                         }
51                 }
52
53                 public virtual XmlNode FirstChild {
54                         get {
55                                 if (LastChild != null) {
56                                         return LastLinkedChild.NextLinkedSibling;
57                                 }
58                                 else {
59                                         return null;
60                                 }
61                         }
62                 }
63
64                 public virtual bool HasChildNodes {
65                         get { return LastChild != null; }
66                 }
67
68                 [MonoTODO]
69                 public virtual string InnerText {
70                         get { throw new NotImplementedException (); }
71                         set { throw new NotImplementedException (); }
72                 }
73
74                 [MonoTODO]
75                 public virtual string InnerXml {
76                         get { throw new NotImplementedException (); }
77                         set { throw new NotImplementedException (); }
78                 }
79
80                 public virtual bool IsReadOnly {
81                         get { return false; }
82                 }
83
84                 [System.Runtime.CompilerServices.IndexerName("Item")]
85                 public virtual XmlElement this [string name] {
86                         get { 
87                                 foreach (XmlNode node in ChildNodes) {
88                                         if ((node.NodeType == XmlNodeType.Element) &&
89                                             (node.Name == name)) {
90                                                 return (XmlElement) node;
91                                         }
92                                 }
93
94                                 return null;
95                         }
96                 }
97
98                 [System.Runtime.CompilerServices.IndexerName("Item")]
99                 public virtual XmlElement this [string localname, string ns] {
100                         get { 
101                                 foreach (XmlNode node in ChildNodes) {
102                                         if ((node.NodeType == XmlNodeType.Element) &&
103                                             (node.LocalName == localname) && 
104                                             (node.NamespaceURI == ns)) {
105                                                 return (XmlElement) node;
106                                         }
107                                 }
108
109                                 return null;
110                         }
111                 }
112
113                 public virtual XmlNode LastChild {
114                         get { return LastLinkedChild; }
115                 }
116
117                 internal virtual XmlLinkedNode LastLinkedChild {
118                         get { return null; }
119                         set { }
120                 }
121
122                 public abstract string LocalName { get; }
123
124                 public abstract string Name     { get; }
125
126                 [MonoTODO]
127                 public virtual string NamespaceURI {
128                         get { throw new NotImplementedException (); }
129                 }
130
131                 public virtual XmlNode NextSibling {
132                         get { return null; }
133                 }
134
135                 public abstract XmlNodeType NodeType { get;     }
136
137                 [MonoTODO]
138                 public virtual string OuterXml {
139                         get { throw new NotImplementedException (); }
140                 }
141
142                 public virtual XmlDocument OwnerDocument {
143                         get { return ownerDocument; }
144                 }
145
146                 public virtual XmlNode ParentNode {
147                         get { return parentNode; }
148                 }
149
150                 [MonoTODO]
151                 public virtual string Prefix {
152                         get { throw new NotImplementedException (); }
153                         set { throw new NotImplementedException (); }
154                 }
155
156                 public virtual XmlNode PreviousSibling {
157                         get { return null; }
158                 }
159
160                 [MonoTODO]
161                 public virtual string Value {
162                         get { throw new NotImplementedException (); }
163                         set { throw new NotImplementedException (); }
164                 }
165
166                 #endregion
167
168                 #region Methods
169
170                 public virtual XmlNode AppendChild (XmlNode newChild)
171                 {
172                         if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute) {
173                                 XmlLinkedNode newLinkedChild = (XmlLinkedNode)newChild;
174                                 XmlLinkedNode lastLinkedChild = LastLinkedChild;
175                                 
176                                 if (lastLinkedChild != null) {
177                                         newLinkedChild.NextLinkedSibling = lastLinkedChild.NextLinkedSibling;
178                                         lastLinkedChild.NextLinkedSibling = newLinkedChild;
179                                 } else
180                                         newLinkedChild.NextLinkedSibling = newLinkedChild;
181                                 
182                                 LastLinkedChild = newLinkedChild;
183
184                                 return newChild;
185                         } else
186                                 throw new InvalidOperationException();
187                 }
188
189                 [MonoTODO]
190                 public virtual XmlNode Clone ()
191                 {
192                         throw new NotImplementedException ();
193                 }
194
195                 public abstract XmlNode CloneNode (bool deep);
196
197                 [MonoTODO]
198                 public XPathNavigator CreateNavigator ()
199                 {
200                         throw new NotImplementedException ();
201                 }
202
203                 public IEnumerator GetEnumerator ()
204                 {
205                         return new XmlNodeListChildren(this).GetEnumerator();
206                 }
207
208                 [MonoTODO]
209                 public virtual string GetNamespaceOfPrefix (string prefix)
210                 {
211                         throw new NotImplementedException ();
212                 }
213
214                 [MonoTODO]
215                 public virtual string GetPrefixOfNamespace (string namespaceURI)
216                 {
217                         throw new NotImplementedException ();
218                 }
219
220                 object ICloneable.Clone ()
221                 {
222                         return Clone ();
223                 }
224
225                 IEnumerator IEnumerable.GetEnumerator ()
226                 {
227                         return GetEnumerator ();
228                 }
229
230                 [MonoTODO]
231                 public virtual XmlNode InsertAfter (XmlNode newChild, XmlNode refChild)
232                 {
233                         throw new NotImplementedException ();
234                 }
235
236                 [MonoTODO]
237                 public virtual XmlNode InsertBefore (XmlNode newChild, XmlNode refChild)
238                 {
239                         throw new NotImplementedException ();
240                 }
241
242                 [MonoTODO]
243                 public virtual void Normalize ()
244                 {
245                         throw new NotImplementedException ();
246                 }
247
248                 [MonoTODO]
249                 public virtual XmlNode PrependChild (XmlNode newChild)
250                 {
251                         throw new NotImplementedException ();
252                 }
253
254                 public virtual void RemoveAll ()
255                 {
256                         LastLinkedChild = null;
257                 }
258
259                 public virtual XmlNode RemoveChild (XmlNode oldChild)
260                 {
261                         if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute) 
262                         {
263                                 if (IsReadOnly)
264                                         throw new ArgumentException();
265
266                                 if (Object.ReferenceEquals(LastLinkedChild, LastLinkedChild.NextLinkedSibling) && Object.ReferenceEquals(LastLinkedChild, oldChild))
267                                         LastLinkedChild = null;
268                                 else {
269                                         XmlLinkedNode oldLinkedChild = (XmlLinkedNode)oldChild;
270                                         XmlLinkedNode beforeLinkedChild = LastLinkedChild;
271                                         
272                                         while (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, LastLinkedChild) && !Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
273                                                 beforeLinkedChild = beforeLinkedChild.NextLinkedSibling;
274
275                                         if (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
276                                                 throw new ArgumentException();
277
278                                         beforeLinkedChild.NextLinkedSibling = oldLinkedChild.NextLinkedSibling;
279                                         oldLinkedChild.NextLinkedSibling = null;
280                                  }
281
282                                 return oldChild;
283                         } 
284                         else
285                                 throw new ArgumentException();
286                 }
287
288                 [MonoTODO]
289                 public virtual XmlNode ReplaceChild (XmlNode newChild, XmlNode oldChild)
290                 {
291                         throw new NotImplementedException ();
292                 }
293
294                 [MonoTODO]
295                 public virtual XmlNodeList SelectNodes (string xpath)
296                 {
297                         throw new NotImplementedException ();
298                 }
299
300                 [MonoTODO]
301                 public virtual XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr)
302                 {
303                         throw new NotImplementedException ();
304                 }
305
306                 [MonoTODO]
307                 public virtual XmlNode SelectSingleNode (string xpath)
308                 {
309                         throw new NotImplementedException ();
310                 }
311
312                 [MonoTODO]
313                 public virtual XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr)
314                 {
315                         throw new NotImplementedException ();
316                 }
317
318                 internal void SetParentNode (XmlNode parent)
319                 {
320                         parentNode = parent;
321                 }
322
323                 [MonoTODO]
324                 public virtual bool Supports (string feature, string version)
325                 {
326                         throw new NotImplementedException ();
327                 }
328
329                 public abstract void WriteContentTo (XmlWriter w);
330
331                 public abstract void WriteTo (XmlWriter w);
332
333                 #endregion
334         }
335 }