5 // Copyright 2007 Novell (http://www.novell.com)
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:
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
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.
28 using System.Collections;
29 using System.Collections.Generic;
34 namespace System.Xml.Linq
36 public abstract class XContainer : XNode
38 internal XContainer ()
45 public XNode FirstNode {
47 internal set { first = value; }
50 public XNode LastNode {
52 internal set { last = value; }
55 void CheckChildType (object o, bool addFirst)
57 if (o == null || o is string || o is XNode)
59 if (o is IEnumerable) {
60 foreach (object oc in ((IEnumerable) o))
61 CheckChildType (oc, addFirst);
65 throw new ArgumentException ("Invalid child type: " + o.GetType ());
68 public void Add (object content)
73 foreach (object o in XUtil.ExpandArray (content))
75 if (!OnAddingObject (o, false, last, false))
77 var node = XUtil.ToNode (o);
78 OnAddingObject (node);
85 void AddNode (XNode n)
87 CheckChildType (n, false);
88 n = (XNode) XUtil.GetDetachedObject (n);
94 n.PreviousNode = last;
99 public void Add (params object [] content)
103 foreach (object o in XUtil.ExpandArray (content))
107 public void AddFirst (object content)
112 first.AddBeforeSelf (XUtil.ExpandArray (content));
115 public void AddFirst (params object [] content)
122 foreach (object o in XUtil.ExpandArray (content))
123 if (!OnAddingObject (o, false, first.PreviousNode, true))
124 first.AddBeforeSelf (o);
127 internal virtual bool OnAddingObject (object o, bool rejectAttribute, XNode refNode, bool addFirst)
132 public XmlWriter CreateWriter ()
134 return new XNodeWriter (this);
137 public IEnumerable <XNode> Nodes ()
140 for (XNode n = FirstNode; n != null; n = next) {
146 public IEnumerable<XNode> DescendantNodes ()
148 foreach (XNode n in Nodes ()) {
150 XContainer c = n as XContainer;
152 foreach (XNode d in c.DescendantNodes ())
157 public IEnumerable <XElement> Descendants ()
159 foreach (XNode n in DescendantNodes ()) {
160 XElement el = n as XElement;
166 public IEnumerable <XElement> Descendants (XName name)
168 foreach (XElement el in Descendants ())
173 public IEnumerable <XElement> Elements ()
175 foreach (XNode n in Nodes ()) {
176 XElement el = n as XElement;
182 public IEnumerable <XElement> Elements (XName name)
184 foreach (XNode n in Nodes ()) {
185 XElement el = n as XElement;
186 if (el != null && el.Name == name)
191 public XElement Element (XName name)
193 foreach (XNode n in Nodes ()) {
194 XElement el = n as XElement;
195 if (el != null && el.Name == name)
201 internal void ReadContentFrom (XmlReader reader, LoadOptions options)
203 while (!reader.EOF) {
204 if (reader.NodeType == XmlNodeType.EndElement)
205 // end of the element.
207 Add (XNode.ReadFrom (reader, options));
211 public void RemoveNodes ()
213 foreach (XNode n in Nodes ())
217 public void ReplaceNodes (object content)
219 // 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
221 if (FirstNode == null) {
226 var l = new List<object> ();
227 foreach (var obj in XUtil.ExpandArray (content))
234 public void ReplaceNodes (params object [] content)
236 ReplaceNodes ((object) content);