-// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-\r
-//\r
-// System.Xml.XmlElement\r
-//\r
-// Author:\r
-// Daniel Weber (daniel-weber@austin.rr.com)\r
-//\r
-// (C) 2001 Daniel Weber\r
-using System;\r
-\r
-namespace System.Xml\r
-{\r
- public class XmlElement : XmlLinkedNode\r
- {\r
- // Private/Protected internal data structures\r
- //===========================================================================\r
- private XmlAttributeCollection _attributes;\r
-\r
- // Public Properties\r
- //===========================================================================\r
-\r
- /// <summary>\r
- /// Return the XmlAttributeCollection on the Element\r
- /// </summary>\r
- public override XmlAttributeCollection Attributes \r
- {\r
- get\r
- {\r
- // TODO - implement Attributes\r
- return _attributes;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Get/Set the value for this node\r
- /// </summary>\r
- public override string Value \r
- {\r
- get\r
- {\r
- return null;\r
- }\r
- \r
- set\r
- {\r
- // Do nothing, can't set value on XmlElement...\r
- }\r
- }\r
-\r
- // Implement abstract methods of XmlNode\r
- //=====================================================================\r
- /// <summary>\r
- /// Remove all children and attributes. If \r
- /// </summary>\r
- public override void RemoveAll()\r
- {\r
- // Remove all child nodes\r
- base.RemoveAll();\r
-\r
- // Remove all attributes\r
- _attributes.RemoveAll();\r
-\r
- // If we have any default attributes, add them back in with the\r
- // appropriate namespace, baseURI, name, localName\r
- // TODO - implement adding default attributes back in XmlElement.RemoveAll()\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 override XmlNode CloneNode( bool deep)\r
- {\r
- // TODO - implement CloneNode()\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 override void WriteContentTo(XmlWriter w)\r
- {\r
- // TODO - implement WriteContentsTo(XmlWriter)\r
- throw new NotImplementedException();\r
- }\r
-\r
- /// <summary>\r
- /// Saves the current node to writer w\r
- /// </summary>\r
- /// <param name="w"></param>\r
- public override void WriteTo(XmlWriter w)\r
- {\r
- // TODO - implement WriteTo(XmlWriter)\r
- throw new NotImplementedException();\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 override string LocalName \r
- {\r
- get\r
- {\r
- // TODO - implement LocalName\r
- throw new NotImplementedException();\r
- }\r
- }\r
-\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 override string Name \r
- { \r
- get\r
- {\r
- // TODO - implement Name\r
- throw new NotImplementedException();\r
- }\r
- }\r
-\r
- public override XmlNodeType NodeType \r
- {\r
- get\r
- {\r
- return XmlNodeType.Element;\r
- }\r
- }\r
-\r
-\r
- // ============= Internal calls =============================================\r
-\r
- // Constructors\r
- // ==========================================================================\r
- internal XmlElement( XmlDocument aOwnerDoc, string elementName ) : base(aOwnerDoc)\r
- {\r
- _attributes = new XmlAttributeCollection(aOwnerDoc, this, null);\r
- }\r
-\r
-\r
- } // class\r
- } //namespace\r
+//
+// System.Xml.XmlElement
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
+//
+// (C) 2002 Jason Diamond http://injektilo.org/
+// (C) 2002 Atsushi Enomoto
+//
+
+using System;
+using System.Collections;
+using System.Xml.XPath;
+using System.IO;
+using System.Text;
+
+namespace System.Xml
+{
+ public class XmlElement : XmlLinkedNode
+ {
+ #region Fields
+
+ private XmlAttributeCollection attributes;
+ private string localName;
+ private string namespaceURI;
+ private string prefix;
+ private bool isEmpty;
+
+ #endregion
+
+ #region Constructor
+
+ protected internal XmlElement (
+ string prefix,
+ string localName,
+ string namespaceURI,
+ XmlDocument doc) : base (doc)
+ {
+ this.prefix = prefix;
+ this.localName = localName;
+ this.namespaceURI = namespaceURI;
+
+ attributes = new XmlAttributeCollection (this);
+
+ // TODO: Adds default attributes
+ if(doc.DocumentType != null)
+ {
+ }
+ }
+
+ #endregion
+
+ #region Properties
+
+ public override XmlAttributeCollection Attributes {
+ get { return attributes; }
+ }
+
+ public virtual bool HasAttributes {
+ get { return attributes.Count > 0; }
+ }
+
+ public override string InnerText {
+ get {
+ return base.InnerText;
+ }
+ set {
+ // Why its behavior (of MS FCL) is different from InnerXml...?
+ if (FirstChild != null && FirstChild.NodeType == XmlNodeType.Text)
+ FirstChild.Value = value;
+ else {
+ if(FirstChild != null) {
+ foreach (XmlNode n in ChildNodes)
+ this.RemoveChild (n);
+ }
+ // creates new Text node
+ AppendChild(OwnerDocument.CreateTextNode(value));
+ }
+ }
+ }
+
+ public override string InnerXml {
+ get {
+ return base.InnerXml;
+ }
+ set {
+ foreach(XmlNode n in ChildNodes)
+ this.RemoveChild(n);
+
+ // I hope there are any well-performance logic...
+ XmlNameTable nt = this.OwnerDocument.NameTable;
+ XmlNamespaceManager nsmgr = this.ConstructNamespaceManager ();
+ XmlParserContext ctx = new XmlParserContext (nt, nsmgr, XmlLang, this.XmlSpace);
+ XmlTextReader xmlReader = OwnerDocument.ReusableReader;
+ xmlReader.SetReaderContext (String.Empty, ctx);
+ xmlReader.SetReaderFragment (new StringReader (value), XmlNodeType.Element);
+
+ do {
+ XmlNode n = OwnerDocument.ReadNode (xmlReader);
+ if(n == null) break;
+ AppendChild (n);
+ } while (true);
+ }
+ }
+
+ public bool IsEmpty {
+ get { return isEmpty; }
+
+ set {
+ if(value)
+ RemoveAll();
+ isEmpty = value;
+ }
+ }
+
+ public override string LocalName {
+ get { return localName; }
+ }
+
+ public override string Name {
+ get {
+ return prefix != String.Empty ? prefix + ":" + localName : localName;
+ }
+ }
+
+ public override string NamespaceURI {
+ get { return namespaceURI; }
+ }
+
+ [MonoTODO]
+ public override XmlNode NextSibling {
+ get {
+ return base.NextSibling;
+ }
+ }
+
+ public override XmlNodeType NodeType {
+ get {
+ return XmlNodeType.Element;
+ }
+ }
+
+ internal override XPathNodeType XPathNodeType {
+ get {
+ return XPathNodeType.Element;
+ }
+ }
+
+ [MonoTODO]
+ public override XmlDocument OwnerDocument {
+ get {
+ return base.OwnerDocument;
+ }
+ }
+
+ public override string Prefix {
+ get { return prefix; }
+ set { prefix = value; }
+ }
+
+ #endregion
+
+ #region Methods
+
+ [MonoTODO]
+ public override XmlNode CloneNode (bool deep)
+ {
+ XmlNode node = new XmlElement (prefix, localName, namespaceURI,
+ OwnerDocument);
+
+ for (int i = 0; i < node.Attributes.Count; i++)
+ node.AppendChild (node.Attributes [i].CloneNode (false));
+
+ if (deep) {
+ while ((node != null) && (node.HasChildNodes)) {
+ AppendChild (node.NextSibling.CloneNode (true));
+ node = node.NextSibling;
+ }
+ } // shallow cloning
+
+ //
+ // Reminder: Also look into Default attributes.
+ //
+ return node;
+ }
+
+ [MonoTODO]
+ public virtual string GetAttribute (string name)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (name);
+ return attributeNode != null ? attributeNode.Value : String.Empty;
+ }
+
+ [MonoTODO]
+ public virtual string GetAttribute (string localName, string namespaceURI)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
+ return attributeNode != null ? attributeNode.Value : String.Empty;
+ }
+
+ [MonoTODO]
+ public virtual XmlAttribute GetAttributeNode (string name)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (name);
+ return attributeNode != null ? attributeNode as XmlAttribute : null;
+ }
+
+ [MonoTODO]
+ public virtual XmlAttribute GetAttributeNode (string localName, string namespaceURI)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
+ return attributeNode != null ? attributeNode as XmlAttribute : null;
+ }
+
+ public virtual XmlNodeList GetElementsByTagName (string name)
+ {
+ ArrayList nodeArrayList = new ArrayList ();
+ this.searchNodesRecursively (this, name, nodeArrayList);
+ return new XmlNodeArrayList (nodeArrayList);
+ }
+
+ private void searchNodesRecursively (XmlNode argNode, string argName,
+ ArrayList argArrayList)
+ {
+ XmlNodeList xmlNodeList = argNode.ChildNodes;
+ foreach (XmlNode node in xmlNodeList){
+ if (node.Name.Equals (argName))
+ argArrayList.Add (node);
+ else
+ this.searchNodesRecursively (node, argName, argArrayList);
+ }
+ }
+
+ private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI,
+ ArrayList argArrayList)
+ {
+ XmlNodeList xmlNodeList = argNode.ChildNodes;
+ foreach (XmlNode node in xmlNodeList)
+ {
+ if (node.LocalName.Equals (argName) && node.NamespaceURI.Equals (argNamespaceURI))
+ argArrayList.Add (node);
+ else
+ this.searchNodesRecursively (node, argName, argNamespaceURI, argArrayList);
+ }
+ }
+
+ public virtual XmlNodeList GetElementsByTagName (string localName, string namespaceURI)
+ {
+ ArrayList nodeArrayList = new ArrayList ();
+ this.searchNodesRecursively (this, localName, namespaceURI, nodeArrayList);
+ return new XmlNodeArrayList (nodeArrayList);
+ }
+
+ [MonoTODO]
+ public virtual bool HasAttribute (string name)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (name);
+ return attributeNode != null;
+ }
+
+ [MonoTODO]
+ public virtual bool HasAttribute (string localName, string namespaceURI)
+ {
+ XmlNode attributeNode = Attributes.GetNamedItem (localName, namespaceURI);
+ return attributeNode != null;
+ }
+
+ [MonoTODO ("confirm not removing default attributes [when DTD feature was implemented.")]
+ public override void RemoveAll ()
+ {
+ // Remove the child nodes.
+ base.RemoveAll ();
+
+ // Remove all attributes.
+ attributes.RemoveAll ();
+ }
+
+ [MonoTODO ("confirm not removing default attributes [when DTD feature was implemented.")]
+ public virtual void RemoveAllAttributes ()
+ {
+ attributes.RemoveAll ();
+ }
+
+ [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
+ public virtual void RemoveAttribute (string name)
+ {
+ attributes.Remove((XmlAttribute)attributes.GetNamedItem(name));
+ }
+
+ [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
+ public virtual void RemoveAttribute (string localName, string namespaceURI)
+ {
+ attributes.Remove((XmlAttribute)attributes.GetNamedItem(localName, namespaceURI));
+ }
+
+ [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
+ public virtual XmlNode RemoveAttributeAt (int i)
+ {
+ return attributes.Remove(attributes[i]);
+ }
+
+ [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
+ public virtual XmlAttribute RemoveAttributeNode (XmlAttribute oldAttr)
+ {
+ return attributes.Remove(oldAttr);
+ }
+
+ [MonoTODO ("confirm not resetting default attributes [when DTD feature was implemented.")]
+ public virtual XmlAttribute RemoveAttributeNode (string localName, string namespaceURI)
+ {
+ return attributes.Remove(attributes[localName, namespaceURI]);
+ }
+
+ [MonoTODO]
+ public virtual void SetAttribute (string name, string value)
+ {
+ XmlAttribute attribute = OwnerDocument.CreateAttribute (name);
+ attribute.SetOwnerElement(this);
+ attribute.Value = value;
+ Attributes.SetNamedItem (attribute);
+ }
+
+// [MonoTODO]
+ public virtual string SetAttribute (string localName, string namespaceURI, string value)
+ {
+ XmlAttribute attr = attributes[localName, namespaceURI];
+ if(attr == null)
+ {
+ attr = OwnerDocument.CreateAttribute(localName, namespaceURI);
+ attr.Value = value;
+ attributes.SetNamedItem(attr);
+ }
+ else
+ attr.Value = value;
+ return attr.Value;
+ }
+
+// [MonoTODO]
+ public virtual XmlAttribute SetAttributeNode (XmlAttribute newAttr)
+ {
+ newAttr.SetOwnerElement(this);
+ XmlNode oldAttr = Attributes.SetNamedItem(newAttr);
+ return oldAttr != null ? oldAttr as XmlAttribute : null;
+ }
+
+ public virtual XmlAttribute SetAttributeNode (string localName, string namespaceURI)
+ {
+ XmlDocument xmlDoc = this.OwnerDocument;
+ XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc);
+ return this.attributes.Append (xmlAttribute);
+ }
+
+ public override void WriteContentTo (XmlWriter w)
+ {
+ foreach(XmlNode childNode in ChildNodes)
+ childNode.WriteTo(w);
+ }
+
+ [MonoTODO]
+ public override void WriteTo (XmlWriter w)
+ {
+ w.WriteStartElement(Prefix, LocalName, NamespaceURI);
+
+ foreach(XmlNode attributeNode in Attributes)
+ attributeNode.WriteTo(w);
+
+ // write namespace declarations(if not exist)
+ foreach(XmlNode attributeNode in Attributes) {
+ if(attributeNode.Prefix != null && attributeNode.Prefix != String.Empty &&\r
+ w.LookupPrefix(attributeNode.Prefix) != attributeNode.NamespaceURI &&\r
+ attributeNode.Prefix != "xmlns")\r
+ w.WriteAttributeString("xmlns", attributeNode.Prefix, "http://www.w3.org/2000/xmlns/", attributeNode.NamespaceURI);
+ }
+
+ WriteContentTo(w);
+
+ w.WriteEndElement();
+ }
+
+ #endregion
+ }
+}