rewrote XmlNode with touchups to XmlDocument, XmlElement, and XmlLinkedNode
[mono.git] / mcs / class / System.XML / System.Xml / XmlNode.cs
index 4240dbb95f170a9bfbd473658540a989be9ff6ac..bfe9a942761d5bfb809c86eecf380a373edcb663 100644 (file)
-// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-\r
-//\r
-// System.Xml.XmlNode\r
-//\r
-// Author:\r
-//   Daniel Weber (daniel-weber@austin.rr.com)\r
-//\r
-// (C) 2001 Daniel Weber\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Xml.XPath;\r
-\r
-namespace System.Xml \r
-{\r
-       public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable \r
-       {\r
-               //======= Private data members ==============================================\r
-               private XmlNodeListAsArrayList _childNodes;\r
-               protected XmlDocument FOwnerDocument;\r
-               protected XmlNode _parent;\r
-\r
-               // Names of node\r
-               // for <foo:bar xmlns:foo="http://www.foobar.com/schema/foobar">... </foo:bar>\r
-               //      qualified name: foo:bar\r
-               //      namespaceURI = "http://www.foobar.com/schema/foobar"\r
-               //  localName = bar\r
-               //      prefix = foo\r
-               // Note that namespaces can be nested (child namespace != parent namespace)\r
-               // namespaces are optional\r
-               protected string Fname;\r
-               protected string FnamespaceURI;\r
-               protected string Fprefix;\r
-               protected string FlocalName;\r
-\r
-               // baseURI holds the location from which the document was loaded\r
-               // If the node was created from a document at c:\tmp.xml, then that's what will be here\r
-               protected string FbaseURI;\r
-\r
-               // value of the node (overriden in classes that do something different)\r
-               //      default behavior is just to store it\r
-               protected string Fvalue;\r
-               \r
-               //=====================================================================\r
-               // ============ Properties ============================================\r
-               //=====================================================================\r
-               /// <summary>\r
-               /// Get the XmlAttributeCollection representing the attributes\r
-               ///   on the node type.  Returns null if the node type is not XmlElement.\r
-               /// </summary>\r
-               public virtual XmlAttributeCollection Attributes \r
-               {\r
-                       get \r
-                       {\r
-                               return null;\r
-                       }\r
-               }\r
-               /// <summary>\r
-               ///  Return the base Uniform Resource Indicator (URI) used to resolve\r
-               ///  this node, or String.Empty.\r
-               /// </summary>\r
-               public virtual string BaseURI \r
-               {\r
-                       get \r
-                       {\r
-                               return FbaseURI;\r
-                       }\r
-\r
-               }\r
-               /// <summary>\r
-               /// Return all child nodes of this node.  If there are no children,\r
-               ///  return an empty XmlNodeList;\r
-               /// </summary>\r
-               public virtual XmlNodeList ChildNodes \r
-               {\r
-                       get \r
-                       {\r
-                               if (_childNodes == null)\r
-                                       _childNodes = new XmlNodeListAsArrayList();\r
-\r
-                               return _childNodes as XmlNodeList;\r
-                       }\r
-               }\r
-               \r
-               /// <summary>\r
-               /// Return first child node as XmlNode or null\r
-               /// if the node has no children\r
-               /// </summary>\r
-               public virtual XmlNode FirstChild \r
-               {\r
-                       get\r
-                       {\r
-                               if (ChildNodes.Count == 0)\r
-                                       return null;\r
-                               else\r
-                                       return ChildNodes[0];\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               ///             Return true if the node has children\r
-               /// </summary>\r
-               public virtual bool HasChildNodes \r
-               {\r
-                       get \r
-                       {\r
-                               if (ChildNodes.Count == 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get or Set the concatenated values of node and children\r
-               /// </summary>\r
-               public virtual string InnerText\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO - implement set InnerText()\r
-                               throw new NotImplementedException();\r
-                       }\r
-\r
-                       set \r
-                       {\r
-                               // TODO - implement set InnerText()\r
-                               throw new NotImplementedException();\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get/Set the XML representing just the child nodes of this node\r
-               /// </summary>\r
-               public virtual string InnerXml\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO - implement set InnerXml()\r
-                               throw new NotImplementedException();\r
-                       }\r
-\r
-                       set \r
-                       {\r
-                               // TODO - implement set InnerXml()\r
-                               throw new NotImplementedException();\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Property Get - true if node is read-only\r
-               /// </summary>\r
-               public virtual bool IsReadOnly\r
-               {\r
-                       get\r
-                       {\r
-                               return OwnerDocument.IsReadOnly;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return the child element named [string].  Returns XmlElement\r
-               /// Indexer for XmlNode class.\r
-               /// </summary>\r
-               [System.Runtime.CompilerServices.IndexerNameAttribute("Item")]\r
-               public virtual XmlElement this [String index]\r
-               {\r
-                       get \r
-                       {\r
-                               // TODO - implement XmlNode.Item(string)\r
-                               throw new NotImplementedException();\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get the last child node, or null if there are no nodes\r
-               /// </summary>\r
-               public virtual XmlNode LastChild\r
-               {\r
-                       get\r
-                       {\r
-                if (_childNodes.Count == 0)\r
-                                return null;\r
-                               else\r
-                                return _childNodes.Item(_childNodes.Count - 1);\r
-                       }\r
-\r
-               }\r
-\r
-               /// <summary>\r
-               /// Returns the local name of the node with qualifiers removed\r
-               /// LocalName of ns:elementName = "elementName"\r
-               /// </summary>\r
-               public abstract string LocalName {get;}\r
-\r
-               /// <summary>\r
-               /// Get the qualified node name\r
-               /// derived classes must implement as behavior varies\r
-               /// by tag type.\r
-               /// </summary>\r
-               public abstract string Name { get; }\r
-\r
-               /// <summary>\r
-               /// Get the namespace URI or String.Empty if none\r
-               /// </summary>\r
-               public virtual string NamespaceURI\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO - implement Namespace URI, or determine abstractness\r
-                               throw new NotImplementedException("XmlNode.NamespaceURI not implemented");\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get the node immediatelly following this node, or null\r
-               /// </summary>\r
-               public virtual XmlNode NextSibling \r
-               {\r
-                       get\r
-                       {\r
-                               \r
-                               if (_parent != null)\r
-                               {\r
-                                       XmlNodeListAsArrayList children = _parent.ChildNodes as XmlNodeListAsArrayList;\r
-                                       int ourIndex = children.data.IndexOf(this);\r
-                                       return children[ourIndex + 1];\r
-                               }\r
-                               else\r
-                                       return null;\r
-                       }\r
-               }\r
-\r
-               public virtual XmlNodeType NodeType \r
-               {\r
-                       get\r
-                       {\r
-                               return XmlNodeType.None;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return the string representing this node and all it's children\r
-               /// </summary>\r
-               public virtual string OuterXml\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO - implement OuterXml {get;}\r
-                               throw new NotImplementedException();\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return owning document.\r
-               /// If this nodeType is a document, return null\r
-               /// </summary>\r
-               public virtual XmlDocument OwnerDocument\r
-               {\r
-                       get\r
-                       {\r
-                               return FOwnerDocument;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Returns the parent node, or null\r
-               /// Return value depends on superclass node type\r
-               /// </summary>\r
-               public virtual XmlNode ParentNode\r
-               {\r
-                       get\r
-                       {\r
-                               return _parent;\r
-                       }\r
-               }\r
-               \r
-               /// <summary>\r
-               /// set/get the namespace prefix for this node, or \r
-               /// string.empty if it does not exist\r
-               /// </summary>\r
-               public virtual string Prefix \r
-               {\r
-                       get\r
-                       {\r
-                               return Fprefix;\r
-                       }\r
-                       \r
-                       set\r
-                       {\r
-                               // TODO - validation on XmlNode.Prefix {set;}? (no)\r
-                               Fprefix = value;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// The preceding XmlNode or null\r
-               /// </summary>\r
-               public virtual XmlNode PreviousSibling {\r
-                       get\r
-                       {\r
-                               if (_parent != null)\r
-                               {\r
-                                       XmlNodeListAsArrayList children = _parent.ChildNodes as XmlNodeListAsArrayList;\r
-                                       int ourIndex = children.data.IndexOf(this);\r
-                                       return children[ourIndex - 1];\r
-                               }\r
-                               else\r
-                                       return null;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get/Set the value for this node\r
-               /// </summary>\r
-               public virtual string Value \r
-               {\r
-                       get\r
-                       {\r
-                               return Fvalue;\r
-                       }\r
-                       \r
-                       set\r
-                       {\r
-                               Fvalue = value;\r
-                       }\r
-               }\r
-\r
-               //=====================================================================\r
-               //======= Methods =====================================================\r
-               //=====================================================================\r
-               /// <summary>\r
-               /// Appends the specified node to the end of the child node list\r
-               /// </summary>\r
-               /// <param name="newChild"></param>\r
-               /// <returns></returns>\r
-               public virtual XmlNode AppendChild (XmlNode newChild)\r
-               {\r
-                       return InsertBefore(newChild, null);\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return a clone of this node\r
-               /// </summary>\r
-               /// <returns></returns>\r
-               public virtual object Clone()\r
-               {\r
-                       // TODO - implement XmlNode.Clone() as object\r
-                       throw new NotImplementedException("object XmlNode.Clone() not implmented");\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return a clone of the node\r
-               /// </summary>\r
-               /// <param name="deep">Make copy of all children</param>\r
-               /// <returns>Cloned node</returns>\r
-               public abstract XmlNode CloneNode( bool deep);\r
-\r
-               /// <summary>\r
-               /// Return an XPathNavigator for navigating this node\r
-               /// </summary>\r
-               /// <returns></returns>\r
-               public System.Xml.XPath.XPathNavigator CreateNavigator()\r
-               {\r
-                       // TODO - implement CreateNavigator()\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Provide support for "for each" \r
-               /// </summary>\r
-               /// <returns></returns>\r
-               public IEnumerator GetEnumerator()\r
-               {\r
-                       return _childNodes.data.GetEnumerator();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Look up the closest namespace for this node that is in scope for the given prefix\r
-               /// </summary>\r
-               /// <param name="prefix"></param>\r
-               /// <returns>Namespace URI</returns>\r
-               public virtual string GetNamespaceOfPrefix(string prefix)\r
-               {\r
-                       // TODO - implement GetNamespaceOfPrefix()\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get the closest xmlns declaration for the given namespace URI that is in scope.\r
-               /// Returns the prefix defined in that declaration.\r
-               /// </summary>\r
-               /// <param name="namespaceURI"></param>\r
-               /// <returns></returns>\r
-               public virtual string GetPrefixOfNamespace(string namespaceURI)\r
-               {\r
-                       // TODO - implement GetPrefixOfNamespace\r
-                       throw new NotImplementedException();\r
-               }\r
-               \r
-               /// <summary>\r
-               /// Insert newChild directly after the reference node.\r
-               /// If refChild is null, newChild is inserted at the beginning of childnodes.\r
-               /// If newChild is a document fragment, all nodes are inserted after refChild.\r
-               /// If newChild is already in the tree, it is first removed.\r
-               /// </summary>\r
-               /// <exception cref="ArgumentException">NewChild was created from differant document.\r
-               /// RefChild not a child of this node or null.\r
-               /// Node is read-only</exception>\r
-               /// <exception cref="InvalidOperationException">Node is of type that does not have children\r
-               /// Node to insert is an ancestor of this node.</exception>\r
-               /// <param name="newChild">Child node to insert.</param>\r
-               /// <param name="refChild">Reference node to insert after</param>\r
-               /// <returns>Removed node, or null if no node removed.</returns>\r
-               public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild)\r
-               {\r
-                       // Checks parent not ancestor, arguments valid, etc.  Throws exception on error\r
-                       InsertionCheck(newChild, refChild);\r
-\r
-                       // Scan the node list, looking for refChild and seeing if newChild is in the list\r
-                       // Note that if refNode is null (prepend), we don't want to do the .Equals(null)\r
-                       XmlNode retval = null;\r
-                       int refNodeIndex = -1;\r
-                       \r
-                       for (int i = 0; i < _childNodes.Count; i++)\r
-                       {\r
-                               XmlNode e = _childNodes.data[i] as XmlNode;\r
-                               if (e.Equals(newChild))\r
-                               {\r
-                                       retval = e;\r
-                                       FOwnerDocument.onNodeRemoving(newChild, newChild.ParentNode);\r
-                                       _childNodes.data.RemoveAt(i);\r
-                                       newChild.setParent(null);\r
-                                       FOwnerDocument.onNodeRemoved(newChild, null);\r
-                                       break;\r
-               \r
-                               }\r
-\r
-                               if ( (refChild != null ) & ( e.Equals(refChild) ) )\r
-                               {\r
-                                       refNodeIndex = i;\r
-\r
-                                       if (retval != null)\r
-                                               break;\r
-                               }\r
-                       }\r
-\r
-                       if ( ( refNodeIndex == -1 ) & (refChild != null) )\r
-                               throw new ArgumentException("Reference node not found (and not null) in call to XmlNode.InsertAfter()");\r
-\r
-                       FOwnerDocument.onNodeInserting(newChild, this);\r
-\r
-                       if (refChild == null)\r
-                               refNodeIndex = 0;\r
-                       else\r
-                               refNodeIndex++;                 // insert after reference...\r
-\r
-                       if (newChild.NodeType == XmlNodeType.DocumentFragment)\r
-                       {\r
-                               // Insert all children, starting from refNodeIndex (0,1,2...n)\r
-                               for (int i = 0; i < newChild.ChildNodes.Count; i++)\r
-                               {\r
-                                       XmlNode e = newChild.ChildNodes[i] as XmlNode;\r
-                                       FOwnerDocument.onNodeInserting(e, this);\r
-                                       _childNodes.data.Insert(refNodeIndex, newChild.ChildNodes[i]);\r
-                                       e.setParent(this);\r
-                                       FOwnerDocument.onNodeInserted(newChild, this);\r
-                                       refNodeIndex ++;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               FOwnerDocument.onNodeInserting(newChild, this);\r
-                               _childNodes.data.Insert(refNodeIndex, newChild);\r
-                               newChild.setParent(this);\r
-                               FOwnerDocument.onNodeInserted(newChild, this);\r
-                       }\r
-\r
-                       return retval;\r
-               }\r
-               \r
-               /// <summary>\r
-               /// Insert newChild directly before the reference node.\r
-               /// If refChild is null, newChild is inserted at the end of childnodes.\r
-               /// If newChild is a document fragment, all nodes are inserted before refChild.\r
-               /// If newChild is already in the tree, it is first removed.\r
-               /// </summary>\r
-               /// <exception cref="ArgumentException">NewChild was created from different document.\r
-               /// RefChild not a child of this node, or is null.\r
-               /// Node is read-only</exception>\r
-               /// <exception cref="InvalidOperationException">Node is of type that does not have children.\r
-               /// Node to insert is an ancestor of this node.</exception>\r
-               /// <param name="newChild">Child node to insert.</param>\r
-               /// <param name="refChild">Reference node to insert after</param>\r
-               /// <returns>Removed node, or null if no node removed.</returns>\r
-               public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild)\r
-               {\r
-                       // Checks parent not ancestor, arguments valid, etc.  Throws exception on error\r
-                       InsertionCheck(newChild, refChild);\r
-\r
-                       // Scan the node list, looking for refChild and seeing if newChild is in the list\r
-                       XmlNode retval = null;\r
-                       int refNodeIndex = -1;\r
-                       \r
-                       for (int i = 0; i < _childNodes.Count; i++)\r
-                       {\r
-                               XmlNode e = _childNodes.data[i] as XmlNode;\r
-                               if (e.Equals(newChild))\r
-                               {\r
-                                       retval = e;\r
-                                       FOwnerDocument.onNodeRemoving(newChild, newChild.ParentNode);\r
-                                       _childNodes.data.RemoveAt(i);\r
-                                       newChild.setParent(null);\r
-                                       FOwnerDocument.onNodeRemoved(newChild, null);\r
-                                       break;\r
-                               }\r
-\r
-                               if ( (refChild != null ) & ( e.Equals(refChild) ) )\r
-                               {\r
-                                       refNodeIndex = i;\r
-\r
-                                       if (retval != null)\r
-                                               break;\r
-                               }\r
-                       }\r
-\r
-                       if ( ( refNodeIndex == -1 ) & (refChild != null) )\r
-                               throw new ArgumentException("Reference node not found (and not null) in call to XmlNode.InsertAfter()");\r
-\r
-                       if (refChild == null)\r
-                               refNodeIndex = _childNodes.Count;\r
-\r
-                       if (newChild.NodeType == XmlNodeType.DocumentFragment)\r
-                       {\r
-                               // Insert all children, starting from refNodeIndex (0,1,2...n)\r
-                               for (int i = 0; i < newChild.ChildNodes.Count; i++)\r
-                               {\r
-                                       XmlNode e = newChild.ChildNodes[i] as XmlNode;\r
-                                       FOwnerDocument.onNodeInserting(e, this);\r
-                                       _childNodes.data.Insert(refNodeIndex, newChild.ChildNodes[i]);\r
-                                       e.setParent(this);\r
-                                       FOwnerDocument.onNodeInserted(newChild, this);\r
-                                       refNodeIndex ++;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               FOwnerDocument.onNodeInserting(newChild, this);\r
-                               _childNodes.data.Insert(refNodeIndex, newChild);\r
-                               newChild.setParent(this);\r
-                               FOwnerDocument.onNodeInserted(newChild, this);\r
-                       }\r
-\r
-                       return retval;\r
-                       \r
-               }\r
-\r
-               /// <summary>\r
-               /// Put all nodes under this node in "normal" form\r
-               /// Whatever that means...\r
-               /// </summary>\r
-               public virtual void Normalize()\r
-               {\r
-                       // TODO - Implement Normalize()\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Add the specified child to the beginning of the child node list\r
-               /// </summary>\r
-               /// <param name="newChild">Node to add</param>\r
-               /// <returns>The node added</returns>\r
-               public virtual XmlNode PrependChild(XmlNode newChild)\r
-               {\r
-                       return InsertAfter(newChild, null);\r
-               }\r
-\r
-               /// <summary>\r
-               /// Remove all children and attributes\r
-               /// </summary>\r
-               public virtual void RemoveAll()\r
-               {\r
-                       if (_childNodes == null)\r
-                               return;\r
-                       else\r
-                       {\r
-                               // Remove in order, 0..n\r
-                               while (_childNodes.Count > 0)\r
-                               {\r
-                                       XmlNode e = _childNodes[0];\r
-                                       FOwnerDocument.onNodeRemoving(e, this);\r
-                                       e.setParent(null);\r
-                                       _childNodes.data.RemoveAt(0);\r
-                                       FOwnerDocument.onNodeRemoved(e, null);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Remove specified child node\r
-               /// </summary>\r
-               /// <param name="oldChild"></param>\r
-               /// <returns>Removed node</returns>\r
-               public virtual XmlNode RemoveChild(XmlNode oldChild)\r
-               {\r
-                       // TODO - implement RemoveChild(oldChild)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Select a list of nodes matching the xpath\r
-               /// </summary>\r
-               /// <param name="xpath"></param>\r
-               /// <returns>matching nodes</returns>\r
-               public XmlNodeList SelectNodes( string xpath)\r
-               {\r
-                       // TODO - imlement SelectNodes(xpath)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Select a list of nodes matching the xpath.  Any prefixes are resolved\r
-               /// using the passed namespace manager\r
-               /// </summary>\r
-               /// <param name="xpath"></param>\r
-               /// <param name="nsmgr"></param>\r
-               /// <returns></returns>\r
-               public XmlNodeList SelectNodes(string xpath, XmlNamespaceManager nsmgr)\r
-               {\r
-                       // TODO - implement SelectNodes(xpath, nsmgr)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Selects the first node that matches xpath\r
-               /// </summary>\r
-               /// <param name="?"></param>\r
-               /// <returns></returns>\r
-               public XmlNode SelectSingleNode(string xpatch)\r
-               {\r
-                       // TODO - implement SelectSingeNode(xpath)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Returns the first node that matches xpath\r
-               /// Uses the passed namespace manager to resolve namespace URI's\r
-               /// </summary>\r
-               /// <param name="xpath"></param>\r
-               /// <param name="nsmgr"></param>\r
-               /// <returns></returns>\r
-               public XmlNode SelectSingleNode(string xpath, XmlNamespaceManager nsmgr)\r
-               {\r
-                       // Implement SelectSingleNode(xpath, nsmgr)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Tests if the DOM implementation supports the passed feature\r
-               /// </summary>\r
-               /// <param name="feature"></param>\r
-               /// <param name="version"></param>\r
-               /// <returns></returns>\r
-               public virtual bool Supports(string feature, string version)\r
-               {\r
-                       //TODO - implement Supports(feature, version)\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Returns a string representation of the current node and it's children\r
-               /// </summary>\r
-               /// <returns></returns>\r
-               public override string ToString()\r
-               {\r
-                       // TODO - implement ToString()\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               /// <summary>\r
-               /// Saves all children of the current node to the passed writer\r
-               /// </summary>\r
-               /// <param name="w"></param>\r
-               public abstract void WriteContentTo(XmlWriter w);\r
-               \r
-               /// <summary>\r
-               /// Saves the current node to writer w\r
-               /// </summary>\r
-               /// <param name="w"></param>\r
-               public abstract void WriteTo(XmlWriter w);\r
-\r
-               //======= Internal methods    ===============================================\r
-               /// <summary>\r
-               /// accessor {set;} for parentNode only visible internally.\r
-               /// </summary>\r
-               /// <param name="newParent">new parent node.</param>\r
-               internal void setParent( XmlNode newParent)\r
-               {\r
-                       if (newParent.OwnerDocument.Equals( FOwnerDocument) )\r
-                               _parent = newParent;\r
-                       else\r
-                               throw new ArgumentException("New parent node owner does not match");\r
-               }\r
-               \r
-               //======= Protected methods    ==============================================\r
-\r
-               //======= Private Methods ===================================================\r
-               /// <summary>\r
-               /// Helper function to perform checks required before insrting a node.\r
-               /// Throws applicable exceptions on error.\r
-               /// </summary>\r
-               /// <param name="newChild"></param>\r
-               /// <param name="refChild"></param>\r
-               private void InsertionCheck( XmlNode newChild, XmlNode refChild)\r
-               {\r
-                       if (newChild == null)\r
-                               throw new ArgumentNullException("Null newNode passed to InsertAfter()");\r
-\r
-                       if (newChild.Equals(this))\r
-                               throw new ArgumentException("Cannot insert node onto itself");\r
-\r
-                       if (! FOwnerDocument.Equals( newChild.OwnerDocument) )\r
-                               throw new ArgumentException("Reference node has different owner document than this node");\r
-               \r
-                       if ( FOwnerDocument.IsReadOnly )\r
-                               throw new ArgumentException("Operation not supported - tree is read-only");\r
-\r
-                       //Check that insert node is not in our path to the root\r
-                       XmlNode curParent = _parent;\r
-                       while ( (curParent != null) & (! FOwnerDocument.Equals(curParent) ))\r
-                       {\r
-                               if (curParent.Equals(newChild) )\r
-                                       throw new ArgumentException("Cannot insert ancestor a node");\r
-                               curParent = curParent.ParentNode;\r
-                       }\r
-\r
-               }\r
-\r
-               // Constructors\r
-               //===========================================================================\r
-               //When we're first created, we won't know parent, etc.\r
-               internal XmlNode( XmlDocument aOwnerDoc )\r
-               {\r
-                       // Don't create childnodes object, since not all derived classes have children\r
-                       FOwnerDocument = aOwnerDoc;\r
-               }\r
-\r
-       }       // XmlNode\r
-}      // using namespace System.Xml\r
-\r
-               
+//
+// System.Xml.XmlProcessingInstruction
+//
+// Author:
+//   Kral Ferch <kral_ferch@hotmail.com>
+//
+// (C) 2002 Kral Ferch
+//
+
+using System;
+using System.Collections;
+using System.Xml.XPath;
+
+namespace System.Xml
+{
+       public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable
+       {
+               XmlDocument ownerDocument;
+               XmlNode parentNode;
+
+               #region Constructors
+
+               protected internal XmlNode(XmlDocument ownerDocument)
+               {
+                       this.ownerDocument = ownerDocument;
+               }
+
+               #endregion
+
+               #region Properties
+
+               public virtual XmlAttributeCollection Attributes
+               {
+                       get { return null; }
+               }
+
+               [MonoTODO]
+               public virtual string BaseURI
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public virtual XmlNodeList ChildNodes
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public virtual XmlNode FirstChild
+               {
+                       get {
+                               if (LastChild != null) {
+                                       return LastLinkedChild.NextLinkedSibling;
+                               }
+                               else {
+                                       return null;
+                               }
+                       }
+               }
+
+               public virtual bool HasChildNodes
+               {
+                       get { return LastChild != null; }
+               }
+
+               [MonoTODO]
+               public virtual string InnerText
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public virtual string InnerXml
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public virtual bool IsReadOnly
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public virtual XmlElement this[string name]
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public virtual XmlElement this[string localname, string ns]
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public virtual XmlNode LastChild
+               {
+                       get { return LastLinkedChild; }
+               }
+
+               internal virtual XmlLinkedNode LastLinkedChild
+               {
+                       get { return null; }
+                       set { }
+               }
+
+               [MonoTODO]
+               public abstract string LocalName
+               {
+                       get;
+               }
+
+               [MonoTODO]
+               public abstract string Name
+               {
+                       get;
+               }
+
+               [MonoTODO]
+               public virtual string NamespaceURI
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public virtual XmlNode NextSibling
+               {
+                       get { return null; }
+               }
+
+               [MonoTODO]
+               public abstract XmlNodeType NodeType
+               {
+                       get;
+               }
+
+               [MonoTODO]
+               public virtual string OuterXml
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public virtual XmlDocument OwnerDocument
+               {
+                       get { return ownerDocument; }
+               }
+
+               public virtual XmlNode ParentNode
+               {
+                       get { return parentNode; }
+               }
+
+               [MonoTODO]
+               public virtual string Prefix
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               public virtual XmlNode PreviousSibling
+               {
+                       get { return null; }
+               }
+
+               [MonoTODO]
+               public virtual string Value
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               #endregion
+
+               #region Methods
+
+               public virtual XmlNode AppendChild (XmlNode newChild)
+               {
+                       if ((NodeType == XmlNodeType.Document) || (NodeType == XmlNodeType.Element)) {
+                               LastLinkedChild = (XmlLinkedNode) newChild;
+                               return LastChild;
+                       }
+                       else {
+                               throw new InvalidOperationException();
+                       }
+               }
+
+               [MonoTODO]
+               public virtual XmlNode Clone ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public abstract XmlNode CloneNode (bool deep);
+
+               [MonoTODO]
+               public XPathNavigator CreateNavigator ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public IEnumerator GetEnumerator ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual string GetNamespaceOfPrefix (string prefix)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual string GetPrefixOfNamespace (string namespaceURI)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               object ICloneable.Clone ()
+               {
+                       return Clone ();
+               }
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return GetEnumerator ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode InsertAfter (XmlNode newChild, XmlNode refChild)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode InsertBefore (XmlNode newChild, XmlNode refChild)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual void Normalize ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode PrependChild (XmlNode newChild)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public virtual void RemoveAll ()
+               {
+                       LastLinkedChild = null;
+               }
+
+               [MonoTODO]
+               public virtual XmlNode RemoveChild (XmlNode oldChild)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode ReplaceChild (XmlNode newChild, XmlNode oldChild)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNodeList SelectNodes (string xpath)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode SelectSingleNode (string xpath)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public virtual XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               internal void SetParentNode (XmlNode parent)
+               {
+                       parentNode = parent;
+               }
+
+               [MonoTODO]
+               public virtual bool Supports (string feature, string version)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public abstract void WriteContentTo (XmlWriter w);
+
+               [MonoTODO]
+               public abstract void WriteTo (XmlWriter w);
+
+               #endregion
+       }
+}