2002-10-26 Piers Haken <piersh@friskit.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlElement.cs
1 //
2 // System.Xml.XmlAttribute
3 //
4 // Author:
5 //   Jason Diamond (jason@injektilo.org)
6 //
7 // (C) 2002 Jason Diamond  http://injektilo.org/
8 //
9
10 using System;
11 using System.Collections;
12
13 namespace System.Xml
14 {
15         public class XmlElement : XmlLinkedNode
16         {
17                 #region Fields
18
19                 private XmlAttributeCollection attributes;
20                 private XmlLinkedNode lastLinkedChild;
21                 private string localName;
22                 private string namespaceURI;
23                 private string prefix;
24
25                 #endregion
26
27                 #region Constructor
28
29                 protected internal XmlElement (
30                         string prefix, 
31                         string localName, 
32                         string namespaceURI, 
33                         XmlDocument doc) : base (doc)
34                 {
35                         this.prefix = prefix;
36                         this.localName = localName;
37                         this.namespaceURI = namespaceURI;
38
39                         attributes = new XmlAttributeCollection (this);
40                 }
41
42                 #endregion
43
44                 #region Properties
45
46                 public override XmlAttributeCollection Attributes {
47                         get { return attributes; }
48                 }
49
50                 public virtual bool HasAttributes {
51                         get { return attributes.Count > 0; }
52                 }
53
54                 [MonoTODO ("Setter.")]
55                 public override string InnerText {
56                         get {
57                                 // Not sure why this is an override.  Passing through for now.
58                                 return base.InnerText;
59                         }
60                         set { throw new NotImplementedException (); }
61                 }
62
63                 [MonoTODO ("Setter is immature")]
64                 public override string InnerXml {
65                         get {
66                                 // Not sure why this is an override.  Passing through for now.
67                                 return base.InnerXml;
68                         }
69                         set {
70                                 foreach(XmlNode n in ChildNodes)
71                                 {
72                                         this.RemoveChild(n);
73                                 }                 
74
75                                 // How to get xml:lang and xml:space? Create logic as ConstructNamespaceManager()?
76                                 XmlNameTable nt = this.OwnerDocument.NameTable;
77                                 XmlNamespaceManager nsmgr = this.ConstructNamespaceManager(); //new XmlNamespaceManager(nt);
78                                 string lang = "";
79                                 XmlSpace space = XmlSpace.Default;
80
81                                 XmlParserContext ctx = new XmlParserContext(nt, nsmgr, lang, space);
82                                 XmlTextReader xmlReader = new XmlTextReader(value, this.NodeType, ctx);
83                                 this.ConstructDOM(xmlReader, this);
84                         }
85                 }
86
87                 [MonoTODO]
88                 public bool IsEmpty {
89                         get { throw new NotImplementedException (); }
90
91                         set { throw new NotImplementedException (); }
92                 }
93
94                 internal override XmlLinkedNode LastLinkedChild {
95                         get { return lastLinkedChild; }
96
97                         set { lastLinkedChild = value; }
98                 }
99                 
100                 public override string LocalName {
101                         get { return localName; }
102                 }
103
104                 public override string Name {
105                         get { 
106                                 return prefix != String.Empty ? prefix + ":" + localName : localName; 
107                         }
108                 }
109
110                 public override string NamespaceURI {
111                         get { return namespaceURI; }
112                 }
113
114                 [MonoTODO]
115                 public override XmlNode NextSibling {
116                         get { 
117                                 return base.NextSibling; 
118                         }
119                 }
120
121                 public override XmlNodeType NodeType {
122                         get { 
123                                 return XmlNodeType.Element; 
124                         }
125                 }
126
127                 [MonoTODO]
128                 public override XmlDocument OwnerDocument {
129                         get { 
130                                 return base.OwnerDocument; 
131                         }
132                 }
133
134                 public override string Prefix {
135                         get { return prefix; }
136                         set { prefix = value; }
137                 }
138
139                 #endregion
140
141                 #region Methods
142                 
143                 [MonoTODO]
144                 public override XmlNode CloneNode (bool deep)
145                 {
146                         XmlNode node =  new XmlElement (prefix, localName, namespaceURI,
147                                                         OwnerDocument);
148
149                         for (int i = 0; i < node.Attributes.Count; i++)
150                                 node.AppendChild (node.Attributes [i].CloneNode (false));
151                         
152                         if (deep) {
153                                 while ((node != null) && (node.HasChildNodes)) {                                        
154                                         AppendChild (node.NextSibling.CloneNode (true));
155                                         node = node.NextSibling;
156                                 }
157                         } // shallow cloning
158                                 
159                         //
160                         // Reminder: Also look into Default attributes.
161                         //
162                         return node;
163                 }
164
165                 [MonoTODO]
166                 public virtual string GetAttribute (string name)
167                 {
168                         XmlNode attributeNode = Attributes.GetNamedItem (name);
169                         return attributeNode != null ? attributeNode.Value : String.Empty;
170                 }
171
172                 [MonoTODO]
173                 public virtual string GetAttribute (string localName, string namespaceURI)
174                 {
175                         XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
176                         return attributeNode != null ? attributeNode.Value : String.Empty;
177                 }
178
179                 [MonoTODO]
180                 public virtual XmlAttribute GetAttributeNode (string name)
181                 {
182                         XmlNode attributeNode = Attributes.GetNamedItem (name);
183                         return attributeNode != null ? attributeNode as XmlAttribute : null;
184                 }
185
186                 [MonoTODO]
187                 public virtual XmlAttribute GetAttributeNode (string localName, string namespaceURI)
188                 {
189                         XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
190                         return attributeNode != null ? attributeNode as XmlAttribute : null;
191                 }
192
193                 public virtual XmlNodeList GetElementsByTagName (string name)
194                 {
195                         ArrayList nodeArrayList = new ArrayList ();
196                         this.searchNodesRecursively (this, name, nodeArrayList);
197                         return new XmlNodeArrayList (nodeArrayList);
198                 }
199
200                 private void searchNodesRecursively (XmlNode argNode, string argName, 
201                         ArrayList argArrayList)
202                 {
203                         XmlNodeList xmlNodeList = argNode.ChildNodes;
204                         foreach (XmlNode node in xmlNodeList){
205                                 if (node.Name.Equals (argName))
206                                         argArrayList.Add (node);
207                                 else    
208                                         this.searchNodesRecursively (node, argName, argArrayList);
209                         }
210                 }
211
212                 private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI, 
213                         ArrayList argArrayList)
214                 {
215                         XmlNodeList xmlNodeList = argNode.ChildNodes;
216                         foreach (XmlNode node in xmlNodeList)
217                         {
218                                 if (node.LocalName.Equals (argName) && node.NamespaceURI.Equals (argNamespaceURI))
219                                         argArrayList.Add (node);
220                                 else    
221                                         this.searchNodesRecursively (node, argName, argNamespaceURI, argArrayList);
222                         }
223                 }
224
225                 public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
226                 {
227                         ArrayList nodeArrayList = new ArrayList ();
228                         this.searchNodesRecursively (this, localName, namespaceURI, nodeArrayList);
229                         return new XmlNodeArrayList (nodeArrayList);
230                 }
231
232                 [MonoTODO]
233                 public virtual bool HasAttribute (string name)
234                 {
235                         XmlNode attributeNode = Attributes.GetNamedItem (name);
236                         return attributeNode != null;
237                 }
238
239                 [MonoTODO]
240                 public virtual bool HasAttribute (string localName, string namespaceURI)
241                 {
242                         throw new NotImplementedException ();
243                 }
244
245                 [MonoTODO ("Don't remove default attributes.")]
246                 public override void RemoveAll ()
247                 {
248                         // Remove the child nodes.
249                         base.RemoveAll ();
250
251                         // Remove all attributes.
252                         attributes.RemoveAll ();
253                 }
254
255                 public virtual void RemoveAllAttributes ()
256                 {
257                         attributes.RemoveAll ();
258                 }
259
260                 [MonoTODO]
261                 public virtual void RemoveAttribute (string name)
262                 {
263                         throw new NotImplementedException ();
264                 }
265
266                 [MonoTODO]
267                 public virtual void RemoveAttribute (string localName, string namespaceURI)
268                 {
269                         throw new NotImplementedException ();
270                 }
271
272                 [MonoTODO]
273                 public virtual XmlNode RemoveAttributeAt (int i)
274                 {
275                         throw new NotImplementedException ();
276                 }
277
278                 [MonoTODO]
279                 public virtual XmlAttribute RemoveAttributeNode (XmlAttribute oldAttr)
280                 {
281                         throw new NotImplementedException ();
282                 }
283
284                 [MonoTODO]
285                 public virtual XmlAttribute RemoveAttributeNode (string localName, string namespaceURI)
286                 {
287                         throw new NotImplementedException ();
288                 }
289
290                 [MonoTODO]
291                 public virtual void SetAttribute (string name, string value)
292                 {
293                         XmlAttribute attribute = OwnerDocument.CreateAttribute (name);
294                         attribute.SetParentNode (this);
295                         attribute.Value = value;
296                         Attributes.SetNamedItem (attribute);
297                 }
298
299                 [MonoTODO]
300                 public virtual string SetAttribute (string localName, string namespaceURI, string value)
301                 {
302                         throw new NotImplementedException ();
303                 }
304
305                 [MonoTODO]
306                 public virtual XmlAttribute SetAttributeNode (XmlAttribute newAttr)
307                 {
308                         newAttr.SetParentNode(this);
309                         XmlNode oldAttr = Attributes.SetNamedItem(newAttr);
310                         return oldAttr != null ? oldAttr as XmlAttribute : null;
311                 }
312
313                 
314                 public virtual XmlAttribute SetAttributeNode (string localName, string namespaceURI)
315                 {
316                         XmlDocument xmlDoc = this.OwnerDocument;\r
317                         XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc);   \r
318                         return this.attributes.Append (xmlAttribute);
319                 }
320
321                 public override void WriteContentTo (XmlWriter w)
322                 {
323                         foreach(XmlNode childNode in ChildNodes)
324                                 childNode.WriteTo(w);
325                 }
326
327                 public override void WriteTo (XmlWriter w)
328                 {
329                         w.WriteStartElement(Prefix, LocalName, NamespaceURI);
330
331                         foreach(XmlNode attributeNode in Attributes)
332                                 attributeNode.WriteTo(w);
333
334                         WriteContentTo(w);
335
336                         w.WriteEndElement();
337                 }
338
339                 #endregion
340         }
341 }