XmlReader简介
XmlReader允许您从流或者XML文档中访问XML数据。这个类提供了对XML数据快速、非缓存、只读、只向前的访问方式。在.NET Framework 1.x中,XmlReader是一个抽象类,其派生类通过实现其提供的方法来提供对XML数据的元素和属性的访问。但是随着.NET Framework 2.0 的发布,XmlReader成为像XmlTextReader类一样的、功能完善的类并对读取XML数据提供了基于各标准的支持。您可以使用XmlReader类来判断各种因素,如XML文档中某一节点的深度、节点是否具有属性、节点中属性的个数以及属 性值。
注意:
虽然您可以使用XmlTextReader类来读取XML数据,但是读取XML数据的最佳方式是使用XmlReader对象,该对象通过XmlReader对象的Create()静态方法创建。这是因为包含在Create()方法中的XmlReader对象比XmlTextReader实现符合更多的标准。例如,XmlTextReader在默认情况下不扩展实体,也不添加默认属性。
XmlTextReader类是XmlReader类的一个派生类并实现了由XmlReader类定义的方法。XmlValidatingReader是另外一个在.NET Framework 1.x中由XmlReader类派生的类,它不仅可以让您读取XML数据,还提供对DTD和模式的验证。请注意,在.NET Framework 2.0中,XmlTextReader和XmlValidatingReader类都被遗弃,它们的功能分别被XmlReader和XmlReaderSettings类代替。
使用XmlReader类读取XML数据之一
XmlReader提供了对XML文件内容的快速、只向前的访问,但不适用于对文件内容或者结构做修改(您可以使用XmlDocument类来实现)。XmlReader类从文件的顶部开始读取数据,每次读取一个节点。当读取了节点之后,您可以忽略该节点,也可以按照应用程序的需求指示而访问节点信息。
使用XmlReader类的步骤如下:
(1) 使用XmlReader类的Create()方法创建该类的一个实例,并将被读取的XML文件名称作为参数传入方法。
(2) 建立一个反复调用Read()方法的循环。这个方法从文件的第一个节点开始,然后读取所有余下的节点,但每次调用只读取一个节点。如果存在一个节点可被读取则返回True,而当到达文件最后时则返回False。
(3) 在这个循环中,将检查XmlReader对象的属性和方法,以获得关于当前节点的信息(它的类型、名称、数据等等)。不断地执行该循环直到Read()返回False。
XmlReader类具有大量的属性和方法。表4-1和表4-2显示了您可能会经常用到的一些属性和方法。
表4-1 XmlReader类的重要属性
属 性 | 说 明 |
AttributeCount | 返回当前节点的属性个数 |
Depth | 返回当前节点的深度;用于判断指定的节点是否具有子节点 |
EOF | 指示读取器是否位于流的末端 |
HasAttritbute | 返回指示当前节点是否具有属性的布尔值 |
HasValue | 返回指示当前节点是否能够具有值的布尔值 |
IsEmptyElement | 指示当前节点是否是一个空元素 |
LocalName | 返回当前节点的本地名称 |
Name | 返回当前节点的限定名称 |
NamespaceURI | 返回当前节点的命名空间URI |
NodeType | 以XmlNodeType枚举的形式返回当前节点的类型 |
Prefix | 返回与当前节点相关的命名空间前缀 |
ReadState | 以ReadState枚举的形式返回读取器的当前状态 |
Settings | 返回用于创建XmlReader实例的XmlReaderSettings对象 |
Value | 获得当前节点的值 |
ValueType | 获得当前节点的CLR类型 |
现在您应该了解了XmlReader类的一些重要属性,表4-2列出了XmlReader类的一些重要方法。
表4-2 XmlReader类的重要方法
方 法 | 说 明 |
Close | 通过将ReadState枚举设置为Closed来关闭XmlReader对象 |
Create | 该工厂方法创建XmlReader对象的实例并将其返回给调用程序;它是获得XmlReader实例的首选机制 |
(续表)
方 法 | 说 明 |
GetAttribute | 获得属性的值 |
IsStartElement | 指示当前节点是否是开始标签 |
MoveToAttribute | 移动读取器至指定的属性 |
MoveToContent | 如果当前节点不是内容节点,则移动读取器至下一个内容节点 |
MoveToElement | 移动读取器至包含当前属性的元素;用于列举属性以及想切换至包含所有这些属性的元素 |
MoveToFirstAttribute | 移动读取器至当前节点的第一个属性 |
MoveToNextAttribute | 移动读取器至下一个属性;特别用于列举节点中的属性 |
Read | 从流中读取下一个节点 |
ReadContentAs | 读取提供类型的对象的内容 |
ReadElementContentAs | 读取当前元素并返回所指定类型的对象的内容 |
ReadEndElement | 移动读取器越过当前结束标签并移动至下一个节点 |
ReadInnerXml | 以字符串形式读取包括标记在内的节点所有内容 |
ReadOuterXml | 读取包括当前节点标记和所有子节点在内的节点的内容 |
ReadToDescendant | 移动读取器至下一个匹配子孙元素的节点 |
ReadToFollowing | 不断读取直到找到指定的元素 |
ReadToNextSibling | 向前移动读取器至下一个匹配兄弟元素的节点 |
ReadValueChunk | 允许您读取嵌入在XML文档中的大型文本流 |
除了表4-2中描述的方法之外,XmlReader还提供了多种ReadContentAsXXX()方法,例如:
● ReadContentAsBase64()
● ReadContentAsBinHex()
● ReadContentAsBoolean()
● ReadContentAsDateTime()
● ReadContentAsDouble()
● ReadContentAsInt()
● ReadContentAsLong()
● ReadContentAsObject()
● ReadContentAsString()
正如其名称所示,这些方法以其名称中指定的类型的对象来返回节点值。例如,ReadContentAsString()方法以字符串类型的对象返回节点值。与ReadContentAsXXX()方法类似,还有很多ReadElementContentAsXXX()方法,如下所示:
● ReadContentAsBase64()
● ReadElementContentAsBinHex()
● ReadElementContentAsBoolean()
● ReadElementContentAsDateTime()
● ReadElementContentAsDouble()
● ReadElementContentAsInt()
● ReadElementContentAsLong()
● ReadElementContentAsObject()
● ReadElementContentAsString()
在所有这些函数当中,最重要的函数是Read(),它告诉XmlReader从文档中获取下一个节点。在您获得了节点之后,就可以使用NodeType属性来找到所需要的内容。NodeType属性返回XmlNodeType枚举的一个成员,其成员都显示在表4-3中。
表4-3 XmlNodeType枚举的成员
成 员 | 说 明 |
Attribute | 属性,如id=1 |
CDATA | CDATA区域,如<![CDATA[Some text]]> |
Comment | XML注释,如<!- - Some comment - -> |
Document | 文档对象,表示XML树的根 |
DocumentFragment | 不是文档本身的XML片断 |
DocumentType | 文档类型声明 |
Element , EndElement | 开始元素和结束元素 |
Entity, EndEntity | 开始实体声明和结束实体声明 |
EntityReference | 实体引用(如<) |
None | 在没有读取节点而查询节点类型时使用 |
Notation | DTD中的符号条目 |
ProcessingInstruction | XML处理指令 |
SignificantWhitespace | 在混合内容模型文档中的空白,或者当设置了xml:space=preserve时使用 |
Text | 元素的文本内容 |
Whitespace | 标记之间的空白 |
XmlDeclaration | 在文档顶部的XML声明 |
既然您已经了解了一些重要的属性和方法,在下面几节中将介绍创建文档、元素、属性和其他数据的不同方式。
1. 开始读取文档
要开始读取XML文档,您可以调用任意一个Read()方法从文档中获取数据。比如,下面这段代码使用了ReadStartElement()移动至文档的第一个元素:
XmlReader reader = XmlReader.Create("Employees.xml");
//Skip the XML declaration and go to the first element
reader.ReadStartElement();
或者,可以调用MoveToContent()方法直接跳至文档内容,如果当前节点不是内容节点则跳至下一个内容节点(内容节点是CDATA、Element、Entity和EntityReference节点)。如果位于属性上,读取器将会返回至包含该属性的元素。
XmlReader reader = XmlReader.Create("Employees.xml");
reader.MoveToContent();
在上面的示例中,如果Employees.xml如下所示:
<?xml version="1.0"?>
<!--Employee Details -->
<firstName>
Nancy
</firstName>
那么上面的代码将直接到达<firstName>元素而跳过之前序言(prolog)中的所有内容。