XPathDocument.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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. namespace System.Xml.XPath
  41. {
  42. #if NET_2_0obsolete
  43. [XmlSchemaProvider ("GetSchema")]
  44. public class XPathDocument : IXPathNavigable//, IXPathEditable,
  45. // IChangeTracking, IRevertibleChangeTracking, IXmlSerializable
  46. {
  47. // FIXME: In the future this switch will disappear.
  48. // Regardless of this switch, those constructors that does
  49. // not take input document use editable XPathDocument.
  50. static bool useEditable;
  51. static XPathDocument ()
  52. {
  53. // FIXME: remove when new XPathDocument2 got more
  54. // stable. This environment value is temporary.
  55. if (Environment.GetEnvironmentVariable ("MONO_XPATH_DOCUMENT_2") == "yes")
  56. useEditable = true;
  57. }
  58. XPathDocument2Editable editable;
  59. DTMXPathDocument dtm;
  60. XmlSchemaSet schemas;
  61. // save parameters
  62. Encoding encoding;
  63. bool preserveWhitespace;
  64. #region Constructors
  65. [MonoTODO]
  66. public XPathDocument ()
  67. : this (new NameTable ())
  68. {
  69. }
  70. [MonoTODO]
  71. public XPathDocument (XmlNameTable nameTable)
  72. {
  73. editable = new XPathDocument2Editable (new XPathDocument2 (nameTable));
  74. InitializeEvents ();
  75. }
  76. public XPathDocument (Stream stream)
  77. : this (stream, true)
  78. {
  79. }
  80. public XPathDocument (string uri)
  81. : this (uri, XmlSpace.None, true)
  82. {
  83. }
  84. public XPathDocument (string uri, bool acceptChangesOnLoad)
  85. : this (uri, XmlSpace.None, acceptChangesOnLoad)
  86. {
  87. }
  88. public XPathDocument (TextReader reader)
  89. : this (reader, true)
  90. {
  91. }
  92. [MonoTODO]
  93. public XPathDocument (XmlReader reader)
  94. : this (reader, XmlSpace.None, true)
  95. {
  96. }
  97. [MonoTODO]
  98. public XPathDocument (XmlReader reader, bool acceptChangesOnLoad)
  99. : this (reader, XmlSpace.None, acceptChangesOnLoad)
  100. {
  101. }
  102. [MonoTODO]
  103. public XPathDocument (string uri, XmlSpace space)
  104. : this (uri, space, true)
  105. {
  106. }
  107. [MonoTODO]
  108. public XPathDocument (XmlReader reader, XmlSpace space)
  109. : this (reader, space, true)
  110. {
  111. }
  112. [MonoTODO]
  113. public XPathDocument (string uri, XmlSpace space, bool acceptChangesOnLoad)
  114. {
  115. XmlValidatingReader vr = null;
  116. try {
  117. vr = new XmlValidatingReader (new XmlTextReader (uri));
  118. vr.ValidationType = ValidationType.None;
  119. Initialize (vr, space, acceptChangesOnLoad);
  120. } finally {
  121. if (vr != null)
  122. vr.Close ();
  123. }
  124. }
  125. [MonoTODO]
  126. public XPathDocument (Stream stream, bool acceptChangesOnLoad)
  127. {
  128. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
  129. vr.ValidationType = ValidationType.None;
  130. Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
  131. }
  132. [MonoTODO]
  133. public XPathDocument (TextReader reader, bool acceptChangesOnLoad)
  134. {
  135. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
  136. vr.ValidationType = ValidationType.None;
  137. Initialize (vr, XmlSpace.None, acceptChangesOnLoad);
  138. }
  139. [MonoTODO]
  140. public XPathDocument (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  141. {
  142. Initialize (reader, space, acceptChangesOnLoad);
  143. }
  144. private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  145. {
  146. if (useEditable)
  147. InitializeEditable (reader, space, acceptChangesOnLoad);
  148. else
  149. dtm = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
  150. }
  151. private void InitializeEditable (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  152. {
  153. XmlReaderSettings settings = new XmlReaderSettings ();
  154. settings.NameTable = reader.NameTable;
  155. settings.IgnoreWhitespace = (space == XmlSpace.Preserve);
  156. XmlReader r = XmlReader.Create (reader, settings);
  157. XPathDocument2 doc = new XPathDocument2 ();
  158. doc.Load (r, space);
  159. editable = new XPathDocument2Editable (doc);
  160. if (acceptChangesOnLoad)
  161. AcceptChanges ();
  162. this.preserveWhitespace = space == XmlSpace.Preserve;
  163. this.schemas = reader.Settings != null ? reader.Settings.Schemas : null;
  164. InitializeEvents ();
  165. }
  166. private void InitializeEvents ()
  167. {
  168. editable.ChangeRejected += this.ChangeRejected;
  169. editable.ItemUpdated += this.ItemUpdated;
  170. editable.ItemUpdating += this.ItemUpdating;
  171. editable.ItemInserted += this.ItemInserted;
  172. editable.ItemInserting += this.ItemInserting;
  173. editable.ItemDeleted += this.ItemDeleted;
  174. editable.ItemDeleting += this.ItemDeleting;
  175. editable.RejectingChange += this.RejectingChange;
  176. }
  177. #endregion
  178. #region Events
  179. public event NodeChangedEventHandler ChangeRejected;
  180. public event NodeChangedEventHandler ItemUpdated;
  181. public event NodeChangedEventHandler ItemUpdating;
  182. public event NodeChangedEventHandler ItemInserted;
  183. public event NodeChangedEventHandler ItemInserting;
  184. public event NodeChangedEventHandler ItemDeleted;
  185. public event NodeChangedEventHandler ItemDeleting;
  186. public event NodeChangedEventHandler RejectingChange;
  187. #endregion // Events
  188. #region Properties
  189. [MonoTODO]
  190. public bool EnableChangeTracking {
  191. get { return editable.EnableChangeTracking; }
  192. set { editable.EnableChangeTracking = value; }
  193. }
  194. public Encoding Encoding {
  195. get { return encoding; }
  196. set { encoding = value; }
  197. }
  198. [MonoTODO]
  199. bool IChangeTracking.IsChanged {
  200. get { return editable.IsChanged; }
  201. }
  202. public XmlNameTable NameTable {
  203. get { return editable.NameTable; }
  204. }
  205. public bool PreserveWhiteSpace {
  206. get { return preserveWhitespace; }
  207. }
  208. public XmlSchemaSet Schemas {
  209. get { return schemas; }
  210. set { schemas = value; }
  211. }
  212. #endregion // Properies
  213. #region Methods
  214. [MonoTODO]
  215. public void AcceptChanges ()
  216. {
  217. editable.AcceptChanges ();
  218. }
  219. /* It will disappear in 2.0 RTM
  220. [MonoTODO]
  221. public XPathChangeNavigator CreateChangeNavigator ()
  222. {
  223. throw new NotImplementedException ();
  224. }
  225. */
  226. public XPathEditableNavigator CreateEditor ()
  227. {
  228. return editable.CreateEditor ();
  229. }
  230. [MonoTODO ("Remove switch")]
  231. public XPathNavigator CreateNavigator ()
  232. {
  233. if (editable != null)
  234. return editable.CreateNavigator ();
  235. else
  236. return dtm.CreateNavigator ();
  237. }
  238. public XmlWriter CreateWriter ()
  239. {
  240. return CreateEditor ().AppendChild ();
  241. }
  242. [MonoTODO]
  243. public virtual XmlSchema GetSchema ()
  244. {
  245. return editable.GetSchema ();
  246. }
  247. [MonoTODO]
  248. public static XmlQualifiedName GetXPathDocumentSchema (XmlSchemaSet schemas)
  249. {
  250. throw new NotImplementedException ();
  251. }
  252. [MonoTODO]
  253. public bool HasChanges ()
  254. {
  255. return editable.HasChanges ();
  256. }
  257. /* It will disappear in 2.0 RTM
  258. [Obsolete]
  259. [MonoTODO]
  260. public void LoadXml (string xml)
  261. {
  262. throw new NotImplementedException ();
  263. // tree = new XPathDocumentTree (xmlReader);
  264. // if (acceptChangesOnLoad)
  265. // AcceptChanges ();
  266. }
  267. */
  268. public void ReadXml (XmlReader reader)
  269. {
  270. editable.ReadXml (reader);
  271. }
  272. [MonoTODO]
  273. public void RejectChanges ()
  274. {
  275. editable.RejectChanges ();
  276. }
  277. [MonoTODO ("Confirm writer settings etc.")]
  278. public void Save (Stream stream)
  279. {
  280. Save (new XmlTextWriter (stream, encoding));
  281. }
  282. [MonoTODO ("Confirm writer settings etc.")]
  283. public void Save (string filename)
  284. {
  285. using (XmlWriter w = new XmlTextWriter (filename, encoding)) {
  286. Save (w);
  287. }
  288. }
  289. [MonoTODO ("Confirm writer settings etc.")]
  290. public void Save (TextWriter writer)
  291. {
  292. Save (new XmlTextWriter (writer));
  293. }
  294. [MonoTODO]
  295. public void Save (XmlWriter writer)
  296. {
  297. writer.WriteNode (CreateNavigator ().ReadSubtree (), false);
  298. }
  299. [MonoTODO]
  300. public XPathNodeIterator SelectNodes (string xpath)
  301. {
  302. return CreateEditor ().Select (xpath);
  303. }
  304. [MonoTODO]
  305. public XPathNodeIterator SelectNodes (XPathExpression expr)
  306. {
  307. return CreateEditor ().Select (expr);
  308. }
  309. [MonoTODO]
  310. public XPathNodeIterator SelectNodes (string xpath ,IXmlNamespaceResolver nsResolver)
  311. {
  312. return CreateEditor ().Select (xpath, nsResolver);
  313. }
  314. [MonoTODO]
  315. public XPathEditableNavigator SelectSingleNode (string xpath)
  316. {
  317. XPathNodeIterator iter = CreateEditor ().Select (xpath);
  318. if (iter.MoveNext ())
  319. return (XPathEditableNavigator) iter.Current;
  320. else
  321. return null;
  322. }
  323. [MonoTODO]
  324. public XPathEditableNavigator SelectSingleNode (XPathExpression expr)
  325. {
  326. XPathNodeIterator iter = CreateEditor ().Select (expr);
  327. if (iter.MoveNext ())
  328. return (XPathEditableNavigator) iter.Current;
  329. else
  330. return null;
  331. }
  332. [MonoTODO]
  333. public XPathEditableNavigator SelectSingleNode (string xpath ,IXmlNamespaceResolver nsResolver)
  334. {
  335. XPathNodeIterator iter = CreateEditor ().Select (xpath, nsResolver);
  336. if (iter.MoveNext ())
  337. return (XPathEditableNavigator) iter.Current;
  338. else
  339. return null;
  340. }
  341. [MonoTODO]
  342. public void WriteXml (XmlWriter writer)
  343. {
  344. Save (writer);
  345. }
  346. #endregion
  347. }
  348. #else // !NET_2_0
  349. public class XPathDocument : IXPathNavigable
  350. {
  351. DTMXPathDocument document;
  352. public XPathDocument (Stream stream)
  353. {
  354. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (stream));
  355. vr.ValidationType = ValidationType.None;
  356. Initialize (vr, XmlSpace.None);
  357. }
  358. public XPathDocument (string uri)
  359. : this (uri, XmlSpace.None)
  360. {
  361. }
  362. public XPathDocument (TextReader reader)
  363. {
  364. XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (reader));
  365. vr.ValidationType = ValidationType.None;
  366. Initialize (vr, XmlSpace.None);
  367. }
  368. public XPathDocument (XmlReader reader)
  369. : this (reader, XmlSpace.None)
  370. {
  371. }
  372. public XPathDocument (string uri, XmlSpace space)
  373. {
  374. XmlValidatingReader vr = null;
  375. try {
  376. vr = new XmlValidatingReader (new XmlTextReader (uri));
  377. vr.ValidationType = ValidationType.None;
  378. Initialize (vr, space);
  379. } finally {
  380. if (vr != null)
  381. vr.Close ();
  382. }
  383. }
  384. public XPathDocument (XmlReader reader, XmlSpace space)
  385. {
  386. Initialize (reader, space);
  387. }
  388. private void Initialize (XmlReader reader, XmlSpace space)
  389. {
  390. document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
  391. }
  392. private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
  393. {
  394. document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
  395. }
  396. public XPathNavigator CreateNavigator ()
  397. {
  398. return document.CreateNavigator ();
  399. }
  400. }
  401. #endif
  402. }