Tải bản đầy đủ (.pdf) (13 trang)

Thao tác XML - Đọc và ghi Streamed XML – Phần 1 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (115.02 KB, 13 trang )

Thao tác XML
Đọc và ghi Streamed XML – Phần 1

Giờ đây chúng ta đã biết những gì có thể thực hiện được, vậy hãy xem .NET
hỗ trợ những gì. Chúng ta sẽ bắt đầu bằng việc chỉ ra cách đọc và viết XML.
Các lớp XmlReader và XmlWriter có vẻ như quen thuộc với những ai đã
từng dùng SAX. Các lớp xuất phát từ XmlReader cung cấp một khả năng
nhanh, chỉ tiến tới (không cho quay lui), chỉ đọc các dòng dữ liệu XML cho
việc xử lí. Vì nó là mô hình luồng nên không đòi hỏi khắc khe về bộ nhớ. Dĩ
nhiên, bạn không có khả năng định hướng và khả năng đọc ghi vì nó không
được hỗ trợ trong mô hình DOM. Các lớp xuất phát từ XmlWriter sẽ tạo ra
một tài liệu XML phù hợp với các chuẩn của không gian tên W3C's XML
1.0.
Cả hai lớp XmlReader và XmlWriter đều là những lớp trừu tượng. Hình vẻ
dưới đây chỉ ra các lớp được thừa kế từ XmlReader và XmlWriter:
XmlTextReader và XmlTextWriter làm việc chung trên các đối tượng luồng
hoặc các đối tượng TextReader/TextWriter trong không gian tên System.IO.
XmlNodeReader sử dụng một XmlNode như là nguồn thay cho một stream.
XmlValidatingReader thêm DTD và sơ đồ thích hợp và tất nhiên cả dữ liệu
hợp lệ. Chúng ta sẽ xem xét nó kĩ hơn trong phần sau của chương.
Sử dụng lớp XmlTextReader
Một lần nữa, XmlTextReader trong rất giống SAX. Một trong những khác
biệt lớn nhất là: SAX là một mô hình kiểu push (có nghĩa là, nó đẩy dữ liệu
ra khỏi ứng dụng, và phát triển sẵn sàng nhận nó), còn XmlTextReader là
một mô hình pull, ở đó dữ liệu được kéo vào ứng dụng yêu cầu nó. Nó tạo ra
một mô hình lập trình dễ dàng và trực quan hơn. Một lợi ích khác là một mô
hình pull có thể lựa chọn dữ liệu để gởi đến ứng dụng: nếu bạn không muốn
tất cả dữ liệu, vì không cần sử lí tất cả chúng. Trong một mô hình push, tất
cả dữ liệu XML cần phải được xử lí bởi ứng dụng mặc cho nó muốn hay
không.
Nào hãy xem xét một ví dụ đơn giản về đọc dữ liệu XML,và sau đó xem xét


kĩ hơn lớp XmlTextReader. Bạn sẽ tìm thấy mã trong thư mục
XmlReaderSample1. Thay vì dùng không gian tên MSXML2 như ví dụ trên,
chúng ta sẽ làm như sau:
using System.Xml;
Chúng ta cũng cần bỏ dòng sau khỏi mã nguồn:
private DOMDocument40 doc;
Đây là sự kiện click của button:
protected void button1_Click (object sender, System.EventArgs e)
{
//Modify this path to find books.xml
string fileName = " \\ \\ \\books.xml";
//Create the new TextReader Object
XmlTextReader tr = new XmlTextReader(fileName);
//Read in a node at a time
while(tr.Read())
{
if(tr.NodeType == XmlNodeType.Text)
listBox1.Items.Add(tr.Value);
}
}
XmlTextReader này khá đơn giản. Trước tiên chúng ta tạo một đối tượng
string chứa tên đường dẫn của file XML. Sau đó chúng ta tạo một
XmlTextReader mới với chuỗi truyền fileName. XmlTextReader có mười ba
quá tải. Chúng ta có thể kết hợp các chuỗi truyền khác nhau (filenames và
URLs), streams và NameTables (khi một thành phần của thuộc tính tên xảy
ra một vài lần, nó có thể được lưu trong một NameTable, để cho phép so
sánh nhanh hơn).
Ngay sau khi một đối tượng XmlTextReader được khởi tạo không có mục nào được
chọn. Không có mục hiện hành. khi chúng ta bước vào vòng lặp tr.Read(), phương
Read() sẽ di chuyển sang mục đầu tiên trong tài liệu. Nó tiêu biểu cho các mục

