XmlReader.cs :  » 2.6.4-mono-.net-core » System.Xml » System » Xml » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Xml 
System.Xml » System » Xml » XmlReader.cs
//
// XmlReader.cs
//
// Authors:
//   Jason Diamond (jason@injektilo.org)
//   Gonzalo Paniagua Javier (gonzalo@ximian.com)
//  Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) 2001, 2002 Jason Diamond  http://injektilo.org/
// (c) 2002 Ximian, Inc. (http://www.ximian.com)
// (C) 2003 Atsushi Enomoto
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text;
#if !MOONLIGHT
using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
using Mono.Xml.Schema; // only required for NET_2_0
#endif
using Mono.Xml; // only required for NET_2_0

namespace System.Xml{
#if NET_2_0
  public abstract class XmlReader : IDisposable
#else
  public abstract class XmlReader
#endif
  {
    private StringBuilder readStringBuffer;
    private XmlReaderBinarySupport binary;
#if NET_2_0
    private XmlReaderSettings settings;
#endif

    #region Constructor

    protected XmlReader ()
    {
    }

    #endregion

    #region Properties

    public abstract int AttributeCount { get; }

    public abstract string BaseURI { get; }

    internal XmlReaderBinarySupport Binary {
      get { return binary; }
    }

    internal XmlReaderBinarySupport.CharGetter BinaryCharGetter {
      get { return binary != null ? binary.Getter : null; }
      set {
        if (binary == null)
          binary = new XmlReaderBinarySupport (this);
        binary.Getter = value;
      }
    }

#if NET_2_0
    // To enable it internally in sys.xml, just insert these
    // two lines into Read():
    //
    //  #if NET_2_0
    //  if (Binary != null)
    //    Binary.Reset ();
    //  #endif
    //
    public virtual bool CanReadBinaryContent {
      get { return false; }
    }

    public virtual bool CanReadValueChunk {
      get { return false; }
    }
#else
    internal virtual bool CanReadBinaryContent {
      get { return false; }
    }

    internal virtual bool CanReadValueChunk {
      get { return false; }
    }
#endif

    public virtual bool CanResolveEntity
    {
      get  { return false; }
    }

    public abstract int Depth { get; }

    public abstract bool EOF { get; }

    public virtual bool HasAttributes
    {
      get { return AttributeCount > 0; }
    }

    public abstract bool HasValue { get; }

    public abstract bool IsEmptyElement { get; }

#if NET_2_0
    public virtual bool IsDefault {
      get { return false; }
    }

    public virtual string this [int i] {
      get { return GetAttribute (i); }
    }

    public virtual string this [string name] {
      get { return GetAttribute (name); }
    }

    public virtual string this [string name, string namespaceURI] {
      get { return GetAttribute (name, namespaceURI); }
    }
#else
    public abstract bool IsDefault { get; }

    public abstract string this [int i] { get; }

    public abstract string this [string name] { get; }

    public abstract string this [string localName, string namespaceName] { get; }
#endif

    public abstract string LocalName { get; }

#if NET_2_0
    public virtual string Name {
      get {
        return Prefix.Length > 0 ?
          String.Concat (Prefix, ":", LocalName) :
          LocalName;
      }
    }
#else
    public abstract string Name { get; }
#endif

    public abstract string NamespaceURI { get; }

    public abstract XmlNameTable NameTable { get; }

    public abstract XmlNodeType NodeType { get; }

    public abstract string Prefix { get; }

#if NET_2_0
    public virtual char QuoteChar {
      get { return '\"'; }
    }
#else
    public abstract char QuoteChar { get; }
#endif

    public abstract ReadState ReadState { get; }

#if NET_2_0
#if !MOONLIGHT
    public virtual IXmlSchemaInfo SchemaInfo {
      get { return null; }
    }
#endif

    public virtual XmlReaderSettings Settings {
      get { return settings; }
    }
#endif

    public abstract string Value { get; }

#if NET_2_0
    public virtual string XmlLang {
      get { return String.Empty; }
    }

    public virtual XmlSpace XmlSpace {
      get { return XmlSpace.None; }
    }
#else
    public abstract string XmlLang { get; }

    public abstract XmlSpace XmlSpace { get; }
#endif

    #endregion

    #region Methods

    public abstract void Close ();

#if NET_2_0
    private static XmlNameTable PopulateNameTable (
      XmlReaderSettings settings)
    {
      XmlNameTable nameTable = settings.NameTable;
      if (nameTable == null)
        nameTable = new NameTable ();
      return nameTable;
    }

    private static XmlParserContext PopulateParserContext (
      XmlReaderSettings settings, string baseUri)
    {
      XmlNameTable nt = PopulateNameTable (settings);
      return new XmlParserContext (nt,
        new XmlNamespaceManager (nt),
        null,
        null,
        null,
        null,
        baseUri,
        null,
        XmlSpace.None,
        null);
    }

    private static XmlNodeType GetNodeType (
      XmlReaderSettings settings)
    {
      ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
      return
        level == ConformanceLevel.Fragment ?
        XmlNodeType.Element :
        XmlNodeType.Document;
    }

    public static XmlReader Create (Stream stream)
    {
      return Create (stream, null);
    }

    public static XmlReader Create (string url)
    {
      return Create (url, null);
    }

    public static XmlReader Create (TextReader reader)
    {
      return Create (reader, null);
    }

    public static XmlReader Create (string url, XmlReaderSettings settings)
    {
      return Create (url, settings, null);
    }

    public static XmlReader Create (Stream stream, XmlReaderSettings settings)
    {
      return Create (stream, settings, String.Empty);
    }

    public static XmlReader Create (TextReader reader, XmlReaderSettings settings)
    {
      return Create (reader, settings, String.Empty);
    }

    static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
    {
      if (src == null)
        return new XmlReaderSettings ();
      else
        return src.Clone ();
    }

    public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
    {
      settings = PopulateSettings (settings);
      return Create (stream, settings,
        PopulateParserContext (settings, baseUri));
    }

    public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
    {
      settings = PopulateSettings (settings);
      return Create (reader, settings,
        PopulateParserContext (settings, baseUri));
    }

    public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
    {
      settings = PopulateSettings (settings);
      XmlReader r = CreateFilteredXmlReader (reader, settings);
      r.settings = settings;
      return r;
    }

    public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
    {
      settings = PopulateSettings (settings);
      bool closeInputBak = settings.CloseInput;
      try {
        settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
        if (context == null)
          context = PopulateParserContext (settings, url);
        XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
        XmlReader ret = CreateCustomizedTextReader (xtr, settings);
        return ret;
      } finally {
        settings.CloseInput = closeInputBak;
      }
    }

    public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
    {
      settings = PopulateSettings (settings);
      if (context == null)
        context = PopulateParserContext (settings, String.Empty);
      return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
    }

    public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
    {
      settings = PopulateSettings (settings);
      if (context == null)
        context = PopulateParserContext (settings, String.Empty);
      return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
    }

    private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
    {
      reader.XmlResolver = settings.XmlResolver;
      // Normalization is set true by default.
      reader.Normalization = true;
      reader.EntityHandling = EntityHandling.ExpandEntities;

      if (settings.ProhibitDtd)
        reader.ProhibitDtd = true;

      if (!settings.CheckCharacters)
        reader.CharacterChecking = false;

      // I guess it might be changed in 2.0 RTM to set true
      // as default, or just disappear. It goes against
      // XmlTextReader's default usage and users will have 
      // to close input manually (that's annoying). Moreover,
      // MS XmlTextReader consumes text input more than 
      // actually read and users can acquire those extra
      // consumption by GetRemainder() that returns different
      // TextReader.
      reader.CloseInput = settings.CloseInput;

      // I would like to support it in detail later;
      // MSDN description looks source of confusion. We don't
      // need examples, but precise list of how it works.
      reader.Conformance = settings.ConformanceLevel;

      reader.AdjustLineInfoOffset (settings.LineNumberOffset,
        settings.LinePositionOffset);

      if (settings.NameTable != null)
        reader.SetNameTable (settings.NameTable);

      XmlReader r = CreateFilteredXmlReader (reader, settings);
      r.settings = settings;
      return r;
    }

    private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
    {
      ConformanceLevel conf = ConformanceLevel.Auto;
      if (reader is XmlTextReader)
        conf = ((XmlTextReader) reader).Conformance;
      else if (reader.Settings != null)
        conf = reader.Settings.ConformanceLevel;
      else
        conf = settings.ConformanceLevel;
      if (settings.ConformanceLevel != ConformanceLevel.Auto &&
        conf != settings.ConformanceLevel)
        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));
      settings.ConformanceLevel = conf;

