touchups on XmlTextWriter attribute writing.
[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                 public virtual XmlDocumentType CreateDocumentType (string name, string publicId,
206                                                                    string systemId, string internalSubset)
207                 {
208                         return new XmlDocumentType (name, publicId, systemId, internalSubset, this);
209                 }
210
211                 public XmlElement CreateElement (string name)
212                 {
213                         int indexOfColon = name.IndexOf (':');
214                         
215                         if (indexOfColon == -1)
216                                 return CreateElement (String.Empty, name, String.Empty);
217
218                         string prefix = name.Substring (0, indexOfColon);
219                         string localName = name.Substring (indexOfColon + 1);
220
221                         return CreateElement (prefix, localName, String.Empty);
222                 }
223
224                 [MonoTODO]
225                 public XmlElement CreateElement (
226                         string qualifiedName, 
227                         string namespaceURI)
228                 {
229                         int indexOfColon = qualifiedName.IndexOf (':');
230                         
231                         if (indexOfColon == -1)
232                                 return CreateElement (String.Empty, qualifiedName, namespaceURI);
233
234                         string prefix = qualifiedName.Substring (0, indexOfColon);
235                         string localName = qualifiedName.Substring (indexOfColon + 1);
236
237                         return CreateElement (prefix, localName, namespaceURI);
238                 }
239
240                 public virtual XmlElement CreateElement (
241                         string prefix,
242                         string localName,
243                         string namespaceURI)
244                 {
245                         return new XmlElement (prefix, localName, namespaceURI, this);
246                 }
247
248                 [MonoTODO]
249                 public virtual XmlEntityReference CreateEntityReference (string name)
250                 {
251                         throw new NotImplementedException ();
252                 }
253
254                 [MonoTODO]
255                 protected internal virtual XPathNavigator CreateNavigator (XmlNode node)
256                 {
257                         throw new NotImplementedException ();
258                 }
259
260                 [MonoTODO]
261                 public virtual XmlNode CreateNode (
262                         string nodeTypeString,
263                         string name,
264                         string namespaceURI)
265                 {
266                         throw new NotImplementedException ();
267                 }
268
269                 [MonoTODO]
270                 public virtual XmlNode CreateNode (
271                         XmlNodeType type,
272                         string name,
273                         string namespaceURI)
274                 {
275                         throw new NotImplementedException ();
276                 }
277
278                 [MonoTODO]
279                 public virtual XmlNode CreateNode (
280                         XmlNodeType type,
281                         string prefix,
282                         string name,
283                         string namespaceURI)
284                 {
285                         throw new NotImplementedException ();
286                 }
287
288                 public virtual XmlProcessingInstruction CreateProcessingInstruction (
289                         string target,
290                         string data)
291                 {
292                         return new XmlProcessingInstruction (target, data, this);
293                 }
294
295                 public virtual XmlSignificantWhitespace CreateSignificantWhitespace (string text)
296                 {
297                         foreach (char c in text)
298                                 if ((c != ' ') && (c != '\r') && (c != '\n') && (c != '\t'))
299                                     throw new ArgumentException ("Invalid whitespace characters.");
300                          
301                         return new XmlSignificantWhitespace (text, this);
302                 }
303
304                 public virtual XmlText CreateTextNode (string text)
305                 {
306                         return new XmlText (text, this);
307                 }
308
309                 public virtual XmlWhitespace CreateWhitespace (string text)
310                 {
311                         foreach (char c in text)
312                                 if ((c != ' ') && (c != '\r') && (c != '\n') && (c != '\t'))
313                                     throw new ArgumentException ("Invalid whitespace characters.");
314                          
315                         return new XmlWhitespace (text, this);
316                 }
317
318                 public virtual XmlDeclaration CreateXmlDeclaration (string version, string encoding,
319                                                                     string standalone)
320                 {
321                         if (version != "1.0")
322                                 throw new ArgumentException ("version string is not correct.");
323
324                         if  ((standalone != null) && !((standalone == "yes") || (standalone == "no")))
325                                 throw new ArgumentException ("standalone string is not correct.");
326                         
327                         return new XmlDeclaration (version, encoding, standalone, this);
328                 }
329
330                 [MonoTODO]
331                 public virtual XmlElement GetElementById (string elementId)
332                 {
333                         throw new NotImplementedException ();
334                 }
335
336                 [MonoTODO]
337                 public virtual XmlNodeList GetElementsByTagName (string name)
338                 {
339                         throw new NotImplementedException ();
340                 }
341
342                 [MonoTODO]
343                 public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
344                 {
345                         throw new NotImplementedException();
346                 }
347
348                 [MonoTODO]
349                 public virtual XmlNode ImportNode (XmlNode node, bool deep)
350                 {
351                         throw new NotImplementedException ();
352                 }
353
354                 [MonoTODO]
355                 public virtual void Load (Stream inStream)
356                 {
357                         throw new NotImplementedException ();
358                 }
359
360                 public virtual void Load (string filename)
361                 {
362                         XmlReader xmlReader = new XmlTextReader (new StreamReader (filename));
363                         Load (xmlReader);
364                 }
365
366                 [MonoTODO]
367                 public virtual void Load (TextReader txtReader)
368                 {
369                         throw new NotImplementedException ();
370                 }
371
372                 public virtual void Load (XmlReader xmlReader)
373                 {
374                         // Reset our document
375                         // For now this just means removing all our children but later this
376                         // may turn out o need to call a private method that resets other things
377                         // like properties we have, etc.
378                         RemoveAll ();
379
380                         XmlNode currentNode = this;
381                         XmlNode newNode;
382
383                         while (xmlReader.Read ()) 
384                         {
385                                 switch (xmlReader.NodeType) {
386
387                                 case XmlNodeType.CDATA:
388                                         newNode = CreateCDataSection(xmlReader.Value);
389                                         currentNode.AppendChild (newNode);
390                                         break;
391
392                                 case XmlNodeType.Comment:
393                                         newNode = CreateComment (xmlReader.Value);
394                                         currentNode.AppendChild (newNode);
395                                         break;
396
397                                 case XmlNodeType.Element:
398                                         XmlElement element = CreateElement (xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
399                                         currentNode.AppendChild (element);
400
401                                         // set the element's attributes.
402                                         while (xmlReader.MoveToNextAttribute ())
403                                                 element.SetAttribute (xmlReader.Name, xmlReader.Value);
404
405                                         xmlReader.MoveToElement ();
406
407                                         // if this element isn't empty, push it onto our "stack".
408                                         if (!xmlReader.IsEmptyElement)
409                                                 currentNode = element;
410
411                                         break;
412
413                                 case XmlNodeType.EndElement:
414                                         currentNode = currentNode.ParentNode;
415                                         break;
416
417                                 case XmlNodeType.ProcessingInstruction:
418                                         newNode = CreateProcessingInstruction (xmlReader.Name, xmlReader.Value);
419                                         currentNode.AppendChild (newNode);
420                                         break;
421
422                                 case XmlNodeType.Text:
423                                         newNode = CreateTextNode (xmlReader.Value);
424                                         currentNode.AppendChild (newNode);
425                                         break;
426                                 }
427                         }
428                 }
429
430                 public virtual void LoadXml (string xml)
431                 {
432                         XmlReader xmlReader = new XmlTextReader (new StringReader (xml));
433                         Load (xmlReader);
434                 }
435
436                 internal void onNodeChanged (XmlNode node, XmlNode Parent)
437                 {
438                         if (NodeChanged != null)
439                                 NodeInserted (node, new XmlNodeChangedEventArgs
440                                         (XmlNodeChangedAction.Change,
441                                         node, Parent, Parent));
442                 }
443
444                 internal void onNodeChanging(XmlNode node, XmlNode Parent)
445                 {
446                         if (NodeInserting != null)
447                                 NodeChanging (node, new XmlNodeChangedEventArgs
448                                         (XmlNodeChangedAction.Change,
449                                         node, Parent, Parent));
450                 }
451
452                 internal void onNodeInserted (XmlNode node, XmlNode newParent)
453                 {
454                         if (NodeInserted != null)
455                                 NodeInserted (node, new XmlNodeChangedEventArgs
456                                         (XmlNodeChangedAction.Insert,
457                                         node, null, newParent));
458                 }
459
460                 internal void onNodeInserting (XmlNode node, XmlNode newParent)
461                 {
462                         if (NodeInserting != null)
463                                 NodeInserting (node, new XmlNodeChangedEventArgs
464                                         (XmlNodeChangedAction.Insert,
465                                         node, null, newParent));
466                 }
467
468                 internal void onNodeRemoved (XmlNode node, XmlNode oldParent)
469                 {
470                         if (NodeRemoved != null)
471                                 NodeRemoved (node, new XmlNodeChangedEventArgs
472                                         (XmlNodeChangedAction.Remove,
473                                         node, oldParent, null));
474                 }
475
476                 internal void onNodeRemoving (XmlNode node, XmlNode oldParent)
477                 {
478                         if (NodeRemoving != null)
479                                 NodeRemoving (node, new XmlNodeChangedEventArgs
480                                         (XmlNodeChangedAction.Remove,
481                                         node, oldParent, null));
482                 }
483
484                 [MonoTODO]
485                 public virtual XmlNode ReadNode(XmlReader reader)
486                 {
487                         throw new NotImplementedException ();
488                 }
489
490                 [MonoTODO]
491                 public virtual void Save(Stream outStream)
492                 {
493                         throw new NotImplementedException ();
494                 }
495
496                 [MonoTODO]
497                 public virtual void Save (string filename)
498                 {
499                         throw new NotImplementedException ();
500                 }
501
502                 [MonoTODO]
503                 public virtual void Save (TextWriter writer)
504                 {
505                         throw new NotImplementedException ();
506                 }
507
508                 [MonoTODO]
509                 public virtual void Save (XmlWriter writer)
510                 {
511                         throw new NotImplementedException ();
512                 }
513
514                 public override void WriteContentTo (XmlWriter w)
515                 {
516                         foreach(XmlNode childNode in ChildNodes)
517                                 childNode.WriteTo(w);
518                 }
519
520                 public override void WriteTo (XmlWriter w)
521                 {
522                         WriteContentTo(w);
523                 }
524
525                 #endregion
526         }
527 }