khai báo XML. Trong ví dụ này, chúng ta duyệt qua từng mục và so sánh tr.NodeType
với bộ XmlNodeType, và thêm các mục được tìm thấy vào listbox. Đây là màn hình
sau khi listbox được load:
Các phương thức Read
Có một vài cách để di chuyển trong tài liệu. Như bạn đã thấy, Read() có có
thể di chuyển sang mục tiếp theo. Chúng ta có thể xem nêu mục đó có một
giá trị (HasValue()) hoặc, hoặc nếu mục đó có các thuộc tính
(HasAttributes()). Chúng ta cũng có thể dùng phương thức
ReadStartElement(), để kiểm tra xem nếu mục hiện tại là thành phần khởi
đầu, và chuyển sang mục tiếp theo. Nếu không phải là mục khởi đầu một
ngoại lệ XmlException sẽ được phát ra. Việc gọi phương thức này giống
như gọi phương thức IsStartElement(), bởi một Read().
Các phương thức ReadString() và ReadChars() đều đọc dữ liệu văn bản từ
một thành tố. ReadString() tra về một chuỗi dữ liệu, trong khi ReadChars()
trả về một mảng dữ liệu kiểu char.
ReadElementString() cũng giống như ReadString(), ngoại trừ việc bạn
không phải truyền tên của một thành tố. Nếu nội dung của mục tiếp theo
không phải là một start tag, hoặc nếu tham số Name không không phải là
Name của mục hiện hành, thì một ngoại lệ sẽ được phát ra.
Đây là ví dụ chỉ ra cách sử dụng ReadElementString() (Bạn có thể tìm thấy
mã trong thư mục XmlReaderSample2). Chú ý rằng ví dụ này sử dụng
FileStreams, vì vậy bạn cần phải bảo đảm rằng đã include không gian tên
System.IO trong câu lệnh using.
protected void button1_Click (object sender, System.EventArgs e)
{
//use a filestream to get the data
FileStream fs = new FileStream(" \\ \\ \\books.xml",FileMode.Open);
XmlTextReader tr = new XmlTextReader(fs);
while(!tr.EOF)
{

//if we hit an element type, try and load it in the listbox
if(tr.MoveToContent() == XmlNodeType.Element &&
tr.Name=="title")
{
listBox1.Items.Add(tr.ReadElementString());
}
else
{
//otherwise move on
tr.Read();
}
}
}
Trong vòng lặp while chúng tôi sử dụng MoveToContent() để tìm trên mỗi
dòng xem XmlNodeType.Element có giống với named title không. Chúng
tôi sử dụng thuộc tính EOF của XmlTextReader như là một điều kiện lặp.
Nếu mục không phải kiểu Element của named title, mệnh đề else phát ra một
phương thức Read() để di chuyển sang mục tiếp theo. Khi chúng ta tìm thấy
một mục thỏa điều kiện, chúng ta trả kết quả của ReadElementString() cho
listbox. Nó cho phép các tựa sách được liệt kê trong listbox. Chú ý rằng
chúng ta không tạo ra một lời gọi Read() sau khi một ReadElementString()
thực hiện thành công. Bởi vì ReadElementString() cũng sẽ di chuyển sang
mục tiếp theo.
Nếu bạn bỏ && tr.Name=="title" trong mệnh đề if, bạn sẽ nhận được ngoại
lệ XmlException. Nếu nhìn vào file dữ liệu, bạn sẽ thấy thành tố đầu tiên mà
MoveToContent() tìm ra là <bookstore>. Tất nhiên nó vì nó không chứa một
kiểu text chuẩn, nên ReadElementString() phát ra một ngoại lệ
XmlException.
Hãy chạy nó, chúng ta sẽ gọi phương thức LoadList(), và truyền trong
XmlTextReader như là một tham số. Nó giống như mã ví dụ sau (bạn sẽ tìm

thấy mã trong thư mục XmlReaderSample3):
protected void button1_Click (object sender, System.EventArgs e)
{
//use a filestream to get the data
FileStream fs = new FileStream(" \\ \\ \\books.xml",FileMode.Open);
XmlTextReader tr = new XmlTextReader(fs);
while(!tr.EOF)
{
//if we hit an element type, try and load it in the listbox
if(tr.MoveToContent() == XmlNodeType.Element)
{
LoadList(tr);
}
else
{
//otherwise move on
tr.Read();
}
}
}
private void LoadList(XmlReader reader)
{
try
{
listBox1.Items.Add(reader.ReadElementString());
}
// if an XmlException is raised, ignore it.
catch(XmlException er){}
}
Đây là kết quả khi chạy:


Có phải nó trông rất quen thuộc? Nó có cùng kết quả với ví dụ trước. Vậy
chúng ta được gì, đó là tính mềm dẻo của các lớp trong không gian tên
System.Xml.
Lấy thuộc tính của dữ liệu
Khi bạn chạy mã ví dụ, bạn nhận ra rằng khi các mục được đọc, bạn không
thấy bất kì thuộc tính nào cả. Đó là vì các thuộc tính không nằm trong tài
liệu. Khi đang đứng trên một mục, bạn có thể kiểm tra các thuộc tính và có
thể lấy giá trị của bất kì giá trị thuộc tính nào.
Thuộc tính HasAttributes sẽ trả về giá trị true nếu có bất kì thuộc tính nào
còn không sẽ trả về false. Thuộc tính AttributeCount sẽ cho bạn biết có bao
nhiêu thuộc tính, và phương thức GetAttribute() sẽ trả về một thuộc tính
thông qua tên hoặc chỉ mục. Nếu bạn muốn lặp qua các thuộc tính bạn có thể
dùng các phương thức MoveToFirstAttribute() và MoveToNextAttribute().
XmlReaderSample4 là một ví dụ về cách lặp qua các thuộc tính :
protected void button1_Click (object sender, System.EventArgs e)
{
//set this path to match your data path structure
string fileName = " \\ \\ \\books.xml";
//Create the new TextReader Object
XmlTextReader tr = new XmlTextReader(fileName);
//Read in node at a time
while(tr.Read())
{
//check to see if it's a NodeType element
if(tr.NodeType == XmlNodeType.Element)
{
//if it's an element, then let's look at the attributes.
for(int i = 0; i < tr.AttributeCount; i++) {
listBox1.Items.Add(tr.GetAttribute(i));

}
}
}
Bây giờ chúng ta xem xét về các mục thành phần. Khi chúng ta tìm thấy một
mục, chúng ta lặp qua tất cả thuộc tính của nó, và dùng phương thức
GetAttribute() để load giá trị của thuộc tính vào listbox. Trong ví dụ này các
thuộc tính đó là genre, publicationdate, và ISBN.


×