      reader = CreateValidatingXmlReader (reader, settings);

      if ( settings.IgnoreComments ||
           settings.IgnoreProcessingInstructions ||
           settings.IgnoreWhitespace)
        return new XmlFilterReader (reader, settings);
      else {
        reader.settings = settings;
        return reader;
      }
    }

    private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
    {
#if MOONLIGHT
      return reader;
#else
      XmlValidatingReader xvr = null;
      switch (settings.ValidationType) {
      // Auto and XDR are obsoleted in 2.0 and therefore ignored.
      default:
        return reader;
      case ValidationType.DTD:
        xvr = new XmlValidatingReader (reader);
        xvr.XmlResolver = settings.XmlResolver;
        xvr.ValidationType = ValidationType.DTD;
        break;
      case ValidationType.Schema:
        return new XmlSchemaValidatingReader (reader, settings);
      }

      // Actually I don't think they are treated in DTD validation though...
      if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
        throw new NotImplementedException ();
      //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
      //  throw new NotImplementedException ();
      //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
      //  throw new NotImplementedException ();
      //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
      //  throw new NotImplementedException ();

      return xvr != null ? xvr : reader;
#endif
    }

    void IDisposable.Dispose ()
    {
      Dispose (false);
    }

    protected virtual void Dispose (bool disposing)
    {
      if (ReadState != ReadState.Closed)
        Close ();
    }
