5 // Kral Ferch <kral_ferch@hotmail.com>
11 using System.Collections;
14 using System.Xml.XPath;
18 public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable
22 XmlDocument ownerDocument;
29 internal XmlNode (XmlDocument ownerDocument)
31 this.ownerDocument = ownerDocument;
38 public virtual XmlAttributeCollection Attributes
43 public virtual string BaseURI
45 get { return ParentNode.BaseURI; }
48 public virtual XmlNodeList ChildNodes {
50 return new XmlNodeListChildren(this);
54 public virtual XmlNode FirstChild {
56 if (LastChild != null) {
57 return LastLinkedChild.NextLinkedSibling;
65 public virtual bool HasChildNodes {
66 get { return LastChild != null; }
70 public virtual string InnerText {
72 StringBuilder builder = new StringBuilder ();
73 AppendChildValues (this, builder);
74 return builder.ToString ();
77 set { throw new NotImplementedException (); }
80 private void AppendChildValues(XmlNode parent, StringBuilder builder)
82 XmlNode node = parent.FirstChild;
84 while (node != null) {
85 builder.Append (node.Value);
86 AppendChildValues (node, builder);
87 node = node.NextSibling;
92 public virtual string InnerXml {
94 StringWriter sw = new StringWriter ();
95 XmlTextWriter xtw = new XmlTextWriter (sw);
99 return sw.GetStringBuilder().ToString();
102 set { throw new NotImplementedException (); }
105 public virtual bool IsReadOnly {
106 get { return false; }
109 [System.Runtime.CompilerServices.IndexerName("Item")]
110 public virtual XmlElement this [string name] {
112 foreach (XmlNode node in ChildNodes) {
113 if ((node.NodeType == XmlNodeType.Element) &&
114 (node.Name == name)) {
115 return (XmlElement) node;
123 [System.Runtime.CompilerServices.IndexerName("Item")]
124 public virtual XmlElement this [string localname, string ns] {
126 foreach (XmlNode node in ChildNodes) {
127 if ((node.NodeType == XmlNodeType.Element) &&
128 (node.LocalName == localname) &&
129 (node.NamespaceURI == ns)) {
130 return (XmlElement) node;
138 public virtual XmlNode LastChild {
139 get { return LastLinkedChild; }
142 internal virtual XmlLinkedNode LastLinkedChild {
147 public abstract string LocalName { get; }
149 public abstract string Name { get; }
151 public virtual string NamespaceURI {
152 get { return String.Empty; }
155 public virtual XmlNode NextSibling {
159 public abstract XmlNodeType NodeType { get; }
161 public virtual string OuterXml {
163 StringWriter sw = new StringWriter ();
164 XmlTextWriter xtw = new XmlTextWriter (sw);
168 return sw.GetStringBuilder().ToString();
172 public virtual XmlDocument OwnerDocument {
173 get { return ownerDocument; }
176 public virtual XmlNode ParentNode {
177 get { return parentNode; }
180 public virtual string Prefix {
181 get { return String.Empty; }
185 public virtual XmlNode PreviousSibling {
189 public virtual string Value {
191 set { throw new InvalidOperationException ("This node does not have a value"); }
198 public virtual XmlNode AppendChild (XmlNode newChild)
200 XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
202 ownerDoc.onNodeInserting (newChild, this);
204 if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute) {
206 if (newChild.OwnerDocument != ownerDoc)
207 throw new ArgumentException ("Can't append a node created by another document.");
209 XmlLinkedNode newLinkedChild = (XmlLinkedNode) newChild;
210 XmlLinkedNode lastLinkedChild = LastLinkedChild;
212 newLinkedChild.parentNode = this;
214 if (lastLinkedChild != null) {
215 newLinkedChild.NextLinkedSibling = lastLinkedChild.NextLinkedSibling;
216 lastLinkedChild.NextLinkedSibling = newLinkedChild;
218 newLinkedChild.NextLinkedSibling = newLinkedChild;
220 LastLinkedChild = newLinkedChild;
222 ownerDoc.onNodeInserted (newChild, newChild.ParentNode);
226 throw new InvalidOperationException();
230 public virtual XmlNode Clone ()
232 throw new NotImplementedException ();
235 public abstract XmlNode CloneNode (bool deep);
238 public XPathNavigator CreateNavigator ()
240 return new XmlDocumentNavigator(this);
243 public IEnumerator GetEnumerator ()
245 return new XmlNodeListChildren(this).GetEnumerator();
249 public virtual string GetNamespaceOfPrefix (string prefix)
251 throw new NotImplementedException ();
255 public virtual string GetPrefixOfNamespace (string namespaceURI)
257 throw new NotImplementedException ();
260 object ICloneable.Clone ()
265 IEnumerator IEnumerable.GetEnumerator ()
267 return GetEnumerator ();
271 public virtual XmlNode InsertAfter (XmlNode newChild, XmlNode refChild)
273 throw new NotImplementedException ();
277 public virtual XmlNode InsertBefore (XmlNode newChild, XmlNode refChild)
279 throw new NotImplementedException ();
283 public virtual void Normalize ()
285 throw new NotImplementedException ();
289 public virtual XmlNode PrependChild (XmlNode newChild)
291 throw new NotImplementedException ();
294 public virtual void RemoveAll ()
296 XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
298 ownerDoc.onNodeRemoving (this, this.ParentNode);
299 LastLinkedChild = null;
300 ownerDoc.onNodeRemoved (this, this.ParentNode);
303 public virtual XmlNode RemoveChild (XmlNode oldChild)
305 OwnerDocument.onNodeRemoving (oldChild, oldChild.ParentNode);
307 if (NodeType == XmlNodeType.Document || NodeType == XmlNodeType.Element || NodeType == XmlNodeType.Attribute)
310 throw new ArgumentException();
312 if (Object.ReferenceEquals(LastLinkedChild, LastLinkedChild.NextLinkedSibling) && Object.ReferenceEquals(LastLinkedChild, oldChild))
313 LastLinkedChild = null;
315 XmlLinkedNode oldLinkedChild = (XmlLinkedNode)oldChild;
316 XmlLinkedNode beforeLinkedChild = LastLinkedChild;
318 while (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, LastLinkedChild) && !Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
319 beforeLinkedChild = beforeLinkedChild.NextLinkedSibling;
321 if (!Object.ReferenceEquals(beforeLinkedChild.NextLinkedSibling, oldLinkedChild))
322 throw new ArgumentException();
324 beforeLinkedChild.NextLinkedSibling = oldLinkedChild.NextLinkedSibling;
325 oldLinkedChild.NextLinkedSibling = null;
328 OwnerDocument.onNodeRemoved (oldChild, oldChild.ParentNode);
333 throw new ArgumentException();
337 public virtual XmlNode ReplaceChild (XmlNode newChild, XmlNode oldChild)
339 throw new NotImplementedException ();
342 public XmlNodeList SelectNodes (string xpath)
344 return SelectNodes (xpath, null);
348 public XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr)
350 XPathNavigator nav = CreateNavigator ();
351 XPathExpression expr = nav.Compile (xpath);
353 expr.SetContext (nsmgr);
354 XPathNodeIterator iter = nav.Select (expr);
355 ArrayList rgNodes = new ArrayList ();
356 while (iter.MoveNext ())
358 rgNodes.Add (((XmlDocumentNavigator) iter.Current).Node);
360 return new XmlNodeArrayList (rgNodes);
363 public XmlNode SelectSingleNode (string xpath)
365 return SelectSingleNode (xpath, null);
369 public XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr)
371 XPathNavigator nav = CreateNavigator ();
372 XPathExpression expr = nav.Compile (xpath);
374 expr.SetContext (nsmgr);
375 XPathNodeIterator iter = nav.Select (expr);
376 if (!iter.MoveNext ())
378 return ((XmlDocumentNavigator) iter.Current).Node;
381 internal void SetParentNode (XmlNode parent)
387 public virtual bool Supports (string feature, string version)
389 throw new NotImplementedException ();
392 public abstract void WriteContentTo (XmlWriter w);
394 public abstract void WriteTo (XmlWriter w);