2 // System.Xml.XPath.XPathDocument
5 // Tim Coleman (tim@timcoleman.com)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
8 // (C) Copyright 2002 Tim Coleman
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.ComponentModel;
38 using System.Xml.Schema;
39 using System.Xml.Serialization;
42 namespace System.Xml.XPath
45 [XmlSchemaProvider ("GetSchema")]
46 public class XPathDocument : IXPathNavigable//, IXPathEditable,
47 // IChangeTracking, IRevertibleChangeTracking, IXmlSerializable
49 // FIXME: In the future this switch will disappear.
50 // Regardless of this switch, those constructors that does
51 // not take input document use editable XPathDocument.
52 static bool useEditable;
54 static XPathDocument ()
56 // FIXME: remove when new XPathDocument2 got more
57 // stable. This environment value is temporary.
58 if (Environment.GetEnvironmentVariable ("MONO_XPATH_DOCUMENT_2") == "yes")
62 XPathDocument2Editable editable;
69 bool preserveWhitespace;
73 public XPathDocument ()
74 : this (new NameTable ())
79 public XPathDocument (XmlNameTable nameTable)
81 editable = new XPathDocument2Editable (new XPathDocument2 (nameTable));
86 public XPathDocument (Stream stream)
91 public XPathDocument (string uri)
92 : this (uri, XmlSpace.None, true)
96 public XPathDocument (string uri, bool acceptChangesOnLoad)
97 : this (uri, XmlSpace.None, acceptChangesOnLoad)
101 public XPathDocument (TextReader reader)
102 : this (reader, true)
107 public XPathDocument (XmlReader reader)
108 : this (reader, XmlSpace.None, true)
113 public XPathDocument (XmlReader reader, bool acceptChangesOnLoad)
114 : this (reader, XmlSpace.None, acceptChangesOnLoad)
119 public XPathDocument (string uri, XmlSpace space)
120 : this (uri, space, true)
125 public XPathDocument (XmlReader reader, XmlSpace space)
126 : this (reader, space, true)
131 public XPathDocument (string uri, XmlSpace space, bool acceptChangesOnLoad)
133 XmlValidatingReader vr = null;
135 vr = new XmlValidatingReader (new XmlTextReader (uri));
136 vr.ValidationType = ValidationType.None;
137 Initialize (vr, space, acceptChangesOnLoad);
145 public XPathDocument (Stream stream, bool acceptChangesOnLoad)
147 XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
148 vr.ValidationType = ValidationType.None;
149 Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
153 public XPathDocument (TextReader reader, bool acceptChangesOnLoad)
155 XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
156 vr.ValidationType = ValidationType.None;
157 Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
161 public XPathDocument (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
163 Initialize (reader, space, acceptChangesOnLoad);
166 private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
169 InitializeEditable (reader, space, acceptChangesOnLoad);
171 dtm = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
174 private void InitializeEditable (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
176 XmlReaderSettings settings = new XmlReaderSettings ();
177 settings.NameTable = reader.NameTable;
178 settings.IgnoreWhitespace = (space == XmlSpace.Preserve);
179 XmlReader r = XmlReader.Create (reader, settings);
180 XPathDocument2 doc = new XPathDocument2 ();
182 editable = new XPathDocument2Editable (doc);
183 if (acceptChangesOnLoad)
185 this.preserveWhitespace = space == XmlSpace.Preserve;
186 this.schemas = reader.Settings != null ? reader.Settings.Schemas : null;
191 private void InitializeEvents ()
193 editable.ChangeRejected += this.ChangeRejected;
194 editable.ItemUpdated += this.ItemUpdated;
195 editable.ItemUpdating += this.ItemUpdating;
196 editable.ItemInserted += this.ItemInserted;
197 editable.ItemInserting += this.ItemInserting;
198 editable.ItemDeleted += this.ItemDeleted;
199 editable.ItemDeleting += this.ItemDeleting;
200 editable.RejectingChange += this.RejectingChange;
206 public event NodeChangedEventHandler ChangeRejected;
208 public event NodeChangedEventHandler ItemUpdated;
210 public event NodeChangedEventHandler ItemUpdating;
212 public event NodeChangedEventHandler ItemInserted;
214 public event NodeChangedEventHandler ItemInserting;
216 public event NodeChangedEventHandler ItemDeleted;
218 public event NodeChangedEventHandler ItemDeleting;
220 public event NodeChangedEventHandler RejectingChange;
227 public bool EnableChangeTracking {
228 get { return editable.EnableChangeTracking; }
229 set { editable.EnableChangeTracking = value; }
232 public Encoding Encoding {
233 get { return encoding; }
234 set { encoding = value; }
238 bool IChangeTracking.IsChanged {
239 get { return editable.IsChanged; }
242 public XmlNameTable NameTable {
243 get { return editable.NameTable; }
246 public bool PreserveWhiteSpace {
247 get { return preserveWhitespace; }
250 public XmlSchemaSet Schemas {
251 get { return schemas; }
252 set { schemas = value; }
255 #endregion // Properies
259 public void AcceptChanges ()
261 editable.AcceptChanges ();
264 /* It will disappear in 2.0 RTM
266 public XPathChangeNavigator CreateChangeNavigator ()
268 throw new NotImplementedException ();
272 public XPathEditableNavigator CreateEditor ()
274 return editable.CreateEditor ();
277 [MonoTODO ("Remove switch")]
278 public XPathNavigator CreateNavigator ()
280 if (editable != null)
281 return editable.CreateNavigator ();
283 return dtm.CreateNavigator ();
286 public XmlWriter CreateWriter ()
288 return CreateEditor ().AppendChild ();
292 public virtual XmlSchema GetSchema ()
294 return editable.GetSchema ();
298 public static XmlQualifiedName GetXPathDocumentSchema (XmlSchemaSet schemas)
300 throw new NotImplementedException ();
304 public bool HasChanges ()
306 return editable.HasChanges ();
309 /* It will disappear in 2.0 RTM
312 public void LoadXml (string xml)
314 throw new NotImplementedException ();
315 // tree = new XPathDocumentTree (xmlReader);
316 // if (acceptChangesOnLoad)
321 public void ReadXml (XmlReader reader)
323 editable.ReadXml (reader);
327 public void RejectChanges ()
329 editable.RejectChanges ();
332 [MonoTODO ("Confirm writer settings etc.")]
333 public void Save (Stream stream)
335 Save (new XmlTextWriter (stream, encoding));
338 [MonoTODO ("Confirm writer settings etc.")]
339 public void Save (string filename)
341 using (XmlWriter w = new XmlTextWriter (filename, encoding)) {
346 [MonoTODO ("Confirm writer settings etc.")]
347 public void Save (TextWriter writer)
349 Save (new XmlTextWriter (writer));
353 public void Save (XmlWriter writer)
355 writer.WriteNode (CreateNavigator ().ReadSubtree (), false);
359 public XPathNodeIterator SelectNodes (string xpath)
361 return CreateEditor ().Select (xpath);
365 public XPathNodeIterator SelectNodes (XPathExpression expr)
367 return CreateEditor ().Select (expr);
371 public XPathNodeIterator SelectNodes (string xpath ,IXmlNamespaceResolver nsResolver)
373 return CreateEditor ().Select (xpath, nsResolver);
377 public XPathEditableNavigator SelectSingleNode (string xpath)
379 XPathNodeIterator iter = CreateEditor ().Select (xpath);
380 if (iter.MoveNext ())
381 return (XPathEditableNavigator) iter.Current;
387 public XPathEditableNavigator SelectSingleNode (XPathExpression expr)
389 XPathNodeIterator iter = CreateEditor ().Select (expr);
390 if (iter.MoveNext ())
391 return (XPathEditableNavigator) iter.Current;
397 public XPathEditableNavigator SelectSingleNode (string xpath ,IXmlNamespaceResolver nsResolver)
399 XPathNodeIterator iter = CreateEditor ().Select (xpath, nsResolver);
400 if (iter.MoveNext ())
401 return (XPathEditableNavigator) iter.Current;
407 public void WriteXml (XmlWriter writer)
417 public class XPathDocument : IXPathNavigable
419 DTMXPathDocument document;
421 public XPathDocument (Stream stream)
423 XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
424 vr.ValidationType = ValidationType.None;
425 Initialize (vr, XmlSpace.None);
428 public XPathDocument (string uri)
429 : this (uri, XmlSpace.None)
433 public XPathDocument (TextReader reader)
435 XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
436 vr.ValidationType = ValidationType.None;
437 Initialize (vr, XmlSpace.None);
440 public XPathDocument (XmlReader reader)
441 : this (reader, XmlSpace.None)
445 public XPathDocument (string uri, XmlSpace space)
447 XmlValidatingReader vr = null;
449 vr = new XmlValidatingReader (new XmlTextReader (uri));
450 vr.ValidationType = ValidationType.None;
451 Initialize (vr, space);
458 public XPathDocument (XmlReader reader, XmlSpace space)
460 Initialize (reader, space);
463 private void Initialize (XmlReader reader, XmlSpace space)
465 document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
468 private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
470 document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
473 public XPathNavigator CreateNavigator ()
475 return document.CreateNavigator ();