摘 要: DataSet對象訪問XML數(shù)據(jù)以及從DataSet數(shù)據(jù)集中輸出XML數(shù)據(jù)的方法。
關鍵詞: ADO.NET XML語言 DataSet XmlDataDocument
由于XML(Extensible Markup Language)具有良好的數(shù)據(jù)描述功能和存儲格式,并且有很高的可擴展性和共享性,所以XML技術得到了快速發(fā)展及普遍應用。XML已成為從中間層傳送數(shù)據(jù)到桌面的工具。由于XML的數(shù)據(jù)可以通過中間層代理與多種后端(數(shù)據(jù)庫)源集成,所以XML技術已得到很多軟件平臺和數(shù)據(jù)庫制造商的支持。Microsoft的.NET圍繞XML這一核心提供了一個強大而快速的開發(fā)工具——C#,它具有前所未有的高開發(fā)效率。特別是在XML與ADO.NET編程方面,通過XML類和ADO.NET之間的緊密集成,將關系數(shù)據(jù)和XML在.NET框架中結合在一起。
1 ADO.NET體系結構
ADO.NET是由一系列的數(shù)據(jù)庫相關類和接口組成的,它的基石是XML技術。通過ADO.NET不僅能訪問關系型數(shù)據(jù)庫中的數(shù)據(jù),而且還能訪問層次化的XML數(shù)據(jù)。
ADO.NET提供了二種數(shù)據(jù)訪問的模式,即連接模式(Connected)和非連接模式(Disconnected)。ADO技術中就有連接模式,而非連接模式是ADO.NET中才具有的。與傳統(tǒng)的數(shù)據(jù)庫訪問模式相比,非連接模式為應用程序提供了更大的可升級性和靈活性。在該模式下,一旦應用程序從數(shù)據(jù)源中獲得所需的數(shù)據(jù),它就斷開與原數(shù)據(jù)源的連接,并將獲得的數(shù)據(jù)以關系數(shù)據(jù)庫中表的形式存放在主存中。在應用程序處理完數(shù)據(jù)后,它再取得與原數(shù)據(jù)源的連接并完成數(shù)據(jù)的更新工作。
ADO.NET中的DataSet類是非連接模式的核心,它提供了一個與數(shù)據(jù)來源無關的數(shù)據(jù)表示方式,數(shù)據(jù)集對象(DataSet)可以將其中的數(shù)據(jù)以XML的形式存放。用戶既可以從遠程或本地的一個數(shù)據(jù)庫中獲取數(shù)據(jù)集對象,也可以從一個XML數(shù)據(jù)流中獲取數(shù)據(jù)集對象。而從用戶的角度來看,數(shù)據(jù)源在哪里并不重要,也無需關心。這種統(tǒng)一的編程模型可被運用于任何使用了數(shù)據(jù)集對象的應用程序。
在ADO.NET體系結構中還有一個非常重要的部分,即數(shù)據(jù)提供者對象(Data Provider),它是訪問數(shù)據(jù)庫的必備條件。通過它可以實現(xiàn)對實際數(shù)據(jù)庫的操作,操作的結果或者在連接模式被直接處理,或者產(chǎn)生相應的數(shù)據(jù)集對象。.NET Data Provider是一個數(shù)據(jù)源和應用程序間盡可能小的層,從而在不犧牲功能的前提下提高了性能。
圖1為ADO.NET總體的體系結構。

