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