XmlReader 类

定义

表示提供对 XML 数据进行快速、非缓存、只进访问的读取器。

public ref class XmlReader abstract : IDisposable
public ref class XmlReader abstract
public abstract class XmlReader : IDisposable
public abstract class XmlReader
type XmlReader = class
    interface IDisposable
type XmlReader = class
Public MustInherit Class XmlReader
Implements IDisposable
Public MustInherit Class XmlReader
继承
XmlReader
派生
实现

示例

以下示例代码演示如何使用异步 API 分析 XML。

async Task TestReader(System.IO.Stream stream)
{
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.Async = true;

    using (XmlReader reader = XmlReader.Create(stream, settings))
    {
        while (await reader.ReadAsync())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    Console.WriteLine("Start Element {0}", reader.Name);
                    break;
                case XmlNodeType.Text:
                    Console.WriteLine("Text Node: {0}",
                             await reader.GetValueAsync());
                    break;
                case XmlNodeType.EndElement:
                    Console.WriteLine("End Element {0}", reader.Name);
                    break;
                default:
                    Console.WriteLine("Other node {0} with value {1}",
                                    reader.NodeType, reader.Value);
                    break;
            }
        }
    }
}
Public Async Function TestReader(stream As System.IO.Stream) As Task
    Dim settings As New XmlReaderSettings()
    settings.Async = True

    Using reader As XmlReader = XmlReader.Create(stream, settings)
        While (Await reader.ReadAsync())
            Select Case (reader.NodeType)
                Case XmlNodeType.Element
                    Console.WriteLine("Start Element {0}", reader.Name)
                Case XmlNodeType.Text
                    Console.WriteLine("Text Node: {0}",
                             Await reader.GetValueAsync())
                Case XmlNodeType.EndElement
                    Console.WriteLine("End Element {0}", reader.Name)
                Case Else
                    Console.WriteLine("Other node {0} with value {1}",
                                    reader.NodeType, reader.Value)
            End Select
        End While
    End Using
End Function

注解

XmlReader 提供对文档或流中 XML 数据的仅向前只读访问权限。 此类符合 W3C 可扩展标记语言 (XML) 1.0 (第四版) XML 1.0 (第三版中的命名空间) 建议。

XmlReader 使用 方法可以浏览 XML 数据并读取节点的内容。 类的属性反映当前节点的值,该节点是读取器的位置。 ReadState属性值指示 XML 读取器的当前状态。 例如, 属性由 XmlReader.Read 方法和 ReadState.ClosedXmlReader.Close 方法设置为 ReadState.InitialXmlReader 还针对 DTD 或架构提供数据一致性检查和验证。

XmlReader 使用拉取模型检索数据。 此模型:

  • 通过自然的自上而下程序优化来简化状态管理。

  • 支持多个输入流和分层。

  • 使客户端能够向分析程序提供直接写入字符串的缓冲区,从而避免额外的字符串复制。

  • 支持选择性处理。 客户端可以跳过项目并处理应用程序感兴趣的项。 还可以提前设置属性来管理 XML 流的处理方式, (例如规范化) 。

本部分内容:

创建 XML 读取器验证 XML 数据符合性浏览节点读取 XML 元素 读取XML 属性读取 XML 内容转换为 CLR 类型异步编程安全注意事项

创建 XML 读取器

Create使用 方法创建XmlReader实例。

尽管 .NET Framework 提供了 类的具体实现XmlReader(例如 XmlTextReaderXmlNodeReaderXmlValidatingReader 类),但建议仅在以下情况下使用专用类:

  • 如果要从 XmlNode 对象读取 XML DOM 子树,请使用 XmlNodeReader 类。 (但是,此类不支持 DTD 或架构验证。)

  • 如果必须根据请求扩展实体,不希望将文本内容规范化,或者不希望返回默认属性,请使用 XmlTextReader 类。

若要指定要在 XML 读取器上启用的功能集,请将 对象 System.Xml.XmlReaderSettings 传递给 Create 方法。 可以使用单个 System.Xml.XmlReaderSettings 对象创建具有相同功能的多个读取器,或修改对象 System.Xml.XmlReaderSettings 以创建具有不同功能集的新读取器。 还可以轻松地将功能添加到现有读取器。

如果不使用 System.Xml.XmlReaderSettings 对象,则使用默认设置。 有关详细信息, Create 请参阅参考页。

XmlReader对 XML 分析错误引发 。XmlException 引发异常后,读取器的状态不可预测。 例如,报告的节点类型可能与当前节点的实际节点类型不同。 ReadState使用 属性检查读取器是否处于错误状态。

验证 XML 数据

若要定义 XML 文档的结构及其元素关系、数据类型和内容约束,请使用文档类型定义 (DTD) 或 XML 架构定义语言 (XSD) 架构。 如果 XML 文档满足 W3C XML 1.0 建议定义的所有语法要求,则它被视为格式良好。 如果格式正确且符合其 DTD 或架构定义的约束,则它被视为有效。 (请参阅 W3C XML 架构第 1 部分:结构和W3C XML 架构第 2 部分:数据类型 建议。) 因此,尽管所有有效的 XML 文档格式正确,但并非所有格式正确的 XML 文档都有效。

可以针对 DTD、内联 XSD 架构或存储在 XmlSchemaSet 缓存) 对象 (XSD 架构来验证数据;参考页上介绍了 Create 这些方案。 XmlReader 不支持 XML-Data 简化 (XDR) 架构验证。

在 类上 XmlReaderSettings 使用以下设置来指定实例支持的验证类型(如果有 XmlReader )。

使用此 XmlReaderSettings 成员 若要指定
DtdProcessing 属性 是否允许 DTD 处理。 默认设置为不允许 DTD 处理。
ValidationType 属性 读取器是否应验证数据,以及执行哪种类型的验证 (DTD 或架构) 。 默认设置为无数据验证。
ValidationEventHandler 事件 一个事件处理程序,用于接收有关验证事件的信息。 如果未提供事件处理程序,在出现第一个验证错误时将引发 XmlException
ValidationFlags 属性 通过 XmlSchemaValidationFlags 枚举成员提供的其他验证选项:

- AllowXmlAttributes-- 允许 XML 属性在实例文档中 (xml:*) ,即使这些属性未在架构中定义也是如此。 属性基于其数据类型进行验证。 XmlSchemaValidationFlags请参阅参考页,了解在特定方案中要使用的设置。 (默认禁用。)
- ProcessIdentityConstraints--处理验证期间遇到的 (xs:IDxs:IDREFxs:keyxs:keyrefxs:unique 、) 的标识约束。 (默认启用。)
- ProcessSchemaLocation --处理 由 xsi:schemaLocationxsi:noNamespaceSchemaLocation 属性指定的架构。 (默认启用。)
- ProcessInlineSchema-- 在验证期间处理内联 XML 架构。 (默认禁用。)
- ReportValidationWarnings--如果发生验证警告,则报告事件。 如果没有验证特定元素或属性时所依据的 DTD 或 XML 架构,通常会发出警告。 ValidationEventHandler 用于通知。 (默认禁用。)
Schemas 用于验证的 XmlSchemaSet
XmlResolver 属性 XmlResolver用于解析和访问外部资源的 。 这可以包括外部实体(如 DTD 和架构)以及 XML 架构中包含的任何 xs:includexs:import 元素。 如果未指定 , XmlResolverXmlReader 使用没有用户凭据的默认值 XmlUrlResolver

数据一致性

默认情况下,由 Create 方法创建的 XML 读取器满足以下合规性要求:

  • 新行和属性值根据 W3C XML 1.0 建议进行规范化。

  • 所有实体都会自动展开。

  • 即使在读取器不进行验证时,也会始终添加在文档类型定义中声明的默认属性。

  • 允许声明映射到正确的 XML 命名空间 URI 的 XML 前缀。

  • 单个属性声明中和NmTokensEnumeration单个NotationType属性声明中的表示法名称是不同的。

使用这些 XmlReaderSettings 属性指定要启用的符合性检查的类型:

使用此属性XmlReaderSettings 功能 默认
CheckCharacters 属性 启用或禁用以下各项的检查:

- 字符在合法 XML 字符的范围内,由 W3C XML 1.0 建议的 2.2 个字符 部分定义。
- 所有 XML 名称都有效,由 W3C XML 1.0 建议的 2.3 通用语法构造 部分定义。

当此属性设置为 true (默认) 时, XmlException 如果 XML 文件包含非法字符或无效的 XML 名称 (,则引发异常,例如,元素名称以数字) 开头。
已启用字符和名称检查。

CheckCharacters 设置为 false 会禁用对字符实体引用的字符检查。 如果读取器正在处理文本数据,则无论此设置如何,它始终检查 XML 名称是否有效。 注意: 存在 DTD 时,XML 1.0 建议需要文档级一致性。 因此,如果将读取器配置为支持 ConformanceLevel.Fragment,但 XML 数据包含文档类型定义 (DTD) , XmlException 则会引发 。
ConformanceLevel 属性 选择要强制执行的符合性级别:

- Document. 符合 格式正确的 XML 1.0 文档的规则。
- Fragment. 符合格式正确的文档片段(可作为 外部分析实体使用)的规则。
- Auto.符合读取器确定的级别。

如果数据不符合标准, XmlException 则会引发异常。
Document

当前节点是 XML 读取器当前所在的 XML 节点。 所有方法都 XmlReader 执行相对于此节点的操作,所有属性都 XmlReader 反映当前节点的值。

通过以下方法可以轻松浏览节点和分析数据。

使用此方法XmlReaderSettings 功能
Read 读取第一个节点,并一次通过一个节点通过流。 此类调用通常在循环中 while 执行。

NodeType使用 属性获取类型 (例如,属性、注释、元素等) 当前节点。
Skip 跳过当前节点的子节点,并移动到下一个节点。
MoveToContentMoveToContentAsync 跳过非内容节点,并移动到下一个内容节点或文件末尾。

非内容节点包括 ProcessingInstruction、、DocumentTypeCommentWhitespaceSignificantWhitespace

内容节点包括非空格文本 、 CDATAEntityReferenceEndEntity
ReadSubtree 读取元素及其所有子元素,并将新 XmlReader 实例集返回为 ReadState.Initial

此方法可用于在 XML 元素周围创建边界;例如,如果要将数据传递给另一个组件进行处理,并且想要限制该组件可以访问的数据量。

XmlReader.Read有关一次浏览一个节点的文本流并显示每个节点的类型的示例,请参阅参考页。

以下部分介绍如何读取特定类型的数据,例如元素、属性和类型化数据。

读取 XML 元素

下表列出了 类为处理元素提供的方法和属性 XmlReader 。 在 XmlReader 置于某个元素上之后,节点属性(例如 Name)将反映元素的值。 除了下面所述的成员之外,XmlReader 类的任何常规方法和属性也可以用于处理元素。 例如,可以使用 ReadInnerXml 方法读取元素的内容。

注意

有关开始标记、结束标记和空元素标记的定义,请参阅 W3C XML 1.0 建议的第 3.1 部分。

使用此 XmlReader 成员 功能
IsStartElement 方法 检查当前节点是开始标记还是空元素标记。
ReadStartElement 方法 检查当前节点是否为元素,并将读取器推进到下一个节点, (调用 IsStartElementRead 跟) 。
ReadEndElement 方法 检查当前节点是否为结束标记,并将读取器推进到下一个节点。
ReadElementString 方法 读取纯文本元素。
ReadToDescendant 方法 将 XML 读取器前进到具有指定名称的下一个后代 (子) 元素。
ReadToNextSibling 方法 将 XML 读取器前进到具有指定名称的下一个同级元素。
IsEmptyElement 属性 检查当前元素是否具有结束元素标记。 例如:

- <item num="123"/>IsEmptyElement (为 true.)
- <item num="123"> </item>IsEmptyElement (为 false,尽管元素的内容为空。)

有关读取元素文本内容的示例,请参阅 ReadString 方法。 以下示例使用 while 循环处理元素。

while (reader.Read()) {
  if (reader.IsStartElement()) {
    if (reader.IsEmptyElement)
                {
                    Console.WriteLine("<{0}/>", reader.Name);
                }
                else {
      Console.Write("<{0}> ", reader.Name);
      reader.Read(); // Read the start tag.
      if (reader.IsStartElement())  // Handle nested elements.
        Console.Write("\r\n<{0}>", reader.Name);
      Console.WriteLine(reader.ReadString());  //Read the text content of the element.
    }
  }
}
While reader.Read()
  If reader.IsStartElement() Then
    If reader.IsEmptyElement Then
      Console.WriteLine("<{0}/>", reader.Name)
    Else
      Console.Write("<{0}> ", reader.Name)
      reader.Read() ' Read the start tag.
      If reader.IsStartElement() Then ' Handle nested elements.
        Console.Write(vbCr + vbLf + "<{0}>", reader.Name)
      End If
      Console.WriteLine(reader.ReadString()) 'Read the text content of the element.
    End If
  End If
End While

读取 XML 属性

XML 属性最常见于元素上,但也允许在 XML 声明和文档类型节点上使用。

定位在元素节点上时, MoveToAttribute 方法允许你浏览元素的属性列表。 请注意,在调用后 MoveToAttribute ,节点属性(如 NameNamespaceURIPrefix )反映该特性的属性,而不是属性所属的元素的属性。

XmlReader 提供这些方法和属性来读取和处理元素上的属性。

使用此 XmlReader 成员 功能
HasAttributes 属性 检查当前节点是否具有任何属性。
AttributeCount 属性 获取当前元素的属性数。
MoveToFirstAttribute 方法 移动到元素中的第一个属性。
MoveToNextAttribute 方法 移动到元素中的下一个属性。
MoveToAttribute 方法 移动到指定的属性。
GetAttribute 方法或 Item[] 属性 获取指定属性的值。
IsDefault 属性 检查当前节点是否是从 DTD 或架构中定义的默认值生成的属性。
MoveToElement 方法 移动到拥有当前属性的元素。 在元素属性中导航后,使用此方法返回到元素。
ReadAttributeValue 方法 将属性值分析为一个或多个 TextEntityReference、 或 EndEntity 节点。

任何常规的 XmlReader 方法和属性也可以用于处理属性。 例如,在 XmlReader 位于某个属性上之后,NameValue 属性将反映该属性的值。 也可以使用任何内容 Read 方法来获取属性的值。

此示例使用 AttributeCount 属性在元素上的所有属性中导航。

// Display all attributes.
if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  for (int i = 0; i < reader.AttributeCount; i++) {
    Console.WriteLine("  {0}", reader[i]);
  }
  // Move the reader back to the element node.
  reader.MoveToElement();
}
' Display all attributes.
If reader.HasAttributes Then
  Console.WriteLine("Attributes of <" + reader.Name + ">")
  Dim i As Integer
  For i = 0 To (reader.AttributeCount - 1)
    Console.WriteLine("  {0}", reader(i))
  Next i
  ' Move the reader back to the element node.
  reader.MoveToElement() 
