深入认识XmlReader
深入认识XmlReader
摘要
XmlReader类是组成.NET的关键技术之一,极大地方便了开发人员对Xml的操作。通过本文您将对XmlReader有一个很好的认识,并将其应用到实际开发中。
目录
1.概要
XmlReader 类是一个提供对 XML 数据的非缓存、只进只读访问的抽象基类。该类符合 W3C 可扩展标记语言 (XML) 1.0 和 XML 中的命名空间的建议。
XmlReader 类支持从流或文件读取 XML 数据。该类定义的方法和属性使您可以浏览数据并读取节点的内容。
XmlReader类是一个抽象类,XmlTextReader,XmlValidatingReader,和XmlNodeReader类都继承自XmlReader类。XmlReader类有很多方法和属性用来读取XML文件的内容、查找XML元素的深度、判断当前元素的内容是否为空,以及导航XML的属性等。
2.创建Xml读取器
我们可以通过Create方法来创建一个XmlReader实例,也可以通过XmlReaderSettings类来配置XmlReader对象。使用XmlReaderSettings类的属性启用或禁用XmlReader对象的特定功能,然后将XmlReaderSettings对象传递给Create方法。
MSDN建议:
尽管在 .NET Framework 2.0 版中,Microsoft .NET Framework 包括 XmlReader 类的具体实现,例如 XmlTextReader、XmlNodeReader 和 XmlValidatingReader类,但是,我们建议您使用 Create 方法创建 XmlReader 实例。
通过使用 Create 方法和 XmlReaderSettings 类,您将得到下列好处:
- 可以指定要在所创建的 XmlReader 对象上支持的功能。
- XmlReaderSettings 类可以重复使用,以创建多个读取器对象。可以使用相同的设置创建多个具有相同功能的读取器。另外,可以修改 XmlReaderSettings 对象并创建具有不同功能集的新读取器。
- 可以将功能添加到现有读取器中。Create 方法可以接受其他 XmlReader 对象。基础 XmlReader 对象可以是用户定义的读取器或 XmlTextReader 对象,也可以是要添加附加功能的另一个 XmlReader 实例。
- 充分利用 .NET Framework 2.0 版本的 XmlReader 类中增加的所有新功能。某些功能只能在通过 Create 方法创建的 XmlReader 对象上使用,例如更好的一致性检查以及与 XML 1.0 建议的一致性。
提示:XmlReaderSettings 类的属性设置可以参考:http://msdn.microsoft.com/zh-cn/library/9khb6435(v=vs.80).aspx
实例化XmlReader:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create("books.xml", settings);
3.访问外部资源
XmlResolver类用于定位并访问XmlReader对象所需的任何资源。XmlResolver可以用于执行以下操作:
- 定位并打开 XML 实例文档。
- 定位并打开 XML 实例文档所引用的任何外部资源。其中可以包括实体、文档类型定义、架构等。
- 如果资源存储在要求身份验证的系统上,System.Xml.XmlResolver.Credentials 属性可以用于指定必要的凭据。
注意:如果未指定 XmlResolver,创建的读取器将使用没有用户凭据的默认 XmlUrlResolver。XmlUrlResover解析由统一资源标识符 (URI) 命名的外部 XML 资源,是 System.Xml 命名空间中的所有类的默认解析器。
以下代码创建一个 XmlReader 实例,使用具有默认凭据的 XmlUrlResolver。

// Create a resolver with default credentials. XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials; // Set the reader settings object to use the resolver. settings.XmlResolver = resolver; // Create the XmlReader object. XmlReader reader = XmlReader.Create("http://ServerName/data/books.xml", settings);

