C#讀取XML文檔使用XMLTextReader類淺析

來源:互聯網
上載者:User

C#讀取XML文檔兩種方法的比較從何談起呢?讓我們首先來看看XMLTextReader和XmlDocument讀取XML檔案的比較:

C#讀取XML文檔之在.NET架構的System.XML名稱空間中包含的XMLTextReader類不需要對系統資源要求很高,就能從XML檔案中快速讀取資料。使用XMLTextReader類能夠從XML檔案中讀取資料,並且將其轉換為HTML格式在瀏覽器中輸出。

讀本文之前,讀者需要瞭解一些基本知識:XML、HTML、C#程式設計語言,以及.NET尤其是ASP.NET架構的一些知識。

C#讀取XML文檔的解決為目的,微軟公司的.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檔案。

本文主要講述的C#讀取XML文檔的方法是第一個類XMLTextReader,這個類設計的目的就是從XML檔案中快速的讀取資料,而對系統資源(主要包括記憶體和處理器時間)不做很高的要求。在父級程式的控制下,它通過每次只處理一個節點的方式對XML檔案進行逐步操作,實現這種工作過程。在XML檔案的每個節點中,父級程式能決定該節點的類型,它的屬性和資料(如果有的話),以及其他有關該節點的資訊。基於這些資訊,父級程式可以選擇是處理這個節點還是忽略該節點的資訊,以滿足各種應用程式請求的需要。這被稱為抽取式(pull)處理模型,因為父級程式發出請求並且從XML檔案中抽取各個節點,然後根據需要處理它或者是不處理它。

我們可以把XMLTextReader類和XML簡單應用程式介面,即SAX相比,後者是在編程人員中非常流行的另一種讀取XML資料的技術。XMLTextReader 和SAX有一點很相似,它們都不需要佔用很多的系統資源,就能迅速的從XML檔案讀取資料。但是,與XMLTextReader的抽取式模型迥然不同,SAX使用的是推入式模型:XML處理器通過 “事件”告知主應用程式哪些節點資料是可以獲得,那些不能獲得;根據需要,主機程式則作出相應的反應或置之不理。換句話說,資料的傳送方向是從SAX處理常式中推入到主機。程式員們勢必會在抽取式和推入式處理模型誰更有優勢的問題上爭論一番,但是大家都不可否認的是,兩種模型都能很好的進行工作。.NET 架構不支援SAX,但是你能使用現存的SAX工具, 例如 MSXML分析器,用於你的.NET 程式。

C#讀取XML文檔之XMLTextReader 類有一些構造程式來適應各種各樣的情況,比如從一個已經存在的資料流或統一資源定位網址讀取資料。最常見的是,你或許想從一個檔案讀取XML資料,那麼也就有一個相應的構造程式來為此服務。這裡有一個例子(我的所有代碼例子都使用的是C#語言,如果你喜歡使用VISUAL BASIC語言,它們轉換起來很容易)。

 
  1. XMLTextReader myReader;  
  2.  
  3. myReader = New XMLTextReader("c:\data\sales.XML")  

建立一個稱為Read()方法的迴圈,這個方法的傳回值總是為真,直到到達檔案的底部時,傳回值才變為假。換句話說, 迴圈在檔案的開始時啟動並且讀入所有的節點, 一次讀入一個節點, 直到到達檔案的結尾:

 
  1. While (myReader.Read()) {  
  2. ...  
  3. // 在這裡處理每個節點.  
  4. ...  
  5. }  

每次成功調用Read()之後,XMLTextReader執行個體化程式包含了目前節點(即剛剛從檔案中讀取的那個節點)的資訊。我們可以從XMLTextReader的成員中獲得上述資訊,就像表格1中描述的一樣;並通過NodeType屬性判斷出當前節點的類型。在節點類型的基礎上,程式的代碼可以讀取節點資料,檢查它是否有屬性,到底是忽略它還是根據程式需要進行相應的操作和處理。

當使用NodeType屬性時,理解節點怎麼聯絡到XML單元是非常重要的。例如, 看下列 XML元素:

﹤city﹥Chongqing﹤/city﹥

C#讀取XML文檔之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塊中),就像你以後在示範程式中看到的一樣。

本文只是一篇相當簡單的介紹C#讀取XML文檔之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 架構的類在C#讀取XML文檔方面如何呢?比如XMLDocument類在讀取XML資料方面表現如何呢?XMLDocument 類與XMLTextReader 類不同,它在儲存空間中建立整個XML文檔的節點樹。這樣就可以隨機的獲得XML資料(與XMLTextReader 類獲得資料的線性方式正好相反),並且在修改XML檔案的資料和結構時,具有非常完美的靈活性。另外,XMLDocument允許執行XSLT 轉變,不過,這些額外的功能是以運行速度的降低和系統資源的更多佔用為代價的。