#endif

    public abstract string GetAttribute (int i);

    public abstract string GetAttribute (string name);

    public abstract string GetAttribute (
      string localName,
      string namespaceName);

    public static bool IsName (string s)
    {
      return s != null && XmlChar.IsName (s);
    }

    public static bool IsNameToken (string s)
    {
      return s != null && XmlChar.IsNmToken (s);
    }

    public virtual bool IsStartElement ()
    {
      return (MoveToContent () == XmlNodeType.Element);
    }

    public virtual bool IsStartElement (string name)
    {
      if (!IsStartElement ())
        return false;

      return (Name == name);
    }

    public virtual bool IsStartElement (string localName, string namespaceName)
    {
      if (!IsStartElement ())
        return false;

      return (LocalName == localName && NamespaceURI == namespaceName);
    }

    public abstract string LookupNamespace (string prefix);

#if NET_2_0
    public virtual void MoveToAttribute (int i)
    {
      if (i >= AttributeCount)
        throw new ArgumentOutOfRangeException ();
      MoveToFirstAttribute ();
      for (int a = 0; a < i; a++)
        MoveToNextAttribute ();
    }
#else
    public abstract void MoveToAttribute (int i);
#endif

    public abstract bool MoveToAttribute (string name);

    public abstract bool MoveToAttribute (
      string localName,
      string namespaceName);

    private bool IsContent (XmlNodeType nodeType)
    {
      /* MS doc says:
       * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
       */
      switch (nodeType) {
      case XmlNodeType.Text:
        return true;
      case XmlNodeType.CDATA:
        return true;
      case XmlNodeType.Element:
        return true;
      case XmlNodeType.EndElement:
        return true;
      case XmlNodeType.EntityReference:
        return true;
      case XmlNodeType.EndEntity:
        return true;
      }

      return false;
    }

    public virtual XmlNodeType MoveToContent ()
    {
      switch (ReadState) {
      case ReadState.Initial:
      case ReadState.Interactive:
        break;
      default:
        return NodeType;
      }

      if (NodeType == XmlNodeType.Attribute)
        MoveToElement ();

      do {
        if (IsContent (NodeType))
          return NodeType;
        Read ();
      } while (!EOF);
      return XmlNodeType.None;
    }

    public abstract bool MoveToElement ();

    public abstract bool MoveToFirstAttribute ();

    public abstract bool MoveToNextAttribute ();

    public abstract bool Read ();

    public abstract bool ReadAttributeValue ();

    public virtual string ReadElementString ()
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      string result = String.Empty;
      if (!IsEmptyElement) {
        Read ();
        result = ReadString ();
        if (NodeType != XmlNodeType.EndElement) {
          string error = String.Format ("'{0}' is an invalid node type.",
                      NodeType.ToString ());
          throw XmlError (error);
        }
      }

      Read ();
      return result;
    }

    public virtual string ReadElementString (string name)
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      if (name != Name) {
        string error = String.Format ("The {0} tag from namespace {1} is expected.",
                    Name, NamespaceURI);
        throw XmlError (error);
      }

      string result = String.Empty;
      if (!IsEmptyElement) {
        Read ();
        result = ReadString ();
        if (NodeType != XmlNodeType.EndElement) {
          string error = String.Format ("'{0}' is an invalid node type.",
                      NodeType.ToString ());
          throw XmlError (error);
        }
      }

      Read ();
      return result;
    }

    public virtual string ReadElementString (string localName, string namespaceName)
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      if (localName != LocalName || NamespaceURI != namespaceName) {
        string error = String.Format ("The {0} tag from namespace {1} is expected.",
                    LocalName, NamespaceURI);
        throw XmlError (error);
      }

      string result = String.Empty;
      if (!IsEmptyElement) {
        Read ();
        result = ReadString ();
        if (NodeType != XmlNodeType.EndElement) {
          string error = String.Format ("'{0}' is an invalid node type.",
                      NodeType.ToString ());
          throw XmlError (error);
        }
      }

      Read ();
      return result;
    }

    public virtual void ReadEndElement ()
    {
      if (MoveToContent () != XmlNodeType.EndElement) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      Read ();
    }

    public virtual string ReadInnerXml ()
    {
      if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
        return String.Empty;

      if (IsEmptyElement) {
        Read ();
        return String.Empty;
      }
      StringWriter sw = new StringWriter ();
      XmlTextWriter xtw = new XmlTextWriter (sw);
      if (NodeType == XmlNodeType.Element) {
        int startDepth = Depth;
        Read ();
        while (startDepth < Depth) {
          if (ReadState != ReadState.Interactive)
            throw XmlError ("Unexpected end of the XML reader.");
          xtw.WriteNode (this, false);
        }
        // reader is now end element, then proceed once more.
        Read ();
      }
      else
        xtw.WriteNode (this, false);

      return sw.ToString ();
    }

    public virtual string ReadOuterXml ()
    {
      if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
        return String.Empty;

      switch (NodeType) {
      case XmlNodeType.Element:
      case XmlNodeType.Attribute:
        StringWriter sw = new StringWriter ();
        XmlTextWriter xtw = new XmlTextWriter (sw);
        xtw.WriteNode (this, false);
        return sw.ToString ();
      default:
        Skip ();
        return String.Empty;
      }
    }

    public virtual void ReadStartElement ()
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      Read ();
    }

    public virtual void ReadStartElement (string name)
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      if (name != Name) {
        string error = String.Format ("The {0} tag from namespace {1} is expected.",
                    Name, NamespaceURI);
        throw XmlError (error);
      }

      Read ();
    }

    public virtual void ReadStartElement (string localName, string namespaceName)
    {
      if (MoveToContent () != XmlNodeType.Element) {
        string error = String.Format ("'{0}' is an invalid node type.",
                    NodeType.ToString ());
        throw XmlError (error);
      }

      if (localName != LocalName || NamespaceURI != namespaceName) {
        string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
                    localName, namespaceName,
                    LocalName, NamespaceURI);
        throw XmlError (error);
      }

      Read ();
    }

    public virtual string ReadString ()
    {
      if (readStringBuffer == null)
        readStringBuffer = new StringBuilder ();
      readStringBuffer.Length = 0;

      MoveToElement ();

      switch (NodeType) {
      default:
        return String.Empty;
      case XmlNodeType.Element:
        if (IsEmptyElement)
          return String.Empty;
        do {
          Read ();
          switch (NodeType) {
          case XmlNodeType.Text:
          case XmlNodeType.CDATA:
          case XmlNodeType.Whitespace:
          case XmlNodeType.SignificantWhitespace:
            readStringBuffer.Append (Value);
            continue;
          }
          break;
        } while (true);
        break;
      case XmlNodeType.Text:
      case XmlNodeType.CDATA:
      case XmlNodeType.Whitespace:
      case XmlNodeType.SignificantWhitespace:
        do {
          switch (NodeType) {
          case XmlNodeType.Text:
          case XmlNodeType.CDATA:
          case XmlNodeType.Whitespace:
          case XmlNodeType.SignificantWhitespace:
            readStringBuffer.Append (Value);
            Read ();
            continue;
          }
          break;
        } while (true);
        break;
      }
      string ret = readStringBuffer.ToString ();
      readStringBuffer.Length = 0;
      return ret;
    }

