5 // Jason Diamond (jason@injektilo.org)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
9 // (C) 2001, 2002 Jason Diamond http://injektilo.org/
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) 2003 Atsushi Enomoto
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Diagnostics;
39 using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
40 using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
41 using Mono.Xml.Schema; // only required for NET_2_0
43 using Mono.Xml; // only required for NET_2_0
48 public abstract class XmlReader : IDisposable
50 public abstract class XmlReader
53 private StringBuilder readStringBuffer;
54 private XmlReaderBinarySupport binary;
56 private XmlReaderSettings settings;
61 protected XmlReader ()
69 public abstract int AttributeCount { get; }
71 public abstract string BaseURI { get; }
73 internal XmlReaderBinarySupport Binary {
74 get { return binary; }
77 internal XmlReaderBinarySupport.CharGetter BinaryCharGetter {
78 get { return binary != null ? binary.Getter : null; }
81 binary = new XmlReaderBinarySupport (this);
82 binary.Getter = value;
87 // To enable it internally in sys.xml, just insert these
88 // two lines into Read():
91 // if (Binary != null)
95 public virtual bool CanReadBinaryContent {
99 public virtual bool CanReadValueChunk {
100 get { return false; }
103 internal virtual bool CanReadBinaryContent {
104 get { return false; }
107 internal virtual bool CanReadValueChunk {
108 get { return false; }
112 public virtual bool CanResolveEntity
114 get { return false; }
117 public abstract int Depth { get; }
119 public abstract bool EOF { get; }
121 public virtual bool HasAttributes
123 get { return AttributeCount > 0; }
127 public abstract bool HasValue { get; }
130 public abstract bool IsEmptyElement { get; }
133 public virtual bool IsDefault {
134 get { return false; }
137 public virtual string this [int i] {
138 get { return GetAttribute (i); }
141 public virtual string this [string name] {
142 get { return GetAttribute (name); }
145 public virtual string this [string name, string namespaceURI] {
146 get { return GetAttribute (name, namespaceURI); }
149 public abstract bool IsDefault { get; }
151 public abstract string this [int i] { get; }
153 public abstract string this [string name] { get; }
155 public abstract string this [string localName, string namespaceName] { get; }
158 public abstract string LocalName { get; }
161 public virtual string Name {
163 return Prefix.Length > 0 ?
164 String.Concat (Prefix, ":", LocalName) :
169 public abstract string Name { get; }
172 public abstract string NamespaceURI { get; }
174 public abstract XmlNameTable NameTable { get; }
176 public abstract XmlNodeType NodeType { get; }
178 public abstract string Prefix { get; }
181 public virtual char QuoteChar {
185 public abstract char QuoteChar { get; }
188 public abstract ReadState ReadState { get; }
192 public virtual IXmlSchemaInfo SchemaInfo {
197 public virtual XmlReaderSettings Settings {
198 get { return settings; }
202 public abstract string Value { get; }
205 public virtual string XmlLang {
206 get { return String.Empty; }
209 public virtual XmlSpace XmlSpace {
210 get { return XmlSpace.None; }
213 public abstract string XmlLang { get; }
215 public abstract XmlSpace XmlSpace { get; }
222 public abstract void Close ();
225 private static XmlNameTable PopulateNameTable (
226 XmlReaderSettings settings)
228 XmlNameTable nameTable = settings.NameTable;
229 if (nameTable == null)
230 nameTable = new NameTable ();
234 private static XmlParserContext PopulateParserContext (
235 XmlReaderSettings settings, string baseUri)
237 XmlNameTable nt = PopulateNameTable (settings);
238 return new XmlParserContext (nt,
239 new XmlNamespaceManager (nt),
250 private static XmlNodeType GetNodeType (
251 XmlReaderSettings settings)
253 ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
255 level == ConformanceLevel.Fragment ?
256 XmlNodeType.Element :
257 XmlNodeType.Document;
260 public static XmlReader Create (Stream stream)
262 return Create (stream, null);
265 public static XmlReader Create (string url)
267 return Create (url, null);
270 public static XmlReader Create (TextReader reader)
272 return Create (reader, null);
275 public static XmlReader Create (string url, XmlReaderSettings settings)
277 return Create (url, settings, null);
280 public static XmlReader Create (Stream stream, XmlReaderSettings settings)
282 return Create (stream, settings, String.Empty);
285 public static XmlReader Create (TextReader reader, XmlReaderSettings settings)
287 return Create (reader, settings, String.Empty);
290 static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
293 return new XmlReaderSettings ();
298 public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
300 settings = PopulateSettings (settings);
301 return Create (stream, settings,
302 PopulateParserContext (settings, baseUri));
305 public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
307 settings = PopulateSettings (settings);
308 return Create (reader, settings,
309 PopulateParserContext (settings, baseUri));
312 public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
314 settings = PopulateSettings (settings);
315 XmlReader r = CreateFilteredXmlReader (reader, settings);
316 r.settings = settings;
320 public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
322 settings = PopulateSettings (settings);
323 bool closeInputBak = settings.CloseInput;
325 settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
327 context = PopulateParserContext (settings, url);
328 XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
329 XmlReader ret = CreateCustomizedTextReader (xtr, settings);
332 settings.CloseInput = closeInputBak;
336 public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
338 settings = PopulateSettings (settings);
340 context = PopulateParserContext (settings, String.Empty);
341 return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
344 public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
346 settings = PopulateSettings (settings);
348 context = PopulateParserContext (settings, String.Empty);
349 return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
352 private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
354 reader.XmlResolver = settings.XmlResolver;
355 // Normalization is set true by default.
356 reader.Normalization = true;
357 reader.EntityHandling = EntityHandling.ExpandEntities;
359 if (settings.ProhibitDtd)
360 reader.ProhibitDtd = true;
362 if (!settings.CheckCharacters)
363 reader.CharacterChecking = false;
365 // I guess it might be changed in 2.0 RTM to set true
366 // as default, or just disappear. It goes against
367 // XmlTextReader's default usage and users will have
368 // to close input manually (that's annoying). Moreover,
369 // MS XmlTextReader consumes text input more than
370 // actually read and users can acquire those extra
371 // consumption by GetRemainder() that returns different
373 reader.CloseInput = settings.CloseInput;
375 // I would like to support it in detail later;
376 // MSDN description looks source of confusion. We don't
377 // need examples, but precise list of how it works.
378 reader.Conformance = settings.ConformanceLevel;
380 reader.AdjustLineInfoOffset (settings.LineNumberOffset,
381 settings.LinePositionOffset);
383 if (settings.NameTable != null)
384 reader.SetNameTable (settings.NameTable);
386 XmlReader r = CreateFilteredXmlReader (reader, settings);
387 r.settings = settings;
391 private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
393 ConformanceLevel conf = ConformanceLevel.Auto;
394 if (reader is XmlTextReader)
395 conf = ((XmlTextReader) reader).Conformance;
396 else if (reader.Settings != null)
397 conf = reader.Settings.ConformanceLevel;
399 conf = settings.ConformanceLevel;
400 if (settings.ConformanceLevel != ConformanceLevel.Auto &&
401 conf != settings.ConformanceLevel)
402 throw new InvalidOperationException (String.Format ("ConformanceLevel cannot be overwritten by a wrapping XmlReader. The source reader has {0}, while {1} is specified.", conf, settings.ConformanceLevel));
403 settings.ConformanceLevel = conf;
405 reader = CreateValidatingXmlReader (reader, settings);
407 if ( settings.IgnoreComments ||
408 settings.IgnoreProcessingInstructions ||
409 settings.IgnoreWhitespace)
410 return new XmlFilterReader (reader, settings);
412 reader.settings = settings;
417 private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
422 XmlValidatingReader xvr = null;
423 switch (settings.ValidationType) {
424 // Auto and XDR are obsoleted in 2.0 and therefore ignored.
427 case ValidationType.DTD:
428 xvr = new XmlValidatingReader (reader);
429 xvr.XmlResolver = settings.XmlResolver;
430 xvr.ValidationType = ValidationType.DTD;
432 case ValidationType.Schema:
433 return new XmlSchemaValidatingReader (reader, settings);
436 // Actually I don't think they are treated in DTD validation though...
437 if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
438 throw new NotImplementedException ();
439 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
440 // throw new NotImplementedException ();
441 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
442 // throw new NotImplementedException ();
443 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
444 // throw new NotImplementedException ();
446 return xvr != null ? xvr : reader;
450 void IDisposable.Dispose ()
455 protected virtual void Dispose (bool disposing)
457 if (ReadState != ReadState.Closed)
462 public abstract string GetAttribute (int i);
464 public abstract string GetAttribute (string name);
466 public abstract string GetAttribute (
468 string namespaceName);
470 public static bool IsName (string s)
472 return s != null && XmlChar.IsName (s);
475 public static bool IsNameToken (string s)
477 return s != null && XmlChar.IsNmToken (s);
480 public virtual bool IsStartElement ()
482 return (MoveToContent () == XmlNodeType.Element);
485 public virtual bool IsStartElement (string name)
487 if (!IsStartElement ())
490 return (Name == name);
493 public virtual bool IsStartElement (string localName, string namespaceName)
495 if (!IsStartElement ())
498 return (LocalName == localName && NamespaceURI == namespaceName);
501 public abstract string LookupNamespace (string prefix);
504 public virtual void MoveToAttribute (int i)
506 if (i >= AttributeCount)
507 throw new ArgumentOutOfRangeException ();
508 MoveToFirstAttribute ();
509 for (int a = 0; a < i; a++)
510 MoveToNextAttribute ();
513 public abstract void MoveToAttribute (int i);
516 public abstract bool MoveToAttribute (string name);
518 public abstract bool MoveToAttribute (
520 string namespaceName);
522 private bool IsContent (XmlNodeType nodeType)
525 * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
528 case XmlNodeType.Text:
530 case XmlNodeType.CDATA:
532 case XmlNodeType.Element:
534 case XmlNodeType.EndElement:
536 case XmlNodeType.EntityReference:
538 case XmlNodeType.EndEntity:
545 public virtual XmlNodeType MoveToContent ()
547 if (NodeType == XmlNodeType.Attribute)
551 if (IsContent (NodeType))
555 return XmlNodeType.None;
558 public abstract bool MoveToElement ();
560 public abstract bool MoveToFirstAttribute ();
562 public abstract bool MoveToNextAttribute ();
564 public abstract bool Read ();
566 public abstract bool ReadAttributeValue ();
568 public virtual string ReadElementString ()
570 if (MoveToContent () != XmlNodeType.Element) {
571 string error = String.Format ("'{0}' is an invalid node type.",
572 NodeType.ToString ());
573 throw XmlError (error);
576 string result = String.Empty;
577 if (!IsEmptyElement) {
579 result = ReadString ();
580 if (NodeType != XmlNodeType.EndElement) {
581 string error = String.Format ("'{0}' is an invalid node type.",
582 NodeType.ToString ());
583 throw XmlError (error);
591 public virtual string ReadElementString (string name)
593 if (MoveToContent () != XmlNodeType.Element) {
594 string error = String.Format ("'{0}' is an invalid node type.",
595 NodeType.ToString ());
596 throw XmlError (error);
600 string error = String.Format ("The {0} tag from namespace {1} is expected.",
602 throw XmlError (error);
605 string result = String.Empty;
606 if (!IsEmptyElement) {
608 result = ReadString ();
609 if (NodeType != XmlNodeType.EndElement) {
610 string error = String.Format ("'{0}' is an invalid node type.",
611 NodeType.ToString ());
612 throw XmlError (error);
620 public virtual string ReadElementString (string localName, string namespaceName)
622 if (MoveToContent () != XmlNodeType.Element) {
623 string error = String.Format ("'{0}' is an invalid node type.",
624 NodeType.ToString ());
625 throw XmlError (error);
628 if (localName != LocalName || NamespaceURI != namespaceName) {
629 string error = String.Format ("The {0} tag from namespace {1} is expected.",
630 LocalName, NamespaceURI);
631 throw XmlError (error);
634 string result = String.Empty;
635 if (!IsEmptyElement) {
637 result = ReadString ();
638 if (NodeType != XmlNodeType.EndElement) {
639 string error = String.Format ("'{0}' is an invalid node type.",
640 NodeType.ToString ());
641 throw XmlError (error);
649 public virtual void ReadEndElement ()
651 if (MoveToContent () != XmlNodeType.EndElement) {
652 string error = String.Format ("'{0}' is an invalid node type.",
653 NodeType.ToString ());
654 throw XmlError (error);
660 public virtual string ReadInnerXml ()
662 if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
665 if (IsEmptyElement) {
669 StringWriter sw = new StringWriter ();
670 XmlTextWriter xtw = new XmlTextWriter (sw);
671 if (NodeType == XmlNodeType.Element) {
672 int startDepth = Depth;
674 while (startDepth < Depth) {
675 if (ReadState != ReadState.Interactive)
676 throw XmlError ("Unexpected end of the XML reader.");
677 xtw.WriteNode (this, false);
679 // reader is now end element, then proceed once more.
683 xtw.WriteNode (this, false);
685 return sw.ToString ();
688 public virtual string ReadOuterXml ()
690 if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
694 case XmlNodeType.Element:
695 case XmlNodeType.Attribute:
696 StringWriter sw = new StringWriter ();
697 XmlTextWriter xtw = new XmlTextWriter (sw);
698 xtw.WriteNode (this, false);
699 return sw.ToString ();
706 public virtual void ReadStartElement ()
708 if (MoveToContent () != XmlNodeType.Element) {
709 string error = String.Format ("'{0}' is an invalid node type.",
710 NodeType.ToString ());
711 throw XmlError (error);
717 public virtual void ReadStartElement (string name)
719 if (MoveToContent () != XmlNodeType.Element) {
720 string error = String.Format ("'{0}' is an invalid node type.",
721 NodeType.ToString ());
722 throw XmlError (error);
726 string error = String.Format ("The {0} tag from namespace {1} is expected.",
728 throw XmlError (error);
734 public virtual void ReadStartElement (string localName, string namespaceName)
736 if (MoveToContent () != XmlNodeType.Element) {
737 string error = String.Format ("'{0}' is an invalid node type.",
738 NodeType.ToString ());
739 throw XmlError (error);
742 if (localName != LocalName || NamespaceURI != namespaceName) {
743 string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
744 localName, namespaceName,
745 LocalName, NamespaceURI);
746 throw XmlError (error);
752 public virtual string ReadString ()
754 if (readStringBuffer == null)
755 readStringBuffer = new StringBuilder ();
756 readStringBuffer.Length = 0;
763 case XmlNodeType.Element:
769 case XmlNodeType.Text:
770 case XmlNodeType.CDATA:
771 case XmlNodeType.Whitespace:
772 case XmlNodeType.SignificantWhitespace:
773 readStringBuffer.Append (Value);
779 case XmlNodeType.Text:
780 case XmlNodeType.CDATA:
781 case XmlNodeType.Whitespace:
782 case XmlNodeType.SignificantWhitespace:
785 case XmlNodeType.Text:
786 case XmlNodeType.CDATA:
787 case XmlNodeType.Whitespace:
788 case XmlNodeType.SignificantWhitespace:
789 readStringBuffer.Append (Value);
797 string ret = readStringBuffer.ToString ();
798 readStringBuffer.Length = 0;
803 public virtual Type ValueType {
804 get { return typeof (string); }
807 public virtual bool ReadToDescendant (string name)
809 if (ReadState == ReadState.Initial) {
811 if (IsStartElement (name))
814 if (NodeType != XmlNodeType.Element || IsEmptyElement)
817 for (Read (); depth < Depth; Read ())
818 if (NodeType == XmlNodeType.Element && name == Name)
823 public virtual bool ReadToDescendant (string localName, string namespaceURI)
825 if (ReadState == ReadState.Initial) {
827 if (IsStartElement (localName, namespaceURI))
830 if (NodeType != XmlNodeType.Element || IsEmptyElement)
833 for (Read (); depth < Depth; Read ())
834 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
839 public virtual bool ReadToFollowing (string name)
842 if (NodeType == XmlNodeType.Element && name == Name)
847 public virtual bool ReadToFollowing (string localName, string namespaceURI)
850 if (NodeType == XmlNodeType.Element && localName == Name && namespaceURI == NamespaceURI)
855 public virtual bool ReadToNextSibling (string name)
857 if (ReadState != ReadState.Interactive)
861 for (; !EOF && depth <= Depth; Skip ())
862 if (NodeType == XmlNodeType.Element && name == Name)
867 public virtual bool ReadToNextSibling (string localName, string namespaceURI)
869 if (ReadState != ReadState.Interactive)
873 for (; !EOF && depth <= Depth; Skip ())
874 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
879 public virtual XmlReader ReadSubtree ()
881 if (NodeType != XmlNodeType.Element)
882 throw new InvalidOperationException (String.Format ("ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is {0}. {1}", NodeType, GetLocation ()));
883 return new SubtreeXmlReader (this);
886 private string ReadContentString ()
888 if (NodeType == XmlNodeType.Attribute)
890 return ReadContentString (true);
893 private string ReadContentString (bool isText)
897 case XmlNodeType.Text:
898 case XmlNodeType.SignificantWhitespace:
899 case XmlNodeType.Whitespace:
900 case XmlNodeType.CDATA:
902 case XmlNodeType.Element:
903 throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
909 string value = String.Empty;
912 case XmlNodeType.Element:
915 throw XmlError ("Child element is not expected in this operation.");
916 case XmlNodeType.EndElement:
918 case XmlNodeType.Text:
919 case XmlNodeType.CDATA:
920 case XmlNodeType.SignificantWhitespace:
921 case XmlNodeType.Whitespace:
926 throw XmlError ("Unexpected end of document.");
929 string GetLocation ()
931 IXmlLineInfo li = this as IXmlLineInfo;
932 return li != null && li.HasLineInfo () ?
933 String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
937 public virtual object ReadElementContentAsObject ()
939 return ReadElementContentAs (ValueType, null);
943 public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
945 return ReadElementContentAs (ValueType, null, localName, namespaceURI);
949 public virtual object ReadContentAsObject ()
951 return ReadContentAs (ValueType, null);
954 public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver)
956 bool isEmpty = IsEmptyElement;
958 object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), type, resolver);
964 public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver, string localName, string namespaceURI)
966 ReadStartElement (localName, namespaceURI);
967 object obj = ReadContentAs (type, resolver);
972 public virtual object ReadContentAs (Type type, IXmlNamespaceResolver resolver)
974 return ValueAs (ReadContentString (), type, resolver);
977 private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver)
980 if (type == typeof (object))
982 if (type == typeof (XmlQualifiedName)) {
983 if (resolver != null)
984 return XmlQualifiedName.Parse (text, resolver);
986 return XmlQualifiedName.Parse (text, this);
989 switch (Type.GetTypeCode (type)) {
990 case TypeCode.Boolean:
991 return XQueryConvert.StringToBoolean (text);
992 case TypeCode.DateTime:
993 return XQueryConvert.StringToDateTime (text);
994 case TypeCode.Decimal:
995 return XQueryConvert.StringToDecimal (text);
996 case TypeCode.Double:
997 return XQueryConvert.StringToDouble (text);
999 return XQueryConvert.StringToInt (text);
1000 case TypeCode.Int64:
1001 return XQueryConvert.StringToInteger (text);
1002 case TypeCode.Single:
1003 return XQueryConvert.StringToFloat (text);
1004 case TypeCode.String:
1007 } catch (Exception ex) {
1008 throw XmlError (String.Format ("Current text value '{0}' is not acceptable for specified type '{1}'. {2}", text, type, ex != null ? ex.Message : String.Empty), ex);
1010 throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
1013 public virtual bool ReadElementContentAsBoolean ()
1016 return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
1017 } catch (FormatException ex) {
1018 throw XmlError ("Typed value is invalid.", ex);
1022 public virtual DateTime ReadElementContentAsDateTime ()
1025 return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
1026 } catch (FormatException ex) {
1027 throw XmlError ("Typed value is invalid.", ex);
1031 public virtual decimal ReadElementContentAsDecimal ()
1034 return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
1035 } catch (FormatException ex) {
1036 throw XmlError ("Typed value is invalid.", ex);
1040 public virtual double ReadElementContentAsDouble ()
1043 return XQueryConvert.StringToDouble (ReadElementContentAsString ());
1044 } catch (FormatException ex) {
1045 throw XmlError ("Typed value is invalid.", ex);
1049 public virtual float ReadElementContentAsFloat ()
1052 return XQueryConvert.StringToFloat (ReadElementContentAsString ());
1053 } catch (FormatException ex) {
1054 throw XmlError ("Typed value is invalid.", ex);
1058 public virtual int ReadElementContentAsInt ()
1061 return XQueryConvert.StringToInt (ReadElementContentAsString ());
1062 } catch (FormatException ex) {
1063 throw XmlError ("Typed value is invalid.", ex);
1067 public virtual long ReadElementContentAsLong ()
1070 return XQueryConvert.StringToInteger (ReadElementContentAsString ());
1071 } catch (FormatException ex) {
1072 throw XmlError ("Typed value is invalid.", ex);
1076 public virtual string ReadElementContentAsString ()
1078 bool isEmpty = IsEmptyElement;
1079 // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1080 if (NodeType != XmlNodeType.Element)
1081 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1082 ReadStartElement ();
1084 return String.Empty;
1085 string s = ReadContentString (false);
1090 public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
1093 return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
1094 } catch (FormatException ex) {
1095 throw XmlError ("Typed value is invalid.", ex);
1099 public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
1102 return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
1103 } catch (FormatException ex) {
1104 throw XmlError ("Typed value is invalid.", ex);
1108 public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
1111 return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
1112 } catch (FormatException ex) {
1113 throw XmlError ("Typed value is invalid.", ex);
1117 public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
1120 return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
1121 } catch (FormatException ex) {
1122 throw XmlError ("Typed value is invalid.", ex);
1126 public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
1129 return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
1130 } catch (FormatException ex) {
1131 throw XmlError ("Typed value is invalid.", ex);
1135 public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
1138 return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
1139 } catch (FormatException ex) {
1140 throw XmlError ("Typed value is invalid.", ex);
1144 public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
1147 return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
1148 } catch (FormatException ex) {
1149 throw XmlError ("Typed value is invalid.", ex);
1153 public virtual string ReadElementContentAsString (string localName, string namespaceURI)
1155 bool isEmpty = IsEmptyElement;
1156 // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1157 if (NodeType != XmlNodeType.Element)
1158 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1159 ReadStartElement (localName, namespaceURI);
1161 return String.Empty;
1162 string s = ReadContentString (false);
1167 public virtual bool ReadContentAsBoolean ()
1170 return XQueryConvert.StringToBoolean (ReadContentString ());
1171 } catch (FormatException ex) {
1172 throw XmlError ("Typed value is invalid.", ex);
1176 public virtual DateTime ReadContentAsDateTime ()
1179 return XQueryConvert.StringToDateTime (ReadContentString ());
1180 } catch (FormatException ex) {
1181 throw XmlError ("Typed value is invalid.", ex);
1185 public virtual decimal ReadContentAsDecimal ()
1188 return XQueryConvert.StringToDecimal (ReadContentString ());
1189 } catch (FormatException ex) {
1190 throw XmlError ("Typed value is invalid.", ex);
1194 public virtual double ReadContentAsDouble ()
1197 return XQueryConvert.StringToDouble (ReadContentString ());
1198 } catch (FormatException ex) {
1199 throw XmlError ("Typed value is invalid.", ex);
1203 public virtual float ReadContentAsFloat ()
1206 return XQueryConvert.StringToFloat (ReadContentString ());
1207 } catch (FormatException ex) {
1208 throw XmlError ("Typed value is invalid.", ex);
1212 public virtual int ReadContentAsInt ()
1215 return XQueryConvert.StringToInt (ReadContentString ());
1216 } catch (FormatException ex) {
1217 throw XmlError ("Typed value is invalid.", ex);
1221 public virtual long ReadContentAsLong ()
1224 return XQueryConvert.StringToInteger (ReadContentString ());
1225 } catch (FormatException ex) {
1226 throw XmlError ("Typed value is invalid.", ex);
1230 public virtual string ReadContentAsString ()
1232 return ReadContentString ();
1235 public virtual int ReadContentAsBase64 (
1236 byte [] buffer, int offset, int length)
1239 return binary.ReadContentAsBase64 (
1240 buffer, offset, length);
1243 public virtual int ReadContentAsBinHex (
1244 byte [] buffer, int offset, int length)
1247 return binary.ReadContentAsBinHex (
1248 buffer, offset, length);
1251 public virtual int ReadElementContentAsBase64 (
1252 byte [] buffer, int offset, int length)
1255 return binary.ReadElementContentAsBase64 (
1256 buffer, offset, length);
1259 public virtual int ReadElementContentAsBinHex (
1260 byte [] buffer, int offset, int length)
1263 return binary.ReadElementContentAsBinHex (
1264 buffer, offset, length);
1267 private void CheckSupport ()
1269 // Default implementation expects both.
1270 if (!CanReadBinaryContent || !CanReadValueChunk)
1271 throw new NotSupportedException ();
1273 binary = new XmlReaderBinarySupport (this);
1279 public virtual int ReadValueChunk (
1280 char [] buffer, int offset, int length)
1282 internal virtual int ReadValueChunk (
1283 char [] buffer, int offset, int length)
1286 if (!CanReadValueChunk)
1287 throw new NotSupportedException ();
1289 binary = new XmlReaderBinarySupport (this);
1290 return binary.ReadValueChunk (buffer, offset, length);
1293 public abstract void ResolveEntity ();
1295 public virtual void Skip ()
1297 if (ReadState != ReadState.Interactive)
1301 if (NodeType != XmlNodeType.Element || IsEmptyElement) {
1307 while (Read () && depth < Depth)
1309 if (NodeType == XmlNodeType.EndElement)
1313 private XmlException XmlError (string message)
1315 return new XmlException (this as IXmlLineInfo, BaseURI, message);
1318 private XmlException XmlError (string message, Exception innerException)
1320 return new XmlException (this as IXmlLineInfo, BaseURI, message);