PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs

https://bitbucket.org/danipen/mono
C# | 235 lines | 180 code | 28 blank | 27 comment | 39 complexity | d95b0f2fe13572b4ab23d6fbc58778b0 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // Authors:
  3. // Atsushi Enomoto
  4. //
  5. // Copyright 2007 Novell (http://www.novell.com)
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining
  8. // a copy of this software and associated documentation files (the
  9. // "Software"), to deal in the Software without restriction, including
  10. // without limitation the rights to use, copy, modify, merge, publish,
  11. // distribute, sublicense, and/or sell copies of the Software, and to
  12. // permit persons to whom the Software is furnished to do so, subject to
  13. // the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be
  16. // included in all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. //
  26. using System;
  27. using System.Collections;
  28. using System.Collections.Generic;
  29. using System.IO;
  30. using System.Text;
  31. using System.Xml;
  32. namespace System.Xml.Linq
  33. {
  34. public abstract class XContainer : XNode
  35. {
  36. internal XContainer ()
  37. {
  38. }
  39. XNode first;
  40. XNode last;
  41. public XNode FirstNode {
  42. get { return first; }
  43. internal set { first = value; }
  44. }
  45. public XNode LastNode {
  46. get { return last; }
  47. internal set { last = value; }
  48. }
  49. void CheckChildType (object o, bool addFirst)
  50. {
  51. if (o == null || o is string || o is XNode)
  52. return;
  53. if (o is IEnumerable) {
  54. foreach (object oc in ((IEnumerable) o))
  55. CheckChildType (oc, addFirst);
  56. return;
  57. }
  58. else
  59. throw new ArgumentException ("Invalid child type: " + o.GetType ());
  60. }
  61. public void Add (object content)
  62. {
  63. if (content == null)
  64. return;
  65. foreach (object o in XUtil.ExpandArray (content))
  66. {
  67. if (!OnAddingObject (o, false, last, false))
  68. {
  69. var node = XUtil.ToNode (o);
  70. OnAddingObject (node);
  71. AddNode (node);
  72. OnAddedObject (node);
  73. }
  74. }
  75. }
  76. void AddNode (XNode n)
  77. {
  78. CheckChildType (n, false);
  79. n = (XNode) XUtil.GetDetachedObject (n);
  80. n.SetOwner (this);
  81. if (first == null)
  82. last = first = n;
  83. else {
  84. last.NextNode = n;
  85. n.PreviousNode = last;
  86. last = n;
  87. }
  88. }
  89. public void Add (params object [] content)
  90. {
  91. if (content == null)
  92. return;
  93. foreach (object o in XUtil.ExpandArray (content))
  94. Add (o);
  95. }
  96. public void AddFirst (object content)
  97. {
  98. if (first == null)
  99. Add (content);
  100. else
  101. first.AddBeforeSelf (XUtil.ExpandArray (content));
  102. }
  103. public void AddFirst (params object [] content)
  104. {
  105. if (content == null)
  106. return;
  107. if (first == null)
  108. Add (content);
  109. else
  110. foreach (object o in XUtil.ExpandArray (content))
  111. if (!OnAddingObject (o, false, first.PreviousNode, true))
  112. first.AddBeforeSelf (o);
  113. }
  114. internal virtual bool OnAddingObject (object o, bool rejectAttribute, XNode refNode, bool addFirst)
  115. {
  116. return false;
  117. }
  118. public XmlWriter CreateWriter ()
  119. {
  120. return new XNodeWriter (this);
  121. }
  122. public IEnumerable <XNode> Nodes ()
  123. {
  124. XNode next;
  125. for (XNode n = FirstNode; n != null; n = next) {
  126. next = n.NextNode;
  127. yield return n;
  128. }
  129. }
  130. public IEnumerable<XNode> DescendantNodes ()
  131. {
  132. foreach (XNode n in Nodes ()) {
  133. yield return n;
  134. XContainer c = n as XContainer;
  135. if (c != null)
  136. foreach (XNode d in c.DescendantNodes ())
  137. yield return d;
  138. }
  139. }
  140. public IEnumerable <XElement> Descendants ()
  141. {
  142. foreach (XNode n in DescendantNodes ()) {
  143. XElement el = n as XElement;
  144. if (el != null)
  145. yield return el;
  146. }
  147. }
  148. public IEnumerable <XElement> Descendants (XName name)
  149. {
  150. foreach (XElement el in Descendants ())
  151. if (el.Name == name)
  152. yield return el;
  153. }
  154. public IEnumerable <XElement> Elements ()
  155. {
  156. foreach (XNode n in Nodes ()) {
  157. XElement el = n as XElement;
  158. if (el != null)
  159. yield return el;
  160. }
  161. }
  162. public IEnumerable <XElement> Elements (XName name)
  163. {
  164. foreach (XElement el in Elements ())
  165. if (el.Name == name)
  166. yield return el;
  167. }
  168. public XElement Element (XName name)
  169. {
  170. foreach (XElement el in Elements ())
  171. if (el.Name == name)
  172. return el;
  173. return null;
  174. }
  175. internal void ReadContentFrom (XmlReader reader, LoadOptions options)
  176. {
  177. while (!reader.EOF) {
  178. if (reader.NodeType == XmlNodeType.EndElement)
  179. // end of the element.
  180. break;
  181. Add (XNode.ReadFrom (reader, options));
  182. }
  183. }
  184. public void RemoveNodes ()
  185. {
  186. foreach (XNode n in Nodes ())
  187. n.Remove ();
  188. }
  189. public void ReplaceNodes (object content)
  190. {
  191. // First, it creates a snapshot copy, then removes the contents, and then adds the copy. http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.replacenodes.aspx
  192. if (FirstNode == null) {
  193. Add (content);
  194. return;
  195. }
  196. var l = new List<object> ();
  197. foreach (var obj in XUtil.ExpandArray (content))
  198. l.Add (obj);
  199. RemoveNodes ();
  200. Add (l);
  201. }
  202. public void ReplaceNodes (params object [] content)
  203. {
  204. ReplaceNodes ((object) content);
  205. }
  206. }
  207. }