XPathDocument.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. //
  2. // System.Xml.XPath.XPathDocument
  3. //
  4. // Authors:
  5. // Tim Coleman ([email protected])
  6. // Atsushi Enomoto ([email protected])
  7. //
  8. // (C) Copyright 2002 Tim Coleman
  9. // (C) 2003 Atsushi Enomoto
  10. //
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. using System;
  32. using System.Collections;
  33. using System.ComponentModel;
  34. using System.IO;
  35. using System.Text;
  36. using System.Xml;
  37. using System.Xml.Schema;
  38. using System.Xml.Serialization;
  39. using Mono.Xml.XPath;
  40. //using InternalBuilder = Mono.Xml.XPath.DTMXPathDocumentBuilder;
  41. //using InternalDocument = Mono.Xml.XPath.DTMXPathDocument;
  42. using InternalBuilder = Mono.Xml.XPath.DTMXPathDocumentBuilder2;
  43. using InternalDocument = Mono.Xml.XPath.DTMXPathDocument2;
  44. namespace System.Xml.XPath
  45. {
  46. #if NET_2_0obsolete
  47. [XmlSchemaProvider ("GetSchema")]
  48. public class XPathDocument : IXPathNavigable//, IXPathEditable,
  49. // IChangeTracking, IRevertibleChangeTracking, IXmlSerializable
  50. {
  51. // FIXME: In the future this switch will disappear.
  52. // Regardless of this switch, those constructors that does
  53. // not take input document use editable XPathDocument.
  54. static bool useEditable;
  55. static XPathDocument ()
  56. {
  57. // FIXME: remove when new XPathDocument2 got more
  58. // stable. This environment value is temporary.
  59. if (Environment.GetEnvironmentVariable ("MONO_XPATH_DOCUMENT_2") == "yes")
  60. useEditable = true;
  61. }
  62. XPathDocument2Editable editable;
  63. InternalDocument dtm;
  64. XmlSchemaSet schemas;
  65. // save parameters
  66. Encoding encoding;
  67. bool preserveWhitespace;
  68. #region Constructors
  69. [MonoTODO]
  70. public XPathDocument ()
  71. : this (new NameTable ())
  72. {
  73. }
  74. [MonoTODO]
  75. public XPathDocument (XmlNameTable nameTable)
  76. {
  77. editable = new XPathDocument2Editable (new XPathDocument2 (nameTable));
  78. InitializeEvents ();
  79. }
  80. public XPathDocument (Stream stream)
  81. : this (stream, true)
  82. {
  83. }
  84. public XPathDocument (string uri)
  85. : this (uri, XmlSpace.None, true)
  86. {
  87. }
  88. public XPathDocument (string uri, bool acceptChangesOnLoad)
  89. : this (uri, XmlSpace.None, acceptChangesOnLoad)
  90. {
  91. }
  92. public XPathDocument (TextReader reader)
  93. : this (reader, true)
  94. {
  95. }
  96. [MonoTODO]
  97. public XPathDocument (XmlReader reader)
  98. : this (reader, XmlSpace.None, true)
  99. {
  100. }
  101. [MonoTODO]
  102. public XPathDocument (XmlReader reader, bool acceptChangesOnLoad)
  103. : this (reader, XmlSpace.None, acceptChangesOnLoad)
  104. {
  105. }
  106. [MonoTODO]
  107. public XPathDocument (string uri, XmlSpace space)
  108. : this (uri, space, true)
  109. {
  110. }
  111. [MonoTODO]
  112. public XPathDocument (XmlReader reader, XmlSpace space)
  113. : this (reader, space, true)
  114. {
  115. }
  116. [MonoTODO]
  117. public XPathDocument (string uri, XmlSpace space, bool acceptChangesOnLoad)
  118. {
  119. XmlValidatingReader vr = null;
  120. try {
  121. vr = new XmlValidatingReader (new XmlTextReader (uri));
  122. vr.ValidationType = ValidationType.None;
  123. Initialize (vr, space, acceptChangesOnLoad);
  124. } finally {
  125. if (vr != null)
  126. vr.Close ();
  127. }
  128. }
  129. [MonoTODO]
  130. public XPathDocument (Stream stream, bool acceptChangesOnLoad)
  131. {
  132. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
  133. vr.ValidationType = ValidationType.None;
  134. Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
  135. }
  136. [MonoTODO]
  137. public XPathDocument (TextReader reader, bool acceptChangesOnLoad)
  138. {
  139. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
  140. vr.ValidationType = ValidationType.None;
  141. Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
  142. }
  143. [MonoTODO]
  144. public XPathDocument (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  145. {
  146. Initialize (reader, space, acceptChangesOnLoad);
  147. }
  148. private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  149. {
  150. if (useEditable)
  151. InitializeEditable (reader, space, acceptChangesOnLoad);
  152. else
  153. dtm = new InternalBuilder (reader, space).CreateDocument ();
  154. }
  155. private void InitializeEditable (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  156. {
  157. XmlReaderSettings settings = new XmlReaderSettings ();
  158. settings.NameTable = reader.NameTable;
  159. settings.IgnoreWhitespace = (space == XmlSpace.Preserve);
  160. XmlReader r = XmlReader.Create (reader, settings);
  161. XPathDocument2 doc = new XPathDocument2 ();
  162. doc.Load (r, space);
  163. editable = new XPathDocument2Editable (doc);
  164. if (acceptChangesOnLoad)
  165. AcceptChanges ();
  166. this.preserveWhitespace = space == XmlSpace.Preserve;
  167. this.schemas = reader.Settings != null ? reader.Settings.Schemas : null;
  168. InitializeEvents ();
  169. }
  170. private void InitializeEvents ()
  171. {
  172. editable.ChangeRejected += this.ChangeRejected;
  173. editable.ItemUpdated += this.ItemUpdated;
  174. editable.ItemUpdating += this.ItemUpdating;
  175. editable.ItemInserted += this.ItemInserted;
  176. editable.ItemInserting += this.ItemInserting;
  177. editable.ItemDeleted += this.ItemDeleted;
  178. editable.ItemDeleting += this.ItemDeleting;
  179. editable.RejectingChange += this.RejectingChange;
  180. }
  181. #endregion
  182. #region Events
  183. public event NodeChangedEventHandler ChangeRejected;
  184. public event NodeChangedEventHandler ItemUpdated;
  185. public event NodeChangedEventHandler ItemUpdating;
  186. public event NodeChangedEventHandler ItemInserted;
  187. public event NodeChangedEventHandler ItemInserting;
  188. public event NodeChangedEventHandler ItemDeleted;
  189. public event NodeChangedEventHandler ItemDeleting;
  190. public event NodeChangedEventHandler RejectingChange;
  191. #endregion // Events
  192. #region Properties
  193. [MonoTODO]
  194. public bool EnableChangeTracking {
  195. get { return editable.EnableChangeTracking; }
  196. set { editable.EnableChangeTracking = value; }
  197. }
  198. public Encoding Encoding {
  199. get { return encoding; }
  200. set { encoding = value; }
  201. }
  202. [MonoTODO]
  203. bool IChangeTracking.IsChanged {
  204. get { return editable.IsChanged; }
  205. }
  206. public XmlNameTable NameTable {
  207. get { return editable.NameTable; }
  208. }
  209. public bool PreserveWhiteSpace {
  210. get { return preserveWhitespace; }
  211. }
  212. public XmlSchemaSet Schemas {
  213. get { return schemas; }
  214. set { schemas = value; }
  215. }
  216. #endregion // Properies
  217. #region Methods
  218. [MonoTODO]
  219. public void AcceptChanges ()
  220. {
  221. editable.AcceptChanges ();
  222. }
  223. /* It will disappear in 2.0 RTM
  224. [MonoTODO]
  225. public XPathChangeNavigator CreateChangeNavigator ()
  226. {
  227. throw new NotImplementedException ();
  228. }
  229. */
  230. public XPathEditableNavigator CreateEditor ()
  231. {
  232. return editable.CreateEditor ();
  233. }
  234. [MonoTODO ("Remove switch")]
  235. public XPathNavigator CreateNavigator ()
  236. {
  237. if (editable != null)
  238. return editable.CreateNavigator ();
  239. else
  240. return dtm.CreateNavigator ();
  241. }
  242. public XmlWriter CreateWriter ()
  243. {
  244. return CreateEditor ().AppendChild ();
  245. }
  246. [MonoTODO]
  247. public virtual XmlSchema GetSchema ()
  248. {
  249. return editable.GetSchema ();
  250. }
  251. [MonoTODO]
  252. public static XmlQualifiedName GetXPathDocumentSchema (XmlSchemaSet schemas)
  253. {
  254. throw new NotImplementedException ();
  255. }
  256. [MonoTODO]
  257. public bool HasChanges ()
  258. {
  259. return editable.HasChanges ();
  260. }
  261. /* It will disappear in 2.0 RTM
  262. [Obsolete]
  263. [MonoTODO]
  264. public void LoadXml (string xml)
  265. {
  266. throw new NotImplementedException ();
  267. // tree = new XPathDocumentTree (xmlReader);
  268. // if (acceptChangesOnLoad)
  269. // AcceptChanges ();
  270. }
  271. */
  272. public void ReadXml (XmlReader reader)
  273. {
  274. editable.ReadXml (reader);
  275. }
  276. [MonoTODO]
  277. public void RejectChanges ()
  278. {
  279. editable.RejectChanges ();
  280. }
  281. [MonoTODO ("Confirm writer settings etc.")]
  282. public void Save (Stream stream)
  283. {
  284. Save (new XmlTextWriter (stream, encoding));
  285. }
  286. [MonoTODO ("Confirm writer settings etc.")]
  287. public void Save (string filename)
  288. {
  289. using (XmlWriter w = new XmlTextWriter (filename, encoding)) {
  290. Save (w);
  291. }
  292. }
  293. [MonoTODO ("Confirm writer settings etc.")]
  294. public void Save (TextWriter writer)
  295. {
  296. Save (new XmlTextWriter (writer));
  297. }
  298. [MonoTODO]
  299. public void Save (XmlWriter writer)
  300. {
  301. writer.WriteNode (CreateNavigator ().ReadSubtree (), false);
  302. }
  303. [MonoTODO]
  304. public XPathNodeIterator SelectNodes (string xpath)
  305. {
  306. return CreateEditor ().Select (xpath);
  307. }
  308. [MonoTODO]
  309. public XPathNodeIterator SelectNodes (XPathExpression expr)
  310. {
  311. return CreateEditor ().Select (expr);
  312. }
  313. [MonoTODO]
  314. public XPathNodeIterator SelectNodes (string xpath ,IXmlNamespaceResolver nsResolver)
  315. {
  316. return CreateEditor ().Select (xpath, nsResolver);
  317. }
  318. [MonoTODO]
  319. public XPathEditableNavigator SelectSingleNode (string xpath)
  320. {
  321. XPathNodeIterator iter = CreateEditor ().Select (xpath);
  322. if (iter.MoveNext ())
  323. return (XPathEditableNavigator) iter.Current;
  324. else
  325. return null;
  326. }
  327. [MonoTODO]
  328. public XPathEditableNavigator SelectSingleNode (XPathExpression expr)
  329. {
  330. XPathNodeIterator iter = CreateEditor ().Select (expr);
  331. if (iter.MoveNext ())
  332. return (XPathEditableNavigator) iter.Current;
  333. else
  334. return null;
  335. }
  336. [MonoTODO]
  337. public XPathEditableNavigator SelectSingleNode (string xpath ,IXmlNamespaceResolver nsResolver)
  338. {
  339. XPathNodeIterator iter = CreateEditor ().Select (xpath, nsResolver);
  340. if (iter.MoveNext ())
  341. return (XPathEditableNavigator) iter.Current;
  342. else
  343. return null;
  344. }
  345. [MonoTODO]
  346. public void WriteXml (XmlWriter writer)
  347. {
  348. Save (writer);
  349. }
  350. #endregion
  351. }
  352. #else // !NET_2_0
  353. public class XPathDocument : IXPathNavigable
  354. {
  355. IXPathNavigable document;
  356. public XPathDocument (Stream stream)
  357. {
  358. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
  359. vr.ValidationType = ValidationType.None;
  360. Initialize (vr, XmlSpace.None);
  361. }
  362. public XPathDocument (string uri)
  363. : this (uri, XmlSpace.None)
  364. {
  365. }
  366. public XPathDocument (TextReader reader)
  367. {
  368. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
  369. vr.ValidationType = ValidationType.None;
  370. Initialize (vr, XmlSpace.None);
  371. }
  372. public XPathDocument (XmlReader reader)
  373. : this (reader, XmlSpace.None)
  374. {
  375. }
  376. public XPathDocument (string uri, XmlSpace space)
  377. {
  378. XmlValidatingReader vr = null;
  379. try {
  380. vr = new XmlValidatingReader (new XmlTextReader (uri));
  381. vr.ValidationType = ValidationType.None;
  382. Initialize (vr, space);
  383. } finally {
  384. if (vr != null)
  385. vr.Close ();
  386. }
  387. }
  388. public XPathDocument (XmlReader reader, XmlSpace space)
  389. {
  390. Initialize (reader, space);
  391. }
  392. private void Initialize (XmlReader reader, XmlSpace space)
  393. {
  394. document = new InternalBuilder (reader, space).CreateDocument ();
  395. }
  396. private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  397. {
  398. document = new InternalBuilder (reader, space).CreateDocument ();
  399. }
  400. public XPathNavigator CreateNavigator ()
  401. {
  402. return document.CreateNavigator ();
  403. }
  404. }
  405. #endif
  406. }