Đọc và ghi Streamed XML
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
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)
):
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: