Sử dụng DOM trong .NET Document Object Model (DOM) thực thi trong .NET hỗ trợ các kĩ thuật W3C DOM Level 1 và Core DOM Level 2. DOM được thực thi thông qua lớp XmlNode, một lớp ảo mô tả một nút của tài liệu. Ngoài ra còn có một lớp XmlNodeList là một danh sách có thứ tự các nút. Đây là một danh sách sống, và bất kì thay đổi nào cũng sẽ cập nhật ngay vào danh sách. XmlNodeList hỗ trợ truy cập chỉ mục và truy cập lặp. Còn có một lớp ảo khác, XmlCharacterData, nó là lớp mở rộng của XmlLinkedNode, và cung cấp các ph ương thức sử dụng văn bản cho các lớp khác. Các lớp XmlNode và XmlNodeList trang điểm cho thực thi DOM trong .NET Framework. Đây là một danh sách các lớp cơ sở trong XmlNode: Class Name Description XmlLinkedNode Trả về nút trước và sau nút hiện tại. Thêm các thuộc tính NextSibling và PreviousSibling vào XmlNode. XmlDocument Miêu tả toàn bộ tài liệu. Thực thi các đặc điểm kĩ thuật DOM Level 1 và Level 2. XmlDocumentFragment Miêu tả mô hình cây thư mục của tài liệu. XmlAttribute Một đối tượng thuộc tính của một đối tượng XmlElement. XmlEntity Phân tách và tổ hợp các nút. XmlNotation Chứa cách chú thích trong môt DTD hoặc sơ đồ. Các lớp sau mở rộng XmlCharacterData: Class Name Description XmlCDataSection Một đối tượng mô tả một đoạn CData section của một tài liệu. XmlComment Mô tả một đối tượng ghi chú XML. XmlSignificantWhitespace Mô tả một nút với khoảng trắng. Các nút chỉ được tạo khi cờ PreserveWhiteSpace là true. XmlWhitespace Miêu tả whitespace trong một thành phần ghi chú. Các nút được tạo chỉ khi cờ PreserveWhiteSpace là true. XmlText Ghi chú dạng văn bản cảu một thành phần hoặc thuộc tính. Cuối cùng, tập các lớp tiếp theo mở rộng lớp XmlLinkedNode: Class Name Description XmlDeclaration Miêu tả nút khai báo (<?xml version='1.0' .>) XmlDocumentType Quan hệ dữ liệu với khai báo kiểu tàiliệu XmlElement Một đối tượng thành phần XML XmlEntityReferenceNode Mô tả một nút tham chiếu tồn tại XmlProcessingInstruction Chứa một cấu trúc xử lí XML Như bạn thấy, .NET tạo sẽ một lớp phù hợp với bất kì kiểu XML nào mà bạn bắt gặp. Bởi vậy, bạn sẵn có một bộ các công cụ mạnh mẽ và mềm dẻo. Chúng ta sẽ không đi vào chi tiết các lớp, nhưng chúng ta sẽ dùng một số ví dụ. Sau đây là sơ đồ các lớp: Sử dụng lớp XmlDocument XmlDocument và lớp xuất phát XmlDataDocument (chúng ta sẽ xem xét sau trong chương) là các lớp bạ n sẽ dùng để miêu tả DOM trong .NET. Không giống như XmlReader và XmlWriter, XmlDocument cho cung cấp cho bạn khả năng đọc và viết như truy xuất ngẫu nhiên cây DOM . XmlDocument tương tự như thực thi DOM trong MSXML. Nếu bạn đã từng lập trình với MSXML bạn sẽ cảm thấy tiện lợi khi dùng XmlDocument. Lấy một ví dụ về tạo một đối tượng XmlDocument, load một tàiliệu từ đĩa, và load các tiêu đề vào một listbox. Nó giống như mọt ví dự mà chúng ta đã tạo trong phần XmlReader. Cái khác ở đây là chúng ta sẽ chọn các nút mà chúng ta sẽ làm việc thay vì duyệt qua các nút trong tàiliệu như đã từng làm. Đây là mã. Hãy xem cách làm việc của nó và so sánh với ví dụ XmlReader (file có thể tìm thấy trong thư mục DOMSample1 ): private void button1_Click(object sender, System.EventArgs e) { // doc is declared at the module level // change path to match your path structure doc.Load(" \\ \\ \\books.xml"); // get only the nodes that we want XmlNodeList nodeLst=doc.GetElementsByTagName("title"); // iterate through the XmlNodeList foreach(XmlNode node in nodeLst) listBox1.Items.Add(node.InnerText); } Chú ý rằng chúng ta cũng có thể thêm khai báo sau vào mô module này: private XmlDocument doc=new XmlDocument(); Nếu chúng ta chỉ muốn làm như vậy thì dùng XmlReader sẽ tốt hơn vì chỉ cần duyệt qua tàiliệu một lần duy nhất để load dữ liệu cho the listbox. XmlReader được thiết kế cho mục đích này. Nếu bạn muốn tham chiếu lại một nút, thì dùng XmlDocument là cách tốt nhất. Mở rộng ví dụ trên bằng cách thêm một quản lí sự kiện khác (đây là DOMSample2 ): private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { //create XPath search string string srch="bookstore/book[title='" + listBox1.SelectedItem.ToString() + "']"; //look for the extra data XmlNode foundNode = doc.SelectSingleNode(srch); if(foundNode != null) MessageBox.Show(foundNode.InnerText); else MessageBox.Show("Not found"); } Trong ví dụ này, chúng ta load các tựa trong tàiliệu books.xml vào listbox, giống như trong ví dụ trên. Khi chúng ta click vào listbox, khi đó sự kiện SelectedIndexChanged() được phát ra. Trong trường hợp này, chúng ta tạo mọt văn bản của đối tượng được tạo trong listbox (tựa của sách) tạo một XPath statement và truyền nó cho phương phương thức SelectSingleNode() của đối tượng doc. Nó trả về sách có tựa được tìm thấy. Sau đó chúng ta biểu diễn InnerText của nút trong một message box. Chúng ta có thể giữ clicking trên mục chọn trong listbox, tài liệ u đã được load lên sẽ không thay đổi cho đến khi chúng ta thả tay ra. Một ghi chú nhanh có liên quan đến phương thức SelectSingleNode(). Đó là thực thi XPath trong lớp XmlDocument. Có hai phương thức SelectSingleNode() và SelectNodes(). Cả hai phương thức này đều được định nghĩa trong XmlNode, là lớp xuất phát của XmlDocument. SelectSingleNode() trả về một XmlNode và SelectNodes() trả về một XmlNodeList. Tất nhiên, không gian System.Xml.XPath chứa một thực thi XPath mạnh, và sẽ xem xét trong chương sau. Inserting Nodes Như chúng ta đã biết trong một ví dụ sử dụng XmlTextWriter trướ c đây tạo một tàiliệu mới. Giới hạn là nó không thể chèn một mục mới vào tàiliệu hiện tại. Với lớp XmlDocument chúng ta có thể làm điều đó. Thay đổi trình quản lí sự kiện button1_Click() trong ví dụ trên như sau (DOMSample3 trong mã download): private void button1_Click(object sender, System.EventArgs e) { //change path to match your structure doc.Load(" \\ \\ \\books.xml"); //create a new 'book' element XmlElement newBook=doc.CreateElement("book"); //set some attributes newBook.SetAttribute("genre","Mystery"); newBook.SetAttribute("publicationdate","2001"); newBook.SetAttribute("ISBN","123456789"); //create a new 'title' element XmlElement newTitle=doc.CreateElement("title"); newTitle.InnerText="The Case of the Missing Cookie"; newBook.AppendChild(newTitle); //create new author element XmlElement newAuthor=doc.CreateElement("author"); newBook.AppendChild(newAuthor); //create new name element XmlElement newName=doc.CreateElement("name"); newName.InnerText="C. Monster"; newAuthor.AppendChild(newName); //create new price element XmlElement newPrice=doc.CreateElement("price"); newPrice.InnerText="9.95"; newBook.AppendChild(newPrice); //add to the current document doc.DocumentElement.AppendChild(newBook); //write out the doc to disk XmlTextWriter tr=new XmlTextWriter(" \\ \\ \\booksEdit.xml",null); tr.Formatting=Formatting.Indented; doc.WriteContentTo(tr); tr.Close(); //load listBox1 with all of the titles, including new one XmlNodeList nodeLst=doc.GetElementsByTagName("title"); foreach(XmlNode node in nodeLst) listBox1.Items.Add(node.InnerText); } Sau khi thực thi mã này, bạn sẽ có như khả năng như ví dụ trên, nhưng ở đây đã thêm một sách mới vào listbox, The Case of the Missing Cookie. Clicking trên tựa bạn sẽ chỉ ra tất cả các thông tin của các tựa khác. Đầu tiên chúng ta tạo một thành phần sách mới: XmlElement newBook = doc.CreateElement("book"); Phương thức CreateElement() có ba quá tải cho phép bạn lựa chọn: • element name • name và không gian tên URI • prefix, localname, and namespace Khi một thành phần được tạo ra chúng ta cần phải thêm các thuộc tính sau: newBook.SetAttribute("genre","Mystery"); newBook.SetAttribute("publicationdate","2001"); newBook.SetAttribute("ISBN","123456789"); Bây giờ chúng ta có các thuộc tính được tạo chúng ta cần thêm các thuộc tính khác của một cuốn sách: XmlElement newTitle = doc.CreateElement("title"); newTitle.InnerText = "The Case of the Missing Cookie"; newBook.AppendChild(newTitle); Trước tiên chúng ta tạo một đối tượng mới xuất phát từ XmlElement. Sau đó chúng ta gán thuộc tính InnerText của tựa sách như đã làm, và thêm vào như một thành phần con của book. Chúng ta lặp lại cho đên khi hết các thành phần. Chú ý răng chúng ta thêm thành phần name như một thành phần con của author. Nó cho chúng ta mối quan hệ thích hợp với các thành phần book khác. Cuối cùng, chúng ta gán thành phần newBook vào mục doc.DocumentElement. Nó cùng cấp với tất cả các thành phần book khác. Bây giờ chúng ta cập nh ật một tàiliệu có sẵn với một thành phần mới. Thao tác cuối cùng là ghi tàiliệu mới lên đĩa. Trong ví dụ này chúng ta tạo một XmlTextWriter mới, và truyền nó cho phương thức WriteContentTo(). WriteContentTo() và WriteTo() cả hai đều tạo ra mọt XmlTextWriter như là một tham số. WriteContentTo() lưu nút hiện tại và tất cảc các nút con của nó vào XmlTextWriter, ngược lại WriteTo() chỉ lưu nút hiện tại. Bởi vì doc là một đối tượng xuất phát từ XmlDocument, nó mô tả toàn bộ tàiliệu và nh ưng gì nó đã lưu. Chúng ta cũng sử dụng phương thức Save(). Nó sẽ luôn lưu toàn bộ tài liệu. Save() có bốn quá tải. Bạn có thể chỉ ra một chuỗi với tên file và đường dẫn, một đối tượng xuất phát từ Stream, một đối tượng xuất phát từ TextWriter, một đối tượng xuất phát từ XmlWriter. Chúng ta cũng gọi phương thức Close() trên XmlTextWriter để đẩy vào vùng nhớ đệm nội và đóng file. Đây là nh ững gì chúng ta sẽ cho khi chạy ví dụ này. Chú ý rằng mục đầu tiên nằm ở đáy của danh sách: Nếu muốn tạo một tàiliệu từ chúng, chúng ta có thể dùng XmlTextWriter như đã thấy trong phần trên. Chúng ta cũng có thể dùng XmlDocument. Tại sao dùng một trong số chúng? Nếu bạn muốn chuyển dữ liệu thành XML là sẵn có và sẵn sàng để ghi, trong trường hợp này lớp XmlTextWriter là lựa chọn tốt nhất. Và khi bạn cần tạo tàiliệuXML từng chút một, và chèn các nút vào những vị trí khác nhau, sau đó tạo tàiliệu khi đó lớp XmlDocument có thể là lựa chọ n tốt nhất. Chúng ta có thể hoàn tất nó bằng thay đổi dòng sau: doc.Load(" \\ \\ \\books.xml"); thành (mã này nằm trong ví dụ DOMSample4 ): //create the declaration section XmlDeclaration newDec = doc.CreateXmlDeclaration("1.0",null,null); doc.AppendChild(newDec); //create the new root element XmlElement newRoot = doc.CreateElement("newBookstore"); doc.AppendChild(newRoot); Trước tiên, chúng ta tạo một XmlDeclaration mới. Các tham số là phiên bản (hiện tại là 1.0), mã hóa, và cờ standalone. Tham số mã hoá có thể được gán bởi một chuỗi là thành phần của lớp System.Text.Encoding nếu null không được dùng . null mặc định là UTF-8. Cờ standalone có thể là yes, no, hoặc null. Nếu nó là null thì thuộc tính không được dùng và sẽ không được mô tả trong tài liệu. Bước kế tiếp tạo ra DocumentElement. Trong trường hợp này chúng ta gọi newBookstore vì vậy bạn có thể nhận thấy khác biệt. Mục đ ích của mã giống như ví dụ trước, và hoạt động theo cùng một cách. Đây là booksEdit.xml được tạo ra từ mã: <?xml version="1.0"?> <newBookstore> <book genre="Mystery" publicationdate="2001" ISBN="123456789"> <title>The Case of the Missing Cookie</title> <author> <name>C. Monster</name> </author> <price>9.95</price> </book> </newBookstore> Chúng ta sẽ không xem xét kĩ lớp XmlDocument, cũng như các lớp khác giúp tạo mô hình DOM trong .NET. Tuy nhiên, chúng ta đã xem xét khả năng và tính mềm dẻo mà thực thi DOM trong .NET hỗ trợ. Bạn sẽ muốn sử dụng lớp XmlDocument khi bạn muốn truy xuất ngẫu nhiên đến tài liệu, hoặc các lớp xuất phát từ XmlReader khi bạn muốn một mô hình kiểu stream thay thế. Nhớ rằng cái giá phải trả cho tính mềm dẻo của XmlNode- based XmlDocument đó là bộ nhớ yêu cầu cao và việc đọc tàiliệu không tốt bằng XmlReader. Vì vậy hãy suy nghĩ kĩ phương thức trước khi chọn. . báo (< ?xml version='1.0' .>) XmlDocumentType Quan hệ dữ liệu với khai báo kiểu tài liệu XmlElement Một đối tượng thành phần XML XmlEntityReferenceNode. hình cây thư mục của tài liệu. XmlAttribute Một đối tượng thuộc tính của một đối tượng XmlElement. XmlEntity Phân tách và tổ hợp các nút. XmlNotation Chứa