看到網路上一片文章,自己式了一下,果然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:datasales.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.cnblogs.com/goody9807/archive/2006/10/24/534888.html