End If

此示例在 MoveToNextAttribute 循环中使用 while 方法在属性中导航。

if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  while (reader.MoveToNextAttribute()) {
    Console.WriteLine(" {0}={1}", reader.Name, reader.Value);
  }
  // Move the reader back to the element node.
  reader.MoveToElement();
}
If reader.HasAttributes Then
  Console.WriteLine("Attributes of <" + reader.Name + ">")
  While reader.MoveToNextAttribute()
    Console.WriteLine(" {0}={1}", reader.Name, reader.Value)
  End While
  ' Move the reader back to the element node.
  reader.MoveToElement()
End If

读取 XML 声明节点上的属性

当 XML 读取器位于 XML 声明节点上时, Value 属性将版本、独立和编码信息作为单个字符串返回。 XmlReaderCreate 方法、 XmlTextReader 类和 XmlValidatingReader 类创建的 对象以属性的形式公开版本、独立和编码项。

读取文档类型节点上的属性

当 XML 读取器位于文档类型节点上时,GetAttributeItem[]方法和 属性可用于返回 SYSTEM 和 PUBLIC 文本的值。 例如,调用 reader.GetAttribute("PUBLIC") 将返回 PUBLIC 值。

读取处理指令节点上的属性

XmlReader 位于某个处理指令节点上时,Value 属性将返回整个文本内容。 处理指令节点中的项不被视为属性。 不能使用 GetAttributeMoveToAttribute 方法读取它们。