4.读取数据
读取数据是处理XML文件最终目的,因此也是本文最重要的部分。下面将详细讨论如何通过XmlReader来读取Xml数据。
4.1 当前节点位置
XmlReader 类提供了对 XML 流或文件的只进访问。当前节点是读取器当前所处的 XML 节点。所有调用的方法和执行的操作与当前节点相关,所有检索到的属性反映当前节点的值。
读取器通过调用一种读取方法(read方法)前进。重复调用该读取方法可以将读取器移至下一个节点。此类调用通常在 While 循环内执行。
下面的示例显示了如何在流中定位来确定当前的节点类型。
reader.MoveToContent();
// Parse the file and display each of the nodes. while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
Console.Write("<{0}>", reader.Name);
break;
case XmlNodeType.Text:
Console.Write(reader.Value);
break;
case XmlNodeType.CDATA:
Console.Write("<![CDATA[{0}]]>", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.Write("<!--{0}-->", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.Write("<?xml version='1.0'?>");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.Write(reader.Name);
break;
case XmlNodeType.EndElement:
Console.Write("</{0}>", reader.Name);
break;
}
}
提示:XmlNodeType为节点类型,详细信息可参考http://msdn.microsoft.com/zh-cn/library/3k5w5zc3(v=vs.80).aspx
4.2 读取元素
下表介绍 XmlReader 类为处理元素提供的方法和属性。
|
成员名称 |
说明 |
|---|---|
|
IsStartElement |
检查当前节点是否是开始标记或空的元素标记。 |
|
ReadStartElement |
检查当前节点是否为元素并将读取器推进到下一个节点。 |
|
ReadEndElement |
检查当前节点是否为结束标记并将读取器推进到下一个节点。 |
|
ReadElementString |
读取纯文本元素。 |
|
ReadToDescendant |
将 XmlReader 前进到具有指定名称的下一个子代元素。 |
|
ReadToNextSibling |
将 XmlReader 前进到具有指定名称的下一个同辈元素。 |
|
IsEmptyElement |
检查当前元素是否包含空的元素标记。此属性使您能够确定下面各项之间的差异:
也就是说,IsEmptyElement 只是报告源文档中的元素是否包含结束元素标记。 |
以下代码使用 ReadStartElement 和 ReadString 方法读取元素。

using (XmlReader reader = XmlReader.Create("book3.xml")) {
// Parse the XML document. ReadString is used to
// read the text content of the elements. reader.Read();
reader.ReadStartElement("book");
reader.ReadStartElement("title");
Console.Write("The content of the title element: ");
Console.WriteLine(reader.ReadString());
reader.ReadEndElement();
reader.ReadStartElement("price");
Console.Write("The content of the price element: ");
Console.WriteLine(reader.ReadString());
reader.ReadEndElement();
reader.ReadEndElement();
}

4.3 读取属性
XmlReader 类提供了各种方法和属性来读取属性。属性在元素上最常见。但是,XML 声明和文档类型节点上也允许使用属性。
在位于某个元素节点上时,使用 MoveToAttribute 方法可以浏览该元素的属性列表。调用了 MoveToAttribute 之后,节点属性(例如 Name、NamespaceURI、Prefix 等)将反映该属性的属性,而不是其所属的包含元素的属性。
下表介绍专门为处理属性而设计的方法和属性。
| 成员名 | 说明 |
|---|---|
|
AttributeCount |
获取元素的属性列表。 |
|
GetAttribute |
获取属性的值。 |
|
HasAttributes |
获取一个值,该值指示当前节点是否有任何属性。 |
|
IsDefault |
获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的属性。 |
|
Item |
获取指定属性的值。 |
|
MoveToAttribute |
移动到指定的属性。 |
|
MoveToElement |
移动到拥有当前属性节点的元素。 |
|
MoveToFirstAttribute |
移动到第一个属性。 |
|
MoveToNextAttribute |
移动到下一个属性。 |
|
ReadAttributeValue |
将属性值分析为一个或多个 Text、EntityReference 或 EndEntity 节点。 |
实例1:使用 AttributeCount 属性读取某个元素的所有属性。

// Display all attributes. if (reader.HasAttributes) {
Console.WriteLine("Attributes of <" + reader.Name + ">");
for (int i = ; i < reader.AttributeCount; i++) {
Console.WriteLine(" {0}", reader[i]);
}
// Move the reader back to the element node. reader.MoveToElement();
}

实例2:在 While 循环中使用 MoveToNextAttribute 属性读取某个元素的所有属性。

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();
}

