Thao tác trên XML part 8

Chia sẻ: Dqdsadasd Qwdasdsad | Ngày: | Loại File: PDF | Số trang:16

1
80
lượt xem
26
download

Thao tác trên XML part 8

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

XML và ADO.NET XML là lớp kết nối giữa ADO.NET với phần còn lại của thế giới. ADO.NET được thiết kế từ sự có phát triển của việc sử dụng môi trường XML. XML được sử dụng để truyền dữ liệu trừ nơi lưu trữ vào ứng dụng hoặc trang web.

Chủ đề:
Lưu

Nội dung Text: Thao tác trên XML part 8

  1. XML và ADO.NET XML là lớp kết nối giữa ADO.NET với phần còn lại của thế giới. ADO.NET được thiết kế từ sự có phát triển của việc sử dụng môi trường XML. XML được sử dụng để truyền dữ liệu trừ nơi lưu trữ vào ứng dụng hoặc trang web. Từ khi ADO.NET sử dụng XML như là môi trường truyền tải, dữ liệu có thể trao đổi giữa ứng dụng và hệ thống nó không chỉ xảy ra trong ADO.NET. Bởi sự quan trọng của XML trong ADO.NET, có một vài đặc tính mạnh mẽ trong ADO.NET cho phép đọc và ghi các tài liệu XML. Không gian tên System.Xml cũng chứa các lớp có thể hủy và sử dụng dữ liệu quan hệ ADO.NET. Chuyển dữ liệu ADO.NET thành XML Trong ví dụ đầu tiên chúng ta sẽ xem xét cách dùng ADO.NET, streams, và XML để "pull" một vài dữ liệu từ cơ sở dữ liệu Northwind vào một DataSet, load một đối tượng XmlDocument với XML từ DataSet, và load XML vào môt listbox. Để chạy ứng dụng chúng ta cần chèn các câu lệnh using sau: using System.Data; using System.Xml; using System.Data.SqlClient; using System.IO; Nếu sử dụng XmlDocument, chúng ta cũng cần phải thêm dòng sau: private XmlDocument doc = new XmlDocument(); Các ví dụ ADO.NET thường có thêm một DataGrid trong forms. Nó cho phép chúng ta thấy dữ liệu trong ADO.NET DataSet. Đây là mã cho ví dụ đầu tiên, mã có thể được tìm thấy trong thư mục ADOSample1: private void button1_Click(object sender, System.EventArgs e) { //create a dataset DataSet ds = new DataSet("XMLProducts"); //connect to the northwind database and //select all of the rows from products table //make sure your login matches your version of SqlServer SqlConnection conn = new SqlConnection (@"server=GLYNNJ_CS\NetSDK;uid=sa;pwd=;database=northwind"); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Products",conn);
  2. Sau khi chúng ta tạo SqlDataAdapter, da, và DataSet, ds, chúng ta tạo một đối tượng MemoryStream, một đối tượng StreamReader, và một đối tượng StreamWriter. Các đối tượng StreamReader và StreamWriter se sử dụng MemoryStream đê di chuyển trong XML: MemoryStream memStrm=new MemoryStream(); StreamReader strmRead=new StreamReader(memStrm); StreamWriter strmWrite=new StreamWriter(memStrm); Chúng ta sẽ dùng một MemoryStream vì vậy không thể ghi bất kì cái ghi lên đĩa, tất nhiên, chúng ta có thể sử dụng bất kì đối tượng này xuất phát từ lớp Stream như FileStream. Tiếp theo, chúng ta điền DataSet và kết nối nó với DataGrid. Dữ liệu trong DataSet bây giờ được hiển thị trong DataGrid: da.Fill(ds,"products"); //load data into DataGrid dataGrid1.DataSource=ds; dataGrid1.DataMember="products"; Bước tiếp theo là phát ra XML. Chúng ta gọi phương thức WriteXml() từ lớp DataSet. Phương thức này phát ra một tài liệu XML. Có hai quá tải của phương thức WriteXml(): một cần một chuỗi chứa tên và đường dẫn của file, một cái khác cần mọt tham số mode. Mode này là một kiểu liệt kê XmlWriteMode, có các giá trị sau: • IgnoreSchema • WriteSchema • DiffGram IgnoreSchema được dùng nếu bạn không muốn WriteXml() ghi một inline schema vào đầu file XML; dùng tham số WriteSchema nếu bạn muốn như vậy. Chúng ta sẽ xem xét DiffGrams ở phần sau. ds.WriteXml(strmWrite,XmlWriteMode.IgnoreSchema); memStrm.Seek(0,SeekOrigin.Begin); //read from the memory stream to an XmlDocument object doc.Load(strmRead); //get all of the products elements XmlNodeList nodeLst=doc.GetElementsByTagName("ProductName"); //load them into the list box foreach(XmlNode nd in nodeLst) listBox1.Items.Add(nd.InnerText); } private void listBox1_SelectedIndexChanged(object sender,
  3. System.EventArgs e) { //when you click on the listbox, //a message box appears with the unit price string srch="XMLProducts/products[ProductName=" + '"'+ listBox1.SelectedItem.ToString() + '"' + "]"; XmlNode foundNode=doc.SelectSingleNode(srch); if(foundNode!=null) MessageBox.Show(foundNode.SelectSingleNode("UnitPrice").InnerText); else MessageBox.Show("Not found"); } Đây là màn hình, bạn có thể nhìn thấy kết quả trong danh sách cũng như trong DataGrid: Nếu bạn chỉ muốn schema, bạn có thể gọi WriteXmlSchema() thay vì WriteXml(). Phương thức này có bốn quá. Một cần một chuỗi, với đường dẫn và tên của file XML. Quá tải thứ hai sử dụng một đối tượng xuất phát từ lớp XmlWriter. Quá tải thứ ba sử dụng mọt đối tượng xuất phát từ lớp TextWriter. Quá tải thứ tư được sử dụng trong ví dụ. Ngoài ra, nếu bạn muốn có phép ghi tài liệu XML lên đĩa, bạn có thể làm như sau: string file = "c:\\test\\product.xml"; ds.WriteXml(file); Nó cho phép ghi tài liệu XML lên đĩa để có thể đọc bởi các luồng khách, hoặc bởi DataSet, hoặc sử dụng một ứng dụng khác, một trang web khác. Khi tham sô XmlMode
  4. không được chỉ định, XmlDocument phải chứa một schema. Trong ví dụ của chúng ta dùng stream như là một tham số cho phương thức XmlDocument.Load(). Khi XmlDocument được chuẩn bị, chúng ta load listbox bằng câu lệnh XPath như chúng ta đã làm. Nếu xem xét kĩ, bạn sẽ thấy rằng chúng ta có thay đổi nhỏ trong sự kiện listBox1_SelectedIndexChanged(). Thay vì chr ra thành phần InnerText, chúngt ta thực một tìm kiếm XPath khác sử dụng SelectSingleNode() để lấy thành phần UnitPrice element. Giờ đây mỗi khi bạn click lên một sản phẩm trong listbox, một MessageBox xuất hiện với UnitPrice. Chúng ta có hai thể hiện của dữ liệu, nhưng quan trọng hơn, chúng ts có thể thao tác trên dữ liệu theo hai kiểu khác nhau. Chúng ta có thể dùng không gian tên System.Data để sử dụng dữ liệu hoặc cũng có thể dùng không gian tên System.Xml. Nó có thể dẫn đến một vài thiết kế mềm dẻo cho các ứng dụng của bạn. Sử dụng kết hợp ADO.NET và System.Xml là cách khôn ngoan nhất. Bạn có nhiều thể hiện của cùng một dữ liệu, và cũng có nhiều cách để truy cập dữ liệu. Trong ví dụ tiếp theo chúng ta sẽ đơn giản hóa quá trình sử lí bằng cách loại trừ ba streams và một vài khả năng của ADO được xây dựng trong không gian tên System.Xml. Chúng ta sẽ cần thay đổi mã: private XmlDocument doc = new XmlDocument(); thành: private XmlDataDocument doc; Chúng ta cân nó bởi vì giờ đây chúng ta sẽ dùng XmlDataDocument. Đây là mã, có thể tìm thấy trong thư mục ADOSample2: private void button1_Click(object sender, System.EventArgs e) { //create a dataset DataSet ds=new DataSet("XMLProducts"); //connect to the northwind database and //select all of the rows from products table //make changes to connect string to match your login and server name SqlConnection conn=new SqlConnection (@"server=GLYNNJ_CS\NetSDK;uid=sa;pwd=;database=northwind"); SqlDataAdapter da=new SqlDataAdapter("SELECT * FROM products",conn); //fill the dataset da.Fill(ds,"products"); //load data into grid dataGrid1.DataSource=ds; dataGrid1.DataMember="products";
  5. doc=new XmlDataDocument(ds); //get all of the products elements XmlNodeList nodeLst=doc.GetElementsByTagName("ProductName"); //load them into the list box //we'll use a for loop this time for(int ctr=0;ctr
  6. 1 Chai 1 1 10 boxes x 20 bags 18 39 0 10 false
  7. Chỉ thành phần đầu tiên được thể hiện. File XML thật sự chứa tất cả các thanh phần trong bảng Products của cơ sở dữ liệu Northwind. Chuyển sang cơ sở dữ liệu quan hệ Các ví dụ trên chỉ thực hiện cho một bảng, nhưng với cơ sở dữ liệu quan hệ thì sao chẳng hạn như multiple DataTables và Relations trong DataSet? Chúng vẫn hoạt động bình thường. Hãy thực hiện các thay đổi sau trong mã nguồn mã chúng ta đã dùng (mã nguồn có thể tìm thấy trong ADOSample3): private void button1_Click(object sender, System.EventArgs e) { //create a dataset DataSet ds=new DataSet("XMLProducts"); //connect to the northwind database and //select all of the rows from products table and from suppliers table //make sure your connect string matches your server configuration SqlConnection conn=new SqlConnection (@"server=GLYNNJ_CS\NetSDK;uid=sa;pwd=;database=northwind"); SqlDataAdapter daProd=new SqlDataAdapter("SELECT * FROM products",conn); SqlDataAdapter daSup=new SqlDataAdapter("SELECT * FROM suppliers",conn); //Fill DataSet from both SqlAdapters daProd.Fill(ds,"products"); daSup.Fill(ds,"suppliers"); //Add the relation ds.Relations.Add(ds.Tables["suppliers"].Columns["SupplierId"], ds.Tables["products"].Columns["SupplierId"]); //Write the XML to a file so we can look at it later ds.WriteXml("..\\..\\..\\SuppProd.xml",XmlWriteMode.WriteSchema); //load data into grid dataGrid1.DataSource=ds; dataGrid1.DataMember="suppliers"; //create the XmlDataDocument doc=new XmlDataDocument(ds); //Select the productname elements and load them in the grid XmlNodeList nodeLst=doc.SelectNodes("//ProductName"); foreach(XmlNode nd in nodeLst) listBox1.Items.Add(nd.InnerXml); }
  8. Trong ví dụ này chúng ta tạo hai DataTables trong DataSet XMLProducts: Products và Suppliers. Quan hệ là Suppliers cung cấp Products. Chúng ta tạo mọt quan hệ trên cột SupplierId ở cả hai bảng. Bảng DataSet trông như sau: Bằng cách tạo phương thức WriteXml() giống như ta đã làm ở ví dụ trước, chúng ta sẽ nhận được file XML như sau (SuppProd.xml):
  9. 1 Chai 1 1 10 boxes x 20 bags 18 39 0 10 false 1 Exotic Liquids Charlotte Cooper Purchasing Manager 49 Gilbert St. London EC1 4SD UK (171) 555-2222 Sơ đồ bao gồm cả hai DataTables trong DataSet. Hơn nữa, dữ liệu bao gồm tất cả dữ liệu trong cả hai bảng. Vì lí do ngắn gọn , chúng ta chỉ chỉ ra nhà cung cấp và các sản phẩm đầu tiên. Giống như trước bạn có thể chỉ lưu schema hoặc dữ liệu thông qua tham số XmlWriteMode. Chuyển đổi XML thành dữ liệu ADO.NET Nếu bạn có một tài liệu XML và muốn chuyển nó thành một ADO.NET DataSet. Để làm điều này bạn load XML vào một, hoặc có thể kết nối dữ liệu với một điều khiển dữ liệu .NET như DataGrid. Cách này bạn có thể thật sự sử dụng tài liệu XML như một kho lưu
  10. trữ dữ liệu, và có thể loại trừ khả năng truy xuất ra ngoài cơ sở dữ liệu. Nếu dữ liệu của bạn vừa phải, thì có thể áp dụng cách này. Mã nằm trong ADOSample4: private void button1_Click(object sender, System.EventArgs e) { //create a new DataSet DataSet ds=new DataSet("XMLProducts"); //read in the XML document to the Dataset ds.ReadXml("..\\..\\..\\prod.xml"); //load data into grid dataGrid1.DataSource=ds; dataGrid1.DataMember="products"; //create the new XmlDataDocument doc=new XmlDataDocument(ds); //load the product names into the listbox XmlNodeList nodeLst=doc.SelectNodes("//ProductName"); foreach(XmlNode nd in nodeLst) listBox1.Items.Add(nd.InnerXml); } Chúng ta khởi tạo một đối tượng DataSet. Sau đó gọi phương thức ReadXml(), và giờ đây bạn có XML trong một DataTable trong DataSet của bạn. Các phương thức WriteXml(), ReadXml() có một tham số XmlReadMode. ReadXml() có một cặp tùy chọn trong XmlReadMode. Bảng sau đây mô tả chúng: Giá trị Giải thích Auto Gán vào XmlReadMode giá trị thích hợp nhất. Nếu dữ liệu được định dạng là DiffGram, DiffGram được chọn. Nếu schema sẵn sàng để đọc, hoặc một schema nội được tìm ra, thì ReadSchema được chọn. Nếu không có schema nào được gán trong DataSet, và không một nội tuyến nào được tìm ra, thì IgnoreSchema được chọn. DiffGram Đọc trong DiffGram và áp dụng các thay đổi cho DataSet. DiffGrams được mô tả trong phần sau. Fragment Đọc tài liệu chứa sơ đồ XDR phân mảnh, như kiểu được tạo bởi SQL Server. IgnoreSchema Bỏ qua các schema nội. Đọc dữ liệu trong sơ đồ DataSet hiện tại.
  11. Giá trị Giải thích Nếu dữ liệu không tìm thấy trong DataSet schema nó được bỏ qua. InferSchema Bỏ qua schema nội. Tạo schema dựa trên tài liệu XML. Nếu một schema có sẵn trong DataSet, schema này được sử dụng, và được mở rộng và thêm vào các cột và các bảng nếu cần. Có thể xảy ra một ngoại lện nếu một cột tồn tại sẵn, nhưng khác kiểu dữ liệu. ReadSchema Đọc schema nội và load dữ liệu. Sẽ không ghi đè một schema trong DataSet, Nhưng sẽ tạo ra một ngoại lện nếu bảng trong schema nội đã có sẵn trong DataSet. Phương thức ReadXmlSchema() sẽ đọc trong một schema độc lập và tạo các bảng, cột và các quan hệ. Bạn sẽ dụng nó nếu schema của bạn không nội tuyến với dữ liệu. ReadXmlSchema() có bốn quá tải: chuỗi với tên và đường dẫn của file, đối tượng xuất phát Stream, đối tượng xuất phát từ TextReader và một đối tượng xuất phát từ XmlReader. private void button1_Click(object sender, System.EventArgs e) { //create the DataSet DataSet ds=new DataSet("XMLProducts"); //read in the XML document ds.ReadXml("..\\..\\..\\SuppProd.xml"); //load data into grid dataGrid1.DataSource=ds; dataGrid1.DataMember="products"; //load the listbox with table, column and datatype info foreach(DataTable dt in ds.Tables) { listBox1.Items.Add(dt.TableName); foreach(DataColumn col in dt.Columns) { listBox1.Items.Add( '\t' + col.ColumnName + " - " + col.DataType.FullName); } } } Chú ý rằng ở đây dùng hai vòng lặp foreach. Vòng lặp thứ nhất dùng để lấy tên của mỗi bảng trong tập hợp the Tables của DataSet. Vòng lặp foreach thứ hai dùng để lấy dữ liệu cho mỗi cột trong DataTable. Chúng ta load dữ liệu này vào listbox, để cho phép hiển thị chúng. Đây là màn hình sau khi chạy:
  12. Bạn nên nhớ rằng cả hai ví dụ trên đều không truyên bất kì giữ liệu nào từ hoặc đến một cơ sở dữ liệu, không có một SqlDataAdapter hoặc SqlConnection nào được định nghĩa. Nó chỉ ra tính mềm dẻo của hai không gian tên System.Xml và ADO.NET: bạn có thể xem xet dữ liệu trong nhiều định dạng. Nếu bạn muốn truyền dữ liệu theo định dạng HTML, hoặc nếu muốn kết nối với một grid, bạn cần có dữ liệu tương tự, và gọi phương thức thích hợp. Đọc và ghi một DiffGram Một DiffGram là một tài liệu XML chứa dữ liệu trước và sau một đợt soạn thảo. Nó có thể bao gồm các thay đổi dữ liệu, thêm và xoá. Một DiffGram có thể được sử dụng như một sổ theo dõi để cho phép và phục hồi xử lí. DBMS được nhiều người sử dụng, nhưng DBMS không có các đặc tính này, nếu bạn sử dụng DBMS thì bạn phải tự thực hiện các thao tác này. Mã dưới đây chỉ ra cách một DiffGram được tạo và một DataSet có thể được tạo từ một DiffGram (mã có thể được tìm thấy trong thư mục ADOSample6). Phần bắt đầu của mã trong rất quen thuộc. Chúng ta định nghĩa một DataSet mới, ds, một SqlConnection mới, conn, và một SqlDataAdapter mới, da. Chúng ta kết nối cơ sở dữ liệu, chọn tất cả các dòng từ bảng Products, tạo một DataTable mới đặt tên là products, và load dữ liệu từ cơ sở dữ liệu vào DataSet: private void button1_Click(object sender, System.EventArgs e) { //new DataSet DataSet ds=new DataSet("XMLProducts"); //Make connection and load products rows SqlConnection conn=new SqlConnection
  13. (@"server=GLYNNJ_CS\NetSDK;uid=sa;pwd=;database=northwind"); SqlDataAdapter da=new SqlDataAdapter("SELECT * FROM products",conn); //fill the DataSet da.Fill(ds,"products"); //edit first row ds.Tables["products"].Rows[0]["ProductName"]="NewProdName"; Trong không mã tiếp theo chúng ta làm hai việc. Trước tiên, chúng ta sửa đổi cột ProductName trong dòng đầu tiên của NewProdName. Thứ hai, chúng ta tạo một dòng mới trong DataTable, đặt giá trị cho các cột, và cuối cùng là thêm các dòng dữ liệu cho DataTable. //add new row DataRow dr=ds.Tables["products"].NewRow();; dr["ProductId"]=100; dr["CategoryId"]=2; dr["Discontinued"]=false; dr["ProductName"]="This is the new product"; dr["QuantityPerUnit"]=12; dr["ReorderLevel"]=1; dr["SupplierId"]=12; dr["UnitPrice"]=23; dr["UnitsInStock"]=5; dr["UnitsOnOrder"]=0; ds.Tables["products"].Rows.Add(dr); Khối tiếp theo là phần thú vị nhất. Trước tiên, chúng ta ghi lại schema với phương thức WriteXmlSchema(). Nó quan trọng bởi vì bạn không thể đọc lại một DiffGram mà không có schema. WriteXml() với tham số XmlWriteMode.DiffGram tạo ra DiffGram. Dòng tiếp theo cho phép các thay đổi được cập nhật. Quan trọng là DiffGram phải được tạo trước khi gọi AcceptChanges(), mặt khác sẽ không có thay đổi trên dữ liệu. //Write the Schema ds.WriteXmlSchema("..\\..\\..\\diffgram.xsd"); //generate the DiffGram ds.WriteXml("..\\..\\..\\diffgram.xml",XmlWriteMode.DiffGram); ds.AcceptChanges(); //load data into grid dataGrid1.DataSource=ds; dataGrid1.DataMember="products"; //new XmlDataDocument
  14. doc=new XmlDataDocument(ds); //load the productnames in the list XmlNodeList nodeLst=doc.SelectNodes("//ProductName"); foreach(XmlNode nd in nodeLst) listBox1.Items.Add(nd.InnerXml); } Thứ tự để lấy dữ liệu vào một DataSet như sau: DataSet dsNew=new DataSet(); dsNew.ReadXmlSchema("..\\..\\..\\diffgram.xsd"); dsNew.XmlRead("..\\..\\..\\diffgram.xml",XmlReadMode.DiffGram); Ở đây chúng ta tạo một DataSet, dsNew. Gọi phương thức ReadXmlSchema() tạo một DataTable dựa trên thông tin schema. Trong trường hợp này nó có thể là bảng dữ liệu products. Giờ đây chúng ta có thể đọc trong DiffGram. DiffGram không chứa thông tin schema, DataTable cân được tạo trước khi gọi phương thức ReadXml(). Đây là ví dụ về DiffGram (diffgram.xml): 1 NewProdName 1 1 10 boxes x 20 bags 18 39 0 10 false ... 100 This is the new product 12
  15. 2 12 23 5 0 1 false 1 Chai 1 1 10 boxes x 20 bags 18 39 0 10 false Sau khi DiffGram được đọc vào DataTable, nó ở trạng thái tạo dữ liệu nhưng trước khi AcceptChanges() được gọi. Tại thời điểm này bạn có thể phục hồi dữ liệu bằng cách gọi phương thức RejectChanges(). Xem xét thuộc tínhh DataRow.Item và truyền cho DataRowVersion.Original và DataRowVersion.Current, bạn có thể thấy giá trị trước và sau trong DataTable. Nếu bạn giữ một một chuỗi DiffGrams thì chúng cho phép bạn phục hồi theo thứ tự. Chắc rằng bạn muốn phục hồi thay đổi nhiều cấp, bạn có thể dùng DiffGrams.

CÓ THỂ BẠN MUỐN DOWNLOAD

Đồng bộ tài khoản