读取 XML 内容

XmlReader 类包括以下成员,这些成员从 XML 文件读取内容,并将内容作为字符串值返回。 (若要返回 CLR 类型,请参阅 下一部分。)

使用此 XmlReader 成员 功能
Value 属性 获取当前节点的文本内容。 返回的值取决于节点类型;有关详细信息, Value 请参阅参考页。
ReadString 方法 获取字符串形式的元素或文本节点的内容。 此方法在处理指令和注释时停止。

有关此方法如何处理特定节点类型的详细信息,请参阅 ReadString 参考页。
ReadInnerXmlReadInnerXmlAsync 方法 获取当前节点的所有内容,包括标记,但不包括开始和结束标记。 例如,对于:

<node>this<child id="123"/></node>

ReadInnerXml 返回:

this<child id="123"/>
ReadOuterXmlReadOuterXmlAsync 方法 获取当前节点及其子节点的所有内容,包括标记和开始/结束标记。 例如,对于:

<node>this<child id="123"/></node>

ReadOuterXml 返回:

<node>this<child id="123"/></node>

转换为 CLR 类型

可以使用下表中列出的类 (成员 XmlReader) 读取 XML 数据,并将值作为公共语言运行时返回, (CLR) 类型而不是字符串。 这些成员使你能够在表示形式中获取最适合编码任务的值,而无需手动分析或转换字符串值。

  • ReadElementContentAs 方法只能在元素节点类型上调用。 这些方法不能在包含子元素或混合内容的元素上使用。 在调用时,XmlReader 对象读取开始标记,读取元素内容,然后移过结束元素标记。 将忽略处理指令和注释并展开实体。

  • ReadContentAs 方法读取当前读取者位置的文本内容,如果 XML 数据没有任何与之关联的架构或数据类型信息,请将文本内容转换为请求的返回类型。 文本、空白、有效空白和 CDATA 节串联在一起。 跳过注释和处理指令,并自动解析实体引用。

XmlReader 使用 W3C XML 架构第 2 部分:数据类型 建议定义的规则。

使用此方法XmlReader 返回此 CLR 类型
ReadContentAsBooleanReadElementContentAsBoolean Boolean
ReadContentAsDateTimeReadElementContentAsDateTime DateTime
ReadContentAsDoubleReadElementContentAsDouble Double
ReadContentAsLongReadElementContentAsLong Int64
ReadContentAsIntReadElementContentAsInt Int32
ReadContentAsStringReadElementContentAsString String
ReadContentAsReadElementContentAs 使用 returnType 参数指定的类型
ReadContentAsObjectReadElementContentAsObject 由 属性指定的 XmlReader.ValueType 最合适的类型。 有关映射信息 ,请参阅System.Xml类中的类型支持

如果元素的格式无法轻松转换为 CLR 类型,则可以使用架构映射来确保成功转换。 以下示例使用 .xsd 文件将 hire-date 元素 xs:date 转换为 类型,然后使用 ReadElementContentAsDateTime 方法将元素作为 DateTime 对象返回。

输入 (hireDate.xml) :

<employee xmlns="urn:empl-hire">
    <ID>12365</ID>
    <hire-date>2003-01-08</hire-date>
    <title>Accountant</title>
</employee>

架构 (hireDate.xsd) :

<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:empl-hire" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="employee">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:unsignedShort" />
        <xs:element name="hire-date" type="xs:date" />
        <xs:element name="title" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

代码:

// Create a validating XmlReader object. The schema
// provides the necessary type information.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add("urn:empl-hire", "hireDate.xsd");
using (XmlReader reader = XmlReader.Create("hireDate.xml", settings)) {

  // Move to the hire-date element.
  reader.MoveToContent();
  reader.ReadToDescendant("hire-date");

  // Return the hire-date as a DateTime object.
  DateTime hireDate = reader.ReadElementContentAsDateTime();
  Console.WriteLine("Six Month Review Date: {0}", hireDate.AddMonths(6));
}
' Create a validating XmlReader object. The schema 
' provides the necessary type information.
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.ValidationType = ValidationType.Schema
settings.Schemas.Add("urn:empl-hire", "hireDate.xsd")
Using reader As XmlReader = XmlReader.Create("hireDate.xml", settings) 
  ' Move to the hire-date element.
  reader.MoveToContent()
  reader.ReadToDescendant("hire-date")

  ' Return the hire-date as a DateTime object.
  Dim hireDate As DateTime = reader.ReadElementContentAsDateTime()
  Console.WriteLine("Six Month Review Date: {0}", hireDate.AddMonths(6))
End Using

输出:

Six Month Review Date:  7/8/2003 12:00:00 AM

异步编程

XmlReader大多数方法的异步对应项在其方法名称末尾具有“Async”。 例如,的 ReadContentAsObject 异步等效项是 ReadContentAsObjectAsync

以下方法可用于异步方法调用:

以下部分介绍没有异步对应项的方法的异步用法。

ReadStartElement 方法

