XmlReader 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
表示提供对 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.Initial 。 XmlReader 还针对 DTD 或架构提供数据一致性检查和验证。
XmlReader 使用拉取模型检索数据。 此模型:
通过自然的自上而下程序优化来简化状态管理。
支持多个输入流和分层。
使客户端能够向分析程序提供直接写入字符串的缓冲区,从而避免额外的字符串复制。
支持选择性处理。 客户端可以跳过项目并处理应用程序感兴趣的项。 还可以提前设置属性来管理 XML 流的处理方式, (例如规范化) 。
本部分内容:
创建 XML 读取器验证 XML 数据符合性浏览节点读取 XML 元素 读取XML 属性读取 XML 内容转换为 CLR 类型异步编程安全注意事项
创建 XML 读取器
尽管 .NET Framework 提供了 类的具体实现XmlReader(例如 XmlTextReader、 XmlNodeReader和 XmlValidatingReader 类),但建议仅在以下情况下使用专用类:
如果要从 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:ID 、xs:IDREF 、xs:key 、 xs:keyref xs:unique 、) 的标识约束。 (默认启用。) - ProcessSchemaLocation --处理 由 xsi:schemaLocation 或 xsi:noNamespaceSchemaLocation 属性指定的架构。 (默认启用。) - ProcessInlineSchema -- 在验证期间处理内联 XML 架构。 (默认禁用。) - ReportValidationWarnings --如果发生验证警告,则报告事件。 如果没有验证特定元素或属性时所依据的 DTD 或 XML 架构,通常会发出警告。 ValidationEventHandler 用于通知。 (默认禁用。) |
Schemas | 用于验证的 XmlSchemaSet。 |
XmlResolver 属性 | XmlResolver用于解析和访问外部资源的 。 这可以包括外部实体(如 DTD 和架构)以及 XML 架构中包含的任何 xs:include 或 xs:import 元素。 如果未指定 , XmlResolver则 XmlReader 使用没有用户凭据的默认值 XmlUrlResolver 。 |
数据一致性
默认情况下,由 Create 方法创建的 XML 读取器满足以下合规性要求:
新行和属性值根据 W3C XML 1.0 建议进行规范化。
所有实体都会自动展开。
即使在读取器不进行验证时,也会始终添加在文档类型定义中声明的默认属性。
允许声明映射到正确的 XML 命名空间 URI 的 XML 前缀。
单个属性声明中和
NmTokens
Enumeration
单个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 | 跳过当前节点的子节点,并移动到下一个节点。 |
MoveToContent 和 MoveToContentAsync | 跳过非内容节点,并移动到下一个内容节点或文件末尾。 非内容节点包括 ProcessingInstruction、、DocumentType、 CommentWhitespace和 SignificantWhitespace。 内容节点包括非空格文本 、 CDATAEntityReference 和 EndEntity。 |
ReadSubtree | 读取元素及其所有子元素,并将新 XmlReader 实例集返回为 ReadState.Initial。 此方法可用于在 XML 元素周围创建边界;例如,如果要将数据传递给另一个组件进行处理,并且想要限制该组件可以访问的数据量。 |
XmlReader.Read有关一次浏览一个节点的文本流并显示每个节点的类型的示例,请参阅参考页。
以下部分介绍如何读取特定类型的数据,例如元素、属性和类型化数据。
读取 XML 元素
下表列出了 类为处理元素提供的方法和属性 XmlReader 。 在 XmlReader 置于某个元素上之后,节点属性(例如 Name)将反映元素的值。 除了下面所述的成员之外,XmlReader 类的任何常规方法和属性也可以用于处理元素。 例如,可以使用 ReadInnerXml 方法读取元素的内容。
注意
有关开始标记、结束标记和空元素标记的定义,请参阅 W3C XML 1.0 建议的第 3.1 部分。
使用此 XmlReader 成员 | 功能 |
---|---|
IsStartElement 方法 | 检查当前节点是开始标记还是空元素标记。 |
ReadStartElement 方法 | 检查当前节点是否为元素,并将读取器推进到下一个节点, (调用 IsStartElement 后 Read 跟) 。 |
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 ,节点属性(如 Name、 NamespaceURI和 Prefix )反映该特性的属性,而不是属性所属的元素的属性。
类 XmlReader 提供这些方法和属性来读取和处理元素上的属性。
使用此 XmlReader 成员 | 功能 |
---|---|
HasAttributes 属性 | 检查当前节点是否具有任何属性。 |
AttributeCount 属性 | 获取当前元素的属性数。 |
MoveToFirstAttribute 方法 | 移动到元素中的第一个属性。 |
MoveToNextAttribute 方法 | 移动到元素中的下一个属性。 |
MoveToAttribute 方法 | 移动到指定的属性。 |
GetAttribute 方法或 Item[] 属性 | 获取指定属性的值。 |
IsDefault 属性 | 检查当前节点是否是从 DTD 或架构中定义的默认值生成的属性。 |
MoveToElement 方法 | 移动到拥有当前属性的元素。 在元素属性中导航后,使用此方法返回到元素。 |
ReadAttributeValue 方法 | 将属性值分析为一个或多个 Text 、 EntityReference 、 或 EndEntity 节点。 |
任何常规的 XmlReader 方法和属性也可以用于处理属性。 例如,在 XmlReader 位于某个属性上之后,Name 和 Value 属性将反映该属性的值。 也可以使用任何内容 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 属性将版本、独立和编码信息作为单个字符串返回。 XmlReader 由 Create 方法、 XmlTextReader 类和 XmlValidatingReader 类创建的 对象以属性的形式公开版本、独立和编码项。
读取文档类型节点上的属性
当 XML 读取器位于文档类型节点上时,GetAttributeItem[]方法和 属性可用于返回 SYSTEM 和 PUBLIC 文本的值。 例如,调用 reader.GetAttribute("PUBLIC")
将返回 PUBLIC 值。
读取处理指令节点上的属性
在 XmlReader 位于某个处理指令节点上时,Value 属性将返回整个文本内容。 处理指令节点中的项不被视为属性。 不能使用 GetAttribute 或 MoveToAttribute 方法读取它们。
读取 XML 内容
XmlReader 类包括以下成员,这些成员从 XML 文件读取内容,并将内容作为字符串值返回。 (若要返回 CLR 类型,请参阅 下一部分。)
使用此 XmlReader 成员 | 功能 |
---|---|
Value 属性 | 获取当前节点的文本内容。 返回的值取决于节点类型;有关详细信息, Value 请参阅参考页。 |
ReadString 方法 | 获取字符串形式的元素或文本节点的内容。 此方法在处理指令和注释时停止。 有关此方法如何处理特定节点类型的详细信息,请参阅 ReadString 参考页。 |
ReadInnerXml 和 ReadInnerXmlAsync 方法 | 获取当前节点的所有内容,包括标记,但不包括开始和结束标记。 例如,对于:<node>this<child id="123"/></node> ReadInnerXml 返回: this<child id="123"/> |
ReadOuterXml 和 ReadOuterXmlAsync 方法 | 获取当前节点及其子节点的所有内容,包括标记和开始/结束标记。 例如,对于:<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 部分:数据类型 建议定义的规则。
如果元素的格式无法轻松转换为 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 处理。 默认情况下,对 XmlReader 由 Create 方法创建的对象禁用 DTD 处理。
如果启用了 DTD 处理,可以使用 XmlSecureResolver 限制 XmlReader 可以访问的资源。 还可以设计应用,使 XML 处理受内存和时间限制。 例如,可以在 ASP.NET 应用中配置超时限制。
XML 数据可以包含对外部资源(例如架构文件)的引用。 默认情况下,使用 XmlUrlResolver 没有用户凭据的对象解析外部资源。 通过执行下列操作之一,可以使此操作更加安全:
通过将 XmlReader 属性设置为 XmlReaderSettings.XmlResolver 对象限制 XmlSecureResolver 可访问的资源。
通过将 XmlReader 属性设置为 XmlReaderSettings.XmlResolver,不允许
null
打开任何外部资源。
ProcessInlineSchema默认情况下,不设置 对象的 和 ProcessSchemaLocation 验证标志XmlReaderSettings。 这样,在处理来自不可信的源的 XML 数据时,可以帮助防止 XmlReader 受到基于架构的攻击。 设置了这些标志后,XmlResolver 对象的 XmlReaderSettings 用于在 XmlReader 中解析实例文档中遇到的架构位置。 如果 属性XmlResolver设置为
null
,则即使设置了 和 ProcessSchemaLocation 验证标志,ProcessInlineSchema也不会解析架构位置。在验证过程中添加的架构会添加新类型,并且可能更改被验证的文档的验证结果。 因此,只应从可信的源解析外部架构。
我们建议在高可用性方案中验证不受信任的大型 XML 文档时,针对对文档的大部分内容具有标识约束的架构禁用 ProcessIdentityConstraints 标志。 默认情况下,此标志处于启用状态。
XML 数据可以包含大量属性、命名空间声明、嵌套元素等,需要大量的时间来处理。 若要限制发送到 XmlReader的输入的大小,可以:
通过设置 MaxCharactersInDocument 属性来限制文档的大小。
通过设置 MaxCharactersFromEntities 属性来限制扩展实体导致的字符数。
IStream
为 XmlReader创建自定义实现。
方法 ReadValueChunk 可用于处理大型数据流。 此方法一次读取少量的字符,而不是为整个值分配单个字符串。
读取具有大量唯一本地名称、命名空间或前缀的 XML 文档时,可能会出现问题。 如果使用派生自 XmlReader的类,并且为每个项调用 LocalName、 Prefix或 NamespaceURI 属性,则返回的字符串将添加到 。NameTable 由 保留的 NameTable 集合永远不会减小大小,从而造成字符串句柄的虚拟内存泄漏。 对此的一种缓解措施是从 类派生 NameTable 并强制实施最大大小配额。 (无法阻止使用 NameTable,或在已满) 时切换 NameTable 。 另一种缓解措施是避免使用提到的属性,并在可能的情况下将 MoveToAttribute 方法与 方法一起使用 IsStartElement ;这些方法不返回字符串,从而避免过度填充 NameTable 集合的问题。
XmlReaderSettings 对象可以包含敏感信息,例如用户凭据。 不可信的组件可能会使用 XmlReaderSettings 对象及其用户凭据来创建 XmlReader 对象,以读取数据。 缓存 XmlReaderSettings 对象或将 XmlReaderSettings 对象从一个组件传递到另一个组件时要小心。
不接受来自不可信的源的支持组件,例如 NameTable、XmlNamespaceManager 和 XmlResolver 对象。
构造函数
XmlReader() |
初始化 |
属性
AttributeCount |
当在派生类中被重写时,获取当前节点上的属性数。 |
BaseURI |
当在派生类中被重写时,获取当前节点的基 URI。 |
CanReadBinaryContent |
获取一个值,该值指示 XmlReader 是否实现二进制内容读取方法。 |
CanReadValueChunk |
获取一个值,该值指示 XmlReader 是否实现 ReadValueChunk(Char[], Int32, Int32) 方法。 |
CanResolveEntity |
获取一个值,该值指示此读取器是否可以分析和解析实体。 |
Depth |
当在派生类中被重写时,获取 XML 文档中当前节点的深度。 |
EOF |
当在派生类中被重写时,获取一个值,该值指示此读取器是否定位在流的结尾。 |
HasAttributes |
获取一个值,该值指示当前节点是否有任何属性。 |
HasValue |
当在派生类中被重写时,获取一个值,该值指示当前节点是否可以具有 Value。 |
IsDefault |
当在派生类中被重写时,获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的特性。 |
IsEmptyElement |
在派生类中重写时,获取一个值,该值指示当前节点是否为空元素 (,例如 |
Item[Int32] |
当在派生类中被重写时,获取具有指定索引的属性的值。 |
Item[String, String] |
当在派生类中被重写时,获取具有指定 LocalName 和 NamespaceURI 的属性的值。 |
Item[String] |
当在派生类中被重写时,获取具有指定 Name 的属性的值。 |
LocalName |
当在派生类中被重写时,获取当前节点的本地名称。 |
Name |
当在派生类中被重写时,获取当前节点的限定名。 |
NamespaceURI |
当在派生类中被重写时,获取读取器定位在其上的节点的命名空间 URI(采用 W3C 命名空间规范中定义的形式)。 |
NameTable |
当在派生类中被重写时,获取与该实现关联的 XmlNameTable。 |
NodeType |
当在派生类中被重写时,获取当前节点的类型。 |
Prefix |
当在派生类中被重写时,获取与当前节点关联的命名空间前缀。 |
QuoteChar |
当在派生类中被重写时,获取用于括住特性节点值的引号字符。 |
ReadState |
当在派生类中被重写时,获取读取器的状态。 |
SchemaInfo |
获取作为架构验证结果分配给当前节点的架构信息。 |
Settings |
获取用于创建此 XmlReader 实例的 XmlReaderSettings 对象。 |
Value |
当在派生类中被重写时,获取当前节点的文本值。 |
ValueType |
获取当前节点的公共语言运行时 (CLR) 类型。 |
XmlLang |
当在派生类中被重写时,获取当前的 |
XmlSpace |
当在派生类中被重写时,获取当前的 |
方法
显式接口实现
IDisposable.Dispose() |
有关此成员的说明,请参见 Dispose()。 |