#if NET_2_0
    public virtual Type ValueType {
      get { return typeof (string); }
    }

    public virtual bool ReadToDescendant (string name)
    {
      if (ReadState == ReadState.Initial) {
        MoveToContent ();
        if (IsStartElement (name))
          return true;
      }
      if (NodeType != XmlNodeType.Element || IsEmptyElement)
        return false;
      int depth = Depth;
      for (Read (); depth < Depth; Read ())
        if (NodeType == XmlNodeType.Element && name == Name)
          return true;
      return false;
    }

    public virtual bool ReadToDescendant (string localName, string namespaceURI)
    {
      if (ReadState == ReadState.Initial) {
        MoveToContent ();
        if (IsStartElement (localName, namespaceURI))
          return true;
      }
      if (NodeType != XmlNodeType.Element || IsEmptyElement)
        return false;
      int depth = Depth;
      for (Read (); depth < Depth; Read ())
        if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
          return true;
      return false;
    }

    public virtual bool ReadToFollowing (string name)
    {
      while (Read ())
        if (NodeType == XmlNodeType.Element && name == Name)
          return true;
      return false;
    }

    public virtual bool ReadToFollowing (string localName, string namespaceURI)
    {
      while (Read ())
        if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
          return true;
      return false;
    }

    public virtual bool ReadToNextSibling (string name)
    {
      if (ReadState != ReadState.Interactive)
        return false;
      int depth = Depth;
      Skip ();
      for (; !EOF && depth <= Depth; Skip ())
        if (NodeType == XmlNodeType.Element && name == Name)
          return true;
      return false;
    }

    public virtual bool ReadToNextSibling (string localName, string namespaceURI)
    {
      if (ReadState != ReadState.Interactive)
        return false;
      int depth = Depth;
      Skip ();
      for (; !EOF && depth <= Depth; Skip ())
        if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
          return true;
      return false;
    }

    public virtual XmlReader ReadSubtree ()
    {
      if (NodeType != XmlNodeType.Element)
        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 ()));
      return new SubtreeXmlReader (this);
    }

    private string ReadContentString ()
    {
      // The latter condition indicates that this XmlReader is on an attribute value
      // (HasAttributes is to indicate it is on attribute value).
      if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
        return Value;
      return ReadContentString (true);
    }

    private string ReadContentString (bool isText)
    {
      if (isText) {
        switch (NodeType) {
        case XmlNodeType.Text:
        case XmlNodeType.SignificantWhitespace:
        case XmlNodeType.Whitespace:
        case XmlNodeType.CDATA:
          break;
        case XmlNodeType.Element:
          throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
        default:
          return String.Empty;
        }
      }

      string value = String.Empty;
      do {
        switch (NodeType) {
        case XmlNodeType.Element:
          if (isText)
            return value;
          throw XmlError ("Child element is not expected in this operation.");
        case XmlNodeType.EndElement:
          return value;
        case XmlNodeType.Text:
        case XmlNodeType.CDATA:
        case XmlNodeType.SignificantWhitespace:
        case XmlNodeType.Whitespace:
          value += Value;
          break;
        }
      } while (Read ());
      throw XmlError ("Unexpected end of document.");
    }

    string GetLocation ()
    {
      IXmlLineInfo li = this as IXmlLineInfo;
      return li != null && li.HasLineInfo () ?
        String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
    }

    [MonoTODO]
    public virtual object ReadElementContentAsObject ()
    {
      return ReadElementContentAs (ValueType, null);
    }

    [MonoTODO]
    public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
    {
      return ReadElementContentAs (ValueType, null, localName, namespaceURI);
    }

    [MonoTODO]
    public virtual object ReadContentAsObject ()
    {
      return ReadContentAs (ValueType, null);
    }

    public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver)
    {
      bool isEmpty = IsEmptyElement;
      ReadStartElement ();
      object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), type, resolver);
      if (!isEmpty)
        ReadEndElement ();
      return obj;
    }

    public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver, string localName, string namespaceURI)
    {
      ReadStartElement (localName, namespaceURI);
      object obj = ReadContentAs (type, resolver);
      ReadEndElement ();
      return obj;
    }

    public virtual object ReadContentAs (Type type, IXmlNamespaceResolver resolver)
    {
      return ValueAs (ReadContentString (), type, resolver);
    }

    private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver)
    {
      try {
        if (type == typeof (object))
          return text;
        if (type == typeof (XmlQualifiedName)) {
          if (resolver != null)
            return XmlQualifiedName.Parse (text, resolver, true);
          else
            return XmlQualifiedName.Parse (text, this, true);
        }
        if (type == typeof (DateTimeOffset))
          return XmlConvert.ToDateTimeOffset (text);

        switch (Type.GetTypeCode (type)) {
        case TypeCode.Boolean:
          return XQueryConvert.StringToBoolean (text);
        case TypeCode.DateTime:
          return XQueryConvert.StringToDateTime (text);
        case TypeCode.Decimal:
          return XQueryConvert.StringToDecimal (text);
        case TypeCode.Double:
          return XQueryConvert.StringToDouble (text);
        case TypeCode.Int32:
          return XQueryConvert.StringToInt (text);
        case TypeCode.Int64:
          return XQueryConvert.StringToInteger (text);
        case TypeCode.Single:
          return XQueryConvert.StringToFloat (text);
        case TypeCode.String:
          return text;
        }
      } catch (Exception ex) {
        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);
      }
      throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
    }

    public virtual bool ReadElementContentAsBoolean ()
    {
      try {
        return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual DateTime ReadElementContentAsDateTime ()
    {
      try {
        return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual decimal ReadElementContentAsDecimal ()
    {
      try {
        return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual double ReadElementContentAsDouble ()
    {
      try {
        return XQueryConvert.StringToDouble (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual float ReadElementContentAsFloat ()
    {
      try {
        return XQueryConvert.StringToFloat (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual int ReadElementContentAsInt ()
    {
      try {
        return XQueryConvert.StringToInt (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual long ReadElementContentAsLong ()
    {
      try {
        return XQueryConvert.StringToInteger (ReadElementContentAsString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual string ReadElementContentAsString ()
    {
      bool isEmpty = IsEmptyElement;
      // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
      if (NodeType != XmlNodeType.Element)
        throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
      ReadStartElement ();
      if (isEmpty)
        return String.Empty;
      string s = ReadContentString (false);
      ReadEndElement ();
      return s;
    }

    public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
    {
      try {
        return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual string ReadElementContentAsString (string localName, string namespaceURI)
    {
      bool isEmpty = IsEmptyElement;
      // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
      if (NodeType != XmlNodeType.Element)
        throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
      ReadStartElement (localName, namespaceURI);
      if (isEmpty)
        return String.Empty;
      string s = ReadContentString (false);
      ReadEndElement ();
      return s;
    }

    public virtual bool ReadContentAsBoolean ()
    {
      try {
        return XQueryConvert.StringToBoolean (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual DateTime ReadContentAsDateTime ()
    {
      try {
        return XQueryConvert.StringToDateTime (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual decimal ReadContentAsDecimal ()
    {
      try {
        return XQueryConvert.StringToDecimal (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual double ReadContentAsDouble ()
    {
      try {
        return XQueryConvert.StringToDouble (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual float ReadContentAsFloat ()
    {
      try {
        return XQueryConvert.StringToFloat (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual int ReadContentAsInt ()
    {
      try {
        return XQueryConvert.StringToInt (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual long ReadContentAsLong ()
    {
      try {
        return XQueryConvert.StringToInteger (ReadContentString ());
      } catch (FormatException ex) {
        throw XmlError ("Typed value is invalid.", ex);
      }
    }

    public virtual string ReadContentAsString ()
    {
      return ReadContentString ();
    }

    public virtual int ReadContentAsBase64 (
      byte [] buffer, int offset, int length)
    {
      CheckSupport ();
      return binary.ReadContentAsBase64 (
        buffer, offset, length);
    }

    public virtual int ReadContentAsBinHex (
      byte [] buffer, int offset, int length)
    {
      CheckSupport ();
      return binary.ReadContentAsBinHex (
        buffer, offset, length);
    }

    public virtual int ReadElementContentAsBase64 (
      byte [] buffer, int offset, int length)
    {
      CheckSupport ();
      return binary.ReadElementContentAsBase64 (
        buffer, offset, length);
    }

    public virtual int ReadElementContentAsBinHex (
      byte [] buffer, int offset, int length)
    {
      CheckSupport ();
      return binary.ReadElementContentAsBinHex (
        buffer, offset, length);
    }

    private void CheckSupport ()
    {
      // Default implementation expects both.
      if (!CanReadBinaryContent || !CanReadValueChunk)
        throw new NotSupportedException ();
      if (binary == null)
        binary = new XmlReaderBinarySupport (this);
    }
    
#endif

#if NET_2_0
    public virtual int ReadValueChunk (
      char [] buffer, int offset, int length)
#else
    internal virtual int ReadValueChunk (
      char [] buffer, int offset, int length)
#endif
    {
      if (!CanReadValueChunk)
        throw new NotSupportedException ();
      if (binary == null)
        binary = new XmlReaderBinarySupport (this);
      return binary.ReadValueChunk (buffer, offset, length);
    }

    public abstract void ResolveEntity ();

    public virtual void Skip ()
    {
      if (ReadState != ReadState.Interactive)
        return;

      MoveToElement ();
      if (NodeType != XmlNodeType.Element || IsEmptyElement) {
        Read ();
        return;
      }
        
      int depth = Depth;
      while (Read () && depth < Depth)
        ;
      if (NodeType == XmlNodeType.EndElement)
        Read ();
    }

    private XmlException XmlError (string message)
    {
      return new XmlException (this as IXmlLineInfo, BaseURI, message);
    }
#if NET_2_0
    private XmlException XmlError (string message, Exception innerException)
    {
      return new XmlException (this as IXmlLineInfo, BaseURI, message);
    }
#endif
    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.