public static async Task ReadStartElementAsync(this XmlReader reader, string localname, string ns)
{
    if (await reader.MoveToContentAsync() != XmlNodeType.Element)
    {
        throw new InvalidOperationException(reader.NodeType.ToString() + " is an invalid XmlNodeType");
    }
    if ((reader.LocalName == localname) && (reader.NamespaceURI == ns))
    {
        await reader.ReadAsync();
    }
    else
    {
        throw new InvalidOperationException("localName or namespace doesn’t match");
    }
}
<Extension()>
Public Async Function ReadStartElementAsync(reader As XmlReader, localname As String, ns As String) As Task
    If (Await reader.MoveToContentAsync() <> XmlNodeType.Element) Then
        Throw New InvalidOperationException(reader.NodeType.ToString() + " is an invalid XmlNodeType")
    End If

    If ((reader.LocalName = localname) And (reader.NamespaceURI = ns)) Then
        Await reader.ReadAsync()
    Else
        Throw New InvalidOperationException("localName or namespace doesn’t match")
    End If
End Function

ReadEndElement 方法

public static async Task ReadEndElementAsync(this XmlReader reader)
{
    if (await reader.MoveToContentAsync() != XmlNodeType.EndElement)
    {
        throw new InvalidOperationException();
    }
    await reader.ReadAsync();
}
<Extension()>
Public Async Function ReadEndElementAsync(reader As XmlReader) As task
    If (Await reader.MoveToContentAsync() <> XmlNodeType.EndElement) Then
        Throw New InvalidOperationException()
    End If
    Await reader.ReadAsync()
End Function

ReadToNextSibling 方法