实例3:按名称获取属性的值。
reader.ReadToFollowing("book");
string isbn = reader.GetAttribute("ISBN");
Console.WriteLine("The ISBN value: " + isbn);
提示:ReadToFollowing方法表示一直读取,直到找到具有指定限定名的元素。使用此方法可以提高在 XML 文档中查找命名元素的速度。 如果找到匹配的元素,它让读取器前进到与指定名称匹配的下一个后续元素,并返回 true。
4.4 读取内容
1. 使用Value属性
Value 属性可以用于获取当前节点的文本内容。返回的值取决于当前节点的节点类型。下表介绍每种可能的节点类型所返回的内容。
| 节点类型 | 值 |
|---|---|
|
Attribute |
属性的值。 |
|
CDATA |
CDATA 节的内容。 |
|
Comment |
注释的内容。 |
|
DocumentType |
内部子集。 |
|
ProcessingInstruction |
全部内容(不包括指令目标)。 |
|
SignificantWhitespace |
混合内容模型中任何标记之间的空白。 |
|
Text |
文本节点的内容。 |
|
Whitespace |
标记之间的空白。 |
|
XmlDeclaration |
声明的内容。 |
|
所有其他节点类型 |
空字符串。 |
2.利用ReadString方法
ReadString 方法以字符串的形式返回元素或文本节点的内容。
如果 XmlReader 位于某个元素上,ReadString 将所有文本、有效空白、空白和 CDATA 节节点串联在一起,并以元素内容的形式返回串联的数据。当遇到任何标记时,读取器停止。这可以在混合内容模型中发生,也可以在读取元素结束标记时发生。
如果 XmlReader 位于某个文本节点上,ReadString 将对文本、有效空白、空白和 CDATA 节节点执行相同的串联。读取器在第一个不属于以前命名的类型的节点处停止。如果读取器定位在属性文本节点上,则 ReadString 与读取器定位在元素开始标记上时的功能相同。它返回所有串联在一起的元素文本节点。
3.利用ReadInnerXml方法
ReadInnerXml 方法返回当前节点的所有内容(包括标记)。不返回当前节点(开始标记)和对应的结束节点(结束标记)。例如,如果包含 XML 字符串 <node>this<child id="123"/></node>,ReadInnerXml 将返回 this<child id="123"/>。
| 节点类型 | 初始位置 | XML 片断 | 返回值 | 位于下列内容之后 |
|---|---|---|---|---|
|
Element |
在 item1 开始标记上。 |
<item1>text1</item1><item2>text2</item2> |
text1 |
在 item2 开始标记上。 |
|
Attribute |
在 attr1 属性节点上。 |
<item attr1="val1" attr2="val2">text</item> |
val1 |
保留在 attr1 属性节点上。 |
如果读取器定位在叶节点上,则调用 ReadInnerXml 等效于调用 Read。
4.利用ReadOuterXml方法
ReadOuterXml 方法返回当前节点及其所有子级的所有 XML 内容,包括标记。其行为与 ReadInnerXml 类似,只是同时还返回开始标记和结束标记。
使用上表中的值,如果读取器位于 item1 开始标记上,ReadOuterXml 将返回 <item1>text1</item1>。如果读取器位于 attr1 属性节点上,ReadOuterXml 将返回 attr1="val1"。
5. 一个简单实例
将菜单food.xml的数据解析,并按一定的格式显示出来。
food.xml数据格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
</breakfast_menu>

C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml; namespace myXmlReader
{
class Program
{
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(@"E:\kemi\CodeNow\Project\XmlReader\food.xml");//创建XmlReader实例
while (reader.Read())
{
if (reader.NodeType.Equals(XmlNodeType.Element))//判断节点类型 {
switch (reader.Name)
{ case "breakfast_menu":
Console.WriteLine("===========breakfast menu==========");
break;
case "name":
Console.WriteLine("Name:{0}", reader.ReadString());//使用ReadString读取数据 break;
case "price":
Console.WriteLine("Price:{0}", reader.ReadString());
break;
case "description":
Console.WriteLine("Description:{0}", reader.ReadInnerXml());//使用ReadInnerXml读取数据 break;
case "calories":
Console.WriteLine("Description:{0}", reader.ReadInnerXml());
break;
default:
Console.WriteLine("");
break;
}
}
} Console.Read();
}
}
}
输出结果:

