2 //------------------------------------------------------------------------------
3 // <copyright file="XmlReader.cs" company="Microsoft">
4 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <owner current="true" primary="true">Microsoft</owner>
7 //------------------------------------------------------------------------------
11 using System
.Security
;
12 using System
.Diagnostics
;
13 using System
.Collections
;
14 using System
.Globalization
;
15 using System
.Security
.Permissions
;
16 using System
.Xml
.Schema
;
17 using System
.Runtime
.Versioning
;
20 using BufferBuilder
=System
.Xml
.BufferBuilder
;
22 using BufferBuilder
= System
.Text
.StringBuilder
;
25 namespace System
.Xml
{
27 // Represents a reader that provides fast, non-cached forward only stream access to XML data.
28 #if !SILVERLIGHT // This is used for displaying the state of the XmlReader in Watch/Locals windows in the Visual Studio during debugging
29 [DebuggerDisplay("{debuggerDisplayProxy}")]
31 public abstract partial class XmlReader
: IDisposable
{
33 static private uint IsTextualNodeBitmap
= 0x6018; // 00 0110 0000 0001 1000
41 // 0 ProcessingInstruction,
45 // 0 DocumentFragment,
48 // 1 SignificantWhitespace,
53 static private uint CanReadContentAsBitmap
= 0x1E1BC; // 01 1110 0001 1011 1100
61 // 1 ProcessingInstruction,
65 // 0 DocumentFragment,
68 // 1 SignificantWhitespace,
73 static private uint HasValueBitmap
= 0x2659C; // 10 0110 0101 1001 1100
81 // 1 ProcessingInstruction,
85 // 0 DocumentFragment,
88 // 1 SignificantWhitespace,
96 internal const int DefaultBufferSize
= 4096;
97 internal const int BiggerBufferSize
= 8192;
98 internal const int MaxStreamLengthForDefaultBufferSize
= 64 * 1024; // 64kB
100 internal const int AsyncBufferSize
= 64 * 1024; //64KB
103 public virtual XmlReaderSettings Settings
{
110 // Get the type of the current node.
111 public abstract XmlNodeType NodeType { get; }
113 // Gets the name of the current node, including the namespace prefix.
114 public virtual string Name
{
116 if (Prefix
.Length
== 0) {
120 return NameTable
.Add(string.Concat(Prefix
, ":", LocalName
));
125 // Gets the name of the current node without the namespace prefix.
126 public abstract string LocalName { get; }
128 // Gets the namespace URN (as defined in the W3C Namespace Specification) of the current namespace scope.
129 public abstract string NamespaceURI { get; }
131 // Gets the namespace prefix associated with the current node.
132 public abstract string Prefix { get; }
134 // Gets a value indicating whether
135 public virtual bool HasValue
{
137 return HasValueInternal(this.NodeType
);
141 // Gets the text value of the current node.
142 public abstract string Value { get; }
144 // Gets the depth of the current node in the XML element stack.
145 public abstract int Depth { get; }
147 // Gets the base URI of the current node.
148 public abstract string BaseURI { get; }
150 // Gets a value indicating whether the current node is an empty element (for example, <MyElement/>).
151 public abstract bool IsEmptyElement { get; }
153 // Gets a value indicating whether the current node is an attribute that was generated from the default value defined
154 // in the DTD or schema.
155 public virtual bool IsDefault
{
162 // Gets the quotation mark character used to enclose the value of an attribute node.
163 public virtual char QuoteChar
{
170 // Gets the current xml:space scope.
171 public virtual XmlSpace XmlSpace
{
173 return XmlSpace
.None
;
177 // Gets the current xml:lang scope.
178 public virtual string XmlLang
{
184 #if !SILVERLIGHT // Removing dependency on XmlSchema
185 // returns the schema info interface of the reader
186 public virtual IXmlSchemaInfo SchemaInfo
{
188 return this as IXmlSchemaInfo
;
193 // returns the type of the current node
194 public virtual System
.Type ValueType
{
196 return typeof(string);
200 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
201 // and returns the content as the most appropriate type (by default as string). Stops at start tags and end tags.
202 public virtual object ReadContentAsObject() {
203 if (!CanReadContentAs()) {
204 throw CreateReadContentAsException("ReadContentAsObject");
206 return InternalReadContentAsString();
209 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
210 // and converts the content to a boolean. Stops at start tags and end tags.
211 public virtual bool ReadContentAsBoolean() {
212 if (!CanReadContentAs()) {
213 throw CreateReadContentAsException("ReadContentAsBoolean");
216 return XmlConvert
.ToBoolean(InternalReadContentAsString());
218 catch (FormatException e
) {
219 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Boolean", e
, this as IXmlLineInfo
);
223 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
224 // and converts the content to a DateTime. Stops at start tags and end tags.
225 public virtual DateTime
ReadContentAsDateTime() {
226 if (!CanReadContentAs()) {
227 throw CreateReadContentAsException("ReadContentAsDateTime");
230 return XmlConvert
.ToDateTime(InternalReadContentAsString(), XmlDateTimeSerializationMode
.RoundtripKind
);
232 catch (FormatException e
) {
233 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "DateTime", e
, this as IXmlLineInfo
);
237 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
238 // and converts the content to a DateTimeOffset. Stops at start tags and end tags.
239 public virtual DateTimeOffset
ReadContentAsDateTimeOffset() {
240 if (!CanReadContentAs()) {
241 throw CreateReadContentAsException("ReadContentAsDateTimeOffset");
244 return XmlConvert
.ToDateTimeOffset(InternalReadContentAsString());
246 catch (FormatException e
) {
247 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "DateTimeOffset", e
, this as IXmlLineInfo
);
251 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
252 // and converts the content to a double. Stops at start tags and end tags.
253 public virtual double ReadContentAsDouble() {
254 if (!CanReadContentAs()) {
255 throw CreateReadContentAsException("ReadContentAsDouble");
258 return XmlConvert
.ToDouble(InternalReadContentAsString());
260 catch (FormatException e
) {
261 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Double", e
, this as IXmlLineInfo
);
265 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
266 // and converts the content to a float. Stops at start tags and end tags.
267 public virtual float ReadContentAsFloat() {
268 if (!CanReadContentAs()) {
269 throw CreateReadContentAsException("ReadContentAsFloat");
272 return XmlConvert
.ToSingle(InternalReadContentAsString());
274 catch (FormatException e
) {
275 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Float", e
, this as IXmlLineInfo
);
279 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
280 // and converts the content to a decimal. Stops at start tags and end tags.
281 public virtual decimal ReadContentAsDecimal() {
282 if (!CanReadContentAs()) {
283 throw CreateReadContentAsException("ReadContentAsDecimal");
286 return XmlConvert
.ToDecimal(InternalReadContentAsString());
288 catch (FormatException e
) {
289 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Decimal", e
, this as IXmlLineInfo
);
293 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
294 // and converts the content to an int. Stops at start tags and end tags.
295 public virtual int ReadContentAsInt() {
296 if (!CanReadContentAs()) {
297 throw CreateReadContentAsException("ReadContentAsInt");
300 return XmlConvert
.ToInt32(InternalReadContentAsString());
302 catch (FormatException e
) {
303 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Int", e
, this as IXmlLineInfo
);
307 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
308 // and converts the content to a long. Stops at start tags and end tags.
309 public virtual long ReadContentAsLong() {
310 if (!CanReadContentAs()) {
311 throw CreateReadContentAsException("ReadContentAsLong");
314 return XmlConvert
.ToInt64(InternalReadContentAsString());
316 catch (FormatException e
) {
317 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, "Long", e
, this as IXmlLineInfo
);
321 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
322 // and returns the content as a string. Stops at start tags and end tags.
323 public virtual string ReadContentAsString() {
324 if (!CanReadContentAs()) {
325 throw CreateReadContentAsException("ReadContentAsString");
327 return InternalReadContentAsString();
330 // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
331 // and converts the content to the requested type. Stops at start tags and end tags.
332 public virtual object ReadContentAs(Type returnType
, IXmlNamespaceResolver namespaceResolver
) {
333 if (!CanReadContentAs()) {
334 throw CreateReadContentAsException("ReadContentAs");
337 string strContentValue
= InternalReadContentAsString();
338 if (returnType
== typeof(string)) {
339 return strContentValue
;
344 return XmlUntypedStringConverter
.Instance
.FromString(strContentValue
, returnType
, (namespaceResolver
== null ? this as IXmlNamespaceResolver
: namespaceResolver
));
346 return XmlUntypedConverter
.Untyped
.ChangeType(strContentValue
, returnType
, (namespaceResolver
== null ? this as IXmlNamespaceResolver
: namespaceResolver
));
349 catch (FormatException e
) {
350 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, returnType
.ToString(), e
, this as IXmlLineInfo
);
352 catch (InvalidCastException e
) {
353 throw new XmlException(Res
.Xml_ReadContentAsFormatException
, returnType
.ToString(), e
, this as IXmlLineInfo
);
358 // Returns the content of the current element as the most appropriate type. Moves to the node following the element's end tag.
359 public virtual object ReadElementContentAsObject() {
360 if (SetupReadElementContentAsXxx("ReadElementContentAsObject")) {
361 object value = ReadContentAsObject();
362 FinishReadElementContentAsXxx();
368 // Checks local name and namespace of the current element and returns its content as the most appropriate type. Moves to the node following the element's end tag.
369 public virtual object ReadElementContentAsObject(string localName
, string namespaceURI
) {
370 CheckElement(localName
, namespaceURI
);
371 return ReadElementContentAsObject();
374 // Returns the content of the current element as a boolean. Moves to the node following the element's end tag.
375 public virtual bool ReadElementContentAsBoolean() {
376 if (SetupReadElementContentAsXxx("ReadElementContentAsBoolean")) {
377 bool value = ReadContentAsBoolean();
378 FinishReadElementContentAsXxx();
381 return XmlConvert
.ToBoolean(string.Empty
);
384 // Checks local name and namespace of the current element and returns its content as a boolean. Moves to the node following the element's end tag.
385 public virtual bool ReadElementContentAsBoolean(string localName
, string namespaceURI
) {
386 CheckElement(localName
, namespaceURI
);
387 return ReadElementContentAsBoolean();
390 // Returns the content of the current element as a DateTime. Moves to the node following the element's end tag.
391 public virtual DateTime
ReadElementContentAsDateTime() {
392 if (SetupReadElementContentAsXxx("ReadElementContentAsDateTime")) {
393 DateTime
value = ReadContentAsDateTime();
394 FinishReadElementContentAsXxx();
397 return XmlConvert
.ToDateTime(string.Empty
, XmlDateTimeSerializationMode
.RoundtripKind
);
400 // Checks local name and namespace of the current element and returns its content as a DateTime.
401 // Moves to the node following the element's end tag.
402 public virtual DateTime
ReadElementContentAsDateTime(string localName
, string namespaceURI
) {
403 CheckElement(localName
, namespaceURI
);
404 return ReadElementContentAsDateTime();
407 // Returns the content of the current element as a double. Moves to the node following the element's end tag.
408 public virtual double ReadElementContentAsDouble() {
409 if (SetupReadElementContentAsXxx("ReadElementContentAsDouble")) {
410 double value = ReadContentAsDouble();
411 FinishReadElementContentAsXxx();
414 return XmlConvert
.ToDouble(string.Empty
);
417 // Checks local name and namespace of the current element and returns its content as a double.
418 // Moves to the node following the element's end tag.
419 public virtual double ReadElementContentAsDouble(string localName
, string namespaceURI
) {
420 CheckElement(localName
, namespaceURI
);
421 return ReadElementContentAsDouble();
424 // Returns the content of the current element as a float. Moves to the node following the element's end tag.
425 public virtual float ReadElementContentAsFloat() {
426 if (SetupReadElementContentAsXxx("ReadElementContentAsFloat")) {
427 float value = ReadContentAsFloat();
428 FinishReadElementContentAsXxx();
431 return XmlConvert
.ToSingle(string.Empty
);
434 // Checks local name and namespace of the current element and returns its content as a float.
435 // Moves to the node following the element's end tag.
436 public virtual float ReadElementContentAsFloat(string localName
, string namespaceURI
) {
437 CheckElement(localName
, namespaceURI
);
438 return ReadElementContentAsFloat();
441 // Returns the content of the current element as a decimal. Moves to the node following the element's end tag.
442 public virtual decimal ReadElementContentAsDecimal() {
443 if (SetupReadElementContentAsXxx("ReadElementContentAsDecimal")) {
444 decimal value = ReadContentAsDecimal();
445 FinishReadElementContentAsXxx();
448 return XmlConvert
.ToDecimal(string.Empty
);
451 // Checks local name and namespace of the current element and returns its content as a decimal.
452 // Moves to the node following the element's end tag.
453 public virtual decimal ReadElementContentAsDecimal(string localName
, string namespaceURI
) {
454 CheckElement(localName
, namespaceURI
);
455 return ReadElementContentAsDecimal();
458 // Returns the content of the current element as an int. Moves to the node following the element's end tag.
459 public virtual int ReadElementContentAsInt() {
460 if (SetupReadElementContentAsXxx("ReadElementContentAsInt")) {
461 int value = ReadContentAsInt();
462 FinishReadElementContentAsXxx();
465 return XmlConvert
.ToInt32(string.Empty
);
468 // Checks local name and namespace of the current element and returns its content as an int.
469 // Moves to the node following the element's end tag.
470 public virtual int ReadElementContentAsInt(string localName
, string namespaceURI
) {
471 CheckElement(localName
, namespaceURI
);
472 return ReadElementContentAsInt();
475 // Returns the content of the current element as a long. Moves to the node following the element's end tag.
476 public virtual long ReadElementContentAsLong() {
477 if (SetupReadElementContentAsXxx("ReadElementContentAsLong")) {
478 long value = ReadContentAsLong();
479 FinishReadElementContentAsXxx();
482 return XmlConvert
.ToInt64(string.Empty
);
485 // Checks local name and namespace of the current element and returns its content as a long.
486 // Moves to the node following the element's end tag.
487 public virtual long ReadElementContentAsLong(string localName
, string namespaceURI
) {
488 CheckElement(localName
, namespaceURI
);
489 return ReadElementContentAsLong();
492 // Returns the content of the current element as a string. Moves to the node following the element's end tag.
493 public virtual string ReadElementContentAsString() {
494 if (SetupReadElementContentAsXxx("ReadElementContentAsString")) {
495 string value = ReadContentAsString();
496 FinishReadElementContentAsXxx();
502 // Checks local name and namespace of the current element and returns its content as a string.
503 // Moves to the node following the element's end tag.
504 public virtual string ReadElementContentAsString(string localName
, string namespaceURI
) {
505 CheckElement(localName
, namespaceURI
);
506 return ReadElementContentAsString();
509 // Returns the content of the current element as the requested type. Moves to the node following the element's end tag.
510 public virtual object ReadElementContentAs(Type returnType
, IXmlNamespaceResolver namespaceResolver
) {
511 if (SetupReadElementContentAsXxx("ReadElementContentAs")) {
512 object value = ReadContentAs(returnType
, namespaceResolver
);
513 FinishReadElementContentAsXxx();
517 return (returnType
== typeof(string)) ? string.Empty
: XmlUntypedStringConverter
.Instance
.FromString(string.Empty
, returnType
, namespaceResolver
);
519 return (returnType
== typeof(string)) ? string.Empty
: XmlUntypedConverter
.Untyped
.ChangeType(string.Empty
, returnType
, namespaceResolver
);
523 // Checks local name and namespace of the current element and returns its content as the requested type.
524 // Moves to the node following the element's end tag.
525 public virtual object ReadElementContentAs(Type returnType
, IXmlNamespaceResolver namespaceResolver
, string localName
, string namespaceURI
) {
526 CheckElement(localName
, namespaceURI
);
527 return ReadElementContentAs(returnType
, namespaceResolver
);
530 // Attribute Accessors
531 // The number of attributes on the current node.
532 public abstract int AttributeCount { get; }
534 // Gets the value of the attribute with the specified Name
535 public abstract string GetAttribute(string name
);
537 // Gets the value of the attribute with the LocalName and NamespaceURI
538 public abstract string GetAttribute(string name
, string namespaceURI
);
540 // Gets the value of the attribute with the specified index.
541 public abstract string GetAttribute(int i
);
543 // Gets the value of the attribute with the specified index.
544 public virtual string this[int i
] {
546 return GetAttribute(i
);
550 // Gets the value of the attribute with the specified Name.
551 public virtual string this[string name
] {
553 return GetAttribute(name
);
557 // Gets the value of the attribute with the LocalName and NamespaceURI
558 public virtual string this[string name
, string namespaceURI
] {
560 return GetAttribute(name
, namespaceURI
);
564 // Moves to the attribute with the specified Name.
565 public abstract bool MoveToAttribute(string name
);
567 // Moves to the attribute with the specified LocalName and NamespaceURI.
568 public abstract bool MoveToAttribute(string name
, string ns
);
570 // Moves to the attribute with the specified index.
571 public virtual void MoveToAttribute(int i
) {
572 if (i
< 0 || i
>= AttributeCount
) {
573 throw new ArgumentOutOfRangeException("i");
576 MoveToFirstAttribute();
579 MoveToNextAttribute();
584 // Moves to the first attribute of the current node.
585 public abstract bool MoveToFirstAttribute();
587 // Moves to the next attribute.
588 public abstract bool MoveToNextAttribute();
590 // Moves to the element that contains the current attribute node.
591 public abstract bool MoveToElement();
593 // Parses the attribute value into one or more Text and/or EntityReference node types.
595 public abstract bool ReadAttributeValue();
597 // Moving through the Stream
598 // Reads the next node from the stream.
600 public abstract bool Read();
602 // Returns true when the XmlReader is positioned at the end of the stream.
603 public abstract bool EOF { get; }
605 // Closes the stream/TextReader (if CloseInput==true), changes the ReadState to Closed, and sets all the properties back to zero/empty string.
606 public virtual void Close() { }
608 // Returns the read state of the XmlReader.
609 public abstract ReadState ReadState { get; }
611 // Skips to the end tag of the current element.
612 public virtual void Skip() {
613 if (ReadState
!= ReadState
.Interactive
) {
621 // Gets the XmlNameTable associated with the XmlReader.
622 public abstract XmlNameTable NameTable { get; }
624 // Resolves a namespace prefix in the current element's scope.
625 public abstract string LookupNamespace(string prefix
);
627 // Returns true if the XmlReader can expand general entities.
628 public virtual bool CanResolveEntity
{
634 // Resolves the entity reference for nodes of NodeType EntityReference.
635 public abstract void ResolveEntity();
637 // Binary content access methods
638 // Returns true if the reader supports call to ReadContentAsBase64, ReadElementContentAsBase64, ReadContentAsBinHex and ReadElementContentAsBinHex.
639 public virtual bool CanReadBinaryContent
{
645 // Returns decoded bytes of the current base64 text content. Call this methods until it returns 0 to get all the data.
646 public virtual int ReadContentAsBase64(byte[] buffer
, int index
, int count
) {
647 throw new NotSupportedException(Res
.GetString(Res
.Xml_ReadBinaryContentNotSupported
, "ReadContentAsBase64"));
650 // Returns decoded bytes of the current base64 element content. Call this methods until it returns 0 to get all the data.
651 public virtual int ReadElementContentAsBase64(byte[] buffer
, int index
, int count
) {
652 throw new NotSupportedException(Res
.GetString(Res
.Xml_ReadBinaryContentNotSupported
, "ReadElementContentAsBase64"));
655 // Returns decoded bytes of the current binhex text content. Call this methods until it returns 0 to get all the data.
656 public virtual int ReadContentAsBinHex(byte[] buffer
, int index
, int count
) {
657 throw new NotSupportedException(Res
.GetString(Res
.Xml_ReadBinaryContentNotSupported
, "ReadContentAsBinHex"));
660 // Returns decoded bytes of the current binhex element content. Call this methods until it returns 0 to get all the data.
661 public virtual int ReadElementContentAsBinHex(byte[] buffer
, int index
, int count
) {
662 throw new NotSupportedException(Res
.GetString(Res
.Xml_ReadBinaryContentNotSupported
, "ReadElementContentAsBinHex"));
665 // Text streaming methods
667 // Returns true if the XmlReader supports calls to ReadValueChunk.
668 public virtual bool CanReadValueChunk
{
674 // Returns a chunk of the value of the current node. Call this method in a loop to get all the data.
675 // Use this method to get a streaming access to the value of the current node.
676 public virtual int ReadValueChunk(char[] buffer
, int index
, int count
) {
677 throw new NotSupportedException(Res
.GetString(Res
.Xml_ReadValueChunkNotSupported
));
681 // Virtual helper methods
682 // Reads the contents of an element as a string. Stops of comments, PIs or entity references.
683 [System
.ComponentModel
.EditorBrowsable(System
.ComponentModel
.EditorBrowsableState
.Never
)]
684 public virtual string ReadString() {
685 if (this.ReadState
!= ReadState
.Interactive
) {
688 this.MoveToElement();
689 if (this.NodeType
== XmlNodeType
.Element
) {
690 if (this.IsEmptyElement
) {
693 else if (!this.Read()) {
694 throw new InvalidOperationException(Res
.GetString(Res
.Xml_InvalidOperation
));
696 if (this.NodeType
== XmlNodeType
.EndElement
) {
700 string result
= string.Empty
;
701 while (IsTextualNode(this.NodeType
)) {
702 result
+= this.Value
;
711 // Checks whether the current node is a content (non-whitespace text, CDATA, Element, EndElement, EntityReference
712 // or EndEntity) node. If the node is not a content node, then the method skips ahead to the next content node or
713 // end of file. Skips over nodes of type ProcessingInstruction, DocumentType, Comment, Whitespace and SignificantWhitespace.
714 public virtual XmlNodeType
MoveToContent() {
716 switch (this.NodeType
) {
717 case XmlNodeType
.Attribute
:
719 goto case XmlNodeType
.Element
;
720 case XmlNodeType
.Element
:
721 case XmlNodeType
.EndElement
:
722 case XmlNodeType
.CDATA
:
723 case XmlNodeType
.Text
:
724 case XmlNodeType
.EntityReference
:
725 case XmlNodeType
.EndEntity
:
726 return this.NodeType
;
729 return this.NodeType
;
732 // Checks that the current node is an element and advances the reader to the next node.
733 public virtual void ReadStartElement() {
734 if (MoveToContent() != XmlNodeType
.Element
) {
735 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
740 // Checks that the current content node is an element with the given Name and advances the reader to the next node.
741 public virtual void ReadStartElement(string name
) {
742 if (MoveToContent() != XmlNodeType
.Element
) {
743 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
745 if (this.Name
== name
) {
749 throw new XmlException(Res
.Xml_ElementNotFound
, name
, this as IXmlLineInfo
);
753 // Checks that the current content node is an element with the given LocalName and NamespaceURI
754 // and advances the reader to the next node.
755 public virtual void ReadStartElement(string localname
, string ns
) {
756 if (MoveToContent() != XmlNodeType
.Element
) {
757 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
759 if (this.LocalName
== localname
&& this.NamespaceURI
== ns
) {
763 throw new XmlException(Res
.Xml_ElementNotFoundNs
, new string[2] { localname, ns }
, this as IXmlLineInfo
);
768 // Reads a text-only element.
769 [System
.ComponentModel
.EditorBrowsable(System
.ComponentModel
.EditorBrowsableState
.Never
)]
770 public virtual string ReadElementString() {
771 string result
= string.Empty
;
773 if (MoveToContent() != XmlNodeType
.Element
) {
774 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
776 if (!this.IsEmptyElement
) {
778 result
= ReadString();
779 if (this.NodeType
!= XmlNodeType
.EndElement
) {
780 throw new XmlException(Res
.Xml_UnexpectedNodeInSimpleContent
, new string[] { this.NodeType.ToString(), "ReadElementString" }
, this as IXmlLineInfo
);
790 // Checks that the Name property of the element found matches the given string before reading a text-only element.
791 [System
.ComponentModel
.EditorBrowsable(System
.ComponentModel
.EditorBrowsableState
.Never
)]
792 public virtual string ReadElementString(string name
) {
793 string result
= string.Empty
;
795 if (MoveToContent() != XmlNodeType
.Element
) {
796 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
798 if (this.Name
!= name
) {
799 throw new XmlException(Res
.Xml_ElementNotFound
, name
, this as IXmlLineInfo
);
802 if (!this.IsEmptyElement
) {
804 result
= ReadString();
805 if (this.NodeType
!= XmlNodeType
.EndElement
) {
806 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
816 // Checks that the LocalName and NamespaceURI properties of the element found matches the given strings
817 // before reading a text-only element.
818 [System
.ComponentModel
.EditorBrowsable(System
.ComponentModel
.EditorBrowsableState
.Never
)]
819 public virtual string ReadElementString(string localname
, string ns
) {
820 string result
= string.Empty
;
821 if (MoveToContent() != XmlNodeType
.Element
) {
822 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
824 if (this.LocalName
!= localname
|| this.NamespaceURI
!= ns
) {
825 throw new XmlException(Res
.Xml_ElementNotFoundNs
, new string[2] { localname, ns }
, this as IXmlLineInfo
);
828 if (!this.IsEmptyElement
) {
830 result
= ReadString();
831 if (this.NodeType
!= XmlNodeType
.EndElement
) {
832 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
843 // Checks that the current content node is an end tag and advances the reader to the next node.
844 public virtual void ReadEndElement() {
845 if (MoveToContent() != XmlNodeType
.EndElement
) {
846 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
851 // Calls MoveToContent and tests if the current content node is a start tag or empty element tag (XmlNodeType.Element).
852 public virtual bool IsStartElement() {
853 return MoveToContent() == XmlNodeType
.Element
;
856 // Calls MoveToContentand tests if the current content node is a start tag or empty element tag (XmlNodeType.Element) and if the
857 // Name property of the element found matches the given argument.
858 public virtual bool IsStartElement(string name
) {
859 return (MoveToContent() == XmlNodeType
.Element
) &&
863 // Calls MoveToContent and tests if the current content node is a start tag or empty element tag (XmlNodeType.Element) and if
864 // the LocalName and NamespaceURI properties of the element found match the given strings.
865 public virtual bool IsStartElement(string localname
, string ns
) {
866 return (MoveToContent() == XmlNodeType
.Element
) &&
867 (this.LocalName
== localname
&& this.NamespaceURI
== ns
);
870 // Reads to the following element with the given Name.
871 public virtual bool ReadToFollowing(string name
) {
872 if (name
== null || name
.Length
== 0) {
873 throw XmlConvert
.CreateInvalidNameArgumentException(name
, "name");
876 name
= NameTable
.Add(name
);
878 // find following element with that name
880 if (NodeType
== XmlNodeType
.Element
&& Ref
.Equal(name
, Name
)) {
887 // Reads to the following element with the given LocalName and NamespaceURI.
888 public virtual bool ReadToFollowing(string localName
, string namespaceURI
) {
889 if (localName
== null || localName
.Length
== 0) {
890 throw XmlConvert
.CreateInvalidNameArgumentException(localName
, "localName");
892 if (namespaceURI
== null) {
893 throw new ArgumentNullException("namespaceURI");
896 // atomize local name and namespace
897 localName
= NameTable
.Add(localName
);
898 namespaceURI
= NameTable
.Add(namespaceURI
);
900 // find following element with that name
902 if (NodeType
== XmlNodeType
.Element
&& Ref
.Equal(localName
, LocalName
) && Ref
.Equal(namespaceURI
, NamespaceURI
)) {
909 // Reads to the first descendant of the current element with the given Name.
910 public virtual bool ReadToDescendant(string name
) {
911 if (name
== null || name
.Length
== 0) {
912 throw XmlConvert
.CreateInvalidNameArgumentException(name
, "name");
914 // save the element or root depth
915 int parentDepth
= Depth
;
916 if (NodeType
!= XmlNodeType
.Element
) {
917 // adjust the depth if we are on root node
918 if (ReadState
== ReadState
.Initial
) {
919 Debug
.Assert(parentDepth
== 0);
926 else if (IsEmptyElement
) {
931 name
= NameTable
.Add(name
);
933 // find the descendant
934 while (Read() && Depth
> parentDepth
) {
935 if (NodeType
== XmlNodeType
.Element
&& Ref
.Equal(name
, Name
)) {
939 Debug
.Assert(NodeType
== XmlNodeType
.EndElement
|| NodeType
== XmlNodeType
.None
|| ReadState
== ReadState
.Error
);
943 // Reads to the first descendant of the current element with the given LocalName and NamespaceURI.
944 public virtual bool ReadToDescendant(string localName
, string namespaceURI
) {
945 if (localName
== null || localName
.Length
== 0) {
946 throw XmlConvert
.CreateInvalidNameArgumentException(localName
, "localName");
948 if (namespaceURI
== null) {
949 throw new ArgumentNullException("namespaceURI");
951 // save the element or root depth
952 int parentDepth
= Depth
;
953 if (NodeType
!= XmlNodeType
.Element
) {
954 // adjust the depth if we are on root node
955 if (ReadState
== ReadState
.Initial
) {
956 Debug
.Assert(parentDepth
== 0);
963 else if (IsEmptyElement
) {
967 // atomize local name and namespace
968 localName
= NameTable
.Add(localName
);
969 namespaceURI
= NameTable
.Add(namespaceURI
);
971 // find the descendant
972 while (Read() && Depth
> parentDepth
) {
973 if (NodeType
== XmlNodeType
.Element
&& Ref
.Equal(localName
, LocalName
) && Ref
.Equal(namespaceURI
, NamespaceURI
)) {
977 Debug
.Assert(NodeType
== XmlNodeType
.EndElement
);
981 // Reads to the next sibling of the current element with the given Name.
982 public virtual bool ReadToNextSibling(string name
) {
983 if (name
== null || name
.Length
== 0) {
984 throw XmlConvert
.CreateInvalidNameArgumentException(name
, "name");
988 name
= NameTable
.Add(name
);
990 // find the next sibling
993 if (!SkipSubtree()) {
997 if (nt
== XmlNodeType
.Element
&& Ref
.Equal(name
, Name
)) {
1000 } while (nt
!= XmlNodeType
.EndElement
&& !EOF
);
1004 // Reads to the next sibling of the current element with the given LocalName and NamespaceURI.
1005 public virtual bool ReadToNextSibling(string localName
, string namespaceURI
) {
1006 if (localName
== null || localName
.Length
== 0) {
1007 throw XmlConvert
.CreateInvalidNameArgumentException(localName
, "localName");
1009 if (namespaceURI
== null) {
1010 throw new ArgumentNullException("namespaceURI");
1013 // atomize local name and namespace
1014 localName
= NameTable
.Add(localName
);
1015 namespaceURI
= NameTable
.Add(namespaceURI
);
1017 // find the next sibling
1020 if (!SkipSubtree()) {
1024 if (nt
== XmlNodeType
.Element
&& Ref
.Equal(localName
, LocalName
) && Ref
.Equal(namespaceURI
, NamespaceURI
)) {
1027 } while (nt
!= XmlNodeType
.EndElement
&& !EOF
);
1031 // Returns true if the given argument is a valid Name.
1032 public static bool IsName(string str
) {
1034 throw new NullReferenceException();
1036 return ValidateNames
.IsNameNoNamespaces(str
);
1039 // Returns true if the given argument is a valid NmToken.
1040 public static bool IsNameToken(string str
) {
1042 throw new NullReferenceException();
1044 return ValidateNames
.IsNmtokenNoNamespaces(str
);
1047 // Returns the inner content (including markup) of an element or attribute as a string.
1048 public virtual string ReadInnerXml() {
1049 if (ReadState
!= ReadState
.Interactive
) {
1050 return string.Empty
;
1052 if ((this.NodeType
!= XmlNodeType
.Attribute
) && (this.NodeType
!= XmlNodeType
.Element
)) {
1054 return string.Empty
;
1057 StringWriter sw
= new StringWriter(CultureInfo
.InvariantCulture
);
1058 XmlWriter xtw
= CreateWriterForInnerOuterXml(sw
);
1061 if (this.NodeType
== XmlNodeType
.Attribute
) {
1062 #if !SILVERLIGHT // Removing dependency on XmlTextWriter
1063 ((XmlTextWriter
)xtw
).QuoteChar
= this.QuoteChar
;
1065 WriteAttributeValue(xtw
);
1067 if (this.NodeType
== XmlNodeType
.Element
) {
1068 this.WriteNode(xtw
, false);
1074 return sw
.ToString();
1077 // Writes the content (inner XML) of the current node into the provided XmlWriter.
1078 private void WriteNode(XmlWriter xtw
, bool defattr
) {
1080 Debug
.Assert(xtw
is XmlTextWriter
);
1082 int d
= this.NodeType
== XmlNodeType
.None
? -1 : this.Depth
;
1083 while (this.Read() && (d
< this.Depth
)) {
1084 switch (this.NodeType
) {
1085 case XmlNodeType
.Element
:
1086 xtw
.WriteStartElement(this.Prefix
, this.LocalName
, this.NamespaceURI
);
1087 #if !SILVERLIGHT // Removing dependency on XmlTextWriter
1088 ((XmlTextWriter
)xtw
).QuoteChar
= this.QuoteChar
;
1090 xtw
.WriteAttributes(this, defattr
);
1091 if (this.IsEmptyElement
) {
1092 xtw
.WriteEndElement();
1095 case XmlNodeType
.Text
:
1096 xtw
.WriteString(this.Value
);
1098 case XmlNodeType
.Whitespace
:
1099 case XmlNodeType
.SignificantWhitespace
:
1100 xtw
.WriteWhitespace(this.Value
);
1102 case XmlNodeType
.CDATA
:
1103 xtw
.WriteCData(this.Value
);
1105 case XmlNodeType
.EntityReference
:
1106 xtw
.WriteEntityRef(this.Name
);
1108 case XmlNodeType
.XmlDeclaration
:
1109 case XmlNodeType
.ProcessingInstruction
:
1110 xtw
.WriteProcessingInstruction(this.Name
, this.Value
);
1112 case XmlNodeType
.DocumentType
:
1113 xtw
.WriteDocType(this.Name
, this.GetAttribute("PUBLIC"), this.GetAttribute("SYSTEM"), this.Value
);
1115 case XmlNodeType
.Comment
:
1116 xtw
.WriteComment(this.Value
);
1118 case XmlNodeType
.EndElement
:
1119 xtw
.WriteFullEndElement();
1123 if (d
== this.Depth
&& this.NodeType
== XmlNodeType
.EndElement
) {
1128 // Writes the attribute into the provided XmlWriter.
1129 private void WriteAttributeValue(XmlWriter xtw
) {
1130 string attrName
= this.Name
;
1131 while (ReadAttributeValue()) {
1132 if (this.NodeType
== XmlNodeType
.EntityReference
) {
1133 xtw
.WriteEntityRef(this.Name
);
1136 xtw
.WriteString(this.Value
);
1139 this.MoveToAttribute(attrName
);
1142 // Returns the current element and its descendants or an attribute as a string.
1143 public virtual string ReadOuterXml() {
1144 if (ReadState
!= ReadState
.Interactive
) {
1145 return string.Empty
;
1147 if ((this.NodeType
!= XmlNodeType
.Attribute
) && (this.NodeType
!= XmlNodeType
.Element
)) {
1149 return string.Empty
;
1152 StringWriter sw
= new StringWriter(CultureInfo
.InvariantCulture
);
1153 XmlWriter xtw
= CreateWriterForInnerOuterXml(sw
);
1156 if (this.NodeType
== XmlNodeType
.Attribute
) {
1157 xtw
.WriteStartAttribute(this.Prefix
, this.LocalName
, this.NamespaceURI
);
1158 WriteAttributeValue(xtw
);
1159 xtw
.WriteEndAttribute();
1162 xtw
.WriteNode(this, false);
1168 return sw
.ToString();
1171 private XmlWriter
CreateWriterForInnerOuterXml(StringWriter sw
) {
1172 #if SILVERLIGHT // Removing dependency on XmlTextWriter
1173 XmlWriterSettings writerSettings
= new XmlWriterSettings();
1174 writerSettings
.OmitXmlDeclaration
= true;
1175 writerSettings
.ConformanceLevel
= ConformanceLevel
.Fragment
;
1176 writerSettings
.CheckCharacters
= false;
1177 writerSettings
.NewLineHandling
= NewLineHandling
.None
;
1178 XmlWriter w
= XmlWriter
.Create(sw
, writerSettings
);
1180 XmlTextWriter w
= new XmlTextWriter(sw
);
1181 // This is a V1 hack; we can put a custom implementation of ReadOuterXml on XmlTextReader/XmlValidatingReader
1182 SetNamespacesFlag(w
);
1187 #if !SILVERLIGHT // Removing dependency on XmlTextWriter
1188 void SetNamespacesFlag(XmlTextWriter xtw
) {
1189 XmlTextReader tr
= this as XmlTextReader
;
1191 xtw
.Namespaces
= tr
.Namespaces
;
1194 #pragma warning disable 618
1195 XmlValidatingReader vr
= this as XmlValidatingReader
;
1197 xtw
.Namespaces
= vr
.Namespaces
;
1200 #pragma warning restore 618
1204 // Returns an XmlReader that will read only the current element and its descendants and then go to EOF state.
1205 public virtual XmlReader
ReadSubtree() {
1206 if (NodeType
!= XmlNodeType
.Element
) {
1207 throw new InvalidOperationException(Res
.GetString(Res
.Xml_ReadSubtreeNotOnElement
));
1209 return new XmlSubtreeReader(this);
1212 // Returns true when the current node has any attributes.
1213 public virtual bool HasAttributes
{
1215 return AttributeCount
> 0;
1220 // IDisposable interface
1222 public void Dispose() {
1226 protected virtual void Dispose(bool disposing
) { //the boolean flag may be used by subclasses to differentiate between disposing and finalizing
1227 if (disposing
&& ReadState
!= ReadState
.Closed
) {
1235 // Validation support
1237 internal virtual XmlNamespaceManager NamespaceManager
{
1244 static internal bool IsTextualNode(XmlNodeType nodeType
) {
1246 // This code verifies IsTextualNodeBitmap mapping of XmlNodeType to a bool specifying
1247 // whether the node is 'textual' = Text, CDATA, Whitespace or SignificantWhitespace.
1248 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.None
)));
1249 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Element
)));
1250 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Attribute
)));
1251 Debug
.Assert(0 != (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Text
)));
1252 Debug
.Assert(0 != (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.CDATA
)));
1253 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.EntityReference
)));
1254 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Entity
)));
1255 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.ProcessingInstruction
)));
1256 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Comment
)));
1257 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Document
)));
1258 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.DocumentType
)));
1259 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.DocumentFragment
)));
1260 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Notation
)));
1261 Debug
.Assert(0 != (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.Whitespace
)));
1262 Debug
.Assert(0 != (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.SignificantWhitespace
)));
1263 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.EndElement
)));
1264 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.EndEntity
)));
1265 Debug
.Assert(0 == (IsTextualNodeBitmap
& (1 << (int)XmlNodeType
.XmlDeclaration
)));
1267 return 0 != (IsTextualNodeBitmap
& (1 << (int)nodeType
));
1270 static internal bool CanReadContentAs(XmlNodeType nodeType
) {
1272 // This code verifies IsTextualNodeBitmap mapping of XmlNodeType to a bool specifying
1273 // whether ReadContentAsXxx calls are allowed on his node type
1274 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.None
)));
1275 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Element
)));
1276 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Attribute
)));
1277 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Text
)));
1278 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.CDATA
)));
1279 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.EntityReference
)));
1280 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Entity
)));
1281 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.ProcessingInstruction
)));
1282 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Comment
)));
1283 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Document
)));
1284 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.DocumentType
)));
1285 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.DocumentFragment
)));
1286 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Notation
)));
1287 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.Whitespace
)));
1288 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.SignificantWhitespace
)));
1289 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.EndElement
)));
1290 Debug
.Assert(0 != (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.EndEntity
)));
1291 Debug
.Assert(0 == (CanReadContentAsBitmap
& (1 << (int)XmlNodeType
.XmlDeclaration
)));
1293 return 0 != (CanReadContentAsBitmap
& (1 << (int)nodeType
));
1296 static internal bool HasValueInternal(XmlNodeType nodeType
) {
1298 // This code verifies HasValueBitmap mapping of XmlNodeType to a bool specifying
1299 // whether the node can have a non-empty Value
1300 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.None
)));
1301 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.Element
)));
1302 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.Attribute
)));
1303 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.Text
)));
1304 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.CDATA
)));
1305 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.EntityReference
)));
1306 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.Entity
)));
1307 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.ProcessingInstruction
)));
1308 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.Comment
)));
1309 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.Document
)));
1310 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.DocumentType
)));
1311 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.DocumentFragment
)));
1312 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.Notation
)));
1313 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.Whitespace
)));
1314 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.SignificantWhitespace
)));
1315 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.EndElement
)));
1316 Debug
.Assert(0 == (HasValueBitmap
& (1 << (int)XmlNodeType
.EndEntity
)));
1317 Debug
.Assert(0 != (HasValueBitmap
& (1 << (int)XmlNodeType
.XmlDeclaration
)));
1319 return 0 != (HasValueBitmap
& (1 << (int)nodeType
));
1325 //SkipSubTree is called whenever validation of the skipped subtree is required on a reader with XsdValidation
1326 private bool SkipSubtree() {
1328 if (NodeType
== XmlNodeType
.Element
&& !IsEmptyElement
) {
1331 while (Read() && depth
< Depth
) {
1332 // Nothing, just read on
1336 if (NodeType
== XmlNodeType
.EndElement
)
1346 internal void CheckElement(string localName
, string namespaceURI
) {
1347 if (localName
== null || localName
.Length
== 0) {
1348 throw XmlConvert
.CreateInvalidNameArgumentException(localName
, "localName");
1350 if (namespaceURI
== null) {
1351 throw new ArgumentNullException("namespaceURI");
1353 if (NodeType
!= XmlNodeType
.Element
) {
1354 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString(), this as IXmlLineInfo
);
1356 if (LocalName
!= localName
|| NamespaceURI
!= namespaceURI
) {
1357 throw new XmlException(Res
.Xml_ElementNotFoundNs
, new string[2] { localName, namespaceURI }
, this as IXmlLineInfo
);
1361 internal Exception
CreateReadContentAsException(string methodName
) {
1362 return CreateReadContentAsException(methodName
, NodeType
, this as IXmlLineInfo
);
1365 internal Exception
CreateReadElementContentAsException(string methodName
) {
1366 return CreateReadElementContentAsException(methodName
, NodeType
, this as IXmlLineInfo
);
1369 internal bool CanReadContentAs() {
1370 return CanReadContentAs(this.NodeType
);
1373 static internal Exception
CreateReadContentAsException(string methodName
, XmlNodeType nodeType
, IXmlLineInfo lineInfo
) {
1374 return new InvalidOperationException(AddLineInfo(Res
.GetString(Res
.Xml_InvalidReadContentAs
, new string[] { methodName, nodeType.ToString() }
), lineInfo
));
1377 static internal Exception
CreateReadElementContentAsException(string methodName
, XmlNodeType nodeType
, IXmlLineInfo lineInfo
) {
1378 return new InvalidOperationException(AddLineInfo(Res
.GetString(Res
.Xml_InvalidReadElementContentAs
, new string[] { methodName, nodeType.ToString() }
), lineInfo
));
1381 static string AddLineInfo(string message
, IXmlLineInfo lineInfo
) {
1382 if (lineInfo
!= null) {
1383 string[] lineArgs
= new string[2];
1384 lineArgs
[0] = lineInfo
.LineNumber
.ToString(CultureInfo
.InvariantCulture
);
1385 lineArgs
[1] = lineInfo
.LinePosition
.ToString(CultureInfo
.InvariantCulture
);
1386 message
+= " " + Res
.GetString(Res
.Xml_ErrorPosition
, lineArgs
);
1391 internal string InternalReadContentAsString() {
1392 string value = string.Empty
;
1393 BufferBuilder sb
= null;
1395 switch (this.NodeType
) {
1396 case XmlNodeType
.Attribute
:
1398 case XmlNodeType
.Text
:
1399 case XmlNodeType
.Whitespace
:
1400 case XmlNodeType
.SignificantWhitespace
:
1401 case XmlNodeType
.CDATA
:
1402 // merge text content
1403 if (value.Length
== 0) {
1408 sb
= new BufferBuilder();
1411 sb
.Append(this.Value
);
1414 case XmlNodeType
.ProcessingInstruction
:
1415 case XmlNodeType
.Comment
:
1416 case XmlNodeType
.EndEntity
:
1417 // skip comments, pis and end entity nodes
1419 case XmlNodeType
.EntityReference
:
1420 if (this.CanResolveEntity
) {
1421 this.ResolveEntity();
1425 case XmlNodeType
.EndElement
:
1429 } while ((this.AttributeCount
!= 0) ? this.ReadAttributeValue() : this.Read());
1432 return (sb
== null) ? value : sb
.ToString();
1435 private bool SetupReadElementContentAsXxx(string methodName
) {
1436 if (this.NodeType
!= XmlNodeType
.Element
) {
1437 throw CreateReadElementContentAsException(methodName
);
1440 bool isEmptyElement
= this.IsEmptyElement
;
1442 // move to content or beyond the empty element
1445 if (isEmptyElement
) {
1449 XmlNodeType nodeType
= this.NodeType
;
1450 if (nodeType
== XmlNodeType
.EndElement
) {
1454 else if (nodeType
== XmlNodeType
.Element
) {
1455 throw new XmlException(Res
.Xml_MixedReadElementContentAs
, string.Empty
, this as IXmlLineInfo
);
1460 private void FinishReadElementContentAsXxx() {
1461 if (this.NodeType
!= XmlNodeType
.EndElement
) {
1462 throw new XmlException(Res
.Xml_InvalidNodeType
, this.NodeType
.ToString());
1467 internal bool IsDefaultInternal
{
1469 #if SILVERLIGHT // Removing dependency on XmlSchema
1470 return this.IsDefault
;
1472 if (this.IsDefault
) {
1475 IXmlSchemaInfo schemaInfo
= this.SchemaInfo
;
1476 if (schemaInfo
!= null && schemaInfo
.IsDefault
) {
1485 internal virtual IDtdInfo DtdInfo
{
1492 #if !SILVERLIGHT // Needed only for XmlTextReader or XmlValidatingReader
1493 internal static Encoding
GetEncoding(XmlReader reader
) {
1494 XmlTextReaderImpl tri
= GetXmlTextReaderImpl(reader
);
1495 return tri
!= null ? tri
.Encoding
: null;
1499 internal static ConformanceLevel
GetV1ConformanceLevel(XmlReader reader
) {
1500 XmlTextReaderImpl tri
= GetXmlTextReaderImpl(reader
);
1501 return tri
!= null ? tri
.V1ComformanceLevel
: ConformanceLevel
.Document
;
1504 private static XmlTextReaderImpl
GetXmlTextReaderImpl(XmlReader reader
) {
1505 XmlTextReaderImpl tri
= reader
as XmlTextReaderImpl
;
1510 #if !SILVERLIGHT // Needed only for XmlTextReader or XmlValidatingReader
1511 XmlTextReader tr
= reader
as XmlTextReader
;
1516 XmlValidatingReaderImpl vri
= reader
as XmlValidatingReaderImpl
;
1518 return vri
.ReaderImpl
;
1520 #pragma warning disable 618
1521 XmlValidatingReader vr
= reader
as XmlValidatingReader
;
1522 #pragma warning restore 618
1524 return vr
.Impl
.ReaderImpl
;
1531 // Static methods for creating readers
1534 // Creates an XmlReader for parsing XML from the given Uri.
1536 [ResourceConsumption(ResourceScope
.Machine
)]
1537 [ResourceExposure(ResourceScope
.Machine
)]
1539 public static XmlReader
Create(string inputUri
) {
1540 return XmlReader
.Create(inputUri
, (XmlReaderSettings
)null, (XmlParserContext
)null);
1543 // Creates an XmlReader according to the settings for parsing XML from the given Uri.
1545 [ResourceConsumption(ResourceScope
.Machine
)]
1546 [ResourceExposure(ResourceScope
.Machine
)]
1548 public static XmlReader
Create(string inputUri
, XmlReaderSettings settings
) {
1549 return XmlReader
.Create(inputUri
, settings
, (XmlParserContext
)null);
1552 // Creates an XmlReader according to the settings and parser context for parsing XML from the given Uri.
1554 [ResourceConsumption(ResourceScope
.Machine
)]
1555 [ResourceExposure(ResourceScope
.Machine
)]
1557 public static XmlReader
Create(String inputUri
, XmlReaderSettings settings
, XmlParserContext inputContext
) {
1558 if (settings
== null) {
1559 settings
= new XmlReaderSettings();
1561 return settings
.CreateReader(inputUri
, inputContext
);
1564 // Creates an XmlReader according for parsing XML from the given stream.
1565 public static XmlReader
Create(Stream input
) {
1566 return Create(input
, (XmlReaderSettings
)null, (string)string.Empty
);
1569 // Creates an XmlReader according to the settings for parsing XML from the given stream.
1570 public static XmlReader
Create(Stream input
, XmlReaderSettings settings
) {
1571 return Create(input
, settings
, string.Empty
);
1574 // Creates an XmlReader according to the settings and base Uri for parsing XML from the given stream.
1575 public static XmlReader
Create(Stream input
, XmlReaderSettings settings
, String baseUri
) {
1576 if (settings
== null) {
1577 settings
= new XmlReaderSettings();
1579 return settings
.CreateReader(input
, null, (string)baseUri
, null);
1582 // Creates an XmlReader according to the settings and parser context for parsing XML from the given stream.
1583 public static XmlReader
Create(Stream input
, XmlReaderSettings settings
, XmlParserContext inputContext
) {
1584 if (settings
== null) {
1585 settings
= new XmlReaderSettings();
1587 return settings
.CreateReader(input
, null, (string)string.Empty
, inputContext
);
1590 // Creates an XmlReader according for parsing XML from the given TextReader.
1591 public static XmlReader
Create(TextReader input
) {
1592 return Create(input
, (XmlReaderSettings
)null, (string)string.Empty
);
1595 // Creates an XmlReader according to the settings for parsing XML from the given TextReader.
1596 public static XmlReader
Create(TextReader input
, XmlReaderSettings settings
) {
1597 return Create(input
, settings
, string.Empty
);
1600 // Creates an XmlReader according to the settings and baseUri for parsing XML from the given TextReader.
1601 public static XmlReader
Create(TextReader input
, XmlReaderSettings settings
, String baseUri
) {
1602 if (settings
== null) {
1603 settings
= new XmlReaderSettings();
1605 return settings
.CreateReader(input
, baseUri
, null);
1608 // Creates an XmlReader according to the settings and parser context for parsing XML from the given TextReader.
1609 public static XmlReader
Create(TextReader input
, XmlReaderSettings settings
, XmlParserContext inputContext
) {
1610 if (settings
== null) {
1611 settings
= new XmlReaderSettings();
1613 return settings
.CreateReader(input
, string.Empty
, inputContext
);
1616 // Creates an XmlReader according to the settings wrapped over the given reader.
1617 public static XmlReader
Create(XmlReader reader
, XmlReaderSettings settings
) {
1618 if (settings
== null) {
1619 settings
= new XmlReaderSettings();
1621 return settings
.CreateReader(reader
);
1626 // NOTE: This method is called via reflection from System.Data.dll and from Analysis Services in Yukon.
1627 // Do not change its signature without notifying the appropriate teams!
1629 internal static XmlReader
CreateSqlReader(Stream input
, XmlReaderSettings settings
, XmlParserContext inputContext
) {
1630 if (input
== null) {
1631 throw new ArgumentNullException("input");
1633 if (settings
== null) {
1634 settings
= new XmlReaderSettings();
1639 // allocate byte buffer
1640 byte[] bytes
= new byte[CalcBufferSize(input
)];
1644 // catch the binary XML input and dump it into a local file (for debugging and testing purposes)
1646 // create dump file name
1647 string dumpFileNameBase
= "~CreateSqlReaderInputDump";
1648 string dumpFileName
;
1652 dumpFileName
= Path
.GetFullPath(string.Concat(dumpFileNameBase
, i
.ToString(), ".bmx"));
1653 } while (File
.Exists(dumpFileName
));
1655 // dump the input into the file
1656 FileStream fs
= new FileStream(dumpFileName
, FileMode
.Create
, FileAccess
.ReadWrite
);
1657 byte[] buffer
= new byte[4096];
1659 while ((bytesRead
= input
.Read(buffer
, 0, buffer
.Length
)) > 0) {
1660 fs
.Write(buffer
, 0, bytesRead
);
1662 fs
.Seek(0, SeekOrigin
.Begin
);
1664 // make sure it will get closed
1665 if (settings
.CloseInput
) {
1669 settings
= settings
.Clone();
1670 settings
.CloseInput
= true;
1676 read
= input
.Read(bytes
, byteCount
, bytes
.Length
- byteCount
);
1678 } while (read
> 0 && byteCount
< 2);
1680 // create text or binary XML reader depenting on the stream first 2 bytes
1681 if (byteCount
>= 2 && (bytes
[0] == 0xdf && bytes
[1] == 0xff)) {
1682 if ( inputContext
!= null )
1683 throw new ArgumentException(Res
.GetString(Res
.XmlBinary_NoParserContext
), "inputContext");
1684 reader
= new XmlSqlBinaryReader(input
, bytes
, byteCount
, string.Empty
, settings
.CloseInput
, settings
);
1687 reader
= new XmlTextReaderImpl(input
, bytes
, byteCount
, settings
, null, string.Empty
, inputContext
, settings
.CloseInput
);
1690 // wrap with validating reader
1691 if ( settings
.ValidationType
!= ValidationType
.None
) {
1692 reader
= settings
.AddValidation( reader
);
1695 if (settings
.Async
) {
1696 reader
= XmlAsyncCheckReader
.CreateAsyncCheckWrapper(reader
);
1703 internal static int CalcBufferSize(Stream input
) {
1704 // determine the size of byte buffer
1705 int bufferSize
= DefaultBufferSize
;
1706 if (input
.CanSeek
) {
1707 long len
= input
.Length
;
1708 if (len
< bufferSize
) {
1709 bufferSize
= checked((int)len
);
1711 else if (len
> MaxStreamLengthForDefaultBufferSize
) {
1712 bufferSize
= BiggerBufferSize
;
1716 // return the byte buffer size
1720 #if !SILVERLIGHT // This is used for displaying the state of the XmlReader in Watch/Locals windows in the Visual Studio during debugging
1721 private object debuggerDisplayProxy { get { return new XmlReaderDebuggerDisplayProxy(this); }
}
1723 [DebuggerDisplay("{ToString()}")]
1724 struct XmlReaderDebuggerDisplayProxy
{
1727 internal XmlReaderDebuggerDisplayProxy( XmlReader reader
) {
1728 this.reader
= reader
;
1731 public override string ToString() {
1732 XmlNodeType nt
= reader
.NodeType
;
1733 string result
= nt
.ToString();
1735 case XmlNodeType
.Element
:
1736 case XmlNodeType
.EndElement
:
1737 case XmlNodeType
.EntityReference
:
1738 case XmlNodeType
.EndEntity
:
1739 result
+= ", Name=\"" + reader
.Name
+ '"';
1741 case XmlNodeType
.Attribute
:
1742 case XmlNodeType
.ProcessingInstruction
:
1743 result
+= ", Name=\"" + reader
.Name
+ "\", Value=\"" + XmlConvert
.EscapeValueForDebuggerDisplay( reader
.Value
) + '"';
1745 case XmlNodeType
.Text
:
1746 case XmlNodeType
.Whitespace
:
1747 case XmlNodeType
.SignificantWhitespace
:
1748 case XmlNodeType
.Comment
:
1749 case XmlNodeType
.XmlDeclaration
:
1750 case XmlNodeType
.CDATA
:
1751 result
+= ", Value=\"" + XmlConvert
.EscapeValueForDebuggerDisplay( reader
.Value
) + '"';
1753 case XmlNodeType
.DocumentType
:
1754 result
+= ", Name=\"" + reader
.Name
+ "'";
1755 result
+= ", SYSTEM=\"" + reader
.GetAttribute( "SYSTEM" ) + '"';
1756 result
+= ", PUBLIC=\"" + reader
.GetAttribute( "PUBLIC" ) + '"';
1757 result
+= ", Value=\"" + XmlConvert
.EscapeValueForDebuggerDisplay( reader
.Value
) + '"';