public static async Task<bool> ReadToNextSiblingAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find the next sibling
    XmlNodeType nt;
    do
    {
        await reader.SkipAsync();
        if (reader.ReadState != ReadState.Interactive)
            break;
        nt = reader.NodeType;
        if (nt == XmlNodeType.Element &&
             ((object)localName == (object)reader.LocalName) &&
             ((object)namespaceURI ==(object)reader.NamespaceURI))
        {
            return true;
        }
    } while (nt != XmlNodeType.EndElement && !reader.EOF);
    
    return false;
}
<Extension()>
Public Async Function ReadToNextSiblingAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find the next sibling
    Dim nt As XmlNodeType
    Do

        Await reader.SkipAsync()
        If (reader.ReadState <> ReadState.Interactive) Then
            Exit Do
        End If
        nt = reader.NodeType
        If ((nt = XmlNodeType.Element) And
           ((CObj(localName) = CObj(reader.LocalName))) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    Loop While (nt <> XmlNodeType.EndElement And (Not reader.EOF))

    Return False

End Function

ReadToFollowing 方法

public static async Task<bool> ReadToFollowingAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find element with that name
    while (await reader.ReadAsync())
    {
        if (reader.NodeType == XmlNodeType.Element && ((object)localName == (object)reader.LocalName) && ((object)namespaceURI == (object)reader.NamespaceURI))
        {
            return true;
        }
    }
    return false;
}
<Extension()>
Public Async Function ReadToFollowingAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find element with that name
    While (Await reader.ReadAsync())
        If ((reader.NodeType = XmlNodeType.Element) And
           (CObj(localName) = CObj(reader.LocalName)) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    End While

    Return False
End Function

ReadToDescendant 方法

public static async Task<bool> ReadToDescendantAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }
    // save the element or root depth
    int parentDepth = reader.Depth;
    if (reader.NodeType != XmlNodeType.Element)
    {
        // adjust the depth if we are on root node
        if (reader.ReadState == ReadState.Initial)
        {
            parentDepth--;
        }
        else
        {
            return false;
        }
    }
    else if (reader.IsEmptyElement)
    {
        return false;
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find the descendant
    while (await reader.ReadAsync() && reader.Depth > parentDepth)
    {
        if (reader.NodeType == XmlNodeType.Element && ((object)localName == (object)reader.LocalName) && ((object)namespaceURI == (object)reader.NamespaceURI))
        {
            return true;
        }
    }
    return false;
}
<Extension()>
Public Async Function ReadToDescendantAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' save the element or root depth
    Dim parentDepth As Integer = reader.Depth
    If (reader.NodeType <> XmlNodeType.Element) Then
        ' adjust the depth if we are on root node
        If (reader.ReadState = ReadState.Initial) Then
            parentDepth -= 1
        Else
            Return False
        End If
    ElseIf (reader.IsEmptyElement) Then
        Return False
    End If
    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find the descendant
    While (Await reader.ReadAsync() And reader.Depth > parentDepth)
        If (reader.NodeType = XmlNodeType.Element And
           (CObj(localName) = CObj(reader.LocalName)) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    End While

    Return False
End Function

安全注意事项

使用 类时, XmlReader 请考虑以下事项:

  • XmlReader 引发的异常可能会泄露你可能不希望向应用冒泡的路径信息。 你的应用必须捕获异常并正确处理它们。

  • 如果担心拒绝服务问题或正在处理不受信任的源,请不要启用 DTD 处理。 默认情况下,对 XmlReaderCreate 方法创建的对象禁用 DTD 处理。

    如果启用了 DTD 处理,可以使用 XmlSecureResolver 限制 XmlReader 可以访问的资源。 还可以设计应用,使 XML 处理受内存和时间限制。 例如,可以在 ASP.NET 应用中配置超时限制。

  • XML 数据可以包含对外部资源(例如架构文件)的引用。 默认情况下,使用 XmlUrlResolver 没有用户凭据的对象解析外部资源。 通过执行下列操作之一,可以使此操作更加安全:

  • ProcessInlineSchema默认情况下,不设置 对象的 和 ProcessSchemaLocation 验证标志XmlReaderSettings。 这样,在处理来自不可信的源的 XML 数据时,可以帮助防止 XmlReader 受到基于架构的攻击。 设置了这些标志后,XmlResolver 对象的 XmlReaderSettings 用于在 XmlReader 中解析实例文档中遇到的架构位置。 如果 属性XmlResolver设置为 null,则即使设置了 和 ProcessSchemaLocation 验证标志,ProcessInlineSchema也不会解析架构位置。

    在验证过程中添加的架构会添加新类型,并且可能更改被验证的文档的验证结果。 因此,只应从可信的源解析外部架构。

    我们建议在高可用性方案中验证不受信任的大型 XML 文档时,针对对文档的大部分内容具有标识约束的架构禁用 ProcessIdentityConstraints 标志。 默认情况下,此标志处于启用状态。

  • XML 数据可以包含大量属性、命名空间声明、嵌套元素等,需要大量的时间来处理。 若要限制发送到 XmlReader的输入的大小,可以:

  • 方法 ReadValueChunk 可用于处理大型数据流。 此方法一次读取少量的字符,而不是为整个值分配单个字符串。

  • 读取具有大量唯一本地名称、命名空间或前缀的 XML 文档时,可能会出现问题。 如果使用派生自 XmlReader的类,并且为每个项调用 LocalNamePrefixNamespaceURI 属性,则返回的字符串将添加到 。NameTable 由 保留的 NameTable 集合永远不会减小大小,从而造成字符串句柄的虚拟内存泄漏。 对此的一种缓解措施是从 类派生 NameTable 并强制实施最大大小配额。 (无法阻止使用 NameTable,或在已满) 时切换 NameTable 。 另一种缓解措施是避免使用提到的属性,并在可能的情况下将 MoveToAttribute 方法与 方法一起使用 IsStartElement ;这些方法不返回字符串,从而避免过度填充 NameTable 集合的问题。

  • XmlReaderSettings 对象可以包含敏感信息,例如用户凭据。 不可信的组件可能会使用 XmlReaderSettings 对象及其用户凭据来创建 XmlReader 对象,以读取数据。 缓存 XmlReaderSettings 对象或将 XmlReaderSettings 对象从一个组件传递到另一个组件时要小心。

  • 不接受来自不可信的源的支持组件,例如 NameTableXmlNamespaceManagerXmlResolver 对象。

构造函数

XmlReader()

初始化 XmlReader 类的新实例。

属性

AttributeCount

当在派生类中被重写时,获取当前节点上的属性数。

BaseURI

当在派生类中被重写时,获取当前节点的基 URI。

CanReadBinaryContent

获取一个值,该值指示 XmlReader 是否实现二进制内容读取方法。

CanReadValueChunk

获取一个值,该值指示 XmlReader 是否实现 ReadValueChunk(Char[], Int32, Int32) 方法。

CanResolveEntity

获取一个值,该值指示此读取器是否可以分析和解析实体。

Depth

当在派生类中被重写时,获取 XML 文档中当前节点的深度。

EOF

当在派生类中被重写时,获取一个值,该值指示此读取器是否定位在流的结尾。

HasAttributes

获取一个值,该值指示当前节点是否有任何属性。

HasValue

当在派生类中被重写时,获取一个值,该值指示当前节点是否可以具有 Value

IsDefault

当在派生类中被重写时,获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的特性。

IsEmptyElement

在派生类中重写时,获取一个值,该值指示当前节点是否为空元素 (,例如 <MyElement/> ,) 。

Item[Int32]

当在派生类中被重写时,获取具有指定索引的属性的值。

Item[String, String]

当在派生类中被重写时,获取具有指定 LocalNameNamespaceURI 的属性的值。

Item[String]

当在派生类中被重写时,获取具有指定 Name 的属性的值。

LocalName

当在派生类中被重写时,获取当前节点的本地名称。

Name

当在派生类中被重写时,获取当前节点的限定名。

NamespaceURI

当在派生类中被重写时,获取读取器定位在其上的节点的命名空间 URI(采用 W3C 命名空间规范中定义的形式)。

NameTable

当在派生类中被重写时,获取与该实现关联的 XmlNameTable

NodeType

当在派生类中被重写时,获取当前节点的类型。

Prefix

当在派生类中被重写时,获取与当前节点关联的命名空间前缀。

QuoteChar

当在派生类中被重写时,获取用于括住特性节点值的引号字符。

ReadState

当在派生类中被重写时,获取读取器的状态。

SchemaInfo

获取作为架构验证结果分配给当前节点的架构信息。

Settings

获取用于创建此 XmlReader 实例的 XmlReaderSettings 对象。

Value

当在派生类中被重写时,获取当前节点的文本值。

ValueType

获取当前节点的公共语言运行时 (CLR) 类型。

XmlLang

当在派生类中被重写时,获取当前的 xml:lang 范围。

XmlSpace

当在派生类中被重写时,获取当前的 xml:space 范围。

方法

Close()

当在派生类中被重写时,将 ReadState 更改为 Closed

Create(Stream)

使用带默认设置的指定流创建新的 XmlReader 实例。

Create(Stream, XmlReaderSettings)

使用指定的流和设置创建一个新的 XmlReader 实例。

Create(Stream, XmlReaderSettings, String)

使用指定的流、基 URI 和设置创建一个新的 XmlReader 实例。

Create(Stream, XmlReaderSettings, XmlParserContext)

使用指定的流、设置和用于分析的上下文信息创建一个新的 XmlReader 实例。

Create(String)

用指定的 URI 创建一个新的 XmlReader 实例。

Create(String, XmlReaderSettings)

使用指定的 URI 和设置创建新的 XmlReader 实例。

Create(String, XmlReaderSettings, XmlParserContext)

使用指定的 URI、设置和进行分析的上下文信息创建一个新的 XmlReader 实例。

Create(TextReader)

使用指定的文本读取器创建一个新的 XmlReader 实例。

Create(TextReader, XmlReaderSettings)

使用指定的文本读取器和设置创建一个新的 XmlReader 实例。

Create(TextReader, XmlReaderSettings, String)

使用指定的文本读取器、设置和基 URI 创建一个新的 XmlReader

Create(TextReader, XmlReaderSettings, XmlParserContext)

使用指定的文本读取器、设置和要用于分析的上下文信息创建一个新的 XmlReader 实例。

Create(XmlReader, XmlReaderSettings)

使用指定的 XML 读取器和设置创建一个新的 XmlReader 实例。

Dispose()

释放 XmlReader 类的当前实例所使用的所有资源。

Dispose(Boolean)

释放由 XmlReader 占用的非托管资源,还可以另外再释放托管资源。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetAttribute(Int32)

当在派生类中被重写时,获取具有指定索引的属性的值。

GetAttribute(String)

当在派生类中被重写时,获取具有指定 Name 的属性的值。

GetAttribute(String, String)

当在派生类中被重写时,获取具有指定 LocalNameNamespaceURI 的属性的值。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
GetValueAsync()

异步获取当前节点的值。

IsName(String)

返回一个值,该值指示字符串自变量是否是有效的 XML 名称。

IsNameToken(String)

返回一个值,该值指示该字符串自变量是否是有效的 XML 名称标记。

IsStartElement()

调用 MoveToContent() 并测试当前内容节点是否是开始标记或空元素标记。

IsStartElement(String)

调用 MoveToContent() 并测试当前内容节点是否是开始标记或空元素标记,以及所找到元素的 Name 属性是否与给定的参数匹配。

IsStartElement(String, String)

调用 MoveToContent() 并测试当前内容节点是否是开始标记或空元素标记,以及所找到元素的 LocalNameNamespaceURI 属性是否与给定的字符串匹配。

LookupNamespace(String)

当在派生类中被重写时,在当前元素的范围内解析命名空间前缀。

MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
MoveToAttribute(Int32)

当在派生类中被重写时,移动到具有指定索引的属性。

MoveToAttribute(String)

当在派生类中被重写时,移动到具有指定 Name 的属性。

MoveToAttribute(String, String)

当在派生类中被重写时,移动到具有指定的 LocalNameNamespaceURI 的属性。

MoveToContent()

检查当前节点是否是内容(非空白文本、CDATAElementEndElementEntityReferenceEndEntity)节点。 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。 它跳过以下类型的节点:ProcessingInstructionDocumentTypeCommentWhitespaceSignificantWhitespace

MoveToContentAsync()

异步检查当前节点是否为内容节点。 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。

MoveToElement()

当在派生类中被重写时,移动到包含当前属性节点的元素。

MoveToFirstAttribute()

当在派生类中被重写时,移动到第一个属性。

MoveToNextAttribute()

当在派生类中被重写时,移动到下一个属性。

Read()

当在派生类中被重写时,从流中读取下一个节点。

ReadAsync()

异步读取该流的下一个节点。

ReadAttributeValue()

当在派生类中被重写时,将属性值解析为一个或多个 TextEntityReferenceEndEntity 节点。

ReadContentAs(Type, IXmlNamespaceResolver)

将内容作为指定类型的对象读取。

ReadContentAsAsync(Type, IXmlNamespaceResolver)

将内容作为指定类型的对象异步读取。

ReadContentAsBase64(Byte[], Int32, Int32)

读取内容并返回 Base64 解码的二进制字节。

ReadContentAsBase64Async(Byte[], Int32, Int32)

异步读取内容并返回 Base64 解码的二进制字节。

ReadContentAsBinHex(Byte[], Int32, Int32)

读取内容并返回 BinHex 解码的二进制字节。

ReadContentAsBinHexAsync(Byte[], Int32, Int32)

异步读取内容并返回 BinHex 解码的二进制字节。

ReadContentAsBoolean()

将当前位置的文本内容作为 Boolean 读取。

ReadContentAsDateTime()

将当前位置的文本内容作为 DateTime 对象读取。

ReadContentAsDateTimeOffset()

将当前位置的文本内容作为 DateTimeOffset 对象读取。

ReadContentAsDecimal()

将当前位置的文本内容作为 Decimal 对象读取。

ReadContentAsDouble()

将当前位置的文本内容作为双精度浮点数读取。

ReadContentAsFloat()

将当前位置的文本内容作为单精度浮点数读取。

ReadContentAsInt()

将当前位置的文本内容作为 32 位有符号整数读取。

ReadContentAsLong()

将当前位置的文本内容作为 64 位有符号整数读取。

ReadContentAsObject()

将当前位置的文本内容作为 Object 读取。

ReadContentAsObjectAsync()

将当前位置的文本内容作为 Object 对象异步读取。

ReadContentAsString()

将当前位置的文本内容作为 String 对象读取。

ReadContentAsStringAsync()

将当前位置的文本内容作为 String 对象异步读取。

ReadElementContentAs(Type, IXmlNamespaceResolver)

将元素内容作为请求类型读取。

ReadElementContentAs(Type, IXmlNamespaceResolver, String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后将元素内容作为请求类型读取。

ReadElementContentAsAsync(Type, IXmlNamespaceResolver)

将元素内容作为请求类型异步读取。

ReadElementContentAsBase64(Byte[], Int32, Int32)

读取元素并对 Base64 内容进行解码。

ReadElementContentAsBase64Async(Byte[], Int32, Int32)

异步读取元素并对 Base64 内容进行解码。

ReadElementContentAsBinHex(Byte[], Int32, Int32)

读取元素并对 BinHex 内容进行解码。

ReadElementContentAsBinHexAsync(Byte[], Int32, Int32)

异步读取元素并对 BinHex 内容进行解码。

ReadElementContentAsBoolean()

读取当前元素并将内容作为 Boolean 对象返回。

ReadElementContentAsBoolean(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 Boolean 对象返回。

ReadElementContentAsDateTime()

读取当前元素并将内容作为 DateTime 对象返回。

ReadElementContentAsDateTime(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 DateTime 对象返回。

ReadElementContentAsDecimal()

读取当前元素并将内容作为 Decimal 对象返回。

ReadElementContentAsDecimal(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 Decimal 对象返回。

ReadElementContentAsDouble()

读取当前元素并将内容作为双精度浮点数返回。

ReadElementContentAsDouble(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为双精度浮点数返回。

ReadElementContentAsFloat()

读取当前元素并将内容作为单精度浮点数返回。

ReadElementContentAsFloat(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为单精度浮点数返回。

ReadElementContentAsInt()

读取当前元素并将内容作为 32 位有符号整数返回。

ReadElementContentAsInt(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 32 位有符号整数返回。

ReadElementContentAsLong()

读取当前元素并将内容作为 64 位有符号整数返回。

ReadElementContentAsLong(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 64 位有符号整数返回。

ReadElementContentAsObject()

读取当前元素并将内容作为 Object 返回。

ReadElementContentAsObject(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 Object 返回。

ReadElementContentAsObjectAsync()

异步读取当前元素并将内容作为 Object 返回。

ReadElementContentAsString()

读取当前元素并将内容作为 String 对象返回。

ReadElementContentAsString(String, String)

检查指定的本地名称和命名空间 URI 与当前元素的本地名称和命名空间 URI 是否匹配,然后读取当前元素,并将内容作为 String 对象返回。

ReadElementContentAsStringAsync()

异步读取当前元素并将内容作为 String 对象返回。

ReadElementString()

读取纯文本元素。 但是,建议改用 ReadElementContentAsString() 方法,因为该方法可以更直接地处理此操作。

ReadElementString(String)

在读取纯文本元素之前,检查所找到元素的 Name 属性是否与给定的字符串匹配。 但是,建议改用 ReadElementContentAsString() 方法,因为该方法可以更直接地处理此操作。

ReadElementString(String, String)

在读取纯文本元素之前,检查所找到元素的 LocalNameNamespaceURI 属性是否与给定的字符串匹配。 但是,建议改用 ReadElementContentAsString(String, String) 方法,因为该方法可以更直接地处理此操作。

ReadEndElement()

检查当前内容节点是否为结束标记并将读取器推进到下一个节点。

ReadInnerXml()

当在派生类中被重写时,将所有内容(包括标记)当做字符串读取。

ReadInnerXmlAsync()

异步读取所有内容,包括作为字符串的标记。

ReadOuterXml()

当在派生类中被重写时,读取表示该节点和所有它的子级的内容(包括标记)。

ReadOuterXmlAsync()

异步读取包含该节点和所有它的子级的内容(包括标记)。

ReadStartElement()

检查当前节点是否为元素并将读取器推进到下一个节点。

ReadStartElement(String)

检查当前内容节点是否为具有给定 Name 的元素并将读取器推进到下一个节点。

ReadStartElement(String, String)

检查当前内容节点是否为具有给定 LocalNameNamespaceURI 的元素并将读取器推进到下一个节点。

ReadString()

当在派生类中被重写时,将元素或文本节点的内容当做字符串读取。 但是,建议改用 ReadElementContentAsString 方法,因为该方法可以更直接地处理此操作。

ReadSubtree()

返回新的 XmlReader 实例,此实例可用于读取当前节点及其所有子节点。

ReadToDescendant(String)

XmlReader 前进到下一个具有指定限定名的子代元素。

ReadToDescendant(String, String)

XmlReader 前进到下一个具有指定的本地名称和命名空间 URI 的子代元素。

ReadToFollowing(String)

一直读取,直到找到具有指定限定名的元素。

ReadToFollowing(String, String)

一直读取,直到找到具有指定的本地名称和命名空间 URI 的元素。

ReadToNextSibling(String)

XmlReader 前进到下一个具有指定限定名的同级元素。

ReadToNextSibling(String, String)

XmlReader 推进到具有指定的本地名称和命名空间 URI 的下一个同级元素。

ReadValueChunk(Char[], Int32, Int32)

读取嵌入在 XML 文档中的大量文本流。

ReadValueChunkAsync(Char[], Int32, Int32)

异步读取嵌入在 XML 文档中的大量文本流。

ResolveEntity()

当在派生类中被重写时,解析 EntityReference 节点的实体引用。

Skip()

跳过当前节点的子级。

SkipAsync()

异步跳过当前节点的子级。

ToString()

返回表示当前对象的字符串。

(继承自 Object)

显式接口实现

IDisposable.Dispose()

有关此成员的说明,请参见 Dispose()

适用于

另请参阅