4609afbe66306062ab04de999821b77524ccff02
[mono.git] / mcs / class / System.XML / System.Xml / XmlNode.cs
1 // -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-\r
2 //\r
3 // System.Xml.XmlNode\r
4 //\r
5 // Author:\r
6 //   Daniel Weber (daniel-weber@austin.rr.com)\r
7 //\r
8 // (C) 2001 Daniel Weber\r
9 \r
10 using System;\r
11 using System.Collections;\r
12 using System.Xml.XPath;\r
13 \r
14 namespace System.Xml \r
15 {\r
16         public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable \r
17         {\r
18                 //======= Private data members ==============================================\r
19                 private XmlNodeListAsArrayList _childNodes;\r
20                 protected XmlDocument FOwnerDocument;\r
21                 protected XmlNode _parent;\r
22                 \r
23                 /// <summary>\r
24                 /// Return a clone of this node\r
25                 /// </summary>\r
26                 /// <returns></returns>\r
27                 public virtual object Clone()\r
28                 {\r
29                         // TODO - implement XmlNode.Clone() as object\r
30                         throw new NotImplementedException("object XmlNode.Clone() not implmented");\r
31                 }\r
32 \r
33                 // ============ Properties ============================\r
34                 /// <summary>\r
35                 /// Get the XmlAttributeCollection representing the attributes\r
36                 ///   on the node type.  Returns null if the node type is not XmlElement.\r
37                 /// </summary>\r
38                 public virtual XmlAttributeCollection Attributes \r
39                 {\r
40                         get \r
41                         {\r
42                                 return null;\r
43                         }\r
44                 }\r
45                 /// <summary>\r
46                 ///  Return the base Uniform Resource Indicator (URI) used to resolve\r
47                 ///  this node, or String.Empty.\r
48                 /// </summary>\r
49                 public virtual string BaseURI \r
50                 {\r
51                         get \r
52                         {\r
53                                 // TODO - implement XmlNode.BaseURI {get;}\r
54                                 throw new NotImplementedException("XmlNode.BaseURI not implemented");\r
55 \r
56                         }\r
57 \r
58                 }\r
59                 /// <summary>\r
60                 /// Return all child nodes of this node.  If there are no children,\r
61                 ///  return an empty XmlNodeList;\r
62                 /// </summary>\r
63                 public virtual XmlNodeList ChildNodes \r
64                 {\r
65                         get \r
66                         {\r
67                                 if (_childNodes == null)\r
68                                         _childNodes = new XmlNodeListAsArrayList();\r
69 \r
70                                 return _childNodes as XmlNodeList;\r
71                         }\r
72                 }\r
73                 \r
74                 /// <summary>\r
75                 /// Return first child node as XmlNode or null\r
76                 /// if the node has no children\r
77                 /// </summary>\r
78                 public virtual XmlNode FirstChild \r
79                 {\r
80                         get\r
81                         {\r
82                                 if (ChildNodes.Count == 0)\r
83                                         return null;\r
84                                 else\r
85                                         return ChildNodes[0];\r
86                         }\r
87                 }\r
88 \r
89                 /// <summary>\r
90                 ///             Return true if the node has children\r
91                 /// </summary>\r
92                 public virtual bool HasChildNodes \r
93                 {\r
94                         get \r
95                         {\r
96                                 if (_childNodes.Count == 0)\r
97                                         return true;\r
98                                 else\r
99                                         return false;\r
100                         }\r
101                 }\r
102 \r
103                 /// <summary>\r
104                 /// Get or Set the concatenated values of node and children\r
105                 /// </summary>\r
106                 public virtual string InnerText\r
107                 {\r
108                         get\r
109                         {\r
110                                 // TODO - implement set InnerText()\r
111                                 throw new NotImplementedException();\r
112                         }\r
113 \r
114                         set \r
115                         {\r
116                                 // TODO - implement set InnerText()\r
117                                 throw new NotImplementedException();\r
118                         }\r
119                 }\r
120 \r
121                 /// <summary>\r
122                 /// Get/Set the XML representing just the child nodes of this node\r
123                 /// </summary>\r
124                 public virtual string InnerXml\r
125                 {\r
126                         get\r
127                         {\r
128                                 // TODO - implement set InnerXml()\r
129                                 throw new NotImplementedException();\r
130                         }\r
131 \r
132                         set \r
133                         {\r
134                                 // TODO - implement set InnerXml()\r
135                                 throw new NotImplementedException();\r
136                         }\r
137                 }\r
138 \r
139                 /// <summary>\r
140                 /// Property Get - true if node is read-only\r
141                 /// </summary>\r
142                 public virtual bool IsReadOnly\r
143                 {\r
144                         get\r
145                         {\r
146                                 return OwnerDocument.IsReadOnly;\r
147                         }\r
148                 }\r
149 \r
150                 /// <summary>\r
151                 /// Return the child element named [string].  Returns XmlElement\r
152                 /// Indexer for XmlNode class.\r
153                 /// </summary>\r
154                 [System.Runtime.CompilerServices.CSharp.IndexerName("Item")]\r
155                 public virtual XmlElement this [String index]\r
156                 {\r
157                         get \r
158                         {\r
159                                 // TODO - implement XmlNode.Item(string)\r
160                                 throw new NotImplementedException();\r
161                         }\r
162                 }\r
163 \r
164                 /// <summary>\r
165                 /// Get the last child node, or null if there are no nodes\r
166                 /// </summary>\r
167                 public virtual XmlNode LastChild\r
168                 {\r
169                         get\r
170                         {\r
171                 if (_childNodes.Count == 0)\r
172                                  return null;\r
173                                 else\r
174                                  return _childNodes.Item(_childNodes.Count - 1);\r
175                         }\r
176 \r
177                 }\r
178 \r
179                 /// <summary>\r
180                 /// Returns the local name of the node with qualifiers removed\r
181                 /// LocalName of ns:elementName = "elementName"\r
182                 /// </summary>\r
183                 public abstract string LocalName {get;}\r
184 \r
185                 /// <summary>\r
186                 /// Get the qualified node name\r
187                 /// derived classes must implement as behavior varies\r
188                 /// by tag type.\r
189                 /// </summary>\r
190                 public abstract string Name { get; }\r
191 \r
192                 /// <summary>\r
193                 /// Get the namespace URI or String.Empty if none\r
194                 /// </summary>\r
195                 public virtual string NamespaceURI\r
196                 {\r
197                         get\r
198                         {\r
199                                 // TODO - implement Namespace URI, or determine abstractness\r
200                                 throw new NotImplementedException("XmlNode.NamespaceURI not implemented");\r
201                         }\r
202                 }\r
203 \r
204                 /// <summary>\r
205                 /// Get the node immediatelly following this node, or null\r
206                 /// </summary>\r
207                 public virtual XmlNode NextSibling \r
208                 {\r
209                         get\r
210                         {\r
211                                 \r
212                                 if (_parent != null)\r
213                                 {\r
214                                         XmlNodeListAsArrayList children = _parent.ChildNodes as XmlNodeListAsArrayList;\r
215                                         int ourIndex = children.data.IndexOf(this);\r
216                                         return children[ourIndex + 1];\r
217                                 }\r
218                                 else\r
219                                         return null;\r
220                         }\r
221                 }\r
222 \r
223                 public virtual XmlNodeType NodeType \r
224                 {\r
225                         get\r
226                         {\r
227                                 return XmlNodeType.None;\r
228                         }\r
229                 }\r
230 \r
231                 /// <summary>\r
232                 /// Return the string representing this node and all it's children\r
233                 /// </summary>\r
234                 public virtual string OuterXml\r
235                 {\r
236                         get\r
237                         {\r
238                                 // TODO - implement OuterXml {get;}\r
239                                 throw new NotImplementedException();\r
240                         }\r
241                 }\r
242 \r
243                 /// <summary>\r
244                 /// Return owning document.\r
245                 /// If this nodeType is a document, return null\r
246                 /// </summary>\r
247                 public virtual XmlDocument OwnerDocument\r
248                 {\r
249                         get\r
250                         {\r
251                                 return FOwnerDocument;\r
252                         }\r
253                 }\r
254 \r
255                 /// <summary>\r
256                 /// Returns the parent node, or null\r
257                 /// Return value depends on superclass node type\r
258                 /// </summary>\r
259                 public virtual XmlNode ParentNode\r
260                 {\r
261                         get\r
262                         {\r
263                                 return _parent;\r
264                         }\r
265                 }\r
266                 \r
267                 /// <summary>\r
268                 /// set/get the namespace prefix for this node, or \r
269                 /// string.empty if it does not exist\r
270                 /// </summary>\r
271                 public virtual string Prefix \r
272                 {\r
273                         get\r
274                         {\r
275                                 // TODO - implement Prefix {get;}\r
276                                 throw new NotImplementedException();\r
277                         }\r
278                         \r
279                         set\r
280                         {\r
281                                 // TODO - implement Prefix {set;}\r
282                                 throw new NotImplementedException();\r
283                         }\r
284                 }\r
285 \r
286                 /// <summary>\r
287                 /// The preceding XmlNode or null\r
288                 /// </summary>\r
289                 public virtual XmlNode PreviousSibling {\r
290                         get\r
291                         {\r
292                                 if (_parent != null)\r
293                                 {\r
294                                         XmlNodeListAsArrayList children = _parent.ChildNodes as XmlNodeListAsArrayList;\r
295                                         int ourIndex = children.data.IndexOf(this);\r
296                                         return children[ourIndex - 1];\r
297                                 }\r
298                                 else\r
299                                         return null;\r
300                         }\r
301                 }\r
302 \r
303                 /// <summary>\r
304                 /// Get/Set the value for this node\r
305                 /// </summary>\r
306                 public virtual string Value \r
307                 {\r
308                         get\r
309                         {\r
310                                 // TODO - implement Value {get;}\r
311                                 throw new NotImplementedException();\r
312                         }\r
313                         \r
314                         set\r
315                         {\r
316                                 // TODO - implement Value {set;}\r
317                                 throw new NotImplementedException();\r
318                         }\r
319                 }\r
320 \r
321                 //======= Methods ==========================\r
322                 /// <summary>\r
323                 /// Appends the specified node to the end of the child node list\r
324                 /// </summary>\r
325                 /// <param name="newChild"></param>\r
326                 /// <returns></returns>\r
327                 public virtual XmlNode AppendChild (XmlNode newChild)\r
328                 {\r
329                         return InsertBefore(newChild, null);\r
330                 }\r
331 \r
332                 /// <summary>\r
333                 /// Return a clone of the node\r
334                 /// </summary>\r
335                 /// <param name="deep">Make copy of all children</param>\r
336                 /// <returns>Cloned node</returns>\r
337                 public abstract XmlNode CloneNode( bool deep);\r
338 \r
339                 /// <summary>\r
340                 /// Return an XPathNavigator for navigating this node\r
341                 /// </summary>\r
342                 /// <returns></returns>\r
343                 public System.Xml.XPath.XPathNavigator CreateNavigator()\r
344                 {\r
345                         // TODO - implement CreateNavigator()\r
346                         throw new NotImplementedException();\r
347                 }\r
348 \r
349                 /// <summary>\r
350                 /// Provide support for "for each" \r
351                 /// </summary>\r
352                 /// <returns></returns>\r
353                 public IEnumerator GetEnumerator()\r
354                 {\r
355                         return _childNodes.data.GetEnumerator();\r
356                 }\r
357 \r
358                 /// <summary>\r
359                 /// Look up the closest namespace for this node that is in scope for the given prefix\r
360                 /// </summary>\r
361                 /// <param name="prefix"></param>\r
362                 /// <returns>Namespace URI</returns>\r
363                 public virtual string GetNamespaceOfPrefix(string prefix)\r
364                 {\r
365                         // TODO - implement GetNamespaceOfPrefix()\r
366                         throw new NotImplementedException();\r
367                 }\r
368 \r
369                 /// <summary>\r
370                 /// Get the closest xmlns declaration for the given namespace URI that is in scope.\r
371                 /// Returns the prefix defined in that declaration.\r
372                 /// </summary>\r
373                 /// <param name="namespaceURI"></param>\r
374                 /// <returns></returns>\r
375                 public virtual string GetPrefixOfNamespace(string namespaceURI)\r
376                 {\r
377                         // TODO - implement GetPrefixOfNamespace\r
378                         throw new NotImplementedException();\r
379                 }\r
380                 \r
381                 /// <summary>\r
382                 /// Insert newChild directly after the reference node.\r
383                 /// If refChild is null, newChild is inserted at the beginning of childnodes.\r
384                 /// If newChild is a document fragment, all nodes are inserted after refChild.\r
385                 /// If newChild is already in the tree, it is first removed.\r
386                 /// </summary>\r
387                 /// <exception cref="ArgumentException">NewChild was created from differant document.\r
388                 /// RefChild not a child of this node or null.\r
389                 /// Node is read-only</exception>\r
390                 /// <exception cref="InvalidOperationException">Node is of type that does not have children\r
391                 /// Node to insert is an ancestor of this node.</exception>\r
392                 /// <param name="newChild">Child node to insert.</param>\r
393                 /// <param name="refChild">Reference node to insert after</param>\r
394                 /// <returns></returns>\r
395                 public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild)\r
396                 {\r
397                         // Checks parent not ancestor, arguments valid, etc.  Throws exception on error\r
398                         InsertionCheck(newChild, refChild);\r
399 \r
400                         // Scan the node list, looking for refChild and seeing if newChild is in the list\r
401                         // Note that if refNode is null (prepend), we don't want to do the .Equals(null)\r
402                         XmlNode retval = null;\r
403                         int refNodeIndex = -1;\r
404                         \r
405                         for (int i = 0; i < _childNodes.Count; i++)\r
406                         {\r
407                                 XmlNode e = _childNodes.data[i] as XmlNode;\r
408                                 if (e.Equals(newChild))\r
409                                 {\r
410                                         retval = e;\r
411                                         FOwnerDocument.onNodeRemoving(newChild, newChild.ParentNode);\r
412                                         _childNodes.data.RemoveAt(i);\r
413                                         newChild.setParent(null);\r
414                                         FOwnerDocument.onNodeRemoved(newChild, null);\r
415                                         break;\r
416                 \r
417                                 }\r
418 \r
419                                 if ( (refChild != null ) & ( e.Equals(refChild) ) )\r
420                                 {\r
421                                         refNodeIndex = i;\r
422 \r
423                                         if (retval != null)\r
424                                                 break;\r
425                                 }\r
426                         }\r
427 \r
428                         if ( ( refNodeIndex == -1 ) & (refChild != null) )\r
429                                 throw new ArgumentException("Reference node not found (and not null) in call to XmlNode.InsertAfter()");\r
430 \r
431                         FOwnerDocument.onNodeInserting(newChild, this);\r
432 \r
433                         if (refChild == null)\r
434                                 refNodeIndex = 0;\r
435                         else\r
436                                 refNodeIndex++;                 // insert after reference...\r
437 \r
438                         if (newChild.NodeType == XmlNodeType.DocumentFragment)\r
439                         {\r
440                                 // Insert all children, starting from refNodeIndex (0,1,2...n)\r
441                                 for (int i = 0; i < newChild.ChildNodes.Count; i++)\r
442                                 {\r
443                                         XmlNode e = newChild.ChildNodes[i] as XmlNode;\r
444                                         FOwnerDocument.onNodeInserting(e, this);\r
445                                         _childNodes.data.Insert(refNodeIndex, newChild.ChildNodes[i]);\r
446                                         e.setParent(this);\r
447                                         FOwnerDocument.onNodeInserted(newChild, this);\r
448                                         refNodeIndex ++;\r
449                                 }\r
450                         }\r
451                         else\r
452                         {\r
453                                 FOwnerDocument.onNodeInserting(newChild, this);\r
454                                 _childNodes.data.Insert(refNodeIndex, newChild);\r
455                                 newChild.setParent(this);\r
456                                 FOwnerDocument.onNodeInserted(newChild, this);\r
457                         }\r
458 \r
459                         return retval;\r
460                 }\r
461                 \r
462                 /// <summary>\r
463                 /// Insert newChild directly before the reference node.\r
464                 /// </summary>\r
465                 /// <param name="newChild"></param>\r
466                 /// <param name="refChild"></param>\r
467                 /// <returns></returns>\r
468                 public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild)\r
469                 {\r
470                         // Checks parent not ancestor, arguments valid, etc.  Throws exception on error\r
471                         InsertionCheck(newChild, refChild);\r
472 \r
473                         // Scan the node list, looking for refChild and seeing if newChild is in the list\r
474                         XmlNode retval = null;\r
475                         int refNodeIndex = -1;\r
476                         \r
477                         for (int i = 0; i < _childNodes.Count; i++)\r
478                         {\r
479                                 XmlNode e = _childNodes.data[i] as XmlNode;\r
480                                 if (e.Equals(newChild))\r
481                                 {\r
482                                         retval = e;\r
483                                         FOwnerDocument.onNodeRemoving(newChild, newChild.ParentNode);\r
484                                         _childNodes.data.RemoveAt(i);\r
485                                         newChild.setParent(null);\r
486                                         FOwnerDocument.onNodeRemoved(newChild, null);\r
487                                         break;\r
488                                 }\r
489 \r
490                                 if ( (refChild != null ) & ( e.Equals(refChild) ) )\r
491                                 {\r
492                                         refNodeIndex = i;\r
493 \r
494                                         if (retval != null)\r
495                                                 break;\r
496                                 }\r
497                         }\r
498 \r
499                         if ( ( refNodeIndex == -1 ) & (refChild != null) )\r
500                                 throw new ArgumentException("Reference node not found (and not null) in call to XmlNode.InsertAfter()");\r
501 \r
502                         \r
503 \r
504                         if (refChild == null)\r
505                                 refNodeIndex = _childNodes.Count;\r
506 \r
507                         if (newChild.NodeType == XmlNodeType.DocumentFragment)\r
508                         {\r
509                                 // Insert all children, starting from refNodeIndex (0,1,2...n)\r
510                                 for (int i = 0; i < newChild.ChildNodes.Count; i++)\r
511                                 {\r
512                                         XmlNode e = newChild.ChildNodes[i] as XmlNode;\r
513                                         FOwnerDocument.onNodeInserting(e, this);\r
514                                         _childNodes.data.Insert(refNodeIndex, newChild.ChildNodes[i]);\r
515                                         e.setParent(this);\r
516                                         FOwnerDocument.onNodeInserted(newChild, this);\r
517                                         refNodeIndex ++;\r
518                                 }\r
519                         }\r
520                         else\r
521                         {\r
522                                 FOwnerDocument.onNodeInserting(newChild, this);\r
523                                 _childNodes.data.Insert(refNodeIndex, newChild);\r
524                                 newChild.setParent(this);\r
525                                 FOwnerDocument.onNodeInserted(newChild, this);\r
526                         }\r
527 \r
528                         return retval;\r
529                         \r
530                 }\r
531 \r
532                 /// <summary>\r
533                 /// Put all nodes under this node in "normal" form\r
534                 /// Whatever that means...\r
535                 /// </summary>\r
536                 public virtual void Normalize()\r
537                 {\r
538                         // TODO - Implement Normalize()\r
539                         throw new NotImplementedException();\r
540                 }\r
541 \r
542                 /// <summary>\r
543                 /// Add the specified child to the beginning of the child node list\r
544                 /// </summary>\r
545                 /// <param name="newChild">Node to add</param>\r
546                 /// <returns>The node added</returns>\r
547                 public virtual XmlNode PrependChild(XmlNode newChild)\r
548                 {\r
549                         return InsertAfter(newChild, null);\r
550                 }\r
551 \r
552                 /// <summary>\r
553                 /// Remove all children and attributes\r
554                 /// </summary>\r
555                 public virtual void RemoveAll()\r
556                 {\r
557                         if (_childNodes == null)\r
558                                 return;\r
559                         else\r
560                         {\r
561                                 // Remove in order, 0..n\r
562                                 while (_childNodes.Count > 0)\r
563                                 {\r
564                                         XmlNode e = _childNodes[0];\r
565                                         FOwnerDocument.onNodeRemoving(e, this);\r
566                                         e.setParent(null);\r
567                                         _childNodes.data.RemoveAt(0);\r
568                                         FOwnerDocument.onNodeRemoved(e, null);\r
569                                 }\r
570                         }\r
571                 }\r
572 \r
573                 /// <summary>\r
574                 /// Remove specified child node\r
575                 /// </summary>\r
576                 /// <param name="oldChild"></param>\r
577                 /// <returns>Removed node</returns>\r
578                 public virtual XmlNode RemoveChild(XmlNode oldChild)\r
579                 {\r
580                         // TODO - implement RemoveChild(oldChild)\r
581                         throw new NotImplementedException();\r
582                 }\r
583 \r
584                 /// <summary>\r
585                 /// Select a list of nodes matching the xpath\r
586                 /// </summary>\r
587                 /// <param name="xpath"></param>\r
588                 /// <returns>matching nodes</returns>\r
589                 public XmlNodeList SelectNodes( string xpath)\r
590                 {\r
591                         // TODO - imlement SelectNodes(xpath)\r
592                         throw new NotImplementedException();\r
593                 }\r
594 \r
595                 /// <summary>\r
596                 /// Select a list of nodes matching the xpath.  Any prefixes are resolved\r
597                 /// using the passed namespace manager\r
598                 /// </summary>\r
599                 /// <param name="xpath"></param>\r
600                 /// <param name="nsmgr"></param>\r
601                 /// <returns></returns>\r
602                 public XmlNodeList SelectNodes(string xpath, XmlNamespaceManager nsmgr)\r
603                 {\r
604                         // TODO - implement SelectNodes(xpath, nsmgr)\r
605                         throw new NotImplementedException();\r
606                 }\r
607 \r
608                 /// <summary>\r
609                 /// Selects the first node that matches xpath\r
610                 /// </summary>\r
611                 /// <param name="?"></param>\r
612                 /// <returns></returns>\r
613                 public XmlNode SelectSingleNode(string xpatch)\r
614                 {\r
615                         // TODO - implement SelectSingeNode(xpath)\r
616                         throw new NotImplementedException();\r
617                 }\r
618 \r
619                 /// <summary>\r
620                 /// Returns the first node that matches xpath\r
621                 /// Uses the passed namespace manager to resolve namespace URI's\r
622                 /// </summary>\r
623                 /// <param name="xpath"></param>\r
624                 /// <param name="nsmgr"></param>\r
625                 /// <returns></returns>\r
626                 public XmlNode SelectSingleNode(string xpath, XmlNamespaceManager nsmgr)\r
627                 {\r
628                         // Implement SelectSingleNode(xpath, nsmgr)\r
629                         throw new NotImplementedException();\r
630                 }\r
631 \r
632                 /// <summary>\r
633                 /// Tests if the DOM implementation supports the passed feature\r
634                 /// </summary>\r
635                 /// <param name="feature"></param>\r
636                 /// <param name="version"></param>\r
637                 /// <returns></returns>\r
638                 public virtual bool Supports(string feature, string version)\r
639                 {\r
640                         //TODO - implement Supports(feature, version)\r
641                         throw new NotImplementedException();\r
642                 }\r
643 \r
644                 /// <summary>\r
645                 /// Returns a string representation of the current node and it's children\r
646                 /// </summary>\r
647                 /// <returns></returns>\r
648                 public override string ToString()\r
649                 {\r
650                         // TODO - implement ToString()\r
651                         throw new NotImplementedException();\r
652                 }\r
653 \r
654                 /// <summary>\r
655                 /// Saves all children of the current node to the passed writer\r
656                 /// </summary>\r
657                 /// <param name="w"></param>\r
658                 public abstract void WriteContentTo(XmlWriter w);\r
659                 \r
660                 /// <summary>\r
661                 /// Saves the current node to writer w\r
662                 /// </summary>\r
663                 /// <param name="w"></param>\r
664                 public abstract void WriteTo(XmlWriter w);\r
665 \r
666                 //======= Internal methods    ===============================================\r
667                 /// <summary>\r
668                 /// accessor {set;} for parentNode only visible internally.\r
669                 /// </summary>\r
670                 /// <param name="newParent">new parent node.</param>\r
671                 internal void setParent( XmlNode newParent)\r
672                 {\r
673                         if (newParent.OwnerDocument.Equals( FOwnerDocument) )\r
674                                 _parent = newParent;\r
675                         else\r
676                                 throw new ArgumentException("New parent node owner does not match");\r
677                 }\r
678                 \r
679 \r
680                 //======= Protected methods    ==============================================\r
681 \r
682                 //======= Private Methods ===================================================\r
683                 /// <summary>\r
684                 /// Helper function to perform checks required before insrting a node.\r
685                 /// Throws applicable exceptions on error.\r
686                 /// </summary>\r
687                 /// <param name="newChild"></param>\r
688                 /// <param name="refChild"></param>\r
689                 private void InsertionCheck( XmlNode newChild, XmlNode refChild)\r
690                 {\r
691                         if (newChild == null)\r
692                                 throw new ArgumentNullException("Null newNode passed to InsertAfter()");\r
693 \r
694                         if (newChild.Equals(this))\r
695                                 throw new ArgumentException("Cannot insert node onto itself");\r
696 \r
697                         if (! FOwnerDocument.Equals( newChild.OwnerDocument) )\r
698                                 throw new ArgumentException("Reference node has different owner document than this node");\r
699                 \r
700                         if ( FOwnerDocument.IsReadOnly )\r
701                                 throw new ArgumentException("Operation not supported - tree is read-only");\r
702 \r
703                         //Check that insert node is not in our path to the root\r
704                         XmlNode curParent = _parent;\r
705                         while ( (curParent != null) & (! FOwnerDocument.Equals(curParent) ))\r
706                         {\r
707                                 if (curParent.Equals(newChild) )\r
708                                         throw new ArgumentException("Cannot insert ancestor a node");\r
709                                 curParent = curParent.ParentNode;\r
710                         }\r
711 \r
712                 }\r
713 \r
714                 // Constructors\r
715                 //===========================================================================\r
716                 //When we're first created, we won't know parent, etc.\r
717                 internal XmlNode( XmlDocument aOwnerDoc )\r
718                 {\r
719                         // Don't create childnodes object, since not all derived classes have children\r
720                         FOwnerDocument = aOwnerDoc;\r
721                 }\r
722 \r
723         }       // XmlNode\r
724 }       // using namespace System.Xml\r
725 \r
726