XMLTextReader和XmlDocument读取XML文件的比较

 
看到网上一片文章,自己式了一下,果然 XMLTextReader 速度要快!
 
.NET 框架的 System.XML 名称空间中包含的 XMLTextReader 类不需要对系统资源要求很高,就能从 XML 文件中快速读取数据。使用 XMLTextReader 类能够从 XML 文件中读取数据,并且将其转换为 HTML 格式在浏览器中输出。
 
 
  读本文之前,读者需要了解一些基本知识: XML HTML C# 编程语言,以及 .NET 尤其是 ASP.NET 框架的一些知识。
 
  微软公司的 .NET 框架为开发者提供了许多开发的便利,随着 XML 的重要性不断增长,开发者们都期待着有一整套功能强大的 XML 工具被开发出来。 .NET 框架没有辜负我们的这番期望,在 System.XML 名称空间中组织进了以下几个用于 XML 的类:
 
   XMLTextReader------ 提供以快速、单向、无缓冲的方式存取 XML 数据。(单向意味着你只能从前往后读取 XML 文件,而不能逆向读取)
 
   XMLValidatingReader------ XMLTextReader 类一起使用,提供验证 DTD XDR XSD 架构的能力。
 
   XMLDocument------ 遵循 W3C 文档对象模型规范的一级和二级标准,实现 XML 数据随机的、有缓存的存取。一级水平包含了 DOM 的最基本的部分,而二级水平增加多种改进,包括增加了对名称空间和级连状图表 (CSS) 的支持。
 
   XMLTextWriter------ 生成遵循 W3C XML 1.0 规范的 XML 文件。
 
  本文主要讲述的是第一个类 XMLTextReader ,这个类设计的目的就是从 XML 文件中快速的读取数据,而对系统资源(主要包括内存和处理器时间)不做很高的要求。在父级程序的控制下,它通过每次只处理一个节点的方式对 XML 文件进行逐步操作,实现这种工作过程。在 XML 文件的每个节点中,父级程序能决定该节点的类型,它的属性和数据(如果有的话),以及其他有关该节点的信息。基于这些信息,父级程序可以选择是处理这个节点还是忽略该节点的信息,以满足各种应用程序请求的需要。这被称为抽取式( pull )处理模型,因为父级程序发出请求并且从 XML 文件中抽取各个节点,然后根据需要处理它或者是不处理它。
  我们可以把 XMLTextReader 类和 XML 简单应用程序接口,即 SAX 相比,后者是在编程人员中非常流行的另一种读取 XML 数据的技术。 XMLTextReader SAX 有一点很相似,它们都不需要占用很多的系统资源,就能迅速的从 XML 文件读取数据。但是,与 XMLTextReader 的抽取式模型迥然不同, SAX 使用的是推入式模型: XML 处理器通过 事件 告知主机应用程序哪些节点数据是可以获得,那些不能获得;根据需要,主机程序则作出相应的反应或置之不理。换句话说,数据的传送方向是从 SAX 处理程序中推入到主机。程序员们势必会在抽取式和推入式处理模型谁更有优势的问题上争论一番,但是大家都不可否认的是,两种模型都能很好的进行工作。 .NET 框架不支持 SAX ,但是你能使用现存的 SAX 工具 , 例如 MSXML 分析器,用于你的 .NET 程序。
 
   XMLTextReader 类有一些构造程序来适应各种各样的情况,比如从一个已经存在的数据流或统一资源定位网址读取数据。最常见的是,你或许想从一个文件读取 XML 数据,那么也就有一个相应的构造程序来为此服务。这里有一个例子(我的所有代码例子都使用的是 C# 语言,如果你喜欢使用 VISUAL BASIC 语言,它们转换起来很容易)。
 
XMLTextReader myReader;
myReader = New XMLTextReader("c:/data/sales.XML")
 
  创建一个称为 Read() 方法的循环,这个方法的返回值总是为真,直到到达文件的底部时,返回值才变为假。换句话说 , 循环在文件的开始时启动并且读入所有的节点 , 一次读入一个节点 , 直到到达文件的结尾:
 
While (myReader.Read()) {
...
//
在这里处理每个节点 .
...
}
 
  每次成功调用 Read() 之后, XMLTextReader 实例化程序包含了目前节点(即刚刚从文件中读取的那个节点)的信息。我们可以从 XMLTextReader 的成员中获得上述信息,就像表格 1 中描述的一样;并通过 NodeType 属性判断出当前节点的类型。在节点类型的基础上,程序的代码可以读取节点数据,检查它是否有属性,到底是忽略它还是根据程序需要进行相应的操作和处理。
 
  当使用 NodeType 属性时,理解节点怎么联系到 XML 单元是非常重要的。例如 , 看下列 XML 元素:
 
city Chongqing /city
 
   XMLtextReader 把这个元素看作 3 个节点,顺序如下:
 
   1 .< city >标签被读为类型 XMLNodeType.Element 节点,元素的名字 “city” 可从 XMLTextReader Name 属性中获得。
 
   2 .文本数据 “Chongqing” 被读为类型为 XMLNodeType.Text 的节点。数据 “Chongqing ” 可从 XMLTextReader Value 属性中取得。
 
   3 .< /city >标签被读为类型为 XMLNodeType.EndElement 节点。同样,元素的名称 “city” 可从 XMLTextReader Name 属性中获得。
 
  这是 3 种重要的节点类型,其它的类型在 .NET 的说明文档中有详细说明,请大家参阅相关资料。
 
  如果 XMLTextReader 遇到一个错误 , 例如出现违反 XML 句法的情况,它抛出一个 System.XML.XMLException 类型的异常。使用这个类的代码应该总是被保护 ( Try……Catch 块中 ) ,就像你以后在演示程序中看到的一样。
  本文只是一篇相当简单的介绍 XMLTextReader 类的文章, XMLTextReader 类有相当多的成员,在这里不可能一一述及。当读入 XML 数据时, XMLTextReader 能提供相当强的灵活性。即便如此,我仍然进行了大量的论述,以保证读者能编制程序来实现现实世界中经常要求完成的任务,也就是从一个 XML 文件读取数据然后以 HTML 的格式输出,从而实现在浏览器中的显示。
 
  这个 ASP.NET 程序 ( 脚本 ) 在服务器上运行并产生一个 HTML 页面返回浏览器。这段脚本程序在代码段 1 给出,它用来工作使用的 XML 数据文件在代码段 2 给出。你能看到这个 XML 文件包含一份表示联系关系的列表;程序的目标即是将这个列表显示出来,为了更容易我们观察,这些列表已经被格式化了。
 
  运行程序:
 
   1 将代码段 1 存为 XMLTextReader.ASPx 文件,将代码段 2 存为 XMLData.XML 文件。
 
   2 把这两个文件都放在一个已经安装好 .NET 框架的网络服务器的虚拟文件夹中。
 
   3 打开 Internet Explorer 并且浏览这个 ASPx 文件,例如,在一个局域网服务器上 , URL 将是 http://localhost/xmltextreader.ASPx ;
 
  程序工作的大部分都由 XMLDisplay 类来做 , 尤其是被 ProcessXML() 方法完成的。它每次读取一个节点 XML 数据,对于感兴趣的元素,节点数据和后跟冒号的节点名将和相应的 HTML 格式化标签一起写入输出结果中。在这阶段, 输出结果 由一个 HTML 文本暂时储存在其中的 StringBuilder 对象构成。
 
   ProcessXML() 方法是从 LoadDocument() 方法调用的。这个方法执行的任务是产生一个 XMLTextReader 实例化程序并在调用 ProcessXML 之前装载 XML 文件。它同时也处理异常,随后产生错误的信息并在浏览器中显示出来。最终该方法返回一个字符串,这个字符串或者包含产生的 HTML 内容,或者如果异常发生的话就包含出错信息,。
 
  程序执行以 Page_Load() 程序开始,当浏览器请求浏览这个页面时,这一步会自动执行。这里的代码实例化了 XMLDisplay 类并调用它的 LoadDocument() 方法。如果一切运行正常的话,格式化的 HTML 形式的返回值将被拷贝到页面的一个< div >标签中,生成的 HTML 文档被送回到浏览器中并显示出来。
 
  其他的 .NET 框架的类,比如 XMLDocument 类在读取 XML 数据方面表现如何呢? XMLDocument 类与 XMLTextReader 类不同,它在存储器中创建整个 XML 文档的节点树。这样就可以随机的获得 XML 数据(与 XMLTextReader 类获得数据的线性方式正好相反),并且在修改 XML 文件的数据和结构时,具有非常完美的灵活性。另外 ,XMLDocument 允许执行 XSLT 转变,不过,这些额外的功能是以运行速度的降低和系统资源的更多占用为代价的。
  代码段 1 XmlTextReader.aspx
 
%@ Import Namespace="System.Xml" %
 
script language="C#" runat=server
 
public class XmlDisplay
file://
这个类读入并处理 XML 文件。
{
 
public string LoadDocument(String XmlFileName) {
XmlTextReader xmlReader = null;
StringBuilder html = new StringBuilder();
try {
file://
创建 XMLTextReader 的实例。
xmlReader = new XmlTextReader(XmlFileName);
//
处理 XML 文件
html.Append(ProcessXml(xmlReader));
}
catch (XmlException ex){
html.Append("
发生一个 XML 异常: " +
ex.ToString());
}
catch (Exception ex){
html.Append("
发生一个普通异常: " +
ex.ToString());
}
finally
{
if (xmlReader != null)
xmlReader.Close();
}
return html.ToString();
}
 
private string ProcessXml(XmlTextReader xmlReader)
{
StringBuilder temp = new StringBuilder();
 
file:// 这个方法读入 XML 文件并生成输出的 HTML 文档。
while ( xmlReader.Read() )
{
//
处理一个元素节点的起始。
if (xmlReader.NodeType == XmlNodeType.Element)
{
file://
忽略< people >和< person >元素
if ((xmlReader.Name != "person") && (xmlReader.Name != "people"))
{
file://
如果是一个< category >元素,开始一个新的段落
if ( xmlReader.Name == "category" )
temp.Append("
p ");
file://
添加元素名到输出中
temp.Append( xmlReader.Name + ": " );
}
}
//
处理文本节点
else if (xmlReader.NodeType == XmlNodeType.Text)
temp.Append(xmlReader.Value + "
br ");
file://
处理元素节点的结尾
else if (xmlReader.NodeType == XmlNodeType.EndElement)
{
file://
如果是< email >节点,添加结束段落的标记
if ( xmlReader.Name == "email" )
temp.Append("
/p ");
}
}//
结束 while 循环
 
return temp.ToString();
 
} file:// 结束 ProcessXML 方法
 
} file:// 结束 XmlDisplay
 
private void Page_Load(Object sender, EventArgs e){
file://
创建 XmlDisplay 类的实例
XmlDisplay XmlDisplayDemo = new XmlDisplay();
output.InnerHtml = XmlDisplayDemo.LoadDocument(Server.MapPath("XMLData.xml"));
}
/script
html
head
/head
body
h2 >演示 XmlTextReader 类< /h2
div id="output" runat="server"/
/body
/html
 
 
 
 
 
 
 
 1    static void Main(string[] args)
 2        {
 3            DateTime d1 =DateTime.Now;
 4            XmlDocumentTest();
 5            DateTime d2 =DateTime.Now;
 6            TimeSpan ts =d2-d1 ;
 7           
 8            Console.WriteLine(ts.TotalMilliseconds) ;   
 9            Console.Read() ;
10
11        }
12
13
14        public static string XmlFileName = "../../XML/1.xml";
15       
16        private static void XmlTextReaderTest()
17        {
18            XmlTextReader reader = new XmlTextReader(XmlFileName);
19            while (reader.Read() )
20            {
21                bool exit =false;
22                switch(reader.NodeType)
23                {
24                    case XmlNodeType.Element :
25                        break;
26                    case XmlNodeType.Text :
27                        if (reader.Value=="last")
28                        {
29                            exit=true;
30                        }
31                        break;
32                    case XmlNodeType.EndElement  :
33                        break;
34                    default:
35                        break;
36                }
37                if(exit)
38                {
39                    return;
40                   
41                }
42
43            }
44        }
45
46        private static void XmlDocumentTest()
47        {
48            XmlDocument xd =new XmlDocument() ;
49            xd.Load(XmlFileName) ;
50            XmlNode node = xd.SelectSingleNode("/people/person[category='last']");
51            Console.Write(node.Name) ;
52        }
 
 
结果发现第一个耗时:
结果发现第二个耗时:
 
 
参考示例 : http://www.5h6.com/article/27744.html
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值