2 使用DataSet對象訪問XML數(shù)據(jù)
.NET提供了一個XmlDataDocument類,它擴展了XmlDocument類。XmlDocument類不僅可以將XML文檔載入內(nèi)存的文檔樹中,還可以通過XmlDataDocument對象的DataSet屬性存儲、獲取和操縱這些結構化的數(shù)據(jù)。DataSet對象在傳輸時是以XML流的形式,而不是用ADO中的Recordset對象的COM對象的形式,這使得在異構系統(tǒng)間傳遞數(shù)據(jù)更為方便。DataSet對象具有非常多的XML操作特性,通過它讀取XML數(shù)據(jù)文件或數(shù)據(jù)流,從而將樹型層次結構的XML數(shù)據(jù)轉換為關系型數(shù)據(jù)結構的形式。對于樹型層次結構的XML數(shù)據(jù),要使用DOM對象模型來描述和操縱;對關系表要使用表(DataTable)、列(DataColumn)、行(DataRow)等對象來描述和操縱。這樣,就可以使用.NET提供的DataSet對象和XmlDataDocument對象從二個不同的角度操縱內(nèi)存中的同一數(shù)據(jù)。
要對XML的數(shù)據(jù)集進行操作,首先要加載XML文件。XML文件有XSD Schema數(shù)據(jù)模式文件、XML無內(nèi)聯(lián)模式數(shù)據(jù)文件、XML內(nèi)聯(lián)模式數(shù)據(jù)文件等類型。讀取XSD Schema數(shù)據(jù)模式文件可以使用DataSet對象的ReadXmlSchema方法從XSD文件或流中導入數(shù)據(jù)。ReadXmlSchema方法有多個重載版本,可以接受Stream、String、Textreader和XmlReader對象。通過這些對象中的任意一個可以告訴ReadXmlSchema方法從哪個XSD Schema文件或流中獲取Schema。這種方法只能獲取XML數(shù)據(jù)的組織模式,而不能獲取XML數(shù)據(jù)。要讀取XML數(shù)據(jù)文件可以使用DataSet對象的ReadXml方法從XML文件或流中導入數(shù)據(jù)。在讀取的XML數(shù)據(jù)文件中,如果包含Schema數(shù)據(jù)組織方式,則這種方法可以在讀取XML數(shù)據(jù)的同時使用內(nèi)聯(lián)的XSD Schema獲取XML數(shù)據(jù)組織方式;如果在XML文件中不存在內(nèi)聯(lián)的Schema模式,則ReadXml方法會根據(jù)XML數(shù)據(jù)嘗試推斷的方法來生成Schema;如果在給定的XML數(shù)據(jù)中無法推斷出Schema,則會拋出異常。例如:

在導入XML XSD Schema文件或內(nèi)聯(lián)Schema的XML數(shù)據(jù)文件后,DataSet對象在數(shù)據(jù)集中建立相應的數(shù)據(jù)組織模式,通過DataSet對象的Tables屬性,可以獲取所有表的信息。對于每一個表,還具有一個Columns屬性,根據(jù)該屬性可以獲取表中所有列的信息;對于每一列,通過DataType屬性可以獲取該列的數(shù)據(jù)類型。因此,可以在這些表和列的集合中進行循環(huán),獲取數(shù)據(jù)模式或數(shù)據(jù)。代碼如下:

DataSet對象的視圖中可以包含XML文件中的所有數(shù)據(jù),也可以根據(jù)需要只映射其中的一部分數(shù)據(jù)。為此,可以先生成一個不包含數(shù)據(jù)的DataSet對象,并為該對象定義數(shù)據(jù)組織模式,然后將它與一個XmlDataDocument對象同步,使用XmlDataDocument對象向其中填充數(shù)據(jù)。這時,DataSet對象的表名和列名作為數(shù)據(jù)組織模式的一部分,與XML文檔中的部分標記相匹配,在XML文檔中選取匹配的元素映射到DataSet數(shù)據(jù)集中。這樣該數(shù)據(jù)集僅反映整個XML文檔層次模式中用戶所需要的部分,可以節(jié)約內(nèi)存資源。但需注意的是所添加的表名和列名必須和XML文檔中的元素嚴格匹配,否則會引發(fā)InvalidOperationException異常。例如:

3 從數(shù)據(jù)庫的表中輸出XML數(shù)據(jù)
SQL Server數(shù)據(jù)庫具有輸出XML數(shù)據(jù)的能力。SQL Server .NET Data Provider支持以XML形式表示的查詢結果。下面介紹其他數(shù)據(jù)庫表示為XML形式的方法。DataSet類作為ADO.NET中的非連接模式的核心,提供了一個與數(shù)據(jù)來源無關的數(shù)據(jù)表示方式。由于XML與DataSet類緊密集成,因此可以通過ADO.NET連接數(shù)據(jù)庫并將操作結果生成DataSet數(shù)據(jù)集。有了DataSet數(shù)據(jù)集就可以將其數(shù)據(jù)輸出為Xml Schema或XML文件的形式。輸出方法有二種,一種是使用DataSet對象的GetXmlSchema方法輸出Xml Schema,使用GetXml方法輸出XML數(shù)據(jù),GetXmlSchema、GetXml方法都返回一個字符串;另一種輸出方法是調(diào)用DataSet對象中的WriteXml方法和WriteXmlSchema方法,WriteXml方法輸出XML數(shù)據(jù),WriteXmlSchema方法輸出Xml Schema。這二個成員方法分別和ReadXml、ReadXmlSchema方法對應,也有多個重載版本,可以將數(shù)據(jù)和數(shù)據(jù)模式寫到流對象、磁盤文件等。例如:
OleDbConnection myConn=new OleDbConnection
(″Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=..\..\txl.mdb″);
OleDbDataAdapter myCommand=new OleDbDataAdapter
(″select *from b1″,myConn);
DataSet ds=new DataSet();
myCommand.Fill(ds,″b1″);
//下面通過調(diào)用DataSet對象中的WriteXml方法,可以將
//DataSet轉換為XML文檔,該方法中第一個參數(shù)為路徑文
//件名,第二個參數(shù)為XML文檔增加了一個內(nèi)聯(lián)XSD模式,
//描述DataSet的相關結構。
ds.WriteXml(″..\..\txl.xml″,XmlWriteMode.WriteSchema);
如果擁有包含數(shù)據(jù)的DataSet對象而希望以XML層次模型的方式訪問DataSet中的數(shù)據(jù),則可以將該DataSet對象作為參數(shù)傳遞給XmlDataDocument對象的構造函數(shù)。XmlDataDocument中的數(shù)據(jù)是對DataSet對象中數(shù)據(jù)的引用,而不是拷貝,這樣創(chuàng)建出來的XmlDataDocument對象將和DataSet對象同步。因此對這二個對象中任一對象數(shù)據(jù)的修改,將會實時地反映到另一對象中。創(chuàng)建過程如下:
OleDbConnection myConn=new OleDbConnection
(″Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=..\..\txl.mdb″);
OleDbDataAdapter myCommand=new OleDbDataAdapter
(″select *from b1″,myConn);
DataSet ds=new DataSet();
myCommand.Fill(ds,″b1″);
XmlDataDocument doc=new XmlDataDocument(ds);
4 結束語
XML和關系型數(shù)據(jù)表是二種有效的數(shù)據(jù)視圖。.NET Framework提供了XmlDocument用來實現(xiàn)DOM編程接口,從而使用戶可以從XML層次視圖的角度處理數(shù)據(jù)。.NET Framework還提供了DataSet來表示關系數(shù)據(jù)模型,從而允許從二維表格、行、列和關系的角度來處理數(shù)據(jù)。在不同的應用場合下,要使用不同的數(shù)據(jù)視圖來處理數(shù)據(jù)。XmlDataDocument對象集成了數(shù)據(jù)集對象DataSet和XML文檔對象XmlDocument,利用它可以處理關系數(shù)據(jù)或XML數(shù)據(jù),并自動維持關系數(shù)據(jù)視圖和DOM視圖,使其同步。
參考文獻
1 Maiani B,Still J著,康博譯.Visual C#.NET編程經(jīng)典.北京:清華大學出版社,2002
2 鄭小平.Visual C#.NET開發(fā)實踐.北京:人民郵電出版社,2001
3 飛思科技產(chǎn)品研發(fā)中心.C#編程指南.北京:電子工業(yè)出版社,2002
