XPathEditableDocument.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. //
  2. // Mono.Xml.XPath.XPathEditableDocument
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // (C)2004 Novell Inc.
  8. //
  9. // Yet another implementation of XPathEditableNavigator.
  10. // (Even runnable under MS.NET 2.0)
  11. //
  12. // By rewriting XPathEditableDocument.CreateNavigator() as just to
  13. // create XmlDocumentNavigator, XmlDocumentEditableNavigator could be used
  14. // as to implement XmlDocument.CreateNavigator().
  15. //
  16. //
  17. // Permission is hereby granted, free of charge, to any person obtaining
  18. // a copy of this software and associated documentation files (the
  19. // "Software"), to deal in the Software without restriction, including
  20. // without limitation the rights to use, copy, modify, merge, publish,
  21. // distribute, sublicense, and/or sell copies of the Software, and to
  22. // permit persons to whom the Software is furnished to do so, subject to
  23. // the following conditions:
  24. //
  25. // The above copyright notice and this permission notice shall be
  26. // included in all copies or substantial portions of the Software.
  27. //
  28. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  29. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  30. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  31. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  32. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  33. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  34. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  35. //
  36. #if NET_2_0
  37. using System;
  38. using System.Collections;
  39. using System.ComponentModel;
  40. using System.IO;
  41. using System.Xml;
  42. using System.Xml.Schema;
  43. using System.Xml.XPath;
  44. using System.Xml.Serialization;
  45. namespace Mono.Xml.XPath
  46. {
  47. public class XPathEditableDocument
  48. : IXPathNavigable, IXPathEditable,
  49. IRevertibleChangeTracking, IChangeTracking, IXmlSerializable
  50. {
  51. /*
  52. public static void Main ()
  53. {
  54. try {
  55. #if true
  56. XmlDocument doc = new XmlDocument ();
  57. XPathEditableDocument pd = new XPathEditableDocument (doc);
  58. XPathEditableNavigator nav = pd.CreateEditor ();
  59. IChangeTracking xp = pd;
  60. #else
  61. XPathDocument doc = new XPathDocument ();
  62. XPathEditableNavigator nav = doc.CreateEditor ();
  63. IChangeTracking xp = doc;
  64. #endif
  65. doc.LoadXml ("<root/>");
  66. nav.MoveToFirstChild (); // root
  67. XmlWriter w = nav.AppendChild ();
  68. Console.WriteLine (((IChangeTracking) xp).IsChanged);
  69. w.WriteElementString ("foo", "foo_text");
  70. w.WriteElementString ("bar", "bar_text");
  71. w.WriteStartElement ("hoge");
  72. w.WriteAttributeString ("fuga", "fugafuga");
  73. w.WriteAttributeString ("unya", "unyaunya");
  74. w.WriteFullEndElement ();
  75. w.Close ();
  76. w = nav.CreateAttributes ();
  77. w.WriteStartAttribute ("namara");
  78. w.WriteString ("mokera");
  79. w.WriteEndAttribute ();
  80. w.WriteAttributeString ("beccho", "giccho");
  81. w.Close ();
  82. nav.MoveToRoot ();
  83. nav.MoveToFirstChild ();
  84. nav.MoveToFirstChild ();
  85. nav.DeleteCurrent (); // delete foo
  86. Console.WriteLine (nav.Name);
  87. nav.MoveToNext ();
  88. Console.WriteLine (nav.Name);
  89. Console.WriteLine (nav.MoveToFirstAttribute ());
  90. nav.DeleteCurrent (); // delete fuga
  91. doc.Save (Console.Out);
  92. } catch (Exception ex) {
  93. Console.WriteLine (ex);
  94. }
  95. }
  96. */
  97. XmlDocument document;
  98. ArrayList changes = new ArrayList ();
  99. public XPathEditableDocument (XmlDocument doc)
  100. {
  101. document = doc;
  102. }
  103. public XPathNavigator CreateNavigator ()
  104. {
  105. return document.CreateNavigator ();
  106. }
  107. public XPathEditableNavigator CreateEditor ()
  108. {
  109. return new XmlDocumentEditableNavigator (this);
  110. }
  111. public XmlWriter CreateWriter ()
  112. {
  113. return CreateEditor ().AppendChild ();
  114. }
  115. public bool HasChanges ()
  116. {
  117. return IsChanged;
  118. }
  119. #region IRevertibleChangeTracking/IChangeTracking
  120. public bool IsChanged {
  121. get { return changes.Count != 0; }
  122. }
  123. public void AcceptChanges ()
  124. {
  125. changes.Clear ();
  126. }
  127. public void RejectChanges ()
  128. {
  129. for (int i = changes.Count - 1; i >= 0; i--) {
  130. Insertion ins = changes [i] as Insertion;
  131. if (ins != null) {
  132. ins.ParentNode.RemoveChild (ins.InsertedNode);
  133. continue;
  134. }
  135. Removal rem = changes [i] as Removal;
  136. if (rem != null) {
  137. if (rem.RemovedNode.NodeType == XmlNodeType.Attribute) {
  138. XmlElement el = (XmlElement) rem.OwnerNode;
  139. el.SetAttributeNode ((XmlAttribute) rem.RemovedNode);
  140. }
  141. else
  142. rem.OwnerNode.InsertBefore (rem.RemovedNode, rem.NextSibling);
  143. continue;
  144. }
  145. AttributeUpdate au = changes [i] as AttributeUpdate;
  146. if (au != null) {
  147. if (au.OldAttribute != null)
  148. au.Element.SetAttributeNode (au.OldAttribute);
  149. else
  150. au.Element.RemoveAttributeNode (au.NewAttribute);
  151. continue;
  152. }
  153. }
  154. changes.Clear ();
  155. }
  156. #endregion
  157. #region IXmlSerializable
  158. public void WriteXml (XmlWriter writer)
  159. {
  160. throw new NotImplementedException ();
  161. }
  162. public void ReadXml (XmlReader reader)
  163. {
  164. throw new NotImplementedException ();
  165. }
  166. public XmlSchema GetSchema ()
  167. {
  168. throw new NotImplementedException ();
  169. }
  170. #endregion
  171. internal bool DeleteNode (XmlNode node)
  172. {
  173. Removal rem = new Removal ();
  174. if (node.NodeType == XmlNodeType.Attribute) {
  175. XmlAttribute attr = node as XmlAttribute;
  176. rem.OwnerNode = attr.OwnerElement;
  177. rem.RemovedNode = node;
  178. attr.OwnerElement.RemoveAttributeNode (attr);
  179. return false;
  180. } else {
  181. rem.OwnerNode = node.ParentNode;
  182. rem.NextSibling = node.NextSibling;
  183. rem.RemovedNode = node;
  184. node.ParentNode.RemoveChild (node);
  185. return rem.NextSibling != null;
  186. }
  187. }
  188. internal XmlWriter CreateInsertionWriter (XmlNode owner, XmlNode previousSibling)
  189. {
  190. return new XmlDocumentInsertionWriter (owner, previousSibling, this);
  191. }
  192. internal XmlWriter CreateAttributesWriter (XmlNode owner)
  193. {
  194. return new XmlDocumentAttributeWriter (owner, this);
  195. }
  196. internal void AttributeUpdate (XmlElement element, XmlAttribute oldAttr, XmlAttribute newAttr)
  197. {
  198. AttributeUpdate au = new AttributeUpdate ();
  199. au.Element = element;
  200. au.OldAttribute = oldAttr;
  201. au.NewAttribute = newAttr;
  202. changes.Add (au);
  203. }
  204. internal void AppendChild (XmlNode parent, XmlNode child)
  205. {
  206. Insertion ins = new Insertion ();
  207. ins.ParentNode = parent;
  208. ins.InsertedNode = child;
  209. changes.Add (ins);
  210. }
  211. }
  212. public class XmlDocumentInsertionWriter : XmlWriter
  213. {
  214. XmlNode current;
  215. XmlNode previousSibling;
  216. XPathEditableDocument document;
  217. Stack nodeStack = new Stack ();
  218. public XmlDocumentInsertionWriter (XmlNode owner, XmlNode previousSibling, XPathEditableDocument doc)
  219. {
  220. this.current = (XmlNode) owner;
  221. if (current == null)
  222. throw new InvalidOperationException ();
  223. this.previousSibling = previousSibling;
  224. this.document = doc;
  225. state = WriteState.Content;
  226. }
  227. WriteState state;
  228. XmlAttribute attribute;
  229. public override WriteState WriteState {
  230. get { return state; }
  231. }
  232. public override void Close ()
  233. {
  234. }
  235. public override void Flush ()
  236. {
  237. }
  238. public override string LookupPrefix (string ns)
  239. {
  240. return current.GetPrefixOfNamespace (ns);
  241. }
  242. public override void WriteStartAttribute (string prefix, string name, string ns)
  243. {
  244. if (state != WriteState.Content)
  245. throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
  246. attribute = current.OwnerDocument.CreateAttribute (prefix, name, ns);
  247. state = WriteState.Attribute;
  248. }
  249. public override void WriteProcessingInstruction (string name, string value)
  250. {
  251. XmlProcessingInstruction pi = current.OwnerDocument.CreateProcessingInstruction (name, value);
  252. current.AppendChild (pi);
  253. document.AppendChild (current, pi);
  254. }
  255. public override void WriteComment (string text)
  256. {
  257. XmlComment comment = current.OwnerDocument.CreateComment (text);
  258. current.AppendChild (comment);
  259. document.AppendChild (current, comment);
  260. }
  261. public override void WriteCData (string text)
  262. {
  263. XmlCDataSection cdata = current.OwnerDocument.CreateCDataSection (text);
  264. current.AppendChild (cdata);
  265. document.AppendChild (current, cdata);
  266. }
  267. public override void WriteStartElement (string prefix, string name, string ns)
  268. {
  269. if (current.OwnerDocument == null)
  270. throw new Exception ("Should not happen.");
  271. XmlElement el = current.OwnerDocument.CreateElement (prefix, name, ns);
  272. current.AppendChild (el);
  273. document.AppendChild (current, el);
  274. nodeStack.Push (current);
  275. current = el;
  276. }
  277. public override void WriteEndElement ()
  278. {
  279. if (nodeStack.Count == 0)
  280. throw new InvalidOperationException ("No element is opened.");
  281. current = nodeStack.Pop () as XmlNode;
  282. }
  283. public override void WriteFullEndElement ()
  284. {
  285. WriteEndElement ();
  286. XmlElement el = current as XmlElement;
  287. if (el != null)
  288. el.IsEmpty = false;
  289. }
  290. public override void WriteDocType (string name, string pubid, string systemId, string intsubset)
  291. {
  292. throw new NotSupportedException ();
  293. }
  294. public override void WriteStartDocument ()
  295. {
  296. throw new NotSupportedException ();
  297. }
  298. public override void WriteStartDocument (bool standalone)
  299. {
  300. throw new NotSupportedException ();
  301. }
  302. public override void WriteEndDocument ()
  303. {
  304. throw new NotSupportedException ();
  305. }
  306. public override void WriteBase64 (byte [] data, int start, int length)
  307. {
  308. WriteString (Convert.ToBase64String (data, start, length));
  309. }
  310. public override void WriteRaw (char [] raw, int start, int length)
  311. {
  312. throw new NotSupportedException ();
  313. }
  314. public override void WriteRaw (string raw)
  315. {
  316. throw new NotSupportedException ();
  317. }
  318. public override void WriteSurrogateCharEntity (char msb, char lsb)
  319. {
  320. throw new NotSupportedException ();
  321. }
  322. public override void WriteCharEntity (char c)
  323. {
  324. throw new NotSupportedException ();
  325. }
  326. public override void WriteEntityRef (string entname)
  327. {
  328. if (state != WriteState.Attribute)
  329. throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
  330. attribute.AppendChild (attribute.OwnerDocument.CreateEntityReference (entname));
  331. }
  332. public override void WriteChars (char [] data, int start, int length)
  333. {
  334. WriteString (new string (data, start, length));
  335. }
  336. public override void WriteString (string text)
  337. {
  338. if (attribute != null)
  339. attribute.Value += text;
  340. else
  341. current.AppendChild (current.OwnerDocument.CreateTextNode (text));
  342. }
  343. public override void WriteWhitespace (string text)
  344. {
  345. if (state != WriteState.Attribute)
  346. current.AppendChild (current.OwnerDocument.CreateTextNode (text));
  347. else if (attribute.ChildNodes.Count == 0)
  348. attribute.AppendChild (attribute.OwnerDocument.CreateWhitespace (text));
  349. else
  350. attribute.Value += text;
  351. }
  352. public override void WriteEndAttribute ()
  353. {
  354. XmlElement element = current as XmlElement;
  355. if (state != WriteState.Attribute || element == null)
  356. throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
  357. document.AttributeUpdate (element, element.SetAttributeNode (attribute), attribute);
  358. attribute = null;
  359. state = WriteState.Content;
  360. }
  361. }
  362. public class XmlDocumentAttributeWriter : XmlWriter
  363. {
  364. XmlElement element;
  365. XPathEditableDocument document;
  366. public XmlDocumentAttributeWriter (XmlNode owner, XPathEditableDocument doc)
  367. {
  368. element = owner as XmlElement;
  369. if (element == null)
  370. throw new ArgumentException ("To write attributes, current node must be an element.");
  371. state = WriteState.Content;
  372. document = doc;
  373. }
  374. WriteState state;
  375. XmlAttribute attribute;
  376. public override WriteState WriteState {
  377. get { return state; }
  378. }
  379. public override void Close ()
  380. {
  381. }
  382. public override void Flush ()
  383. {
  384. }
  385. public override string LookupPrefix (string ns)
  386. {
  387. return element.GetPrefixOfNamespace (ns);
  388. }
  389. public override void WriteStartAttribute (string prefix, string name, string ns)
  390. {
  391. if (state != WriteState.Content)
  392. throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
  393. attribute = element.OwnerDocument.CreateAttribute (prefix, name, ns);
  394. state = WriteState.Attribute;
  395. }
  396. public override void WriteProcessingInstruction (string name, string value)
  397. {
  398. throw new NotSupportedException ();
  399. }
  400. public override void WriteComment (string text)
  401. {
  402. throw new NotSupportedException ();
  403. }
  404. public override void WriteCData (string text)
  405. {
  406. throw new NotSupportedException ();
  407. }
  408. public override void WriteStartElement (string prefix, string name, string ns)
  409. {
  410. throw new NotSupportedException ();
  411. }
  412. public override void WriteEndElement ()
  413. {
  414. throw new NotSupportedException ();
  415. }
  416. public override void WriteFullEndElement ()
  417. {
  418. throw new NotSupportedException ();
  419. }
  420. public override void WriteDocType (string name, string pubid, string systemId, string intsubset)
  421. {
  422. throw new NotSupportedException ();
  423. }
  424. public override void WriteStartDocument ()
  425. {
  426. throw new NotSupportedException ();
  427. }
  428. public override void WriteStartDocument (bool standalone)
  429. {
  430. throw new NotSupportedException ();
  431. }
  432. public override void WriteEndDocument ()
  433. {
  434. throw new NotSupportedException ();
  435. }
  436. public override void WriteBase64 (byte [] data, int start, int length)
  437. {
  438. throw new NotSupportedException ();
  439. }
  440. public override void WriteRaw (char [] raw, int start, int length)
  441. {
  442. throw new NotSupportedException ();
  443. }
  444. public override void WriteRaw (string raw)
  445. {
  446. throw new NotSupportedException ();
  447. }
  448. public override void WriteSurrogateCharEntity (char msb, char lsb)
  449. {
  450. throw new NotSupportedException ();
  451. }
  452. public override void WriteCharEntity (char c)
  453. {
  454. throw new NotSupportedException ();
  455. }
  456. public override void WriteEntityRef (string entname)
  457. {
  458. if (state != WriteState.Attribute)
  459. throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
  460. attribute.AppendChild (attribute.OwnerDocument.CreateEntityReference (entname));
  461. }
  462. public override void WriteChars (char [] data, int start, int length)
  463. {
  464. WriteString (new string (data, start, length));
  465. }
  466. public override void WriteString (string text)
  467. {
  468. if (state != WriteState.Attribute)
  469. throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
  470. attribute.Value += text;
  471. }
  472. public override void WriteWhitespace (string text)
  473. {
  474. if (state != WriteState.Attribute)
  475. throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
  476. if (attribute.ChildNodes.Count == 0)
  477. attribute.AppendChild (attribute.OwnerDocument.CreateWhitespace (text));
  478. else
  479. attribute.Value += text;
  480. }
  481. public override void WriteEndAttribute ()
  482. {
  483. if (state != WriteState.Attribute)
  484. throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
  485. document.AttributeUpdate (element, element.SetAttributeNode (attribute), attribute);
  486. attribute = null;
  487. state = WriteState.Content;
  488. }
  489. }
  490. public class Insertion
  491. {
  492. // AppendChild : last child / true
  493. // InsertBefore : current node / false
  494. // InsertAfter : current node / true
  495. // PrependChild : first child / false
  496. public XmlNode ParentNode;
  497. public XmlNode InsertedNode;
  498. public bool Afterward;
  499. }
  500. public class Removal
  501. {
  502. public XmlNode OwnerNode;
  503. public XmlNode NextSibling;
  504. public XmlNode RemovedNode;
  505. }
  506. public class AttributeUpdate
  507. {
  508. public XmlElement Element;
  509. public XmlAttribute NewAttribute;
  510. public XmlAttribute OldAttribute;
  511. }
  512. public class XmlDocumentEditableNavigator : XPathEditableNavigator, IHasXmlNode
  513. {
  514. XPathEditableDocument document;
  515. XPathNavigator navigator;
  516. public XmlDocumentEditableNavigator (XPathEditableDocument doc)
  517. {
  518. document = doc;
  519. navigator = doc.CreateNavigator ();
  520. }
  521. public XmlDocumentEditableNavigator (XmlDocumentEditableNavigator nav)
  522. {
  523. document = nav.document;
  524. navigator = nav.navigator.Clone ();
  525. }
  526. public override string BaseURI {
  527. get { return navigator.BaseURI; }
  528. }
  529. public override bool IsEmptyElement {
  530. get { return navigator.IsEmptyElement; }
  531. }
  532. public override string LocalName {
  533. get { return navigator.LocalName; }
  534. }
  535. public override XmlNameTable NameTable {
  536. get { return navigator.NameTable; }
  537. }
  538. public override string Name {
  539. get { return navigator.Name; }
  540. }
  541. public override string NamespaceURI {
  542. get { return navigator.NamespaceURI; }
  543. }
  544. public override XPathNodeType NodeType {
  545. get { return navigator.NodeType; }
  546. }
  547. public override string Prefix {
  548. get { return navigator.Prefix; }
  549. }
  550. public override string Value {
  551. get { return navigator.Value; }
  552. }
  553. public override XPathNavigator Clone ()
  554. {
  555. return new XmlDocumentEditableNavigator (this);
  556. }
  557. public override XPathNavigator CreateNavigator ()
  558. {
  559. return navigator.Clone ();
  560. }
  561. public XmlNode GetNode ()
  562. {
  563. return ((IHasXmlNode) navigator).GetNode ();
  564. }
  565. public override bool IsSamePosition (XPathNavigator other)
  566. {
  567. XmlDocumentEditableNavigator nav = other as XmlDocumentEditableNavigator;
  568. if (nav != null)
  569. return navigator.IsSamePosition (nav.navigator);
  570. else
  571. return navigator.IsSamePosition (nav);
  572. }
  573. public override bool MoveTo (XPathNavigator other)
  574. {
  575. XmlDocumentEditableNavigator nav = other as XmlDocumentEditableNavigator;
  576. if (nav != null)
  577. return navigator.MoveTo (nav.navigator);
  578. else
  579. return navigator.MoveTo (nav);
  580. }
  581. public override bool MoveToFirstAttribute ()
  582. {
  583. return navigator.MoveToFirstAttribute ();
  584. }
  585. public override bool MoveToFirstChild ()
  586. {
  587. return navigator.MoveToFirstChild ();
  588. }
  589. public override bool MoveToFirstNamespace (XPathNamespaceScope scope)
  590. {
  591. return navigator.MoveToFirstNamespace (scope);
  592. }
  593. public override bool MoveToId (string id)
  594. {
  595. return navigator.MoveToId (id);
  596. }
  597. public override bool MoveToNext ()
  598. {
  599. return navigator.MoveToNext ();
  600. }
  601. public override bool MoveToNextAttribute ()
  602. {
  603. return navigator.MoveToNextAttribute ();
  604. }
  605. public override bool MoveToNextNamespace (XPathNamespaceScope scope)
  606. {
  607. return navigator.MoveToNextNamespace (scope);
  608. }
  609. public override bool MoveToParent ()
  610. {
  611. return navigator.MoveToParent ();
  612. }
  613. public override bool MoveToPrevious ()
  614. {
  615. return navigator.MoveToPrevious ();
  616. }
  617. public override void Validate (XmlSchemaSet schemas, ValidationEventHandler handler)
  618. {
  619. throw new NotImplementedException ();
  620. /*
  621. // FIXME: use handler
  622. XmlReaderSettings settings = new XmlReaderSettings ();
  623. settings.Schemas.Add (schemas);
  624. settings.NameTable = this.NameTable;
  625. settings.XsdValidate = true;
  626. settings.DtdValidate = false;
  627. XmlReader xvr = XmlReader.Create (new XPathNavigatorReader (this), settings);
  628. while (!xvr.EOF)
  629. xvr.Read ();
  630. */
  631. }
  632. public override XmlWriter AppendChild ()
  633. {
  634. XmlNode n = ((IHasXmlNode) navigator).GetNode ();
  635. if (n == null)
  636. throw new InvalidOperationException ("Should not happen.");
  637. return document.CreateInsertionWriter (n, null);
  638. }
  639. public override XmlWriter InsertBefore ()
  640. {
  641. XmlNode n = ((IHasXmlNode) navigator).GetNode ();
  642. return document.CreateInsertionWriter (n.ParentNode, n.PreviousSibling);
  643. }
  644. public override XmlWriter CreateAttributes ()
  645. {
  646. XmlNode n = ((IHasXmlNode) navigator).GetNode ();
  647. return document.CreateInsertionWriter (n, null);
  648. }
  649. public override bool DeleteCurrent ()
  650. {
  651. XmlNode n = ((IHasXmlNode) navigator).GetNode ();
  652. if (!navigator.MoveToNext ())
  653. navigator.MoveToParent ();
  654. return document.DeleteNode (n);
  655. }
  656. public override void SetValue (object value)
  657. {
  658. XmlNode n = ((IHasXmlNode) navigator).GetNode ();
  659. foreach (XmlNode c in n.ChildNodes)
  660. document.DeleteNode (c);
  661. XmlWriter w = document.CreateInsertionWriter (n, null);
  662. // FIXME: Hmm, it does not look like using it.
  663. w.WriteFromObject (value);
  664. w.Close ();
  665. }
  666. }
  667. }
  668. #endif