深入认识XmlReader的更多相关文章
- XmlValidationHelper XSD、Schema(XmlSchemaSet)、XmlReader(XmlValidationSettings)、XmlDocument、XDocument Validate
namespace Test { using Microshaoft; using System; using System.Xml; using System.Xml.Linq; class Pro ...
- XmlReader和XElement组合之读取大型xml文档
简介 在.NET framework 中存在大量操作xml数据的类库和api,但在.NET framework 3.5后我们的首选一般就是linq to xml. linq to xml操作xml数据 ...
- php xml 文件读取 XMLReader
php xml 文件读取 <?php /** $xmlString = '<xml> <persons count="10"> <person ...
- C# XmlReader
一个非常全面的XML解析类 using System; using UnityEngine; using System.Xml; using System.Collections; using Uni ...
- XmlReader读取XML
StringBuilder output = new StringBuilder(); String xmlString = @"<bookstore> <book gen ...
- XML参考 :XmlReader 详解、实例
XML参考 :XmlReader 详解.实例-- 详解 转:http://www.cnblogs.com/Dlonghow/archive/2008/07/28/1252191.html XML参考 ...
- XmlWriter/XmlReader示例代码
在Silverlight项目中,如果您想最大程度的减少xap包的大小,仅使用默认System.Xml命名空间下提供的功能来实现“XML序列化/反序列化”,恐怕XmlReader/XmlWriter将成 ...
- C# XmlReader/XmlWriter 类
XmlReader用于读取Xml文件,XmlWriter用于将数据写到Xml文件.其实,在印象当中,XML很多的操作类都支持直接Save.Read也支持接受XmlReader与XmlWriter类的示 ...
- 使用XmlReader读取xml文件之二
在.net开发中经常需要读写xml形式的文件(app.config和web.config分别是WinForm和WebForm中使用到的 xml文件的一个特列,并且微软提供了通用的方法,在此就不赘述了) ...
- 使用XmlReader读Xml
XmlDocument和XElement在读取Xml时要将整个Xml文档放到内存中去操作,这样做操作简单,但是很费内存和IO(可能是磁盘IO或者网络IO):而在有些场景下我们必须考虑尽可能节省内存和I ...
随机推荐
- Python-WXPY实现微信监控报警
概述: 本文主要分享一下博主在学习wxpy 的过程中开发的一个小程序.博主在最近有一个监控报警的需求需要完成,然后刚好在学习wxpy 这个东西,因此很巧妙的将工作和学习联系在一起. 博文中主要使用到的 ...
- 一步一步学Vue (一)
vue应该是前端主流框架中的集成大成者,它吸取了knockout,angular,react设置avalon的经验,支持各种模式写法,入门很简单,从本章开始,会记录学习vue中的点点滴滴,以笔记的形式 ...
- java Script 用if else 实现从大到小指定输出,升序排列
我只是一个小白 各位大神看到不要介意 var a = Number(prompt("请输入你需要排列的第一个数字")) var b = Number(prompt("请输 ...
- .net 自动摘要等算法 HanLP.net
参考资料: http://www.hankcs.com/nlp/call-hanlp-in-csharp.html 目前自动摘要算法似乎没有.net 版本,而以java,python 居多 自动摘要算 ...
- 理解Linux文件系统之inode
很少转发别人的文章,但是这篇写的太好了. 理解inode 作者: 阮一峰 inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统 ...
- Hibernate 实体映射类的状态值自动转换
经常会遇到有些字段在数据库只是一个 byte 值,但是取出数据后需要转换为真实的状态名称. 举个栗子:一个图书管理系统,书籍有一个属性 stat(借出状态),在库中只需要保存一个 0/1/2/3/4 ...
- spring框架的IOC的底层原理
1.IOC概念:spring容器创建对象并管理 2.IOC的底层原理的具体实现: 1)所使用的技术: (1). dom4j解析xml配置文件 (2).工厂设计模式(解耦合) (3).反射 第一步:配置 ...
- Windows远程linux服务器执行shell命令
一.前言 借用百度百科关于putty的描述:PuTTY是一个Telnet.SSH.rlogin.纯TCP以及串行接口连接软件.较早的版本仅支持Windows平台,在最近的版本中开始支持各类Unix平台 ...
- 【echart】学习笔记
1. x 轴 y轴 的max min 只能为5的倍数 2.
- java对Microsoft Document的操作--->对Excel的操作
起初,自己想对网站上爬取一些数据来写到Excel表格中,便在网上找了找java操作Excel接口,了解到Apache的POI接口可以对微软的文档进行操作,WIKI搜索的结果如下, HSSF - 提供读 ...