* XmlDeclaration.cs : Fixed ParseInput() more parse strictly.
[mono.git] / mcs / class / System.XML / System.Xml / XmlDocument.cs
1 //
2 // System.Xml.XmlDocument
3 //
4 // Authors:
5 //   Daniel Weber (daniel-weber@austin.rr.com)
6 //   Kral Ferch <kral_ferch@hotmail.com>
7 //   Jason Diamond <jason@injektilo.org>
8 //   Miguel de Icaza (miguel@ximian.com)
9 //   Duncan Mak (duncan@ximian.com)
10 //
11 // (C) 2001 Daniel Weber
12 // (C) 2002 Kral Ferch, Jason Diamond, Miguel de Icaza, Duncan Mak
13 //
14
15 using System;
16 using System.IO;
17 using System.Text;
18 using System.Xml.XPath;
19 using System.Diagnostics;
20 using System.Collections;
21
22 namespace System.Xml
23 {
24         public class XmlDocument : XmlNode
25         {
26                 #region Fields
27
28                 XmlLinkedNode lastLinkedChild;
29                 XmlNameTable nameTable;
30                 string baseURI = String.Empty;
31
32                 #endregion
33
34                 #region Constructors
35
36                 public XmlDocument () : base (null)
37                 {
38                         System.Xml.NameTable nt = new NameTable();
39                         // keys below are default of MS .NET Framework
40                         nt.Add("#text");
41                         nt.Add("xml");
42                         nt.Add("xmlns");
43                         nt.Add("#entity");
44                         nt.Add("#document-fragment");
45                         nt.Add("#comment");
46                         nt.Add("space");
47                         nt.Add("id");
48                         nt.Add("#whitespace");
49                         nt.Add("http://www.w3.org/2000/xmlns/");
50                         nt.Add("#cdata-section");
51                         nt.Add("lang");
52
53                         nameTable = nt;
54                 }
55
56                 [MonoTODO]
57                 protected internal XmlDocument (XmlImplementation imp) : base (null)
58                 {
59                         throw new NotImplementedException ();
60                 }
61
62                 public XmlDocument (XmlNameTable nt) : base (null)
63                 {
64                         nameTable = nt;
65                 }
66
67                 #endregion
68
69                 #region Events
70
71                 public event XmlNodeChangedEventHandler NodeChanged;
72
73                 public event XmlNodeChangedEventHandler NodeChanging;
74
75                 public event XmlNodeChangedEventHandler NodeInserted;
76
77                 public event XmlNodeChangedEventHandler NodeInserting;
78
79                 public event XmlNodeChangedEventHandler NodeRemoved;
80
81                 public event XmlNodeChangedEventHandler NodeRemoving;
82
83                 #endregion
84
85                 #region Properties
86
87                 public override string BaseURI {
88                         get {
89                                 return baseURI;
90                         }
91                 }
92
93                 public XmlElement DocumentElement {
94                         get {
95                                 XmlNode node = FirstChild;
96
97                                 while (node != null) {
98                                         if (node is XmlElement)
99                                                 break;
100                                         node = node.NextSibling;
101                                 }
102
103                                 return node != null ? node as XmlElement : null;
104                         }
105                 }
106
107                 [MonoTODO]
108                 public virtual XmlDocumentType DocumentType {
109                         get { throw new NotImplementedException(); }
110                 }
111
112                 [MonoTODO]
113                 public XmlImplementation Implementation {
114                         get { throw new NotImplementedException(); }
115                 }
116
117                 [MonoTODO ("Setter.")]
118                 public override string InnerXml {
119                         get {
120                                 // Not sure why this is an override.  Passing through for now.
121                                 return base.InnerXml;
122                         }
123                         set { throw new NotImplementedException(); }
124                 }
125
126                 public override bool IsReadOnly {
127                         get { return false; }
128                 }
129
130                 internal override XmlLinkedNode LastLinkedChild {
131                         get     {
132                                 return lastLinkedChild;
133                         }
134
135                         set {
136                                 lastLinkedChild = value;
137                         }
138                 }
139                 
140                 public override string LocalName {
141                         get { return "#document"; }
142                 }
143
144                 public override string Name {
145                         get { return "#document"; }
146                 }
147
148                 public XmlNameTable NameTable {
149                         get { return nameTable; }
150                 }
151
152                 public override XmlNodeType NodeType {
153                         get { return XmlNodeType.Document; }
154                 }
155
156                 public override XmlDocument OwnerDocument {
157                         get { return null; }
158                 }
159
160                 [MonoTODO]
161                 public bool PreserveWhitespace {
162                         get { throw new NotImplementedException(); }
163                         set { throw new NotImplementedException(); }
164                 }
165
166                 [MonoTODO]
167                 public virtual XmlResolver XmlResolver {
168                         set { throw new NotImplementedException(); }
169                 }
170
171                 #endregion
172
173                 #region Methods
174
175                 [MonoTODO]
176                 public override XmlNode CloneNode (bool deep)
177                 {
178                         throw new NotImplementedException ();
179                 }
180
181                 public XmlAttribute CreateAttribute (string name)
182                 {
183                         return CreateAttribute (name, String.Empty);
184                 }
185
186                 public XmlAttribute CreateAttribute (string qualifiedName, string namespaceURI)
187                 {
188                         string prefix;
189                         string localName;
190
191                         ParseName (qualifiedName, out prefix, out localName);
192
193                         return CreateAttribute (prefix, localName, namespaceURI);
194                 }
195
196                 public virtual XmlAttribute CreateAttribute (string prefix, string localName, string namespaceURI)
197                 {
198                         if ((localName == null) || (localName == String.Empty))
199                                 throw new ArgumentException ("The attribute local name cannot be empty.");
200
201                         return new XmlAttribute (prefix, localName, namespaceURI, this);
202                 }
203
204                 public virtual XmlCDataSection CreateCDataSection (string data)
205                 {
206                         return new XmlCDataSection (data, this);
207                 }
208
209                 public virtual XmlComment CreateComment (string data)
210                 {
211                         return new XmlComment(data, this);
212                 }
213
214                 [MonoTODO]
215                 protected internal virtual XmlAttribute CreateDefaultAttribute (string prefix, string localName, string namespaceURI)
216                 {
217                         throw new NotImplementedException ();
218                 }
219
220                 [MonoTODO]
221                 public virtual XmlDocumentFragment CreateDocumentFragment ()
222                 {
223                         throw new NotImplementedException ();
224                 }
225
226                 public virtual XmlDocumentType CreateDocumentType (string name, string publicId,
227                                                                    string systemId, string internalSubset)
228                 {
229                         return new XmlDocumentType (name, publicId, systemId, internalSubset, this);
230                 }
231
232                 public XmlElement CreateElement (string name)
233                 {
234                         return CreateElement (name, String.Empty);
235                 }
236
237                 public XmlElement CreateElement (
238                         string qualifiedName, 
239                         string namespaceURI)
240                 {
241                         string prefix;
242                         string localName;
243
244                         ParseName (qualifiedName, out prefix, out localName);
245
246                         return CreateElement (prefix, localName, namespaceURI);
247                 }
248
249                 public virtual XmlElement CreateElement (
250                         string prefix,
251                         string localName,
252                         string namespaceURI)
253                 {
254                         if ((localName == null) || (localName == String.Empty))
255                                 throw new ArgumentException ("The local name for elements or attributes cannot be null or an empty string.");
256
257                         return new XmlElement (prefix != null ? prefix : String.Empty, localName, namespaceURI != null ? namespaceURI : String.Empty, this);
258                 }
259
260                 [MonoTODO]
261                 public virtual XmlEntityReference CreateEntityReference (string name)
262                 {
263                         throw new NotImplementedException ();
264                 }
265
266                 [MonoTODO]
267                 protected internal virtual XPathNavigator CreateNavigator (XmlNode node)
268                 {
269                         throw new NotImplementedException ();
270                 }
271
272                 public virtual XmlNode CreateNode (
273                         string nodeTypeString,
274                         string name,
275                         string namespaceURI)
276                 {
277                         return CreateNode (GetNodeTypeFromString (nodeTypeString), name, namespaceURI);
278                 }
279
280                 public virtual XmlNode CreateNode (
281                         XmlNodeType type,
282                         string name,
283                         string namespaceURI)
284                 {
285                         string prefix = null;
286                         string localName = name;
287
288                         if ((type == XmlNodeType.Attribute) || (type == XmlNodeType.Element) || (type == XmlNodeType.EntityReference))
289                                 ParseName (name, out prefix, out localName);
290                         
291                         return CreateNode (type, prefix, localName, namespaceURI);
292                 }
293
294                 public virtual XmlNode CreateNode (
295                         XmlNodeType type,
296                         string prefix,
297                         string name,
298                         string namespaceURI)
299                 {
300                         switch (type) {
301                                 case XmlNodeType.Attribute: return CreateAttribute (prefix, name, namespaceURI);
302                                 case XmlNodeType.CDATA: return CreateCDataSection (null);
303                                 case XmlNodeType.Comment: return CreateComment (null);
304                                 case XmlNodeType.Document: return new XmlDocument (); // TODO - test to see which constructor to use, i.e. use existing NameTable or not.
305                                 case XmlNodeType.DocumentFragment: return CreateDocumentFragment ();
306                                 case XmlNodeType.DocumentType: return CreateDocumentType (null, null, null, null);
307                                 case XmlNodeType.Element: return CreateElement (prefix, name, namespaceURI);
308                                 case XmlNodeType.EntityReference: return CreateEntityReference (null);
309                                 case XmlNodeType.ProcessingInstruction: return CreateProcessingInstruction (null, null);
310                                 case XmlNodeType.SignificantWhitespace: return CreateSignificantWhitespace (String.Empty);
311                                 case XmlNodeType.Text: return CreateTextNode (null);
312                                 case XmlNodeType.Whitespace: return CreateWhitespace (String.Empty);
313                                 case XmlNodeType.XmlDeclaration: return CreateXmlDeclaration ("1.0", null, null);
314                                 default: throw new ArgumentOutOfRangeException(String.Format("{0}\nParameter name: {1}",
315                                                          "Specified argument was out of the range of valid values", type.ToString ()));
316                         }
317                 }
318
319                 public virtual XmlProcessingInstruction CreateProcessingInstruction (
320                         string target,
321                         string data)
322                 {
323                         return new XmlProcessingInstruction (target, data, this);
324                 }
325
326                 public virtual XmlSignificantWhitespace CreateSignificantWhitespace (string text)
327                 {
328                         foreach (char c in text)
329                                 if ((c != ' ') && (c != '\r') && (c != '\n') && (c != '\t'))
330                                     throw new ArgumentException ("Invalid whitespace characters.");
331                          
332                         return new XmlSignificantWhitespace (text, this);
333                 }
334
335                 public virtual XmlText CreateTextNode (string text)
336                 {
337                         return new XmlText (text, this);
338                 }
339
340                 public virtual XmlWhitespace CreateWhitespace (string text)
341                 {
342                         foreach (char c in text)
343                                 if ((c != ' ') && (c != '\r') && (c != '\n') && (c != '\t'))
344                                     throw new ArgumentException ("Invalid whitespace characters.");
345                          
346                         return new XmlWhitespace (text, this);
347                 }
348
349                 public virtual XmlDeclaration CreateXmlDeclaration (string version, string encoding,
350                                                                     string standalone)
351                 {
352                         if (version != "1.0")
353                                 throw new ArgumentException ("version string is not correct.");
354
355                         if  ((standalone != null) && !((standalone == "yes") || (standalone == "no")))
356                                 throw new ArgumentException ("standalone string is not correct.");
357                         
358                         return new XmlDeclaration (version, encoding, standalone, this);
359                 }
360
361                 [MonoTODO]
362                 public virtual XmlElement GetElementById (string elementId)
363                 {
364                         throw new NotImplementedException ();
365                 }
366
367                 public virtual XmlNodeList GetElementsByTagName (string name)
368                 {
369                         ArrayList nodeArrayList = new ArrayList ();
370                         this.searchNodesRecursively (this, name, nodeArrayList);
371                         return new XmlNodeArrayList (nodeArrayList);
372                 }
373
374                 private void searchNodesRecursively (XmlNode argNode, string argName, 
375                         ArrayList argArrayList)
376                 {
377                         XmlNodeList xmlNodeList = argNode.ChildNodes;
378                         foreach (XmlNode node in xmlNodeList){
379                                 if (node.Name.Equals (argName))
380                                         argArrayList.Add (node);
381                                 else    
382                                         this.searchNodesRecursively (node, argName, argArrayList);
383                         }
384                 }
385
386                 private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI, 
387                         ArrayList argArrayList)
388                 {
389                         XmlNodeList xmlNodeList = argNode.ChildNodes;
390                         foreach (XmlNode node in xmlNodeList){
391                                 if (node.LocalName.Equals (argName) && node.NamespaceURI.Equals (argNamespaceURI))
392                                         argArrayList.Add (node);
393                                 else    
394                                         this.searchNodesRecursively (node, argName, argNamespaceURI, argArrayList);
395                         }
396                 }
397
398                 public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
399                 {
400                         ArrayList nodeArrayList = new ArrayList ();
401                         this.searchNodesRecursively (this, localName, namespaceURI, nodeArrayList);
402                         return new XmlNodeArrayList (nodeArrayList);
403                 }
404
405                 private XmlNodeType GetNodeTypeFromString (string nodeTypeString)
406                 {
407                         switch (nodeTypeString) {
408                                 case "attribute": return XmlNodeType.Attribute;
409                                 case "cdatasection": return XmlNodeType.CDATA;
410                                 case "comment": return XmlNodeType.Comment;
411                                 case "document": return XmlNodeType.Document;
412                                 case "documentfragment": return XmlNodeType.DocumentFragment;
413                                 case "documenttype": return XmlNodeType.DocumentType;
414                                 case "element": return XmlNodeType.Element;
415                                 case "entityreference": return XmlNodeType.EntityReference;
416                                 case "processinginstruction": return XmlNodeType.ProcessingInstruction;
417                                 case "significantwhitespace": return XmlNodeType.SignificantWhitespace;
418                                 case "text": return XmlNodeType.Text;
419                                 case "whitespace": return XmlNodeType.Whitespace;
420                                 default:
421                                         throw new ArgumentException(String.Format("The string doesn't represent any node type : {0}.", nodeTypeString));
422                         }
423                 }
424
425                 [MonoTODO]
426                 public virtual XmlNode ImportNode (XmlNode node, bool deep)
427                 {
428                         // How to resolve default attribute values?
429                         switch(node.NodeType)
430                         {
431                                 case XmlNodeType.Attribute:
432                                         {
433                                                 XmlAttribute src_att = node as XmlAttribute;
434                                                 XmlAttribute dst_att = this.CreateAttribute(src_att.Prefix, src_att.LocalName, src_att.NamespaceURI);
435                                                 // TODO: resolve default attribute values
436                                                 dst_att.Value = src_att.Value;
437                                                 return dst_att;
438                                         }
439
440                                 case XmlNodeType.CDATA:
441                                         return this.CreateCDataSection(node.Value);
442
443                                 case XmlNodeType.Comment:
444                                         return this.CreateComment(node.Value);
445
446                                 case XmlNodeType.Document:
447                                         throw new XmlException("Document cannot be imported.");
448
449                                 case XmlNodeType.DocumentFragment:
450                                         {
451                                                 XmlDocumentFragment df = this.CreateDocumentFragment();
452                                                 if(deep)
453                                                 {
454                                                         foreach(XmlNode n in node.ChildNodes)
455                                                         {
456                                                                 df.AppendChild(this.ImportNode(n, deep));
457                                                         }
458                                                 }
459                                                 return df;
460                                         }
461
462                                 case XmlNodeType.DocumentType:
463                                         throw new XmlException("DocumentType cannot be imported.");
464
465                                 case XmlNodeType.Element:
466                                         {
467                                                 XmlElement src = (XmlElement)node;
468                                                 XmlElement dst = this.CreateElement(src.Prefix, src.LocalName, src.NamespaceURI);
469                                                 foreach(XmlAttribute attr in src.Attributes)
470                                                 {
471                                                         // TODO: create default attribute values
472                                                         dst.SetAttributeNode((XmlAttribute)this.ImportNode(attr, deep));
473                                                 }
474                                                 if(deep)
475                                                 {
476                                                         foreach(XmlNode n in src.ChildNodes)
477                                                                 dst.AppendChild(this.ImportNode(n, deep));
478                                                 }
479                                                 return dst;
480                                         }
481
482                                 case XmlNodeType.EndElement:
483                                         throw new XmlException ("Illegal ImportNode call for NodeType.EndElement");
484                                 case XmlNodeType.EndEntity:
485                                         throw new XmlException ("Illegal ImportNode call for NodeType.EndEntity");
486                                 case XmlNodeType.Entity:
487                                         throw new NotImplementedException ();
488
489                                 // [2002.10.14] CreateEntityReference not implemented.
490                                 case XmlNodeType.EntityReference:
491                                         throw new NotImplementedException("ImportNode of EntityReference not implemented mainly because CreateEntityReference was implemented in the meantime.");
492 //                                      return this.CreateEntityReference(node.Name);
493
494                                 case XmlNodeType.None:
495                                         throw new XmlException ("Illegal ImportNode call for NodeType.None");
496                                 case XmlNodeType.Notation:
497                                         throw new NotImplementedException ();
498
499                                 case XmlNodeType.ProcessingInstruction:
500                                         XmlProcessingInstruction pi = node as XmlProcessingInstruction;
501                                         return this.CreateProcessingInstruction(pi.Target, pi.Data);
502
503                                 case XmlNodeType.SignificantWhitespace:
504                                         return this.CreateSignificantWhitespace(node.Value);
505
506                                 case XmlNodeType.Text:
507                                         return this.CreateTextNode(node.Value);
508
509                                 case XmlNodeType.Whitespace:
510                                         return this.CreateWhitespace(node.Value);
511
512                                 // I don't know how to test it...
513                                 case XmlNodeType.XmlDeclaration:
514                                 //      return this.CreateNode(XmlNodeType.XmlDeclaration, String.Empty, node.Value);
515                                         throw new NotImplementedException ();
516
517                                 default:
518                                         throw new NotImplementedException ();
519                         }
520                 }
521
522                 public virtual void Load (Stream inStream)
523                 {
524                         XmlReader xmlReader = new XmlTextReader (inStream);
525                         Load (xmlReader);
526                 }
527
528                 public virtual void Load (string filename)
529                 {
530                         baseURI = filename;
531                         XmlReader xmlReader = new XmlTextReader (new StreamReader (filename));
532                         Load (xmlReader);
533                 }
534
535                 public virtual void Load (TextReader txtReader)
536                 {
537                         Load (new XmlTextReader (txtReader));
538                 }
539
540                 public virtual void Load (XmlReader xmlReader)
541                 {
542                         // Reset our document
543                         // For now this just means removing all our children but later this
544                         // may turn out o need to call a private method that resets other things
545                         // like properties we have, etc.
546                         RemoveAll ();
547
548                         XmlNode currentNode = this;
549                         XmlNode newNode;
550
551 #if true
552                         this.ConstructDOM(xmlReader, currentNode);
553 #else
554                         // Below are copied to XmlNode.Construct(currentNode, xmlReader)
555                         while (xmlReader.Read ()) 
556                         {
557                                 switch (xmlReader.NodeType) {
558
559                                 case XmlNodeType.CDATA:
560                                         newNode = CreateCDataSection(xmlReader.Value);
561                                         currentNode.AppendChild (newNode);
562                                         break;
563
564                                 case XmlNodeType.Comment:
565                                         newNode = CreateComment (xmlReader.Value);
566                                         currentNode.AppendChild (newNode);
567                                         break;
568
569                                 case XmlNodeType.Element:
570                                         XmlElement element = CreateElement (xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
571                                         currentNode.AppendChild (element);
572
573                                         // set the element's attributes.
574                                         while (xmlReader.MoveToNextAttribute ()) {
575                                                 XmlAttribute attribute = CreateAttribute (xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
576                                                 attribute.Value = xmlReader.Value;
577                                                 element.SetAttributeNode (attribute);
578                                         }
579
580                                         xmlReader.MoveToElement ();
581
582                                         // if this element isn't empty, push it onto our "stack".
583                                         if (!xmlReader.IsEmptyElement)
584                                                 currentNode = element;
585
586                                         break;
587
588                                 case XmlNodeType.EndElement:
589                                         currentNode = currentNode.ParentNode;
590                                         break;
591
592                                 case XmlNodeType.ProcessingInstruction:
593                                         newNode = CreateProcessingInstruction (xmlReader.Name, xmlReader.Value);
594                                         currentNode.AppendChild (newNode);
595                                         break;
596
597                                 case XmlNodeType.Text:
598                                         newNode = CreateTextNode (xmlReader.Value);
599                                         currentNode.AppendChild (newNode);
600                                         break;
601                                 }
602                         }
603 #endif
604                 }
605
606                 public virtual void LoadXml (string xml)
607                 {
608                         XmlReader xmlReader = new XmlTextReader (new StringReader (xml));
609                         Load (xmlReader);
610                 }
611
612                 internal void onNodeChanged (XmlNode node, XmlNode Parent)
613                 {
614                         if (NodeChanged != null)
615                                 NodeChanged (node, new XmlNodeChangedEventArgs
616                                         (XmlNodeChangedAction.Change,
617                                         node, Parent, Parent));
618                 }
619
620                 internal void onNodeChanging(XmlNode node, XmlNode Parent)
621                 {
622                         if (NodeChanging != null)
623                                 NodeChanging (node, new XmlNodeChangedEventArgs
624                                         (XmlNodeChangedAction.Change,
625                                         node, Parent, Parent));
626                 }
627
628                 internal void onNodeInserted (XmlNode node, XmlNode newParent)
629                 {
630                         if (NodeInserted != null)
631                                 NodeInserted (node, new XmlNodeChangedEventArgs
632                                         (XmlNodeChangedAction.Insert,
633                                         node, null, newParent));
634                 }
635
636                 internal void onNodeInserting (XmlNode node, XmlNode newParent)
637                 {
638                         if (NodeInserting != null)
639                                 NodeInserting (node, new XmlNodeChangedEventArgs
640                                         (XmlNodeChangedAction.Insert,
641                                         node, null, newParent));
642                 }
643
644                 internal void onNodeRemoved (XmlNode node, XmlNode oldParent)
645                 {
646                         if (NodeRemoved != null)
647                                 NodeRemoved (node, new XmlNodeChangedEventArgs
648                                         (XmlNodeChangedAction.Remove,
649                                         node, oldParent, null));
650                 }
651
652                 internal void onNodeRemoving (XmlNode node, XmlNode oldParent)
653                 {
654                         if (NodeRemoving != null)
655                                 NodeRemoving (node, new XmlNodeChangedEventArgs
656                                         (XmlNodeChangedAction.Remove,
657                                         node, oldParent, null));
658                 }
659
660                 private void ParseName (string name, out string prefix, out string localName)
661                 {
662                         int indexOfColon = name.IndexOf (':');
663                         
664                         if (indexOfColon != -1) {
665                                 prefix = name.Substring (0, indexOfColon);
666                                 localName = name.Substring (indexOfColon + 1);
667                         } else {
668                                 prefix = "";
669                                 localName = name;
670                         }
671                 }
672
673                 [MonoTODO]
674                 public virtual XmlNode ReadNode(XmlReader reader)
675                 {
676                         throw new NotImplementedException ();
677                 }
678
679                 [MonoTODO ("Verify what encoding is used by default;  Should use PreserveWhiteSpace")]
680                 public virtual void Save(Stream outStream)
681                 {
682                         XmlTextWriter xmlWriter = new XmlTextWriter (outStream, Encoding.UTF8);
683                         WriteContentTo (xmlWriter);
684                         xmlWriter.Close ();
685                 }
686
687                 [MonoTODO ("Verify what encoding is used by default; Should use PreseveWhiteSpace")]
688                 public virtual void Save (string filename)
689                 {
690                         XmlTextWriter xmlWriter = new XmlTextWriter (filename, Encoding.UTF8);
691                         WriteContentTo (xmlWriter);
692                         xmlWriter.Close ();
693                 }
694
695                 [MonoTODO]
696                 public virtual void Save (TextWriter writer)
697                 {
698                         XmlTextWriter xmlWriter = new XmlTextWriter (writer);
699                         WriteContentTo (xmlWriter);
700                         xmlWriter.Flush ();
701                 }
702
703                 [MonoTODO ("Should preserve white space if PreserveWhisspace is set")]
704                 public virtual void Save (XmlWriter xmlWriter)
705                 {
706                         //
707                         // This should preserve white space if PreserveWhiteSpace is true
708                         //
709                         WriteContentTo (xmlWriter);
710                         xmlWriter.Flush ();
711                 }
712
713                 public override void WriteContentTo (XmlWriter w)
714                 {
715                         foreach(XmlNode childNode in ChildNodes)
716                                 childNode.WriteTo(w);
717                 }
718
719                 public override void WriteTo (XmlWriter w)
720                 {
721                         WriteContentTo(w);
722                 }
723
724                 #endregion
725         }
726 }