深入认识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 ...
随机推荐
- 《JavaScript高级程序设计》 -- 基本概念(一)
之前看过好几遍<JavaScript高级程序设计>这一书,但是始终没有完完整整的看过一遍.从现在开始我会把它完整的啃一遍,每章节都记录笔记,自己的心得,加油! 由于前三章的内容比较简单,因 ...
- java循环、数组练习
System.out.println("请输入学生个数"); int a=sc.nextInt();//定义一个变量说明学生的数量 int max=0; int[] scores= ...
- Linux 下搭建www服务器
偶然的机会接触了前端开发,尽管最初的意愿是后台. 不过现在看来,前端后台数据库密不可分! 回想起来感觉自己学习的层次也还很好,因为之前有学习c语言.c++的基础,所以在学习html,js的过程中感觉还 ...
- Rsync:一个很实用的文件同步命令
sync是Linux系统下的文件同步和数据传输工具,可用于同步文件.代码发布 1.安装. yum install -y xinetd yum insatll -y rsync 2.配置 打开rsync ...
- MongoDB数据库索引构建情况分析
前面的话 本文将详细介绍MongoDB数据库索引构建情况分析 概述 创建索引可以加快索引相关的查询,但是会增加磁盘空间的消耗,降低写入性能.这时,就需要评判当前索引的构建情况是否合理.有4种方法可以使 ...
- Liunx上传下载和压缩问题分享
昨天紧急需求需要测试,开发远程发了个包需要部署到生产环境.我通过FileZila连接到服务器,然后把补丁包发送到服务器对应路径,通过CRT操作,进行包的解压.重启. 同时,为了配合开发定位问题,需要从 ...
- Android 自定义 permission
Android 自定义 permission Android 添加自定义权限 permission-tree 权限的根节点,3个成员都要定义 name 一般来说需要2个".":比如 ...
- Jquery table元素操作-创建|数据填充|重置|隐藏行
1.Jquery创建表格 /** * 创建表格 * @param label 标题 json格式,数据结构见附录1 * @param data 数据 json格式,数据结构见附录1 * @param ...
- WMware虚拟机NAT模式配置网络设置Linux虚拟机固定IP
一.主机配置 1.查看本机ip 2.给vmnet8设置固定IP和网段 3.根据vmnet8网段设置VMware NAT模式网段 4.点击NAT设置网关 二.启动虚拟机 网络设置如下: 这个地址值在这个 ...
- wpf的一些总结
wpf技巧 隐藏控件不占空间,设置visibility为:Collapsed tabcontrol的高度宽度跟随界面的大小变化:属性height\width绑定grid的actualheight\ac ...