2002-03-13 Duncan Mak <duncan@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlDocument.cs
1 //
2 // System.Xml.XmlDocument
3 //
4 // Author:
5 //   Daniel Weber (daniel-weber@austin.rr.com)
6 //
7 // (C) 2001 Daniel Weber
8
9 using System;
10 using System.IO;
11 using System.Xml.XPath;
12
13 namespace System.Xml
14 {
15         public delegate void XmlNodeChangedEventHandler (XmlNodeChangedEventArgs args);
16
17         public class XmlDocument : XmlNode
18         {
19                 #region Fields
20
21                 private XmlLinkedNode lastLinkedChild;
22
23                 #endregion
24
25                 #region Constructors
26
27                 public XmlDocument () : base (null) { }
28
29                 [MonoTODO]
30                 protected internal XmlDocument (XmlImplementation imp) : base (null)
31                 {
32                         throw new NotImplementedException ();
33                 }
34
35                 [MonoTODO]
36                 public XmlDocument (NameTable nt) : base (null)
37                 {
38                         throw new NotImplementedException ();
39                 }
40
41                 #endregion
42
43                 #region Events
44
45                 public event XmlNodeChangedEventHandler NodeChanged;
46
47                 public event XmlNodeChangedEventHandler NodeChanging;
48
49                 public event XmlNodeChangedEventHandler NodeInserted;
50
51                 public event XmlNodeChangedEventHandler NodeInserting;
52
53                 public event XmlNodeChangedEventHandler NodeRemoved;
54
55                 public event XmlNodeChangedEventHandler NodeRemoving;
56
57                 #endregion
58
59                 #region Properties
60
61                 [MonoTODO]
62                 public override string BaseURI {
63                         get { throw new NotImplementedException(); }
64                 }
65
66                 public XmlElement DocumentElement {
67                         get {
68                                 XmlNode node = FirstChild;
69
70                                 while (node != null) {
71                                         if (node is XmlElement)
72                                                 break;
73                                         node = node.NextSibling;
74                                 }
75
76                                 return node != null ? node as XmlElement : null;
77                         }
78                 }
79
80                 [MonoTODO]
81                 public virtual XmlDocumentType DocumentType {
82                         get { throw new NotImplementedException(); }
83                 }
84
85                 [MonoTODO]
86                 public XmlImplementation Implementation {
87                         get { throw new NotImplementedException(); }
88                 }
89
90                 [MonoTODO]
91                 public override string InnerXml {
92                         get { throw new NotImplementedException(); }
93                         set { throw new NotImplementedException(); }
94                 }
95
96                 public override bool IsReadOnly {
97                         get { return false; }
98                 }
99
100                 internal override XmlLinkedNode LastLinkedChild {
101                         get     {
102                                 return lastLinkedChild;
103                         }
104
105                         set {
106                                 lastLinkedChild = value;
107                         }
108                 }
109                 
110                 public override string LocalName {
111                         get { return "#document"; }
112                 }
113
114                 public override string Name {
115                         get { return "#document"; }
116                 }
117
118                 [MonoTODO]
119                 public XmlNameTable NameTable {
120                         get { throw new NotImplementedException(); }
121                 }
122
123                 public override XmlNodeType NodeType {
124                         get { return XmlNodeType.Document; }
125                 }
126
127                 public override XmlDocument OwnerDocument {
128                         get { return null; }
129                 }
130
131                 [MonoTODO]
132                 public bool PreserveWhitespace {
133                         get { throw new NotImplementedException(); }
134                         set { throw new NotImplementedException(); }
135                 }
136
137                 [MonoTODO]
138                 public XmlResolver XmlResolver {
139                         set { throw new NotImplementedException(); }
140                 }
141
142                 #endregion
143
144                 #region Methods
145
146                 [MonoTODO]
147                 public override XmlNode CloneNode (bool deep)
148                 {
149                         throw new NotImplementedException ();
150                 }
151
152                 [MonoTODO]
153                 public XmlAttribute CreateAttribute (string name)
154                 {
155                         int indexOfColon = name.IndexOf (':');
156                         
157                         if (indexOfColon == -1)
158                                 return CreateAttribute (String.Empty, name, String.Empty);
159
160                         string prefix = name.Substring (0, indexOfColon);
161                         string localName = name.Substring (indexOfColon + 1);
162
163                         return CreateAttribute (prefix, localName, String.Empty);
164                 }
165
166                 [MonoTODO]
167                 public XmlAttribute CreateAttribute (string qualifiedName, string namespaceURI)
168                 {
169                         int indexOfColon = qualifiedName.IndexOf (':');
170                         
171                         if (indexOfColon == -1)
172                                 return CreateAttribute (String.Empty, qualifiedName, String.Empty);
173
174                         string prefix = qualifiedName.Substring (0, indexOfColon);
175                         string localName = qualifiedName.Substring (indexOfColon + 1);
176
177                         return CreateAttribute (prefix, localName, String.Empty);
178                 }
179
180                 public virtual XmlAttribute CreateAttribute (string prefix, string localName, string namespaceURI)
181                 {
182                         return new XmlAttribute (prefix, localName, namespaceURI, this);
183                 }
184
185                 public virtual XmlCDataSection CreateCDataSection (string data)
186                 {
187                         return new XmlCDataSection (data, this);
188                 }
189
190                 public virtual XmlComment CreateComment (string data)
191                 {
192                         return new XmlComment(data, this);
193                 }
194
195                 [MonoTODO]
196                 protected internal virtual XmlAttribute CreateDefaultAttribute (string prefix, string localName, string namespaceURI)
197                 {
198                         throw new NotImplementedException ();
199                 }
200
201                 [MonoTODO]
202                 public virtual XmlDocumentFragment CreateDocumentFragment ()
203                 {
204                         throw new NotImplementedException ();
205                 }
206
207                 [MonoTODO]
208                 public virtual XmlDocumentType CreateDocumentType (
209                         string name,
210                         string publicId,
211                         string systemId,
212                         string internalSubset)
213                 {
214                         throw new NotImplementedException ();
215                 }
216
217                 public XmlElement CreateElement (string name)
218                 {
219                         int indexOfColon = name.IndexOf (':');
220                         
221                         if (indexOfColon == -1)
222                                 return CreateElement (String.Empty, name, String.Empty);
223
224                         string prefix = name.Substring (0, indexOfColon);
225                         string localName = name.Substring (indexOfColon + 1);
226
227                         return CreateElement (prefix, localName, String.Empty);
228                 }
229
230                 [MonoTODO]
231                 public XmlElement CreateElement (
232                         string qualifiedName, 
233                         string namespaceURI)
234                 {
235                         int indexOfColon = qualifiedName.IndexOf (':');
236                         
237                         if (indexOfColon == -1)
238                                 return CreateElement (String.Empty, qualifiedName, namespaceURI);
239
240                         string prefix = qualifiedName.Substring (0, indexOfColon);
241                         string localName = qualifiedName.Substring (indexOfColon + 1);
242
243                         return CreateElement (prefix, localName, namespaceURI);
244                 }
245
246                 public virtual XmlElement CreateElement (
247                         string prefix,
248                         string localName,
249                         string namespaceURI)
250                 {
251                         return new XmlElement (prefix, localName, namespaceURI, this);
252                 }
253
254                 [MonoTODO]
255                 public virtual XmlEntityReference CreateEntityReference (string name)
256                 {
257                         throw new NotImplementedException ();
258                 }
259
260                 [MonoTODO]
261                 protected internal virtual XPathNavigator CreateNavigator (XmlNode node)
262                 {
263                         throw new NotImplementedException ();
264                 }
265
266                 [MonoTODO]
267                 public virtual XmlNode CreateNode (
268                         string nodeTypeString,
269                         string name,
270                         string namespaceURI)
271                 {
272                         throw new NotImplementedException ();
273                 }
274
275                 [MonoTODO]
276                 public virtual XmlNode CreateNode (
277                         XmlNodeType type,
278                         string name,
279                         string namespaceURI)
280                 {
281                         throw new NotImplementedException ();
282                 }
283
284                 [MonoTODO]
285                 public virtual XmlNode CreateNode (
286                         XmlNodeType type,
287                         string prefix,
288                         string name,
289                         string namespaceURI)
290                 {
291                         throw new NotImplementedException ();
292                 }
293
294                 public virtual XmlProcessingInstruction CreateProcessingInstruction (
295                         string target,
296                         string data)
297                 {
298                         return new XmlProcessingInstruction (target, data, this);
299                 }
300
301                 [MonoTODO]
302                 public virtual XmlSignificantWhitespace CreateSignificantWhitespace (string text)
303                 {
304                         throw new NotImplementedException ();
305                 }
306
307                 public virtual XmlText CreateTextNode (string text)
308                 {
309                         return new XmlText (text, this);
310                 }
311
312                 [MonoTODO]
313                 public virtual XmlWhitespace CreateWhitespace (string text)
314                 {
315                         throw new NotImplementedException ();
316                 }
317
318                 [MonoTODO]
319                 public virtual XmlDeclaration CreateXmlDeclaration (
320                         string version,
321                         string encoding,
322                         string standalone)
323                 {
324                         throw new NotImplementedException();
325                 }
326
327                 [MonoTODO]
328                 public virtual XmlElement GetElementById (string elementId)
329                 {
330                         throw new NotImplementedException ();
331                 }
332
333                 [MonoTODO]
334                 public virtual XmlNodeList GetElementsByTagName (string name)
335                 {
336                         throw new NotImplementedException ();
337                 }
338
339                 [MonoTODO]
340                 public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
341                 {
342                         throw new NotImplementedException();
343                 }
344
345                 [MonoTODO]
346                 public virtual XmlNode ImportNode (XmlNode node, bool deep)
347                 {
348                         throw new NotImplementedException ();
349                 }
350
351                 [MonoTODO]
352                 public virtual void Load (Stream inStream)
353                 {
354                         throw new NotImplementedException ();
355                 }
356
357                 public virtual void Load (string filename)
358                 {
359                         XmlReader xmlReader = new XmlTextReader (new StreamReader (filename));
360                         Load (xmlReader);
361                 }
362
363                 [MonoTODO]
364                 public virtual void Load (TextReader txtReader)
365                 {
366                         throw new NotImplementedException ();
367                 }
368
369                 public virtual void Load (XmlReader xmlReader)
370                 {
371                         // Reset our document
372                         // For now this just means removing all our children but later this
373                         // may turn out o need to call a private method that resets other things
374                         // like properties we have, etc.
375                         RemoveAll ();
376
377                         XmlNode currentNode = this;
378
379                         while (xmlReader.Read ()) 
380                         {
381                                 switch (xmlReader.NodeType) {
382
383                                 case XmlNodeType.CDATA:
384                                         XmlCDataSection cdataSection = CreateCDataSection(xmlReader.Value);
385                                         currentNode.AppendChild (cdataSection);
386                                         break;
387
388                                 case XmlNodeType.Comment:
389                                         XmlComment comment = CreateComment (xmlReader.Value);
390                                         currentNode.AppendChild (comment);
391                                         break;
392
393                                 case XmlNodeType.Element:
394                                         XmlElement element = CreateElement (xmlReader.Name, xmlReader.LocalName, xmlReader.NamespaceURI);
395                                         currentNode.AppendChild (element);
396
397                                         // set the element's attributes.
398                                         while (xmlReader.MoveToNextAttribute ())
399                                                 element.SetAttribute (xmlReader.Name, xmlReader.Value);
400
401                                         // if this element isn't empty, push it onto our "stack".
402                                         if (!xmlReader.IsEmptyElement)
403                                                 currentNode = element;
404
405                                         break;
406
407                                 case XmlNodeType.EndElement:
408                                         currentNode = currentNode.ParentNode;
409                                         break;
410
411                                 case XmlNodeType.ProcessingInstruction:
412                                         XmlProcessingInstruction processingInstruction = CreateProcessingInstruction (xmlReader.Name, xmlReader.Value);
413                                         // Where does a processing instruction go in the doc?
414                                         // I think we need to just hold on to them in an internal array in doc.
415                                         break;
416
417                                 case XmlNodeType.Text:
418                                         XmlText text = CreateTextNode (xmlReader.Value);
419                                         currentNode.AppendChild (text);
420                                         break;
421                                 }
422                         }
423                 }
424
425                 public virtual void LoadXml (string xml)
426                 {
427                         XmlReader xmlReader = new XmlTextReader (new StringReader (xml));
428                         Load (xmlReader);
429                 }
430
431                 [MonoTODO]
432                 public virtual XmlNode ReadNode(XmlReader reader)
433                 {
434                         throw new NotImplementedException ();
435                 }
436
437                 [MonoTODO]
438                 public virtual void Save(Stream outStream)
439                 {
440                         throw new NotImplementedException ();
441                 }
442
443                 [MonoTODO]
444                 public virtual void Save (string filename)
445                 {
446                         throw new NotImplementedException ();
447                 }
448
449                 [MonoTODO]
450                 public virtual void Save (TextWriter writer)
451                 {
452                         throw new NotImplementedException ();
453                 }
454
455                 [MonoTODO]
456                 public virtual void Save (XmlWriter writer)
457                 {
458                         throw new NotImplementedException ();
459                 }
460
461                 [MonoTODO]
462                 public override void WriteContentTo (XmlWriter xw)
463                 {
464                         throw new NotImplementedException ();
465                 }
466
467                 [MonoTODO]
468                 public override void WriteTo (XmlWriter w)
469                 {
470                         throw new NotImplementedException ();
471                 }
472
473                 internal void onNodeChanging(XmlNode node, XmlNode Parent)
474                 {
475                         if (NodeInserting != null)
476                                 NodeChanging( new XmlNodeChangedEventArgs(XmlNodeChangedAction.Change,
477                                         node, Parent, Parent));
478                 }
479
480                 internal void onNodeChanged(XmlNode node, XmlNode Parent)
481                 {
482                         if (NodeChanged != null)
483                                 NodeInserted( new XmlNodeChangedEventArgs(XmlNodeChangedAction.Change,
484                                         node, Parent, Parent));
485                 }
486
487                 internal void onNodeInserting(XmlNode node, XmlNode newParent)
488                 {
489                         if (NodeInserting != null)
490                                 NodeInserting( new XmlNodeChangedEventArgs(XmlNodeChangedAction.Insert,
491                                         node, null, newParent));
492                 }
493
494                 internal void onNodeInserted(XmlNode node, XmlNode newParent)
495                 {
496                         if (NodeInserted != null)
497                                 NodeInserted( new XmlNodeChangedEventArgs(XmlNodeChangedAction.Insert,
498                                         node, null, newParent));
499                 }
500
501                 internal void onNodeRemoving(XmlNode node, XmlNode oldParent)
502                 {
503                         if (NodeRemoving != null)
504                                 NodeRemoving(new XmlNodeChangedEventArgs(XmlNodeChangedAction.Remove,
505                                         node, oldParent, null));
506                 }
507
508                 internal void onNodeRemoved(XmlNode node, XmlNode oldParent)
509                 {
510                         if (NodeRemoved != null)
511                                 NodeRemoved(new XmlNodeChangedEventArgs(XmlNodeChangedAction.Remove,
512                                         node, oldParent, null));
513                 }
514
515                 #endregion
516         }
517 }