2 // System.Xml.XmlElement
5 // Jason Diamond (jason@injektilo.org)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
8 // (C) 2002 Jason Diamond http://injektilo.org/
9 // (C) 2002 Atsushi Enomoto
13 using System.Collections;
14 using System.Xml.XPath;
20 public class XmlElement : XmlLinkedNode
24 private XmlAttributeCollection attributes;
25 private string localName;
26 private string namespaceURI;
27 private string prefix;
34 protected internal XmlElement (
38 XmlDocument doc) : base (doc)
41 this.localName = localName;
42 this.namespaceURI = namespaceURI;
44 attributes = new XmlAttributeCollection (this);
46 // TODO: Adds default attributes
47 if(doc.DocumentType != null)
56 public override XmlAttributeCollection Attributes {
57 get { return attributes; }
60 public virtual bool HasAttributes {
61 get { return attributes.Count > 0; }
64 public override string InnerText {
66 return base.InnerText;
69 // Why its behavior (of MS FCL) is different from InnerXml...?
70 if (FirstChild != null && FirstChild.NodeType == XmlNodeType.Text)
71 FirstChild.Value = value;
73 if(FirstChild != null) {
74 foreach (XmlNode n in ChildNodes)
77 // creates new Text node
78 AppendChild(OwnerDocument.CreateTextNode(value));
83 public override string InnerXml {
88 while (FirstChild != null)
89 this.RemoveChild (FirstChild);
91 // I hope there are any well-performance logic...
92 XmlNameTable nt = this.OwnerDocument.NameTable;
93 XmlNamespaceManager nsmgr = this.ConstructNamespaceManager ();
94 XmlParserContext ctx = new XmlParserContext (nt, nsmgr, XmlLang, this.XmlSpace);
95 XmlTextReader xmlReader = OwnerDocument.ReusableReader;
96 xmlReader.Initialize (String.Empty, ctx, new StringReader (value), XmlNodeType.Element);
99 XmlNode n = OwnerDocument.ReadNode (xmlReader);
106 public bool IsEmpty {
107 get { return isEmpty; }
116 public override string LocalName {
117 get { return localName; }
120 public override string Name {
122 if (prefix == String.Empty || prefix == null)
125 return prefix + ":" + localName;
129 public override string NamespaceURI {
130 get { return namespaceURI; }
134 public override XmlNode NextSibling {
136 return base.NextSibling;
140 public override XmlNodeType NodeType {
142 return XmlNodeType.Element;
146 internal override XPathNodeType XPathNodeType {
148 return XPathNodeType.Element;
153 public override XmlDocument OwnerDocument {
155 return base.OwnerDocument;
159 public override string Prefix {
160 get { return prefix; }
161 set { prefix = value; }
169 public override XmlNode CloneNode (bool deep)
171 XmlNode node = new XmlElement (prefix, localName, namespaceURI,
174 for (int i = 0; i < node.Attributes.Count; i++)
175 node.AppendChild (node.Attributes [i].CloneNode (false));
178 while ((node != null) && (node.HasChildNodes)) {
179 AppendChild (node.NextSibling.CloneNode (true));
180 node = node.NextSibling;
185 // Reminder: Also look into Default attributes.
191 public virtual string GetAttribute (string name)
193 XmlNode attributeNode = Attributes.GetNamedItem (name);
194 return attributeNode != null ? attributeNode.Value : String.Empty;
198 public virtual string GetAttribute (string localName, string namespaceURI)
200 XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
201 return attributeNode != null ? attributeNode.Value : String.Empty;
205 public virtual XmlAttribute GetAttributeNode (string name)
207 XmlNode attributeNode = Attributes.GetNamedItem (name);
208 return attributeNode != null ? attributeNode as XmlAttribute : null;
212 public virtual XmlAttribute GetAttributeNode (string localName, string namespaceURI)
214 XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
215 return attributeNode != null ? attributeNode as XmlAttribute : null;
218 public virtual XmlNodeList GetElementsByTagName (string name)
220 ArrayList nodeArrayList = new ArrayList ();
221 this.searchNodesRecursively (this, name, nodeArrayList);
222 return new XmlNodeArrayList (nodeArrayList);
225 private void searchNodesRecursively (XmlNode argNode, string argName,
226 ArrayList argArrayList)
228 XmlNodeList xmlNodeList = argNode.ChildNodes;
229 foreach (XmlNode node in xmlNodeList){
230 if (node.Name.Equals (argName))
231 argArrayList.Add (node);
233 this.searchNodesRecursively (node, argName, argArrayList);
237 private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI,
238 ArrayList argArrayList)
240 XmlNodeList xmlNodeList = argNode.ChildNodes;
241 foreach (XmlNode node in xmlNodeList)
243 if (node.LocalName.Equals (argName) && node.NamespaceURI.Equals (argNamespaceURI))
244 argArrayList.Add (node);
246 this.searchNodesRecursively (node, argName, argNamespaceURI, argArrayList);
250 public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
252 ArrayList nodeArrayList = new ArrayList ();
253 this.searchNodesRecursively (this, localName, namespaceURI, nodeArrayList);
254 return new XmlNodeArrayList (nodeArrayList);
258 public virtual bool HasAttribute (string name)
260 XmlNode attributeNode = Attributes.GetNamedItem (name);
261 return attributeNode != null;
265 public virtual bool HasAttribute (string localName, string namespaceURI)
267 XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
268 return attributeNode != null;
271 [MonoTODO ("confirm not removing default attributes [when DTD feature was implemented.")]
272 public override void RemoveAll ()
274 // Remove the child nodes.
277 // Remove all attributes.
278 attributes.RemoveAll ();
281 [MonoTODO ("confirm not removing default attributes [when DTD feature was implemented.")]
282 public virtual void RemoveAllAttributes ()
284 attributes.RemoveAll ();
287 [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
288 public virtual void RemoveAttribute (string name)
290 XmlAttribute attr = attributes.GetNamedItem (name) as XmlAttribute;
292 attributes.Remove(attr);
295 [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
296 public virtual void RemoveAttribute (string localName, string namespaceURI)
298 XmlAttribute attr = attributes.GetNamedItem(localName, namespaceURI) as XmlAttribute;
300 attributes.Remove(attr);
303 [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
304 public virtual XmlNode RemoveAttributeAt (int i)
306 return attributes.RemoveAt (i);
309 [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
310 public virtual XmlAttribute RemoveAttributeNode (XmlAttribute oldAttr)
312 return attributes.Remove(oldAttr);
315 [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
316 public virtual XmlAttribute RemoveAttributeNode (string localName, string namespaceURI)
318 return attributes.Remove(attributes[localName, namespaceURI]);
322 public virtual void SetAttribute (string name, string value)
324 XmlAttribute attribute = OwnerDocument.CreateAttribute (name);
325 attribute.SetOwnerElement(this);
326 attribute.Value = value;
327 Attributes.SetNamedItem (attribute);
331 public virtual string SetAttribute (string localName, string namespaceURI, string value)
333 XmlAttribute attr = attributes[localName, namespaceURI];
336 attr = OwnerDocument.CreateAttribute(localName, namespaceURI);
338 attributes.SetNamedItem(attr);
346 public virtual XmlAttribute SetAttributeNode (XmlAttribute newAttr)
348 newAttr.SetOwnerElement(this);
349 XmlNode oldAttr = Attributes.SetNamedItem(newAttr);
350 return oldAttr != null ? oldAttr as XmlAttribute : null;
353 public virtual XmlAttribute SetAttributeNode (string localName, string namespaceURI)
355 XmlDocument xmlDoc = this.OwnerDocument;
356 XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc);
357 return this.attributes.Append (xmlAttribute);
360 public override void WriteContentTo (XmlWriter w)
362 foreach(XmlNode childNode in ChildNodes)
363 childNode.WriteTo(w);
367 public override void WriteTo (XmlWriter w)
369 w.WriteStartElement(Prefix, LocalName, NamespaceURI);
371 foreach(XmlNode attributeNode in Attributes)
372 attributeNode.WriteTo(w);
374 // write namespace declarations(if not exist)
375 foreach(XmlNode attributeNode in Attributes) {
376 if(attributeNode.Prefix != null && attributeNode.Prefix != String.Empty &&
\r
377 w.LookupPrefix(attributeNode.NamespaceURI) != attributeNode.Prefix &&
378 attributeNode.Prefix != "xmlns")
\r
379 w.WriteAttributeString("xmlns", attributeNode.Prefix, "http://www.w3.org/2000/xmlns/", attributeNode.NamespaceURI);