2 // System.Xml.XPath.XPathNavigator
5 // Jason Diamond (jason@injektilo.org)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // (C) 2002 Jason Diamond http://injektilo.org/
9 // (C) 2004 Novell Inc.
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.
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Diagnostics;
41 using System.Xml.Schema;
45 using NSResolver = System.Xml.IXmlNamespaceResolver;
47 using NSResolver = System.Xml.XmlNamespaceManager;
50 namespace System.Xml.XPath
53 public abstract class XPathNavigator : XPathItem,
54 ICloneable, IXPathNavigable, IXmlNamespaceResolver
56 public abstract class XPathNavigator : ICloneable
59 #region Static members
61 public static IEqualityComparer NavigatorComparer {
62 get { return XPathNavigatorComparer.Instance; }
69 protected XPathNavigator ()
77 public abstract string BaseURI { get; }
80 public virtual bool CanEdit {
84 public virtual bool HasAttributes {
86 if (!MoveToFirstAttribute ())
93 public virtual bool HasChildren {
95 if (!MoveToFirstChild ())
102 public abstract bool HasAttributes { get; }
104 public abstract bool HasChildren { get; }
107 public abstract bool IsEmptyElement { get; }
109 public abstract string LocalName { get; }
111 public abstract string Name { get; }
113 public abstract string NamespaceURI { get; }
115 public abstract XmlNameTable NameTable { get; }
117 public abstract XPathNodeType NodeType { get; }
119 public abstract string Prefix { get; }
122 public virtual string XmlLang {
124 XPathNavigator nav = Clone ();
125 switch (nav.NodeType) {
126 case XPathNodeType.Attribute:
127 case XPathNodeType.Namespace:
132 if (nav.MoveToAttribute ("lang", "http://www.w3.org/XML/1998/namespace"))
134 } while (nav.MoveToParent ());
139 public abstract string Value { get; }
141 public abstract string XmlLang { get; }
148 public abstract XPathNavigator Clone ();
150 public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
152 if (IsSamePosition (nav))
153 return XmlNodeOrder.Same;
155 // quick check for direct descendant
156 if (IsDescendant (nav))
157 return XmlNodeOrder.Before;
159 // quick check for direct ancestor
160 if (nav.IsDescendant (this))
161 return XmlNodeOrder.After;
163 XPathNavigator nav1 = Clone ();
164 XPathNavigator nav2 = nav.Clone ();
166 // check if document instance is the same.
169 if (!nav1.IsSamePosition (nav2))
170 return XmlNodeOrder.Unknown;
175 while (nav1.MoveToParent ())
179 while (nav2.MoveToParent ())
183 // find common parent depth
185 for (;common > depth2; common--)
186 nav1.MoveToParent ();
187 for (int i = depth2; i > common; i--)
188 nav2.MoveToParent ();
189 while (!nav1.IsSamePosition (nav2)) {
190 nav1.MoveToParent ();
191 nav2.MoveToParent ();
195 // For each this and target, move to the node that is
196 // ancestor of the node and child of the common parent.
198 for (int i = depth1; i > common + 1; i--)
199 nav1.MoveToParent ();
201 for (int i = depth2; i > common + 1; i--)
202 nav2.MoveToParent ();
204 // Those children of common parent are comparable.
205 // namespace nodes precede to attributes, and they
206 // precede to other nodes.
207 if (nav1.NodeType == XPathNodeType.Namespace) {
208 if (nav2.NodeType != XPathNodeType.Namespace)
209 return XmlNodeOrder.Before;
210 while (nav1.MoveToNextNamespace ())
211 if (nav1.IsSamePosition (nav2))
212 return XmlNodeOrder.Before;
213 return XmlNodeOrder.After;
215 if (nav2.NodeType == XPathNodeType.Namespace)
216 return XmlNodeOrder.After;
217 if (nav1.NodeType == XPathNodeType.Attribute) {
218 if (nav2.NodeType != XPathNodeType.Attribute)
219 return XmlNodeOrder.Before;
220 while (nav1.MoveToNextAttribute ())
221 if (nav1.IsSamePosition (nav2))
222 return XmlNodeOrder.Before;
223 return XmlNodeOrder.After;
225 while (nav1.MoveToNext ())
226 if (nav1.IsSamePosition (nav2))
227 return XmlNodeOrder.Before;
228 return XmlNodeOrder.After;
231 public virtual XPathExpression Compile (string xpath)
233 return XPathExpression.Compile (xpath);
236 internal virtual XPathExpression Compile (string xpath, System.Xml.Xsl.IStaticXsltContext ctx)
238 return XPathExpression.Compile (xpath, null, ctx);
241 public virtual object Evaluate (string xpath)
243 return Evaluate (Compile (xpath));
246 public virtual object Evaluate (XPathExpression expr)
248 return Evaluate (expr, null);
251 public virtual object Evaluate (XPathExpression expr, XPathNodeIterator context)
253 return Evaluate (expr, context, null);
256 internal virtual object Evaluate (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
258 CompiledExpression cexpr = (CompiledExpression) expr;
260 ctx = cexpr.NamespaceManager;
263 context = new NullIterator (this, ctx);
264 BaseIterator iterContext = (BaseIterator) context;
265 iterContext.NamespaceManager = ctx;
266 return cexpr.Evaluate (iterContext);
269 internal XPathNodeIterator EvaluateNodeSet (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
271 CompiledExpression cexpr = (CompiledExpression) expr;
273 ctx = cexpr.NamespaceManager;
276 context = new NullIterator (this, cexpr.NamespaceManager);
277 BaseIterator iterContext = (BaseIterator) context;
278 iterContext.NamespaceManager = ctx;
279 return cexpr.EvaluateNodeSet (iterContext);
282 internal string EvaluateString (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
284 CompiledExpression cexpr = (CompiledExpression) expr;
286 ctx = cexpr.NamespaceManager;
289 context = new NullIterator (this, cexpr.NamespaceManager);
290 BaseIterator iterContext = (BaseIterator) context;
291 iterContext.NamespaceManager = ctx;
292 return cexpr.EvaluateString (iterContext);
295 internal double EvaluateNumber (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
297 CompiledExpression cexpr = (CompiledExpression) expr;
299 ctx = cexpr.NamespaceManager;
302 context = new NullIterator (this, cexpr.NamespaceManager);
303 BaseIterator iterContext = (BaseIterator) context;
304 iterContext.NamespaceManager = ctx;
305 return cexpr.EvaluateNumber (iterContext);
308 internal bool EvaluateBoolean (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
310 CompiledExpression cexpr = (CompiledExpression) expr;
312 ctx = cexpr.NamespaceManager;
315 context = new NullIterator (this, cexpr.NamespaceManager);
316 BaseIterator iterContext = (BaseIterator) context;
317 iterContext.NamespaceManager = ctx;
318 return cexpr.EvaluateBoolean (iterContext);
322 public virtual string GetAttribute (string localName, string namespaceURI)
324 if (!MoveToAttribute (localName, namespaceURI))
326 string value = Value;
331 public virtual string GetNamespace (string name)
333 if (!MoveToNamespace (name))
335 string value = Value;
341 public abstract string GetAttribute (string localName, string namespaceURI);
343 public abstract string GetNamespace (string name);
346 object ICloneable.Clone ()
351 public virtual bool IsDescendant (XPathNavigator nav)
356 while (nav.MoveToParent ())
358 if (IsSamePosition (nav))
365 public abstract bool IsSamePosition (XPathNavigator other);
367 public virtual bool Matches (string xpath)
369 return Matches (Compile (xpath));
372 public virtual bool Matches (XPathExpression expr)
374 Expression e = ((CompiledExpression) expr).ExpressionNode;
376 return NodeType == XPathNodeType.Root;
378 NodeTest nt = e as NodeTest;
380 switch (nt.Axis.Axis) {
385 throw new XPathException ("Only child and attribute pattern are allowed for a pattern.");
387 return nt.Match (((CompiledExpression)expr).NamespaceManager, this);
389 if (e is ExprFilter) {
391 e = ((ExprFilter) e).LeftHandSide;
392 } while (e is ExprFilter);
394 if (e is NodeTest && !((NodeTest) e).Match (((CompiledExpression) expr).NamespaceManager, this))
398 XPathResultType resultType = e.ReturnType;
399 switch (resultType) {
400 case XPathResultType.Any:
401 case XPathResultType.NodeSet:
407 switch (e.EvaluatedNodeType) {
408 case XPathNodeType.Attribute:
409 case XPathNodeType.Namespace:
410 if (NodeType != e.EvaluatedNodeType)
415 XPathNodeIterator nodes;
416 nodes = this.Select (expr);
417 while (nodes.MoveNext ()) {
418 if (IsSamePosition (nodes.Current))
422 // ancestors might select this node.
424 XPathNavigator navigator = Clone ();
426 while (navigator.MoveToParent ()) {
427 nodes = navigator.Select (expr);
429 while (nodes.MoveNext ()) {
430 if (IsSamePosition (nodes.Current))
438 public abstract bool MoveTo (XPathNavigator other);
441 public virtual bool MoveToAttribute (string localName, string namespaceURI)
443 if (MoveToFirstAttribute ()) {
445 if (LocalName == localName && NamespaceURI == namespaceURI)
447 } while (MoveToNextAttribute ());
453 public virtual bool MoveToNamespace (string name)
455 if (MoveToFirstNamespace ()) {
457 if (LocalName == name)
459 } while (MoveToNextNamespace ());
466 public virtual bool MoveToFirst ()
468 if (MoveToPrevious ()) {
469 // It would be able to invoke MoveToPrevious() until the end, but this way would be much faster
478 public virtual bool MoveToFirst ()
480 return MoveToFirstImpl ();
483 public virtual void MoveToRoot ()
485 while (MoveToParent ())
489 public abstract bool MoveToAttribute (string localName, string namespaceURI);
491 public abstract bool MoveToNamespace (string name);
493 public abstract bool MoveToFirst ();
495 public abstract void MoveToRoot ();
498 internal bool MoveToFirstImpl ()
501 case XPathNodeType.Attribute:
502 case XPathNodeType.Namespace:
505 if (!MoveToParent ())
507 // Follow these 2 steps so that we can skip
508 // some types of nodes .
514 public abstract bool MoveToFirstAttribute ();
516 public abstract bool MoveToFirstChild ();
518 public bool MoveToFirstNamespace ()
520 return MoveToFirstNamespace (XPathNamespaceScope.All);
523 public abstract bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope);
525 public abstract bool MoveToId (string id);
527 public abstract bool MoveToNext ();
529 public abstract bool MoveToNextAttribute ();
531 public bool MoveToNextNamespace ()
533 return MoveToNextNamespace (XPathNamespaceScope.All);
536 public abstract bool MoveToNextNamespace (XPathNamespaceScope namespaceScope);
538 public abstract bool MoveToParent ();
540 public abstract bool MoveToPrevious ();
542 public virtual XPathNodeIterator Select (string xpath)
544 return Select (Compile (xpath));
547 public virtual XPathNodeIterator Select (XPathExpression expr)
549 return Select (expr, null);
552 internal virtual XPathNodeIterator Select (XPathExpression expr, NSResolver ctx)
554 CompiledExpression cexpr = (CompiledExpression) expr;
556 ctx = cexpr.NamespaceManager;
558 BaseIterator iter = new NullIterator (this, ctx);
559 return cexpr.EvaluateNodeSet (iter);
562 public virtual XPathNodeIterator SelectAncestors (XPathNodeType type, bool matchSelf)
564 Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
565 return SelectTest (new NodeTypeTest (axis, type));
568 public virtual XPathNodeIterator SelectAncestors (string name, string namespaceURI, bool matchSelf)
571 throw new ArgumentNullException ("name");
572 if (namespaceURI == null)
573 throw new ArgumentNullException ("namespaceURI");
575 Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
576 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
577 return SelectTest (new NodeNameTest (axis, qname, true));
580 public virtual XPathNodeIterator SelectChildren (XPathNodeType type)
582 return SelectTest (new NodeTypeTest (Axes.Child, type));
585 public virtual XPathNodeIterator SelectChildren (string name, string namespaceURI)
588 throw new ArgumentNullException ("name");
589 if (namespaceURI == null)
590 throw new ArgumentNullException ("namespaceURI");
592 Axes axis = Axes.Child;
593 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
594 return SelectTest (new NodeNameTest (axis, qname, true));
597 public virtual XPathNodeIterator SelectDescendants (XPathNodeType type, bool matchSelf)
599 Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
600 return SelectTest (new NodeTypeTest (axis, type));
603 public virtual XPathNodeIterator SelectDescendants (string name, string namespaceURI, bool matchSelf)
606 throw new ArgumentNullException ("name");
607 if (namespaceURI == null)
608 throw new ArgumentNullException ("namespaceURI");
611 Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
612 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
613 return SelectTest (new NodeNameTest (axis, qname, true));
616 internal XPathNodeIterator SelectTest (NodeTest test)
618 return test.EvaluateNodeSet (new NullIterator (this));
621 public override string ToString ()
630 public virtual bool CheckValidity (XmlSchemaSet schemas, ValidationEventHandler handler)
632 XmlReaderSettings settings = new XmlReaderSettings ();
633 settings.NameTable = NameTable;
634 settings.SetSchemas (schemas);
635 settings.ValidationEventHandler += handler;
636 settings.ValidationType = ValidationType.Schema;
638 XmlReader r = XmlReader.Create (
639 ReadSubtree (), settings);
642 } catch (XmlSchemaValidationException) {
648 public virtual XPathNavigator CreateNavigator ()
654 public virtual object Evaluate (string xpath, IXmlNamespaceResolver nsResolver)
656 return Evaluate (Compile (xpath), null, nsResolver);
660 public virtual IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
662 IDictionary<string, string> table = new Dictionary<string, string> ();
663 XPathNamespaceScope xpscope =
664 scope == XmlNamespaceScope.Local ?
665 XPathNamespaceScope.Local :
666 scope == XmlNamespaceScope.ExcludeXml ?
667 XPathNamespaceScope.ExcludeXml :
668 XPathNamespaceScope.All;
669 XPathNavigator nav = Clone ();
670 if (nav.NodeType != XPathNodeType.Element)
672 if (!nav.MoveToFirstNamespace (xpscope))
675 table.Add (nav.Name, nav.Value);
676 } while (nav.MoveToNextNamespace (xpscope));
680 public virtual string LookupNamespace (string prefix)
682 XPathNavigator nav = Clone ();
683 if (nav.NodeType != XPathNodeType.Element)
685 if (nav.MoveToNamespace (prefix))
690 public virtual string LookupPrefix (string namespaceUri)
692 XPathNavigator nav = Clone ();
693 if (nav.NodeType != XPathNodeType.Element)
695 if (!nav.MoveToFirstNamespace ())
698 if (nav.Value == namespaceUri)
700 } while (nav.MoveToNextNamespace ());
704 private bool MoveTo (XPathNodeIterator iter)
706 if (iter.MoveNext ()) {
707 MoveTo (iter.Current);
714 public virtual bool MoveToChild (XPathNodeType type)
716 return MoveTo (SelectChildren (type));
719 public virtual bool MoveToChild (string localName, string namespaceURI)
721 return MoveTo (SelectChildren (localName, namespaceURI));
724 bool MoveToDescendant (XPathNodeType type)
726 return MoveTo (SelectDescendants (type, false));
729 bool MoveToDescendant (string localName, string namespaceURI)
731 return MoveTo (SelectDescendants (localName, namespaceURI, false));
734 public virtual bool MoveToNext (string localName, string namespaceURI)
736 XPathNavigator nav = Clone ();
737 while (nav.MoveToNext ()) {
738 if (nav.LocalName == localName &&
739 nav.NamespaceURI == namespaceURI) {
747 public virtual bool MoveToNext (XPathNodeType type)
749 XPathNavigator nav = Clone ();
750 while (nav.MoveToNext ()) {
751 if (nav.NodeType == type) {
760 public virtual bool MoveToFollowing (string localName,
763 return MoveToFollowing (localName, namespaceURI, null);
767 public virtual bool MoveToFollowing (string localName,
768 string namespaceURI, XPathNavigator end)
770 XPathNavigator nav = Clone ();
773 if (!skip && nav.MoveToDescendant (localName,
776 switch (nav.ComparePosition (end)) {
777 case XmlNodeOrder.After:
778 case XmlNodeOrder.Unknown:
787 if (!nav.MoveToNext ()) {
788 if (!nav.MoveToParent ())
797 public virtual bool MoveToFollowing (XPathNodeType type)
799 return MoveToFollowing (type, null);
803 public virtual bool MoveToFollowing (XPathNodeType type,
806 XPathNavigator nav = Clone ();
809 if (!skip && nav.MoveToDescendant (type)) {
811 switch (nav.ComparePosition (end)) {
812 case XmlNodeOrder.After:
813 case XmlNodeOrder.Unknown:
822 if (!nav.MoveToNext ()) {
823 if (!nav.MoveToParent ())
832 public virtual XmlReader ReadSubtree ()
834 return new XPathNavigatorReader (this);
837 public virtual XPathNodeIterator Select (string xpath, IXmlNamespaceResolver nsResolver)
839 return Select (Compile (xpath), nsResolver);
842 public virtual XPathNavigator SelectSingleNode (string xpath)
844 return SelectSingleNode (xpath, null);
847 public virtual XPathNavigator SelectSingleNode (string xpath, IXmlNamespaceResolver nsResolver)
849 XPathExpression expr = Compile (xpath);
850 expr.SetContext (nsResolver);
851 return SelectSingleNode (expr);
854 public virtual XPathNavigator SelectSingleNode (XPathExpression expression)
856 XPathNodeIterator iter = Select (expression);
857 if (iter.MoveNext ())
864 public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
866 throw new NotImplementedException ();
870 public virtual void WriteSubtree (XmlWriter writer)
872 XmlReader st = ReadSubtree ();
873 writer.WriteNode (st, false);
877 public virtual string InnerXml {
879 XmlReader r = ReadSubtree ();
881 // skip the element itself (or will reach to
882 // EOF if other than element) unless writing
885 if (NodeType != XPathNodeType.Root)
887 StringWriter sw = new StringWriter ();
888 XmlWriter xtw = XmlWriter.Create (sw);
889 while (!r.EOF && r.Depth > depth)
890 xtw.WriteNode (r, false);
891 return sw.ToString ();
895 if (NodeType == XPathNodeType.Attribute) {
904 public override bool IsNode {
909 public virtual string OuterXml {
911 StringWriter sw = new StringWriter ();
912 XmlTextWriter xtw = new XmlTextWriter (sw);
915 return sw.ToString ();
919 case XPathNodeType.Root:
920 case XPathNodeType.Attribute:
921 case XPathNodeType.Namespace:
922 throw new XmlException ("Setting OuterXml Root, Attribute and Namespace is not supported.");
932 public virtual IXmlSchemaInfo SchemaInfo {
939 public override object TypedValue {
942 case XPathNodeType.Element:
943 case XPathNodeType.Attribute:
946 XmlSchemaDatatype dt = XmlType.Datatype;
949 return dt.ParseValue (Value, NameTable, this as IXmlNamespaceResolver);
956 public virtual object UnderlyingObject {
957 get { throw new NotImplementedException (); }
961 public override bool ValueAsBoolean {
962 get { return XQueryConvert.StringToBoolean (Value); }
966 public override DateTime ValueAsDateTime {
967 get { return XmlConvert.ToDateTime (Value); }
971 public override double ValueAsDouble {
972 get { return XQueryConvert.StringToDouble (Value); }
976 public override int ValueAsInt {
977 get { return XQueryConvert.StringToInt (Value); }
981 public override long ValueAsLong {
982 get { return XQueryConvert.StringToInteger (Value); }
986 public override Type ValueType {
988 return SchemaInfo != null &&
989 SchemaInfo.SchemaType != null &&
990 SchemaInfo.SchemaType.Datatype != null ?
991 SchemaInfo.SchemaType.Datatype.ValueType
997 public override XmlSchemaType XmlType {
999 if (SchemaInfo != null)
1000 return SchemaInfo.SchemaType;
1011 private XmlReader CreateFragmentReader (string fragment)
1013 return new XmlTextReader (fragment, XmlNodeType.Element, new XmlParserContext (NameTable, null, null, XmlSpace.None));
1016 public virtual XmlWriter AppendChild ()
1018 throw new NotSupportedException ();
1022 public virtual void AppendChild (
1023 string xmlFragments)
1025 // FIXME: should XmlParserContext be something?
1026 AppendChild (CreateFragmentReader (xmlFragments));
1030 public virtual void AppendChild (
1033 XmlWriter w = AppendChild ();
1035 w.WriteNode (reader, false);
1040 public virtual void AppendChild (
1043 AppendChild (new XPathNavigatorReader (nav));
1046 public virtual void AppendChildElement (string prefix, string name, string ns, string value)
1048 XmlWriter xw = AppendChild ();
1049 xw.WriteStartElement (prefix, name, ns);
1050 xw.WriteString (value);
1051 xw.WriteEndElement ();
1055 public virtual void CreateAttribute (string prefix, string localName, string namespaceURI, string value)
1057 using (XmlWriter w = CreateAttributes ()) {
1058 w.WriteAttributeString (prefix, localName, namespaceURI, value);
1062 public virtual XmlWriter CreateAttributes ()
1064 throw new NotSupportedException ();
1067 public virtual void DeleteSelf ()
1069 throw new NotSupportedException ();
1072 [MonoTODO ("no concrete implementation yet")]
1073 public virtual void DeleteRange (XPathNavigator nav)
1075 throw new NotSupportedException ();
1078 [MonoTODO ("no concrete implementation yet")]
1079 public virtual XmlWriter ReplaceRange (XPathNavigator nav)
1081 throw new NotSupportedException ();
1084 public virtual XmlWriter InsertAfter ()
1086 XPathNavigator nav = Clone ();
1087 if (nav.MoveToNext ())
1088 return nav.InsertBefore ();
1090 return AppendChild ();
1093 public virtual void InsertAfter (string xmlFragments)
1095 InsertAfter (CreateFragmentReader (xmlFragments));
1099 public virtual void InsertAfter (XmlReader reader)
1101 using (XmlWriter w = InsertAfter ()) {
1102 w.WriteNode (reader, false);
1107 public virtual void InsertAfter (XPathNavigator nav)
1109 InsertAfter (new XPathNavigatorReader (nav));
1112 public virtual XmlWriter InsertBefore ()
1114 throw new NotSupportedException ();
1117 public virtual void InsertBefore (string xmlFragments)
1119 InsertBefore (CreateFragmentReader (xmlFragments));
1123 public virtual void InsertBefore (XmlReader reader)
1125 using (XmlWriter w = InsertBefore ()) {
1126 w.WriteNode (reader, false);
1131 public virtual void InsertBefore (XPathNavigator nav)
1133 InsertBefore (new XPathNavigatorReader (nav));
1136 public virtual void InsertElementAfter (string prefix,
1137 string localName, string namespaceURI, string value)
1139 using (XmlWriter w = InsertAfter ()) {
1140 w.WriteElementString (prefix, localName, namespaceURI, value);
1144 public virtual void InsertElementBefore (string prefix,
1145 string localName, string namespaceURI, string value)
1147 using (XmlWriter w = InsertBefore ()) {
1148 w.WriteElementString (prefix, localName, namespaceURI, value);
1152 public virtual XmlWriter PrependChild ()
1154 XPathNavigator nav = Clone ();
1155 if (nav.MoveToFirstChild ())
1156 return nav.InsertBefore ();
1158 return InsertBefore ();
1161 public virtual void PrependChild (string xmlFragments)
1163 PrependChild (CreateFragmentReader (xmlFragments));
1167 public virtual void PrependChild (XmlReader reader)
1169 using (XmlWriter w = PrependChild ()) {
1170 w.WriteNode (reader, false);
1175 public virtual void PrependChild (XPathNavigator nav)
1177 PrependChild (new XPathNavigatorReader (nav));
1180 public virtual void PrependChildElement (string prefix,
1181 string localName, string namespaceURI, string value)
1183 using (XmlWriter w = PrependChild ()) {
1184 w.WriteElementString (prefix, localName, namespaceURI, value);
1189 public virtual void ReplaceSelf (string xmlFragment)
1191 ReplaceSelf (XmlReader.Create (new StringReader (xmlFragment)));
1195 public virtual void ReplaceSelf (XmlReader reader)
1197 InsertBefore (reader);
1202 public virtual void ReplaceSelf (XPathNavigator navigator)
1204 ReplaceSelf (new XPathNavigatorReader (navigator));
1207 // Dunno the exact purpose, but maybe internal editor use
1209 public virtual void SetTypedValue (object value)
1211 throw new NotSupportedException ();
1214 public virtual void SetValue (string value)
1216 throw new NotSupportedException ();
1220 private void DeleteChildren ()
1223 case XPathNodeType.Namespace:
1224 throw new InvalidOperationException ("Removing namespace node content is not supported.");
1225 case XPathNodeType.Attribute:
1227 case XPathNodeType.Text:
1228 case XPathNodeType.SignificantWhitespace:
1229 case XPathNodeType.Whitespace:
1230 case XPathNodeType.ProcessingInstruction:
1231 case XPathNodeType.Comment:
1237 XPathNavigator nav = Clone ();
1238 nav.MoveToFirstChild ();
1239 while (!nav.IsSamePosition (this))