Type Summary

Type Summary

public abstract class XmlReader


    // Constructors

       protected XmlReader();

    // Properties

       public abstract int AttributeCount { get; }

       public abstract string BaseURI { get; }

       public virtual bool CanResolveEntity { get; }

       public abstract int Depth { get; }

       public abstract bool EOF { get; }

       public virtual bool HasAttributes { get; }

       public abstract bool HasValue { get; }

       public abstract bool IsDefault { get; }

       public abstract bool IsEmptyElement { get; }

       public abstract string LocalName { get; }

       public abstract string Name { get; }

       public abstract string NamespaceURI { get; }

       public abstract XmlNameTable NameTable { get; }

       public abstract XmlNodeType NodeType { get; }

       public abstract string Prefix { get; }

       public abstract char QuoteChar { get; }

       public abstract ReadState ReadState { get; }

       public abstract string Value { get; }

       public abstract string XmlLang { get; }

       public abstract XmlSpace XmlSpace { get; }

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

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

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

    // Methods

       public abstract void Close();

       public abstract string GetAttribute(int i);

       public abstract string GetAttribute(string name);

       public abstract string GetAttribute(string name, string namespaceURI);

       public static bool IsName(string str);

       public static bool IsNameToken(string str);

       public virtual bool IsStartElement();

       public virtual bool IsStartElement(string name);

       public virtual bool IsStartElement(string localname, string ns);

       public abstract string LookupNamespace(string prefix);

       public abstract void MoveToAttribute(int i);

       public abstract bool MoveToAttribute(string name);

       public abstract bool MoveToAttribute(string name, string ns);

       public virtual XmlNodeType MoveToContent();

       public abstract bool MoveToElement();

       public abstract bool MoveToFirstAttribute();

       public abstract bool MoveToNextAttribute();

       public abstract bool Read();

       public abstract bool ReadAttributeValue();

       public virtual string ReadElementString();

       public virtual string ReadElementString(string name);

       public virtual string ReadElementString(string localname, string ns);

       public virtual void ReadEndElement();

       public virtual string ReadInnerXml();

       public virtual string ReadOuterXml();

       public virtual void ReadStartElement();

       public virtual void ReadStartElement(string name);

       public virtual void ReadStartElement(string localname, string ns);

       public virtual string ReadString();

       public abstract void ResolveEntity();

       public virtual void Skip();


MF The XmlReader was a significant innovation in XML parsing due to its pull model approach and caused a significant amount of acclaim in the industry. Until then developers had to endure the SAX push model, which although great for XML parser implementers (just push out an event when something happens), was painful for developers to use. The XmlReader reversed this position allowing you to do simple, procedural code where you could get the XmlReader to do the heavy lifting for you, like skipping elements that you did not care about or throwing away white space from the document. The XmlReader was inspired by seeing the use of other readers in the .NET Framework such as the StringReader class and applying the same principles to XML.

MF There are aspects of the XmlReader design where we had to choose between usability and performance. For example, due to the attribute indexer methods all the attributes for an element have to be cached, which does not allow for a complete streaming API. On the whole the majority of XML documents have small numbers of attributes so improved usability was the best design.

CL In addition to the reason Mark just noted, you have to cache all the attributes anyway in order to know the namespace of the element. SAX had the exact same problem—only worse. In SAX, an Array object is created with all of the attributes that is then passed to your handler. At least here we avoid that array creation.

JM The Read and Skip methods are, of course, different beasts. But they are more similar than you might think. If the reader is on any node besides a non-empty element node, Read and Skip behave the same. Otherwise, Skip positions the reader following the corresponding EndElement node, not exposing any properties along the way (while Read will expose the properties).

CL In general the XmlReader makes recursive descent parsing of a given XML document a snap. In fact, it is so easy that the XmlSerializer generates IL code for you that calls the XmlReader to parse the XML while it builds your own custom objects from what it finds in the stream. Hence, XmlSerialization is probably the #1 customer of the XmlReader class in terms of overall volume of XML parsed.

Notice that XmlReader is abstract. If you want to just parse XML text, you need the concrete subclass XmlTextReader discussed later. Why did we bother with an abstract base class? Because we envisioned the creation of lots of different kinds of XML readers that took their data from other sources besides text. It also means you can plug in additional behavior into the XML processing pipeline. Suppose someone consumes an XML reader. Well, you can wrap the XmlTextReader with an XmlValidatingReader and pass that instead, and now you are causing your consumer to validate while they parse without them even knowing it.

HK Although the XmlReader was designed as an abstract class, it has a few properties that are bound to the text representation of XML, such as QuoteChar or IsEmptyElement. As was pointed out quite a few times by our users, it is annoying that the XmlReader reports empty and non-empty elements differently. For non-empty element <a>…</a> the reader returns Element and EndElement events, but for empty element <a/> it only returns a single Element event. The user has to check the IsEmptyElement property to see whether he should expect a closing EndElement or not. In many cases this causes two similar code paths in the handling code, one for empty elements and one for non-empty ones.

     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows