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; }
126 public abstract bool HasValue { get; }
128 public abstract bool IsEmptyElement { get; }
131 public virtual bool IsDefault {
132 get { return false; }
135 public virtual string this [int i] {
136 get { return GetAttribute (i); }
139 public virtual string this [string name] {
140 get { return GetAttribute (name); }
143 public virtual string this [string name, string namespaceURI] {
144 get { return GetAttribute (name, namespaceURI); }
147 public abstract bool IsDefault { get; }
149 public abstract string this [int i] { get; }
151 public abstract string this [string name] { get; }
153 public abstract string this [string localName, string namespaceName] { get; }
156 public abstract string LocalName { get; }
159 public virtual string Name {
161 return Prefix.Length > 0 ?
162 String.Concat (Prefix, ":", LocalName) :
167 public abstract string Name { get; }
170 public abstract string NamespaceURI { get; }
172 public abstract XmlNameTable NameTable { get; }
174 public abstract XmlNodeType NodeType { get; }
176 public abstract string Prefix { get; }
179 public virtual char QuoteChar {
183 public abstract char QuoteChar { get; }
186 public abstract ReadState ReadState { get; }
190 public virtual IXmlSchemaInfo SchemaInfo {
195 public virtual XmlReaderSettings Settings {
196 get { return settings; }
200 public abstract string Value { get; }
203 public virtual string XmlLang {
204 get { return String.Empty; }
207 public virtual XmlSpace XmlSpace {
208 get { return XmlSpace.None; }
211 public abstract string XmlLang { get; }
213 public abstract XmlSpace XmlSpace { get; }
220 public abstract void Close ();
223 private static XmlNameTable PopulateNameTable (
224 XmlReaderSettings settings)
226 XmlNameTable nameTable = settings.NameTable;
227 if (nameTable == null)
228 nameTable = new NameTable ();
232 private static XmlParserContext PopulateParserContext (
233 XmlReaderSettings settings, string baseUri)
235 XmlNameTable nt = PopulateNameTable (settings);
236 return new XmlParserContext (nt,
237 new XmlNamespaceManager (nt),
248 private static XmlNodeType GetNodeType (
249 XmlReaderSettings settings)
251 ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
253 level == ConformanceLevel.Fragment ?
254 XmlNodeType.Element :
255 XmlNodeType.Document;
258 public static XmlReader Create (Stream stream)
260 return Create (stream, null);
263 public static XmlReader Create (string url)
265 return Create (url, null);
268 public static XmlReader Create (TextReader reader)
270 return Create (reader, null);
273 public static XmlReader Create (string url, XmlReaderSettings settings)
275 return Create (url, settings, null);
278 public static XmlReader Create (Stream stream, XmlReaderSettings settings)
280 return Create (stream, settings, String.Empty);
283 public static XmlReader Create (TextReader reader, XmlReaderSettings settings)
285 return Create (reader, settings, String.Empty);
288 static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
291 return new XmlReaderSettings ();
296 public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
298 settings = PopulateSettings (settings);
299 return Create (stream, settings,
300 PopulateParserContext (settings, baseUri));
303 public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
305 settings = PopulateSettings (settings);
306 return Create (reader, settings,
307 PopulateParserContext (settings, baseUri));
310 public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
312 settings = PopulateSettings (settings);
313 XmlReader r = CreateFilteredXmlReader (reader, settings);
314 r.settings = settings;
318 public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
320 settings = PopulateSettings (settings);
321 bool closeInputBak = settings.CloseInput;
323 settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
325 context = PopulateParserContext (settings, url);
326 XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
327 XmlReader ret = CreateCustomizedTextReader (xtr, settings);
330 settings.CloseInput = closeInputBak;
334 public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
336 settings = PopulateSettings (settings);
338 context = PopulateParserContext (settings, String.Empty);
339 return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
342 public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
344 settings = PopulateSettings (settings);
346 context = PopulateParserContext (settings, String.Empty);
347 return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
350 private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
352 reader.XmlResolver = settings.XmlResolver;
353 // Normalization is set true by default.
354 reader.Normalization = true;
355 reader.EntityHandling = EntityHandling.ExpandEntities;
357 if (settings.ProhibitDtd)
358 reader.ProhibitDtd = true;
360 if (!settings.CheckCharacters)
361 reader.CharacterChecking = false;
363 // I guess it might be changed in 2.0 RTM to set true
364 // as default, or just disappear. It goes against
365 // XmlTextReader's default usage and users will have
366 // to close input manually (that's annoying). Moreover,
367 // MS XmlTextReader consumes text input more than
368 // actually read and users can acquire those extra
369 // consumption by GetRemainder() that returns different
371 reader.CloseInput = settings.CloseInput;
373 // I would like to support it in detail later;
374 // MSDN description looks source of confusion. We don't
375 // need examples, but precise list of how it works.
376 reader.Conformance = settings.ConformanceLevel;
378 reader.AdjustLineInfoOffset (settings.LineNumberOffset,
379 settings.LinePositionOffset);
381 if (settings.NameTable != null)
382 reader.SetNameTable (settings.NameTable);
384 XmlReader r = CreateFilteredXmlReader (reader, settings);
385 r.settings = settings;
389 private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
391 ConformanceLevel conf = ConformanceLevel.Auto;
392 if (reader is XmlTextReader)
393 conf = ((XmlTextReader) reader).Conformance;
394 else if (reader.Settings != null)
395 conf = reader.Settings.ConformanceLevel;
397 conf = settings.ConformanceLevel;
398 if (settings.ConformanceLevel != ConformanceLevel.Auto &&
399 conf != settings.ConformanceLevel)
400 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));
401 settings.ConformanceLevel = conf;
403 reader = CreateValidatingXmlReader (reader, settings);
405 if ( settings.IgnoreComments ||
406 settings.IgnoreProcessingInstructions ||
407 settings.IgnoreWhitespace)
408 return new XmlFilterReader (reader, settings);
410 reader.settings = settings;
415 private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
420 XmlValidatingReader xvr = null;
421 switch (settings.ValidationType) {
422 // Auto and XDR are obsoleted in 2.0 and therefore ignored.
425 case ValidationType.DTD:
426 xvr = new XmlValidatingReader (reader);
427 xvr.XmlResolver = settings.XmlResolver;
428 xvr.ValidationType = ValidationType.DTD;
430 case ValidationType.Schema:
431 return new XmlSchemaValidatingReader (reader, settings);
434 // Actually I don't think they are treated in DTD validation though...
435 if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
436 throw new NotImplementedException ();
437 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
438 // throw new NotImplementedException ();
439 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
440 // throw new NotImplementedException ();
441 //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
442 // throw new NotImplementedException ();
444 return xvr != null ? xvr : reader;
448 void IDisposable.Dispose ()
453 protected virtual void Dispose (bool disposing)
455 if (ReadState != ReadState.Closed)
460 public abstract string GetAttribute (int i);
462 public abstract string GetAttribute (string name);
464 public abstract string GetAttribute (
466 string namespaceName);
468 public static bool IsName (string s)
470 return s != null && XmlChar.IsName (s);
473 public static bool IsNameToken (string s)
475 return s != null && XmlChar.IsNmToken (s);
478 public virtual bool IsStartElement ()
480 return (MoveToContent () == XmlNodeType.Element);
483 public virtual bool IsStartElement (string name)
485 if (!IsStartElement ())
488 return (Name == name);
491 public virtual bool IsStartElement (string localName, string namespaceName)
493 if (!IsStartElement ())
496 return (LocalName == localName && NamespaceURI == namespaceName);
499 public abstract string LookupNamespace (string prefix);
502 public virtual void MoveToAttribute (int i)
504 if (i >= AttributeCount)
505 throw new ArgumentOutOfRangeException ();
506 MoveToFirstAttribute ();
507 for (int a = 0; a < i; a++)
508 MoveToNextAttribute ();
511 public abstract void MoveToAttribute (int i);
514 public abstract bool MoveToAttribute (string name);
516 public abstract bool MoveToAttribute (
518 string namespaceName);
520 private bool IsContent (XmlNodeType nodeType)
523 * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
526 case XmlNodeType.Text:
528 case XmlNodeType.CDATA:
530 case XmlNodeType.Element:
532 case XmlNodeType.EndElement:
534 case XmlNodeType.EntityReference:
536 case XmlNodeType.EndEntity:
543 public virtual XmlNodeType MoveToContent ()
546 case ReadState.Initial:
547 case ReadState.Interactive:
553 if (NodeType == XmlNodeType.Attribute)
557 if (IsContent (NodeType))
561 return XmlNodeType.None;
564 public abstract bool MoveToElement ();
566 public abstract bool MoveToFirstAttribute ();
568 public abstract bool MoveToNextAttribute ();
570 public abstract bool Read ();
572 public abstract bool ReadAttributeValue ();
574 public virtual string ReadElementString ()
576 if (MoveToContent () != XmlNodeType.Element) {
577 string error = String.Format ("'{0}' is an invalid node type.",
578 NodeType.ToString ());
579 throw XmlError (error);
582 string result = String.Empty;
583 if (!IsEmptyElement) {
585 result = ReadString ();
586 if (NodeType != XmlNodeType.EndElement) {
587 string error = String.Format ("'{0}' is an invalid node type.",
588 NodeType.ToString ());
589 throw XmlError (error);
597 public virtual string ReadElementString (string name)
599 if (MoveToContent () != XmlNodeType.Element) {
600 string error = String.Format ("'{0}' is an invalid node type.",
601 NodeType.ToString ());
602 throw XmlError (error);
606 string error = String.Format ("The {0} tag from namespace {1} is expected.",
608 throw XmlError (error);
611 string result = String.Empty;
612 if (!IsEmptyElement) {
614 result = ReadString ();
615 if (NodeType != XmlNodeType.EndElement) {
616 string error = String.Format ("'{0}' is an invalid node type.",
617 NodeType.ToString ());
618 throw XmlError (error);
626 public virtual string ReadElementString (string localName, string namespaceName)
628 if (MoveToContent () != XmlNodeType.Element) {
629 string error = String.Format ("'{0}' is an invalid node type.",
630 NodeType.ToString ());
631 throw XmlError (error);
634 if (localName != LocalName || NamespaceURI != namespaceName) {
635 string error = String.Format ("The {0} tag from namespace {1} is expected.",
636 LocalName, NamespaceURI);
637 throw XmlError (error);
640 string result = String.Empty;
641 if (!IsEmptyElement) {
643 result = ReadString ();
644 if (NodeType != XmlNodeType.EndElement) {
645 string error = String.Format ("'{0}' is an invalid node type.",
646 NodeType.ToString ());
647 throw XmlError (error);
655 public virtual void ReadEndElement ()
657 if (MoveToContent () != XmlNodeType.EndElement) {
658 string error = String.Format ("'{0}' is an invalid node type.",
659 NodeType.ToString ());
660 throw XmlError (error);
666 public virtual string ReadInnerXml ()
668 if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
671 if (IsEmptyElement) {
675 StringWriter sw = new StringWriter ();
676 XmlTextWriter xtw = new XmlTextWriter (sw);
677 if (NodeType == XmlNodeType.Element) {
678 int startDepth = Depth;
680 while (startDepth < Depth) {
681 if (ReadState != ReadState.Interactive)
682 throw XmlError ("Unexpected end of the XML reader.");
683 xtw.WriteNode (this, false);
685 // reader is now end element, then proceed once more.
689 xtw.WriteNode (this, false);
691 return sw.ToString ();
694 public virtual string ReadOuterXml ()
696 if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
700 case XmlNodeType.Element:
701 case XmlNodeType.Attribute:
702 StringWriter sw = new StringWriter ();
703 XmlTextWriter xtw = new XmlTextWriter (sw);
704 xtw.WriteNode (this, false);
705 return sw.ToString ();
712 public virtual void ReadStartElement ()
714 if (MoveToContent () != XmlNodeType.Element) {
715 string error = String.Format ("'{0}' is an invalid node type.",
716 NodeType.ToString ());
717 throw XmlError (error);
723 public virtual void ReadStartElement (string name)
725 if (MoveToContent () != XmlNodeType.Element) {
726 string error = String.Format ("'{0}' is an invalid node type.",
727 NodeType.ToString ());
728 throw XmlError (error);
732 string error = String.Format ("The {0} tag from namespace {1} is expected.",
734 throw XmlError (error);
740 public virtual void ReadStartElement (string localName, string namespaceName)
742 if (MoveToContent () != XmlNodeType.Element) {
743 string error = String.Format ("'{0}' is an invalid node type.",
744 NodeType.ToString ());
745 throw XmlError (error);
748 if (localName != LocalName || NamespaceURI != namespaceName) {
749 string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
750 localName, namespaceName,
751 LocalName, NamespaceURI);
752 throw XmlError (error);
758 public virtual string ReadString ()
760 if (readStringBuffer == null)
761 readStringBuffer = new StringBuilder ();
762 readStringBuffer.Length = 0;
769 case XmlNodeType.Element:
775 case XmlNodeType.Text:
776 case XmlNodeType.CDATA:
777 case XmlNodeType.Whitespace:
778 case XmlNodeType.SignificantWhitespace:
779 readStringBuffer.Append (Value);
785 case XmlNodeType.Text:
786 case XmlNodeType.CDATA:
787 case XmlNodeType.Whitespace:
788 case XmlNodeType.SignificantWhitespace:
791 case XmlNodeType.Text:
792 case XmlNodeType.CDATA:
793 case XmlNodeType.Whitespace:
794 case XmlNodeType.SignificantWhitespace:
795 readStringBuffer.Append (Value);
803 string ret = readStringBuffer.ToString ();
804 readStringBuffer.Length = 0;
809 public virtual Type ValueType {
810 get { return typeof (string); }
813 public virtual bool ReadToDescendant (string name)
815 if (ReadState == ReadState.Initial) {
817 if (IsStartElement (name))
820 if (NodeType != XmlNodeType.Element || IsEmptyElement)
823 for (Read (); depth < Depth; Read ())
824 if (NodeType == XmlNodeType.Element && name == Name)
829 public virtual bool ReadToDescendant (string localName, string namespaceURI)
831 if (ReadState == ReadState.Initial) {
833 if (IsStartElement (localName, namespaceURI))
836 if (NodeType != XmlNodeType.Element || IsEmptyElement)
839 for (Read (); depth < Depth; Read ())
840 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
845 public virtual bool ReadToFollowing (string name)
848 if (NodeType == XmlNodeType.Element && name == Name)
853 public virtual bool ReadToFollowing (string localName, string namespaceURI)
856 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
861 public virtual bool ReadToNextSibling (string name)
863 if (ReadState != ReadState.Interactive)
867 for (; !EOF && depth <= Depth; Skip ())
868 if (NodeType == XmlNodeType.Element && name == Name)
873 public virtual bool ReadToNextSibling (string localName, string namespaceURI)
875 if (ReadState != ReadState.Interactive)
879 for (; !EOF && depth <= Depth; Skip ())
880 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
885 public virtual XmlReader ReadSubtree ()
887 if (NodeType != XmlNodeType.Element)
888 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 ()));
889 return new SubtreeXmlReader (this);
892 private string ReadContentString ()
894 // The latter condition indicates that this XmlReader is on an attribute value
895 // (HasAttributes is to indicate it is on attribute value).
896 if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
898 return ReadContentString (true);
901 private string ReadContentString (bool isText)
905 case XmlNodeType.Text:
906 case XmlNodeType.SignificantWhitespace:
907 case XmlNodeType.Whitespace:
908 case XmlNodeType.CDATA:
910 case XmlNodeType.Element:
911 throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
917 string value = String.Empty;
920 case XmlNodeType.Element:
923 throw XmlError ("Child element is not expected in this operation.");
924 case XmlNodeType.EndElement:
926 case XmlNodeType.Text:
927 case XmlNodeType.CDATA:
928 case XmlNodeType.SignificantWhitespace:
929 case XmlNodeType.Whitespace:
934 throw XmlError ("Unexpected end of document.");
937 string GetLocation ()
939 IXmlLineInfo li = this as IXmlLineInfo;
940 return li != null && li.HasLineInfo () ?
941 String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
945 public virtual object ReadElementContentAsObject ()
947 return ReadElementContentAs (ValueType, null);
951 public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
953 return ReadElementContentAs (ValueType, null, localName, namespaceURI);
957 public virtual object ReadContentAsObject ()
959 return ReadContentAs (ValueType, null);
962 public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver)
964 bool isEmpty = IsEmptyElement;
966 object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), type, resolver);
972 public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver, string localName, string namespaceURI)
974 ReadStartElement (localName, namespaceURI);
975 object obj = ReadContentAs (type, resolver);
980 public virtual object ReadContentAs (Type type, IXmlNamespaceResolver resolver)
982 return ValueAs (ReadContentString (), type, resolver);
985 private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver)
988 if (type == typeof (object))
990 if (type == typeof (XmlQualifiedName)) {
991 if (resolver != null)
992 return XmlQualifiedName.Parse (text, resolver, true);
994 return XmlQualifiedName.Parse (text, this, true);
996 if (type == typeof (DateTimeOffset))
997 return XmlConvert.ToDateTimeOffset (text);
999 switch (Type.GetTypeCode (type)) {
1000 case TypeCode.Boolean:
1001 return XQueryConvert.StringToBoolean (text);
1002 case TypeCode.DateTime:
1003 return XQueryConvert.StringToDateTime (text);
1004 case TypeCode.Decimal:
1005 return XQueryConvert.StringToDecimal (text);
1006 case TypeCode.Double:
1007 return XQueryConvert.StringToDouble (text);
1008 case TypeCode.Int32:
1009 return XQueryConvert.StringToInt (text);
1010 case TypeCode.Int64:
1011 return XQueryConvert.StringToInteger (text);
1012 case TypeCode.Single:
1013 return XQueryConvert.StringToFloat (text);
1014 case TypeCode.String:
1017 } catch (Exception ex) {
1018 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);
1020 throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
1023 public virtual bool ReadElementContentAsBoolean ()
1026 return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
1027 } catch (FormatException ex) {
1028 throw XmlError ("Typed value is invalid.", ex);
1032 public virtual DateTime ReadElementContentAsDateTime ()
1035 return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
1036 } catch (FormatException ex) {
1037 throw XmlError ("Typed value is invalid.", ex);
1041 public virtual decimal ReadElementContentAsDecimal ()
1044 return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
1045 } catch (FormatException ex) {
1046 throw XmlError ("Typed value is invalid.", ex);
1050 public virtual double ReadElementContentAsDouble ()
1053 return XQueryConvert.StringToDouble (ReadElementContentAsString ());
1054 } catch (FormatException ex) {
1055 throw XmlError ("Typed value is invalid.", ex);
1059 public virtual float ReadElementContentAsFloat ()
1062 return XQueryConvert.StringToFloat (ReadElementContentAsString ());
1063 } catch (FormatException ex) {
1064 throw XmlError ("Typed value is invalid.", ex);
1068 public virtual int ReadElementContentAsInt ()
1071 return XQueryConvert.StringToInt (ReadElementContentAsString ());
1072 } catch (FormatException ex) {
1073 throw XmlError ("Typed value is invalid.", ex);
1077 public virtual long ReadElementContentAsLong ()
1080 return XQueryConvert.StringToInteger (ReadElementContentAsString ());
1081 } catch (FormatException ex) {
1082 throw XmlError ("Typed value is invalid.", ex);
1086 public virtual string ReadElementContentAsString ()
1088 bool isEmpty = IsEmptyElement;
1089 // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1090 if (NodeType != XmlNodeType.Element)
1091 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1092 ReadStartElement ();
1094 return String.Empty;
1095 string s = ReadContentString (false);
1100 public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
1103 return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
1104 } catch (FormatException ex) {
1105 throw XmlError ("Typed value is invalid.", ex);
1109 public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
1112 return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
1113 } catch (FormatException ex) {
1114 throw XmlError ("Typed value is invalid.", ex);
1118 public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
1121 return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
1122 } catch (FormatException ex) {
1123 throw XmlError ("Typed value is invalid.", ex);
1127 public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
1130 return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
1131 } catch (FormatException ex) {
1132 throw XmlError ("Typed value is invalid.", ex);
1136 public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
1139 return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
1140 } catch (FormatException ex) {
1141 throw XmlError ("Typed value is invalid.", ex);
1145 public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
1148 return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
1149 } catch (FormatException ex) {
1150 throw XmlError ("Typed value is invalid.", ex);
1154 public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
1157 return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
1158 } catch (FormatException ex) {
1159 throw XmlError ("Typed value is invalid.", ex);
1163 public virtual string ReadElementContentAsString (string localName, string namespaceURI)
1165 bool isEmpty = IsEmptyElement;
1166 // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1167 if (NodeType != XmlNodeType.Element)
1168 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1169 ReadStartElement (localName, namespaceURI);
1171 return String.Empty;
1172 string s = ReadContentString (false);
1177 public virtual bool ReadContentAsBoolean ()
1180 return XQueryConvert.StringToBoolean (ReadContentString ());
1181 } catch (FormatException ex) {
1182 throw XmlError ("Typed value is invalid.", ex);
1186 public virtual DateTime ReadContentAsDateTime ()
1189 return XQueryConvert.StringToDateTime (ReadContentString ());
1190 } catch (FormatException ex) {
1191 throw XmlError ("Typed value is invalid.", ex);
1195 public virtual decimal ReadContentAsDecimal ()
1198 return XQueryConvert.StringToDecimal (ReadContentString ());
1199 } catch (FormatException ex) {
1200 throw XmlError ("Typed value is invalid.", ex);
1204 public virtual double ReadContentAsDouble ()
1207 return XQueryConvert.StringToDouble (ReadContentString ());
1208 } catch (FormatException ex) {
1209 throw XmlError ("Typed value is invalid.", ex);
1213 public virtual float ReadContentAsFloat ()
1216 return XQueryConvert.StringToFloat (ReadContentString ());
1217 } catch (FormatException ex) {
1218 throw XmlError ("Typed value is invalid.", ex);
1222 public virtual int ReadContentAsInt ()
1225 return XQueryConvert.StringToInt (ReadContentString ());
1226 } catch (FormatException ex) {
1227 throw XmlError ("Typed value is invalid.", ex);
1231 public virtual long ReadContentAsLong ()
1234 return XQueryConvert.StringToInteger (ReadContentString ());
1235 } catch (FormatException ex) {
1236 throw XmlError ("Typed value is invalid.", ex);
1240 public virtual string ReadContentAsString ()
1242 return ReadContentString ();
1245 public virtual int ReadContentAsBase64 (
1246 byte [] buffer, int offset, int length)
1249 return binary.ReadContentAsBase64 (
1250 buffer, offset, length);
1253 public virtual int ReadContentAsBinHex (
1254 byte [] buffer, int offset, int length)
1257 return binary.ReadContentAsBinHex (
1258 buffer, offset, length);
1261 public virtual int ReadElementContentAsBase64 (
1262 byte [] buffer, int offset, int length)
1265 return binary.ReadElementContentAsBase64 (
1266 buffer, offset, length);
1269 public virtual int ReadElementContentAsBinHex (
1270 byte [] buffer, int offset, int length)
1273 return binary.ReadElementContentAsBinHex (
1274 buffer, offset, length);
1277 private void CheckSupport ()
1279 // Default implementation expects both.
1280 if (!CanReadBinaryContent || !CanReadValueChunk)
1281 throw new NotSupportedException ();
1283 binary = new XmlReaderBinarySupport (this);
1289 public virtual int ReadValueChunk (
1290 char [] buffer, int offset, int length)
1292 internal virtual int ReadValueChunk (
1293 char [] buffer, int offset, int length)
1296 if (!CanReadValueChunk)
1297 throw new NotSupportedException ();
1299 binary = new XmlReaderBinarySupport (this);
1300 return binary.ReadValueChunk (buffer, offset, length);
1303 public abstract void ResolveEntity ();
1305 public virtual void Skip ()
1307 if (ReadState != ReadState.Interactive)
1311 if (NodeType != XmlNodeType.Element || IsEmptyElement) {
1317 while (Read () && depth < Depth)
1319 if (NodeType == XmlNodeType.EndElement)
1323 private XmlException XmlError (string message)
1325 return new XmlException (this as IXmlLineInfo, BaseURI, message);
1328 private XmlException XmlError (string message, Exception innerException)
1330 return new XmlException (this as IXmlLineInfo, BaseURI, message);