首頁  >  文章  >  後端開發  >  XMLTextReader與XmlDocument讀取XML檔的比較

XMLTextReader與XmlDocument讀取XML檔的比較

黄舟
黄舟原創
2017-02-28 16:29:561703瀏覽

看到網路上一片文章,自己式了一下,果然 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 XmlDisplayfile://这个类读入并处理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        }

以上就是XMLTextReader和XmlDocument读取XML文件的比较的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn