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;
42 using System.Xml.Schema;
46 using NSResolver = System.Xml.IXmlNamespaceResolver;
48 using NSResolver = System.Xml.XmlNamespaceManager;
51 namespace System.Xml.XPath
54 public abstract class XPathNavigator : XPathItem,
55 ICloneable, IXPathNavigable, IXmlNamespaceResolver
57 public abstract class XPathNavigator : ICloneable
60 #region Static members
62 public static IEqualityComparer NavigatorComparer {
63 get { return XPathNavigatorComparer.Instance; }
70 protected XPathNavigator ()
78 public abstract string BaseURI { get; }
81 public virtual bool CanEdit {
85 public virtual bool HasAttributes {
87 if (!MoveToFirstAttribute ())
94 public virtual bool HasChildren {
96 if (!MoveToFirstChild ())
103 public abstract bool HasAttributes { get; }
105 public abstract bool HasChildren { get; }
108 public abstract bool IsEmptyElement { get; }
110 public abstract string LocalName { get; }
112 public abstract string Name { get; }
114 public abstract string NamespaceURI { get; }
116 public abstract XmlNameTable NameTable { get; }
118 public abstract XPathNodeType NodeType { get; }
120 public abstract string Prefix { get; }
123 public virtual string XmlLang {
125 XPathNavigator nav = Clone ();
126 switch (nav.NodeType) {
127 case XPathNodeType.Attribute:
128 case XPathNodeType.Namespace:
133 if (nav.MoveToAttribute ("lang", "http://www.w3.org/XML/1998/namespace"))
135 } while (nav.MoveToParent ());
140 public abstract string Value { get; }
142 public abstract string XmlLang { get; }
149 public abstract XPathNavigator Clone ();
151 public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
153 if (IsSamePosition (nav))
154 return XmlNodeOrder.Same;
156 // quick check for direct descendant
157 if (IsDescendant (nav))
158 return XmlNodeOrder.Before;
160 // quick check for direct ancestor
161 if (nav.IsDescendant (this))
162 return XmlNodeOrder.After;
164 XPathNavigator nav1 = Clone ();
165 XPathNavigator nav2 = nav.Clone ();
167 // check if document instance is the same.
170 if (!nav1.IsSamePosition (nav2))
171 return XmlNodeOrder.Unknown;
176 while (nav1.MoveToParent ())
180 while (nav2.MoveToParent ())
184 // find common parent depth
186 for (;common > depth2; common--)
187 nav1.MoveToParent ();
188 for (int i = depth2; i > common; i--)
189 nav2.MoveToParent ();
190 while (!nav1.IsSamePosition (nav2)) {
191 nav1.MoveToParent ();
192 nav2.MoveToParent ();
196 // For each this and target, move to the node that is
197 // ancestor of the node and child of the common parent.
199 for (int i = depth1; i > common + 1; i--)
200 nav1.MoveToParent ();
202 for (int i = depth2; i > common + 1; i--)
203 nav2.MoveToParent ();
205 // Those children of common parent are comparable.
206 // namespace nodes precede to attributes, and they
207 // precede to other nodes.
208 if (nav1.NodeType == XPathNodeType.Namespace) {
209 if (nav2.NodeType != XPathNodeType.Namespace)
210 return XmlNodeOrder.Before;
211 while (nav1.MoveToNextNamespace ())
212 if (nav1.IsSamePosition (nav2))
213 return XmlNodeOrder.Before;
214 return XmlNodeOrder.After;
216 if (nav2.NodeType == XPathNodeType.Namespace)
217 return XmlNodeOrder.After;
218 if (nav1.NodeType == XPathNodeType.Attribute) {
219 if (nav2.NodeType != XPathNodeType.Attribute)
220 return XmlNodeOrder.Before;
221 while (nav1.MoveToNextAttribute ())
222 if (nav1.IsSamePosition (nav2))
223 return XmlNodeOrder.Before;
224 return XmlNodeOrder.After;
226 while (nav1.MoveToNext ())
227 if (nav1.IsSamePosition (nav2))
228 return XmlNodeOrder.Before;
229 return XmlNodeOrder.After;
232 public virtual XPathExpression Compile (string xpath)
234 return XPathExpression.Compile (xpath);
237 internal virtual XPathExpression Compile (string xpath, System.Xml.Xsl.IStaticXsltContext ctx)
239 return XPathExpression.Compile (xpath, null, ctx);
242 public virtual object Evaluate (string xpath)
244 return Evaluate (Compile (xpath));
247 public virtual object Evaluate (XPathExpression expr)
249 return Evaluate (expr, null);
252 public virtual object Evaluate (XPathExpression expr, XPathNodeIterator context)
254 return Evaluate (expr, context, null);
257 internal virtual object Evaluate (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
259 CompiledExpression cexpr = (CompiledExpression) expr;
261 ctx = cexpr.NamespaceManager;
264 context = new NullIterator (this, ctx);
265 BaseIterator iterContext = (BaseIterator) context;
266 iterContext.NamespaceManager = ctx;
267 return cexpr.Evaluate (iterContext);
270 internal XPathNodeIterator EvaluateNodeSet (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
272 CompiledExpression cexpr = (CompiledExpression) expr;
274 ctx = cexpr.NamespaceManager;
277 context = new NullIterator (this, cexpr.NamespaceManager);
278 BaseIterator iterContext = (BaseIterator) context;
279 iterContext.NamespaceManager = ctx;
280 return cexpr.EvaluateNodeSet (iterContext);
283 internal string EvaluateString (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
285 CompiledExpression cexpr = (CompiledExpression) expr;
287 ctx = cexpr.NamespaceManager;
290 context = new NullIterator (this, cexpr.NamespaceManager);
291 BaseIterator iterContext = (BaseIterator) context;
292 iterContext.NamespaceManager = ctx;
293 return cexpr.EvaluateString (iterContext);
296 internal double EvaluateNumber (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
298 CompiledExpression cexpr = (CompiledExpression) expr;
300 ctx = cexpr.NamespaceManager;
303 context = new NullIterator (this, cexpr.NamespaceManager);
304 BaseIterator iterContext = (BaseIterator) context;
305 iterContext.NamespaceManager = ctx;
306 return cexpr.EvaluateNumber (iterContext);
309 internal bool EvaluateBoolean (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
311 CompiledExpression cexpr = (CompiledExpression) expr;
313 ctx = cexpr.NamespaceManager;
316 context = new NullIterator (this, cexpr.NamespaceManager);
317 BaseIterator iterContext = (BaseIterator) context;
318 iterContext.NamespaceManager = ctx;
319 return cexpr.EvaluateBoolean (iterContext);
323 public virtual string GetAttribute (string localName, string namespaceURI)
325 if (!MoveToAttribute (localName, namespaceURI))
327 string value = Value;
332 public virtual string GetNamespace (string name)
334 if (!MoveToNamespace (name))
336 string value = Value;
342 public abstract string GetAttribute (string localName, string namespaceURI);
344 public abstract string GetNamespace (string name);
347 object ICloneable.Clone ()
352 public virtual bool IsDescendant (XPathNavigator nav)
357 while (nav.MoveToParent ())
359 if (IsSamePosition (nav))
366 public abstract bool IsSamePosition (XPathNavigator other);
368 public virtual bool Matches (string xpath)
370 return Matches (Compile (xpath));
373 public virtual bool Matches (XPathExpression expr)
375 Expression e = ((CompiledExpression) expr).ExpressionNode;
377 return NodeType == XPathNodeType.Root;
379 NodeTest nt = e as NodeTest;
381 switch (nt.Axis.Axis) {
386 throw new XPathException ("Only child and attribute pattern are allowed for a pattern.");
388 return nt.Match (((CompiledExpression)expr).NamespaceManager, this);
390 if (e is ExprFilter) {
392 e = ((ExprFilter) e).LeftHandSide;
393 } while (e is ExprFilter);
395 if (e is NodeTest && !((NodeTest) e).Match (((CompiledExpression) expr).NamespaceManager, this))
399 XPathResultType resultType = e.ReturnType;
400 switch (resultType) {
401 case XPathResultType.Any:
402 case XPathResultType.NodeSet:
408 switch (e.EvaluatedNodeType) {
409 case XPathNodeType.Attribute:
410 case XPathNodeType.Namespace:
411 if (NodeType != e.EvaluatedNodeType)
416 XPathNodeIterator nodes;
417 nodes = this.Select (expr);
418 while (nodes.MoveNext ()) {
419 if (IsSamePosition (nodes.Current))
423 // ancestors might select this node.
425 XPathNavigator navigator = Clone ();
427 while (navigator.MoveToParent ()) {
428 nodes = navigator.Select (expr);
430 while (nodes.MoveNext ()) {
431 if (IsSamePosition (nodes.Current))
439 public abstract bool MoveTo (XPathNavigator other);
442 public virtual bool MoveToAttribute (string localName, string namespaceURI)
444 if (MoveToFirstAttribute ()) {
446 if (LocalName == localName && NamespaceURI == namespaceURI)
448 } while (MoveToNextAttribute ());
454 public virtual bool MoveToNamespace (string name)
456 if (MoveToFirstNamespace ()) {
458 if (LocalName == name)
460 } while (MoveToNextNamespace ());
467 public virtual bool MoveToFirst ()
469 if (MoveToPrevious ()) {
470 // It would be able to invoke MoveToPrevious() until the end, but this way would be much faster
479 public virtual bool MoveToFirst ()
481 return MoveToFirstImpl ();
484 public virtual void MoveToRoot ()
486 while (MoveToParent ())
490 public abstract bool MoveToAttribute (string localName, string namespaceURI);
492 public abstract bool MoveToNamespace (string name);
494 public abstract bool MoveToFirst ();
496 public abstract void MoveToRoot ();
499 internal bool MoveToFirstImpl ()
502 case XPathNodeType.Attribute:
503 case XPathNodeType.Namespace:
506 if (!MoveToParent ())
508 // Follow these 2 steps so that we can skip
509 // some types of nodes .
515 public abstract bool MoveToFirstAttribute ();
517 public abstract bool MoveToFirstChild ();
519 public bool MoveToFirstNamespace ()
521 return MoveToFirstNamespace (XPathNamespaceScope.All);
524 public abstract bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope);
526 public abstract bool MoveToId (string id);
528 public abstract bool MoveToNext ();
530 public abstract bool MoveToNextAttribute ();
532 public bool MoveToNextNamespace ()
534 return MoveToNextNamespace (XPathNamespaceScope.All);
537 public abstract bool MoveToNextNamespace (XPathNamespaceScope namespaceScope);
539 public abstract bool MoveToParent ();
541 public abstract bool MoveToPrevious ();
543 public virtual XPathNodeIterator Select (string xpath)
545 return Select (Compile (xpath));
548 public virtual XPathNodeIterator Select (XPathExpression expr)
550 return Select (expr, null);
553 internal virtual XPathNodeIterator Select (XPathExpression expr, NSResolver ctx)
555 CompiledExpression cexpr = (CompiledExpression) expr;
557 ctx = cexpr.NamespaceManager;
559 BaseIterator iter = new NullIterator (this, ctx);
560 return cexpr.EvaluateNodeSet (iter);
563 public virtual XPathNodeIterator SelectAncestors (XPathNodeType type, bool matchSelf)
565 Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
566 return SelectTest (new NodeTypeTest (axis, type));
569 public virtual XPathNodeIterator SelectAncestors (string name, string namespaceURI, bool matchSelf)
572 throw new ArgumentNullException ("name");
573 if (namespaceURI == null)
574 throw new ArgumentNullException ("namespaceURI");
576 Axes axis = (matchSelf) ? Axes.AncestorOrSelf : Axes.Ancestor;
577 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
578 return SelectTest (new NodeNameTest (axis, qname, true));
581 public virtual XPathNodeIterator SelectChildren (XPathNodeType type)
583 return SelectTest (new NodeTypeTest (Axes.Child, type));
586 public virtual XPathNodeIterator SelectChildren (string name, string namespaceURI)
589 throw new ArgumentNullException ("name");
590 if (namespaceURI == null)
591 throw new ArgumentNullException ("namespaceURI");
593 Axes axis = Axes.Child;
594 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
595 return SelectTest (new NodeNameTest (axis, qname, true));
598 public virtual XPathNodeIterator SelectDescendants (XPathNodeType type, bool matchSelf)
600 Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
601 return SelectTest (new NodeTypeTest (axis, type));
604 public virtual XPathNodeIterator SelectDescendants (string name, string namespaceURI, bool matchSelf)
607 throw new ArgumentNullException ("name");
608 if (namespaceURI == null)
609 throw new ArgumentNullException ("namespaceURI");
612 Axes axis = (matchSelf) ? Axes.DescendantOrSelf : Axes.Descendant;
613 XmlQualifiedName qname = new XmlQualifiedName (name, namespaceURI);
614 return SelectTest (new NodeNameTest (axis, qname, true));
617 internal XPathNodeIterator SelectTest (NodeTest test)
619 return test.EvaluateNodeSet (new NullIterator (this));
622 public override string ToString ()
631 public virtual bool CheckValidity (XmlSchemaSet schemas, ValidationEventHandler handler)
633 XmlReaderSettings settings = new XmlReaderSettings ();
634 settings.NameTable = NameTable;
635 settings.SetSchemas (schemas);
636 settings.ValidationEventHandler += handler;
637 settings.ValidationType = ValidationType.Schema;
639 XmlReader r = XmlReader.Create (
640 ReadSubtree (), settings);
643 } catch (XmlSchemaValidationException) {
649 public virtual XPathNavigator CreateNavigator ()
654 public virtual object Evaluate (string xpath, IXmlNamespaceResolver nsResolver)
656 return Evaluate (Compile (xpath), null, nsResolver);
659 public virtual IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
661 IDictionary<string, string> table = new Dictionary<string, string> ();
662 XPathNamespaceScope xpscope =
663 scope == XmlNamespaceScope.Local ?
664 XPathNamespaceScope.Local :
665 scope == XmlNamespaceScope.ExcludeXml ?
666 XPathNamespaceScope.ExcludeXml :
667 XPathNamespaceScope.All;
668 XPathNavigator nav = Clone ();
669 if (nav.NodeType != XPathNodeType.Element)
671 if (!nav.MoveToFirstNamespace (xpscope))
674 table.Add (nav.Name, nav.Value);
675 } while (nav.MoveToNextNamespace (xpscope));
679 public virtual string LookupNamespace (string prefix)
681 XPathNavigator nav = Clone ();
682 if (nav.NodeType != XPathNodeType.Element)
684 if (nav.MoveToNamespace (prefix))
689 public virtual string LookupPrefix (string namespaceUri)
691 XPathNavigator nav = Clone ();
692 if (nav.NodeType != XPathNodeType.Element)
694 if (!nav.MoveToFirstNamespace ())
697 if (nav.Value == namespaceUri)
699 } while (nav.MoveToNextNamespace ());
703 private bool MoveTo (XPathNodeIterator iter)
705 if (iter.MoveNext ()) {
706 MoveTo (iter.Current);
713 public virtual bool MoveToChild (XPathNodeType type)
715 return MoveTo (SelectChildren (type));
718 public virtual bool MoveToChild (string localName, string namespaceURI)
720 return MoveTo (SelectChildren (localName, namespaceURI));
723 public virtual bool MoveToNext (string localName, string namespaceURI)
725 XPathNavigator nav = Clone ();
726 while (nav.MoveToNext ()) {
727 if (nav.LocalName == localName &&
728 nav.NamespaceURI == namespaceURI) {
736 public virtual bool MoveToNext (XPathNodeType type)
738 XPathNavigator nav = Clone ();
739 while (nav.MoveToNext ()) {
740 if (type == XPathNodeType.All || nav.NodeType == type) {
748 public virtual bool MoveToFollowing (string localName,
751 return MoveToFollowing (localName, namespaceURI, null);
754 public virtual bool MoveToFollowing (string localName,
755 string namespaceURI, XPathNavigator end)
757 if (localName == null)
758 throw new ArgumentNullException ("localName");
759 if (namespaceURI == null)
760 throw new ArgumentNullException ("namespaceURI");
761 localName = NameTable.Get (localName);
762 if (localName == null)
764 namespaceURI = NameTable.Get (namespaceURI);
765 if (namespaceURI == null)
768 XPathNavigator nav = Clone ();
769 switch (nav.NodeType) {
770 case XPathNodeType.Attribute:
771 case XPathNodeType.Namespace:
776 if (!nav.MoveToFirstChild ()) {
778 if (!nav.MoveToNext ()) {
779 if (!nav.MoveToParent ())
786 if (end != null && end.IsSamePosition (nav))
788 if (object.ReferenceEquals (localName, nav.LocalName) &&
789 object.ReferenceEquals (namespaceURI, nav.NamespaceURI)) {
796 public virtual bool MoveToFollowing (XPathNodeType type)
798 return MoveToFollowing (type, null);
801 public virtual bool MoveToFollowing (XPathNodeType type,
804 if (type == XPathNodeType.Root)
805 return false; // will never match
806 XPathNavigator nav = Clone ();
807 switch (nav.NodeType) {
808 case XPathNodeType.Attribute:
809 case XPathNodeType.Namespace:
814 if (!nav.MoveToFirstChild ()) {
816 if (!nav.MoveToNext ()) {
817 if (!nav.MoveToParent ())
824 if (end != null && end.IsSamePosition (nav))
826 if (type == XPathNodeType.All || nav.NodeType == type) {
833 public virtual XmlReader ReadSubtree ()
836 case XPathNodeType.Element:
837 case XPathNodeType.Root:
838 return new XPathNavigatorReader (this);
840 throw new InvalidOperationException (String.Format ("NodeType {0} is not supported to read as a subtree of an XPathNavigator.", NodeType));
844 public virtual XPathNodeIterator Select (string xpath, IXmlNamespaceResolver nsResolver)
846 return Select (Compile (xpath), nsResolver);
849 public virtual XPathNavigator SelectSingleNode (string xpath)
851 return SelectSingleNode (xpath, null);
854 public virtual XPathNavigator SelectSingleNode (string xpath, IXmlNamespaceResolver nsResolver)
856 XPathExpression expr = Compile (xpath);
857 expr.SetContext (nsResolver);
858 return SelectSingleNode (expr);
861 public virtual XPathNavigator SelectSingleNode (XPathExpression expression)
863 XPathNodeIterator iter = Select (expression);
864 if (iter.MoveNext ())
870 // it is not very effective code but should just work
871 public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
873 return new XmlAtomicValue (Value, XmlSchemaSimpleType.XsString).ValueAs (type, nsResolver);
876 public virtual void WriteSubtree (XmlWriter writer)
878 writer.WriteNode (this, false);
881 static readonly char [] escape_text_chars =
882 new char [] {'&', '<', '>'};
883 static readonly char [] escape_attr_chars =
884 new char [] {'"', '&', '<', '>', '\r', '\n'};
886 static string EscapeString (string value, bool attr)
888 StringBuilder sb = null;
889 char [] escape = attr ? escape_attr_chars : escape_text_chars;
890 if (value.IndexOfAny (escape) < 0)
892 sb = new StringBuilder (value, value.Length + 10);
894 sb.Replace ("\"", """);
895 sb.Replace ("<", "<");
896 sb.Replace (">", ">");
898 sb.Replace ("\r\n", " ");
899 sb.Replace ("\r", " ");
900 sb.Replace ("\n", " ");
902 return sb.ToString ();
905 public virtual string InnerXml {
908 case XPathNodeType.Element:
909 case XPathNodeType.Root:
911 case XPathNodeType.Attribute:
912 case XPathNodeType.Namespace:
913 return EscapeString (Value, true);
914 case XPathNodeType.Text:
915 case XPathNodeType.Whitespace:
916 case XPathNodeType.SignificantWhitespace:
918 case XPathNodeType.ProcessingInstruction:
919 case XPathNodeType.Comment:
923 XmlReader r = ReadSubtree ();
925 // skip the element itself (or will reach to
926 // EOF if other than element) unless writing
929 if (NodeType != XPathNodeType.Root)
931 StringWriter sw = new StringWriter ();
932 XmlWriterSettings s = new XmlWriterSettings ();
933 s.ConformanceLevel = ConformanceLevel.Fragment;
934 s.OmitXmlDeclaration = true;
935 XmlWriter xtw = XmlWriter.Create (sw, s);
936 while (!r.EOF && r.Depth > depth)
937 xtw.WriteNode (r, false);
938 return sw.ToString ();
942 if (NodeType == XPathNodeType.Attribute) {
950 public override sealed bool IsNode {
954 public virtual string OuterXml {
957 case XPathNodeType.Attribute:
958 return String.Concat (
960 Prefix.Length > 0 ? ":" : String.Empty,
963 EscapeString (Value, true),
966 case XPathNodeType.Namespace:
967 return String.Concat (
969 LocalName.Length > 0 ? ":" : String.Empty,
972 EscapeString (Value, true),
975 case XPathNodeType.Text:
976 return EscapeString (Value, false);
977 case XPathNodeType.Whitespace:
978 case XPathNodeType.SignificantWhitespace:
982 XmlWriterSettings s = new XmlWriterSettings ();
984 s.OmitXmlDeclaration = true;
985 s.ConformanceLevel = ConformanceLevel.Fragment;
986 StringBuilder sb = new StringBuilder ();
987 using (XmlWriter w = XmlWriter.Create (sb, s)) {
990 return sb.ToString ();
994 case XPathNodeType.Root:
995 case XPathNodeType.Attribute:
996 case XPathNodeType.Namespace:
997 throw new XmlException ("Setting OuterXml Root, Attribute and Namespace is not supported.");
1001 AppendChild (value);
1002 MoveToFirstChild ();
1006 public virtual IXmlSchemaInfo SchemaInfo {
1012 public override object TypedValue {
1015 case XPathNodeType.Element:
1016 case XPathNodeType.Attribute:
1017 if (XmlType == null)
1019 XmlSchemaDatatype dt = XmlType.Datatype;
1022 return dt.ParseValue (Value, NameTable, this as IXmlNamespaceResolver);
1028 public virtual object UnderlyingObject {
1029 get { return null; }
1032 public override bool ValueAsBoolean {
1033 get { return XQueryConvert.StringToBoolean (Value); }
1036 public override DateTime ValueAsDateTime {
1037 get { return XmlConvert.ToDateTime (Value); }
1040 public override double ValueAsDouble {
1041 get { return XQueryConvert.StringToDouble (Value); }
1044 public override int ValueAsInt {
1045 get { return XQueryConvert.StringToInt (Value); }
1048 public override long ValueAsLong {
1049 get { return XQueryConvert.StringToInteger (Value); }
1052 public override Type ValueType {
1054 return SchemaInfo != null &&
1055 SchemaInfo.SchemaType != null &&
1056 SchemaInfo.SchemaType.Datatype != null ?
1057 SchemaInfo.SchemaType.Datatype.ValueType
1062 public override XmlSchemaType XmlType {
1064 if (SchemaInfo != null)
1065 return SchemaInfo.SchemaType;
1070 private XmlReader CreateFragmentReader (string fragment)
1072 XmlReaderSettings settings = new XmlReaderSettings ();
1073 settings.ConformanceLevel = ConformanceLevel.Fragment;
1074 XmlNamespaceManager nsmgr = new XmlNamespaceManager (NameTable);
1075 foreach (KeyValuePair<string,string> nss in GetNamespacesInScope (XmlNamespaceScope.All))
1076 nsmgr.AddNamespace (nss.Key, nss.Value);
1077 return XmlReader.Create (
1078 new StringReader (fragment),
1080 new XmlParserContext (NameTable, nsmgr, null, XmlSpace.None));
1083 // must override it.
1084 public virtual XmlWriter AppendChild ()
1086 throw new NotSupportedException ();
1089 public virtual void AppendChild (
1090 string xmlFragments)
1092 AppendChild (CreateFragmentReader (xmlFragments));
1095 public virtual void AppendChild (
1098 XmlWriter w = AppendChild ();
1100 w.WriteNode (reader, false);
1104 public virtual void AppendChild (
1107 AppendChild (new XPathNavigatorReader (nav));
1110 public virtual void AppendChildElement (string prefix, string name, string ns, string value)
1112 XmlWriter xw = AppendChild ();
1113 xw.WriteStartElement (prefix, name, ns);
1114 xw.WriteString (value);
1115 xw.WriteEndElement ();
1119 public virtual void CreateAttribute (string prefix, string localName, string namespaceURI, string value)
1121 using (XmlWriter w = CreateAttributes ()) {
1122 w.WriteAttributeString (prefix, localName, namespaceURI, value);
1126 // must override it.
1127 public virtual XmlWriter CreateAttributes ()
1129 throw new NotSupportedException ();
1132 // must override it.
1133 public virtual void DeleteSelf ()
1135 throw new NotSupportedException ();
1138 // must override it.
1139 public virtual void DeleteRange (XPathNavigator nav)
1141 throw new NotSupportedException ();
1144 public virtual XmlWriter ReplaceRange (XPathNavigator nav)
1146 throw new NotSupportedException ();
1149 public virtual XmlWriter InsertAfter ()
1152 case XPathNodeType.Root:
1153 case XPathNodeType.Attribute:
1154 case XPathNodeType.Namespace:
1155 throw new InvalidOperationException (String.Format ("Insertion after {0} is not allowed.", NodeType));
1157 XPathNavigator nav = Clone ();
1158 if (nav.MoveToNext ())
1159 return nav.InsertBefore ();
1160 else if (nav.MoveToParent ())
1161 return nav.AppendChild ();
1163 throw new InvalidOperationException ("Could not move to parent to insert sibling node");
1166 public virtual void InsertAfter (string xmlFragments)
1168 InsertAfter (CreateFragmentReader (xmlFragments));
1171 public virtual void InsertAfter (XmlReader reader)
1173 using (XmlWriter w = InsertAfter ()) {
1174 w.WriteNode (reader, false);
1178 public virtual void InsertAfter (XPathNavigator nav)
1180 InsertAfter (new XPathNavigatorReader (nav));
1183 public virtual XmlWriter InsertBefore ()
1185 throw new NotSupportedException ();
1188 public virtual void InsertBefore (string xmlFragments)
1190 InsertBefore (CreateFragmentReader (xmlFragments));
1193 public virtual void InsertBefore (XmlReader reader)
1195 using (XmlWriter w = InsertBefore ()) {
1196 w.WriteNode (reader, false);
1200 public virtual void InsertBefore (XPathNavigator nav)
1202 InsertBefore (new XPathNavigatorReader (nav));
1205 public virtual void InsertElementAfter (string prefix,
1206 string localName, string namespaceURI, string value)
1208 using (XmlWriter w = InsertAfter ()) {
1209 w.WriteElementString (prefix, localName, namespaceURI, value);
1213 public virtual void InsertElementBefore (string prefix,
1214 string localName, string namespaceURI, string value)
1216 using (XmlWriter w = InsertBefore ()) {
1217 w.WriteElementString (prefix, localName, namespaceURI, value);
1221 public virtual XmlWriter PrependChild ()
1223 XPathNavigator nav = Clone ();
1224 if (nav.MoveToFirstChild ())
1225 return nav.InsertBefore ();
1227 return AppendChild ();
1230 public virtual void PrependChild (string xmlFragments)
1232 PrependChild (CreateFragmentReader (xmlFragments));
1235 public virtual void PrependChild (XmlReader reader)
1237 using (XmlWriter w = PrependChild ()) {
1238 w.WriteNode (reader, false);
1242 public virtual void PrependChild (XPathNavigator nav)
1244 PrependChild (new XPathNavigatorReader (nav));
1247 public virtual void PrependChildElement (string prefix,
1248 string localName, string namespaceURI, string value)
1250 using (XmlWriter w = PrependChild ()) {
1251 w.WriteElementString (prefix, localName, namespaceURI, value);
1255 public virtual void ReplaceSelf (string xmlFragment)
1257 ReplaceSelf (CreateFragmentReader (xmlFragment));
1260 // must override it.
1261 public virtual void ReplaceSelf (XmlReader reader)
1263 throw new NotSupportedException ();
1266 public virtual void ReplaceSelf (XPathNavigator navigator)
1268 ReplaceSelf (new XPathNavigatorReader (navigator));
1271 // Dunno the exact purpose, but maybe internal editor use
1273 public virtual void SetTypedValue (object value)
1275 throw new NotSupportedException ();
1278 public virtual void SetValue (string value)
1280 throw new NotSupportedException ();
1283 private void DeleteChildren ()
1286 case XPathNodeType.Namespace:
1287 throw new InvalidOperationException ("Removing namespace node content is not supported.");
1288 case XPathNodeType.Attribute:
1290 case XPathNodeType.Text:
1291 case XPathNodeType.SignificantWhitespace:
1292 case XPathNodeType.Whitespace:
1293 case XPathNodeType.ProcessingInstruction:
1294 case XPathNodeType.Comment:
1300 XPathNavigator nav = Clone ();
1301 nav.MoveToFirstChild ();
1302 while (!nav.IsSamePosition (this))