使用XmlReader读Xml XmlDocument和XElement在读取Xml时要将整个Xml文档放到内存中去操作,这样做操作简单,但是很费内存和IO(可能是磁盘IO或者网络IO);而在有些场景下我们必须考虑尽可能节省内存和IO的开销,这时候就该XmlReader和XmlWriter出场了。
XmlReader读取Xml需要通过Read()实例方法,不断读取Xml文档中的声明,节点开始,节点内容,节点结束,以及空白等等,直到文档结束,Read()方法返回false。
如下读取Xml内容实例代码和注释说明
//玉开技术博客:http://www.cnblogs.com/yukaizhao
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Xml;
using
System.IO;
namespace
UseXmlReader
{
class
Program
{
static
void
Main(
string
[] args)
{
//声明StringReader传入Xml文本,作为XmlReader.Create的参数
using
(StringReader strRdr =
new
StringReader(
@"
I'm a Cat
"
))
{
//通过XmlReader.Create静态方法创建XmlReader实例
using
(XmlReader rdr = XmlReader.Create(strRdr))
{
//循环Read方法直到文档结束
while
(rdr.Read())
{
Console.WriteLine(
"rdr.NodeType = "
+ rdr.NodeType);
//如果是开始节点
if
(rdr.NodeType == XmlNodeType.Element) {
//通过rdr.Name得到节点名
string
elementName = rdr.Name;
Console.WriteLine(elementName +
" element start"
);
if
(elementName ==
"root"
) {
}
//读取到cat元素 这时rdr.Read()读取到的内容为
else
if
(elementName ==
"cat"
)
{
//可以通过中括号获得属性值
string
colorVal = rdr[
"color"
];
Console.WriteLine(
"\tcat's color is "
+ colorVal);
//读取到节点内文本内容
if
(rdr.Read()) {
//通过rdr.Value获得文本内容
Console.WriteLine(
"\t cat said:"
+ rdr.Value);
}
}
}
else
if
(rdr.NodeType == XmlNodeType.EndElement)
{
//在节点结束时也可以通过rdr.Name获得节点名字
string
elementName = rdr.Name;
Console.WriteLine(elementName +
" element end"
);
}
}
}
}
Console.Read();
}
}
}
如果觉得代码不明白,下面是一张读取顺序图,标明了读取顺序号和每次读取的内容,如下图所示: 从图中可以看到XmlReader在读取这段Xml时: 第1次Read()读取的是Xml文档声明部分 第2次Read()读取的是声明后的空白 第3次Read()读取的是根节点root的开始标签 第4次Read()读取的是根节点开始后的空白 第5次Read()读取的是cat节点的开始部分,从左尖括号到右尖括号包括该节点的属性 第6次读取的是cat节点的内容 第7次读取的是cat节点的结束标签 第8次读取的是cat节点结束标签后的空白 第9次读取的是dog节点的开始部分,注意是从左尖括号开始到结束斜杠之前 第10次读取的是dog标签的结束/> 第11次读取的是dog标签结束后的空白 第12次读取的是root的结束标签 感谢@Kingthy对文中消耗IO说法提出问题,XmlReader和XmlDocument消耗的IO是一样的;不同的是XmlReader可以读取一点,显示一点,而XmlDocument必须完全读入之后才可以开始处理。
C#处理Xml的相关随笔:
1.通过XmlDocument读写Xml文档 2.使用XmlReader读Xml,使用XmlWriter写Xml 3.使用Linq to xml存取XML 4.通过XmlScheme定义固定格式xml文档 5.Xml序列化或者反序列化类 6.通过XPath查找Xml节点 7.通过Xslt转化Xml格式
XmlDocument和XElement在读取Xml时要将整个Xml文档放到内存中去操作,这样做操作简单,但是很费内存和IO(可能是磁盘IO或者网络IO);而在有些场景下我们必须考虑尽可能节省内存和IO的开销,这时候就该XmlReader和XmlWriter出场了。
XmlReader读取Xml需要通过Read()实例方法,不断读取Xml文档中的声明,节点开始,节点内容,节点结束,以及空白等等,直到文档结束,Read()方法返回false。
如下读取Xml内容实例代码和注释说明
//玉开技术博客:http://www.cnblogs.com/yukaizhao using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; namespace UseXmlReader { class Program { static void Main( string [] args) { //声明StringReader传入Xml文本,作为XmlReader.Create的参数 using (StringReader strRdr = new StringReader( @"
" )) { //通过XmlReader.Create静态方法创建XmlReader实例 using (XmlReader rdr = XmlReader.Create(strRdr)) { //循环Read方法直到文档结束 while (rdr.Read()) { Console.WriteLine( "rdr.NodeType = " + rdr.NodeType); //如果是开始节点 if (rdr.NodeType == XmlNodeType.Element) { //通过rdr.Name得到节点名 string elementName = rdr.Name; Console.WriteLine(elementName + " element start" ); if (elementName == "root" ) { } //读取到cat元素 这时rdr.Read()读取到的内容为 else if (elementName == "cat" ) { //可以通过中括号获得属性值 string colorVal = rdr[ "color" ]; Console.WriteLine( "\tcat's color is " + colorVal); //读取到节点内文本内容 if (rdr.Read()) { //通过rdr.Value获得文本内容 Console.WriteLine( "\t cat said:" + rdr.Value); } } } else if (rdr.NodeType == XmlNodeType.EndElement) { //在节点结束时也可以通过rdr.Name获得节点名字 string elementName = rdr.Name; Console.WriteLine(elementName + " element end" ); } } } } Console.Read(); } } } |
如果觉得代码不明白,下面是一张读取顺序图,标明了读取顺序号和每次读取的内容,如下图所示:
从图中可以看到XmlReader在读取这段Xml时:
第1次Read()读取的是Xml文档声明部分
第2次Read()读取的是声明后的空白
第3次Read()读取的是根节点root的开始标签
第4次Read()读取的是根节点开始后的空白
第5次Read()读取的是cat节点的开始部分,从左尖括号到右尖括号包括该节点的属性
第6次读取的是cat节点的内容
第7次读取的是cat节点的结束标签
第8次读取的是cat节点结束标签后的空白
第9次读取的是dog节点的开始部分,注意是从左尖括号开始到结束斜杠之前
第10次读取的是dog标签的结束/>
第11次读取的是dog标签结束后的空白
第12次读取的是root的结束标签
感谢@Kingthy对文中消耗IO说法提出问题,XmlReader和XmlDocument消耗的IO是一样的;不同的是XmlReader可以读取一点,显示一点,而XmlDocument必须完全读入之后才可以开始处理。
C#处理Xml的相关随笔:
1.通过XmlDocument读写Xml文档
2.使用XmlReader读Xml,使用XmlWriter写Xml
3.使用Linq to xml存取XML
4.通过XmlScheme定义固定格式xml文档
5.Xml序列化或者反序列化类
6.通过XPath查找Xml节点
7.通过Xslt转化Xml格式