//
-// System.Xml.XmlProcessingInstruction
+// System.Xml.XmlNode
//
// Author:
// Kral Ferch <kral_ferch@hotmail.com>
using System;
using System.Collections;
+using System.IO;
+using System.Text;
using System.Xml.XPath;
namespace System.Xml
{
public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable
{
+ #region Fields
+
XmlDocument ownerDocument;
XmlNode parentNode;
+ #endregion
+
#region Constructors
- protected internal XmlNode(XmlDocument ownerDocument)
+ internal XmlNode (XmlDocument ownerDocument)
{
this.ownerDocument = ownerDocument;
}
get { return null; }
}
- [MonoTODO]
public virtual string BaseURI
{
- get { throw new NotImplementedException (); }
+ get { return ParentNode.BaseURI; }
}
- [MonoTODO]
- public virtual XmlNodeList ChildNodes
- {
- get { throw new NotImplementedException (); }
+ public virtual XmlNodeList ChildNodes {
+ get {
+ return new XmlNodeListChildren(this);
+ }
}
- public virtual XmlNode FirstChild
- {
+ public virtual XmlNode FirstChild {
get {
if (LastChild != null) {
return LastLinkedChild.NextLinkedSibling;
}
}
- public virtual bool HasChildNodes
- {
+ public virtual bool HasChildNodes {
get { return LastChild != null; }
}
[MonoTODO]
- public virtual string InnerText
- {
- get { throw new NotImplementedException (); }
+ public virtual string InnerText {
+ get {
+ StringBuilder builder = new StringBuilder ();
+ AppendChildValues (this, builder);
+ return builder.ToString ();
+ }
+
set { throw new NotImplementedException (); }
}
- [MonoTODO]
- public virtual string InnerXml
+ private void AppendChildValues (XmlNode parent, StringBuilder builder)
{
- get { throw new NotImplementedException (); }
+ XmlNode node = parent.FirstChild;
+
+ while (node != null) {
+ if (node.NodeType == XmlNodeType.Text)
+ builder.Append (node.Value);
+ AppendChildValues (node, builder);
+ node = node.NextSibling;
+ }
+ }
+
+ [MonoTODO("Setter.")]
+ public virtual string InnerXml {
+ get {
+ StringWriter sw = new StringWriter ();
+ XmlTextWriter xtw = new XmlTextWriter (sw);
+
+ WriteContentTo(xtw);
+
+ return sw.GetStringBuilder().ToString();
+ }
+
set { throw new NotImplementedException (); }
}
- [MonoTODO]
- public virtual bool IsReadOnly
- {
- get { throw new NotImplementedException (); }
+ public virtual bool IsReadOnly {
+ get { return false; }
}
- [MonoTODO]
- public virtual XmlElement this[string name]
- {
- get { throw new NotImplementedException (); }
+ [System.Runtime.CompilerServices.IndexerName("Item")]
+ public virtual XmlElement this [string name] {
+ get {
+ foreach (XmlNode node in ChildNodes) {
+ if ((node.NodeType == XmlNodeType.Element) &&
+ (node.Name == name)) {
+ return (XmlElement) node;
+ }
+ }
+
+ return null;
+ }
}
- [MonoTODO]
- public virtual XmlElement this[string localname, string ns]
- {
- get { throw new NotImplementedException (); }
+ [System.Runtime.CompilerServices.IndexerName("Item")]
+ public virtual XmlElement this [string localname, string ns] {
+ get {
+ foreach (XmlNode node in ChildNodes) {
+ if ((node.NodeType == XmlNodeType.Element) &&
+ (node.LocalName == localname) &&
+ (node.NamespaceURI == ns)) {
+ return (XmlElement) node;
+ }
+ }
+
+ return null;
+ }
}
- public virtual XmlNode LastChild
- {
+ public virtual XmlNode LastChild {
get { return LastLinkedChild; }
}
- internal virtual XmlLinkedNode LastLinkedChild
- {
+ internal virtual XmlLinkedNode LastLinkedChild {
get { return null; }
set { }
}
- [MonoTODO]
- public abstract string LocalName
- {
- get;
- }
+ public abstract string LocalName { get; }
- [MonoTODO]
- public abstract string Name
- {
- get;
- }
+ public abstract string Name { get; }
- [MonoTODO]
- public virtual string NamespaceURI
- {
- get { throw new NotImplementedException (); }
+ public virtual string NamespaceURI {
+ get { return String.Empty; }
}
- public virtual XmlNode NextSibling
- {
+ public virtual XmlNode NextSibling {
get { return null; }
}
- [MonoTODO]
- public abstract XmlNodeType NodeType
- {
- get;
- }
+ public abstract XmlNodeType NodeType { get; }
- [MonoTODO]
- public virtual string OuterXml
- {
- get { throw new NotImplementedException (); }
+ public virtual string OuterXml {
+ get {
+ StringWriter sw = new StringWriter ();
+ XmlTextWriter xtw = new XmlTextWriter (sw);
+
+ WriteTo(xtw);
+
+ return sw.GetStringBuilder().ToString();
+ }
}
- public virtual XmlDocument OwnerDocument
- {
+ public virtual XmlDocument OwnerDocument {
get { return ownerDocument; }
}
- public virtual XmlNode ParentNode
- {
+ public virtual XmlNode ParentNode {
get { return parentNode; }
}
- [MonoTODO]
- public virtual string Prefix
- {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ public virtual string Prefix {
+ get { return String.Empty; }
+ set {}
}
- public virtual XmlNode PreviousSibling
- {
+ public virtual XmlNode PreviousSibling {
get { return null; }
}
- [MonoTODO]
- public virtual string Value
- {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ public virtual string Value {
+ get { return null; }
+ set { throw new InvalidOperationException ("This node does not have a value"); }
}
#endregion
public virtual XmlNode AppendChild (XmlNode newChild)
{
- if ((NodeType == XmlNodeType.Document) || (NodeType == XmlNodeType.Element)) {
- LastLinkedChild = (XmlLinkedNode) newChild;
- return LastChild;
- }
- else {
+ XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
+
+ ownerDoc.onNodeInserting (newChild, this);
+
+ if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute) {
+
+ if (newChild.OwnerDocument != ownerDoc)
+ throw new ArgumentException ("Can't append a node created by another document.");
+
+ XmlLinkedNode newLinkedChild = (XmlLinkedNode) newChild;
+ XmlLinkedNode lastLinkedChild = LastLinkedChild;
+
+ newLinkedChild.parentNode = this;
+
+ if (lastLinkedChild != null) {
+ newLinkedChild.NextLinkedSibling = lastLinkedChild.NextLinkedSibling;
+ lastLinkedChild.NextLinkedSibling = newLinkedChild;
+ } else
+ newLinkedChild.NextLinkedSibling = newLinkedChild;
+
+ LastLinkedChild = newLinkedChild;
+
+ ownerDoc.onNodeInserted (newChild, newChild.ParentNode);
+
+ return newChild;
+ } else
throw new InvalidOperationException();
- }
}
[MonoTODO]
[MonoTODO]
public XPathNavigator CreateNavigator ()
{
- throw new NotImplementedException ();
+ return new XmlDocumentNavigator(this);
}
- [MonoTODO]
public IEnumerator GetEnumerator ()
{
- throw new NotImplementedException ();
+ return new XmlNodeListChildren(this).GetEnumerator();
}
[MonoTODO]
public virtual void RemoveAll ()
{
+ XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
+
+ ownerDoc.onNodeRemoving (this, this.ParentNode);
LastLinkedChild = null;
+ ownerDoc.onNodeRemoved (this, this.ParentNode);
}
- [MonoTODO]
public virtual XmlNode RemoveChild (XmlNode oldChild)
{
- throw new NotImplementedException ();
+ OwnerDocument.onNodeRemoving (oldChild, oldChild.ParentNode);
+
+ if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute)
+ {
+ if (IsReadOnly)
+ throw new ArgumentException();
+
+ if (Object.ReferenceEquals(LastLinkedChild, LastLinkedChild.NextLinkedSibling) && Object.ReferenceEquals(LastLinkedChild, oldChild))
+ LastLinkedChild = null;
+ else {
+ XmlLinkedNode oldLinkedChild = (XmlLinkedNode)oldChild;
+ XmlLinkedNode beforeLinkedChild = LastLinkedChild;
+
+ while (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, LastLinkedChild) && !Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
+ beforeLinkedChild = beforeLinkedChild.NextLinkedSibling;
+
+ if (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
+ throw new ArgumentException();
+
+ beforeLinkedChild.NextLinkedSibling = oldLinkedChild.NextLinkedSibling;
+ oldLinkedChild.NextLinkedSibling = null;
+ }
+
+ OwnerDocument.onNodeRemoved (oldChild, oldChild.ParentNode);
+
+ return oldChild;
+ }
+ else
+ throw new ArgumentException();
}
[MonoTODO]
throw new NotImplementedException ();
}
- [MonoTODO]
- public virtual XmlNodeList SelectNodes (string xpath)
+ public XmlNodeList SelectNodes (string xpath)
{
- throw new NotImplementedException ();
+ return SelectNodes (xpath, null);
}
[MonoTODO]
- public virtual XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr)
+ public XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr)
{
- throw new NotImplementedException ();
+ XPathNavigator nav = CreateNavigator ();
+ XPathExpression expr = nav.Compile (xpath);
+ if (nsmgr != null)
+ expr.SetContext (nsmgr);
+ XPathNodeIterator iter = nav.Select (expr);
+ ArrayList rgNodes = new ArrayList ();
+ while (iter.MoveNext ())
+ {
+ rgNodes.Add (((XmlDocumentNavigator) iter.Current).Node);
+ }
+ return new XmlNodeArrayList (rgNodes);
}
- [MonoTODO]
- public virtual XmlNode SelectSingleNode (string xpath)
+ public XmlNode SelectSingleNode (string xpath)
{
- throw new NotImplementedException ();
+ return SelectSingleNode (xpath, null);
}
[MonoTODO]
- public virtual XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr)
+ public XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr)
{
- throw new NotImplementedException ();
+ XPathNavigator nav = CreateNavigator ();
+ XPathExpression expr = nav.Compile (xpath);
+ if (nsmgr != null)
+ expr.SetContext (nsmgr);
+ XPathNodeIterator iter = nav.Select (expr);
+ if (!iter.MoveNext ())
+ return null;
+ return ((XmlDocumentNavigator) iter.Current).Node;
}
internal void SetParentNode (XmlNode parent)
throw new NotImplementedException ();
}
- [MonoTODO]
public abstract void WriteContentTo (XmlWriter w);
- [MonoTODO]
public abstract void WriteTo (XmlWriter w);
#endregion