XmlElement.cs 10 KB

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