C#讀取XML文檔使用XMLTextReader類程式碼片段:XmlTextReader.aspx

 
  1. ﹤%@ Import Namespace="System.Xml" %﹥  
  2. ﹤script language="C#" runat=server﹥  
  3. public class XmlDisplay  
  4. file://這個類讀入並處理XML檔案。  
  5. {  
  6. public string LoadDocument(String XmlFileName) {  
  7. XmlTextReader xmlReader = null;  
  8. StringBuilder html = new StringBuilder();  
  9. try {  
  10. file://建立XMLTextReader的執行個體。  
  11. xmlReader = new XmlTextReader(XmlFileName);  
  12. // 處理XML檔案  
  13. html.Append(ProcessXml(xmlReader));  
  14. }  
  15. catch (XmlException ex){  
  16. html.Append("發生一個XML異常:" +   
  17. ex.ToString());  
  18. }   
  19. catch (Exception ex){  
  20. html.Append("發生一個普通異常:" +   
  21. ex.ToString());  
  22. }   
  23. finally   
  24. {  
  25. if (xmlReader != null)  
  26. xmlReader.Close();  
  27. }  
  28. return html.ToString();  
  29. }  
  30. private string ProcessXml(XmlTextReader xmlReader)   
  31. {  
  32. StringBuilder temp = new StringBuilder();  
  33. file://這個方法讀入XML檔案並產生輸出的HTML文檔。  
  34. while ( xmlReader.Read() )   
  35. {  
  36. // 處理一個元素節點的起始。  
  37. if (xmlReader.NodeType == XmlNodeType.Element)   
  38. {   
  39. file://忽略﹤people﹥和﹤person﹥元素  
  40. if ((xmlReader.Name != "person") && (xmlReader.Name != "people"))   
  41. {  
  42. file://如果是一個﹤category﹥元素,開始一個新的段落  
  43. if ( xmlReader.Name == "category" )  
  44. temp.Append("﹤p﹥");  
  45. file://添加元素名到輸出中  
  46. temp.Append( xmlReader.Name + ": " );  
  47. }  
  48. }  
  49. // 處理文本節點  
  50. else if (xmlReader.NodeType == XmlNodeType.Text)   
  51. temp.Append(xmlReader.Value + "﹤br﹥");  
  52. file://處理元素節點的結尾  
  53. else if (xmlReader.NodeType == XmlNodeType.EndElement)   
  54. {  
  55. file://如果是﹤email﹥節點,添加結束段落的標記  
  56. if ( xmlReader.Name == "email" )   
  57. temp.Append("﹤/p﹥");   
  58. }   
  59. }//結束while迴圈  
  60. return temp.ToString();  
  61. } file://結束ProcessXML方法  
  62. } file://結束XmlDisplay類  
  63. private void Page_Load(Object sender, EventArgs e){  
  64. file://建立XmlDisplay類的執行個體  
  65. XmlDisplay XmlDisplayDemo = new XmlDisplay();  
  66. output.InnerHtml = XmlDisplayDemo.LoadDocument(Server.MapPath("XMLData.xml"));  
  67. }  
  68. ﹤/script﹥  
  69. ﹤html﹥  
  70. ﹤head﹥  
  71. ﹤/head﹥  
  72. ﹤body﹥  
  73. ﹤h2﹥示範XmlTextReader類﹤/h2﹥  
  74. ﹤div id="output" runat="server"/﹥  
  75. ﹤/body﹥  
  76. ﹤/html﹥  
  77.     static void Main(string[] args)  
  78.         {  
  79.             DateTime d1 =DateTime.Now;  
  80.             XmlDocumentTest();  
  81.             DateTime d2 =DateTime.Now;  
  82.             TimeSpan ts =d2-d1 ;  
  83.               
  84.             Console.WriteLine(ts.TotalMilliseconds) ;      
  85.             Console.Read() ;  
  86.  
  87.         }  
  88.  
  89.  
  90.         public static string XmlFileName = "http://www.cnblogs.com/XML/1.xml";  
  91.           
  92.         private static void XmlTextReaderTest()  
  93.         {  
  94.             XmlTextReader reader = new XmlTextReader(XmlFileName);  
  95.             while (reader.Read() )  
  96.             {  
  97.                 bool exit =false;  
  98.                 switch(reader.NodeType)  
  99.                 {  
  100.                     case XmlNodeType.Element :  
  101.                         break;  
  102.                     case XmlNodeType.Text :  
  103.                         if (reader.Value=="last")  
  104.                         {  
  105.                             exit=true;  
  106.                         }  
  107.                         break;  
  108.                     case XmlNodeType.EndElement  :  
  109.                        break;  
  110.                     default:  
  111.                        break;  
  112.                 }  
  113.                 if(exit)  
  114.                 {  
  115.                     return;  
  116.                       
  117.                 }  
  118.  
  119.             }  
  120.         }  
  121.  
  122.         private static void XmlDocumentTest()  
  123.         {  
  124.             XmlDocument xd =new XmlDocument() ;  
  125.            xd.Load(XmlFileName) ;  
  126.             XmlNode node = xd.SelectSingleNode("/people/person[category='last']");   
  127.             Console.Write(node.Name) ;   
  128.        } 

C#讀取XML文檔使用XMLTextReader類的方法就向你介紹到這裡,希望對你理解和學習C#讀取XML文檔使用XMLTextReader類有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.