1. Trang chủ
  2. » Công Nghệ Thông Tin

Thao tác trên XML part 5

12 342 1
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Thao tác trên XML Part 5
Định dạng
Số trang 12
Dung lượng 163,16 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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.. 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

Trang 1

Đọ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

Trang 2

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()

Trang 3

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ư

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);

Trang 4

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

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)

Trang 5

{

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

Trang 6

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()

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

Sử dụng lớp XmlValidatingReader

Nếu bạn muốn xác nhận một tài liệu XML, bạn sẽ cần phải sử dụng lớp

XmlValidatingReader Nó chứac các khả năng giống như XmlTextReader (Cả hai đều xuất phát từ XmlReader) nhưng XmlValidatingReader có thêm thuộc tính

ValidationType, thuộc tính Schemas và SchemaType

Nếu bạn gán thuộc tính ValidationType giá trị xác nhận mà bạn muốn Giá trị hợp lệ của thuộc tính này được liệt kê trong bảng sau:

Property Value Description

Trang 7

Property Value Description

Auto Nếu một DTD được khai báo trong một khai báo <!DOCTYPE >,

điều này cho phép DTD sẽ được load và xử lí Giá trị mặc định cho các DTD

Nếu một thuộc tính XSD schemalocation được tìm thấy, XSD được load và xử lí, và sẽ trả về các giá trị mặc định trong sơ đồ

Nếu một không gian tên với tiếp đầu ngữ MSXML x-schema được tìm thấy, nó sẽ load và xử lí sơ đồ XDR và trả về các thuộc tính mặc định

đã được định nghĩa

DTD Phù hợp theo chuẩn DTD

Schema Phù hợp theo sơ đồ XSD

XDR Phù hợp theo sơ đồ XDR

None Không giá trị hợp lệ nào được thực thi

Khi một thuộc tính trong này được chọn, Một ValidationEventHandler cần phải được gán Đây là một sự kiện được tạo ra do các lỗi Bạn có thể tác động lại lỗi theo các mà bạn cho là phù hợp

Hãy xem cách làm việc của ví dụ sau Trướct tiên chúng ta sẽ thêm một sơ đồ không gian tên XDR (XM- Data Reduced) vào file books.xml của chúng ta, và đổi tên file này thành

<?xml version='1.0'?>

<! This file represents a fragment of a book store inventory database >

<bookstore xmlns="x-schema:books.xdr">

<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">

<title>The Autobiography of Benjamin Franklin</title>

<author>

<first-name>Benjamin</first-name>

<list-name>Franklin</list-name>

</author>

<price>8.99</price>

</book>

</bookstore>

Chú ý rằng bookstore bây giờ có thuộc tính xmlns="x-schema:books.xdr" Nó sẽ ánh xạ đến sơ đồ XDR sau, gọi books.xdr:

Trang 8

<?xml version="1.0"?>

<Schema xmlns="urn:schemas-microsoft-com:xml-data"

xmlns:dt="urn:schemas-microsoft-com:datatypes">

<ElementType name="first-name" content="textOnly"/>

<ElementType name="last-name" content="textOnly"/>

<ElementType name="name" content="textOnly"/>

<ElementType name="price" content="textOnly" dt:type="fixed.14.4"/>

<ElementType name="author" content="eltOnly" order="one">

<group order="seq">

<element type="name"/>

</group>

<group order="seq">

<element type="first-name"/>

<element type="last-name"/>

</group>

</ElementType>

<ElementType name="title" content="textOnly"/>

<AttributeType name="genre" dt:type="string"/>

<ElementType name="book" content="eltOnly">

<attribute type="genre" required="yes"/>

<element type="title"/>

<element type="author"/>

<element type="price"/>

</ElementType>

<ElementType name="bookstore" content="eltOnly">

<element type="book"/>

</ElementType>

</Schema>

Giờ đây mọi thứ trông khá rõ ràng chúng ta có một file XML với hai thuộc tính được định nghĩa trong sơ đồ (publicationdate và ISBN từ các thành phần của sách) Chúng ta

sẽ thêm chúng vào để bẫy các lỗi phát ra Mã nguồn nằm trong thư mục

First, you will also need to add:

using System.Xml.Schema;

to your class Then add the following to the button event handler:

protected void button1_Click (object sender, System.EventArgs e)

{

//change this to match your path structure

Trang 9

string fileName = " \\ \\ \\booksVal.xml";

XmlTextReader tr=new XmlTextReader(fileName);

XmlValidatingReader trv = new XmlValidatingReader(tr);

//Set validation type

trv.ValidationType=ValidationType.XDR;

//Add in the Validation eventhandler

trv.ValidationEventHandler +=

new ValidationEventHandler(this.ValidationEvent);

//Read in node at a time

while(trv.Read())

{

if(trv.NodeType == XmlNodeType.Text)

listBox1.Items.Add(trv.Value);

}

}

public void ValidationEvent (object sender, ValidationEventArgs args)

{

MessageBox.Show(args.Message);

}

Ở đây chúng tôi tạo một XmlTextReader truyền cho XmlValidatingReader Trước tiên XmlValidatingReader được tạo, chúng ta có thể dùng nó giống như cách đã làm với XmlTextReader trong ví dụ trước Chỉ khác là chúng ta chỉ rõ ValidationType, và thêm vào một ValidationEventHandler Bạn có thể bẫy lỗi theo cách mà bạn cho là hợp lí trong

ví dụ này chung tôi đưa ra một thông báo lỗi Thông báo trông như thế này khi có ngoại

lệ ValidationEvent xảy ra:

Không giống như một vài thành viên khác, ngưng khi có ngoại lệ xảy ra,

XmlValidatingReader sẽ giữ nó trong quá trình đọc Nhiệm vụ của bạn là ngưng đọc và

xử lí lỗi nếu bạn cho rằng đây là một lỗi quan trọng

Trang 10

Sử dụng Schemas Property

Schemas property của XmlValidatingReader chứa một XmlSchemaCollection, có thể tìm thấy trong không gian tên System.Xml.Schema Tập hợp này tổ chức load lại loaded XSD và XDR schemas Nó cực nhanh đặc biệc là khi bạn cần kiểm tra sự hợp lệ của nhiều tài liệu khác nhau, vì sơ đồ sẽ không được load mỗi khi kiểm tra Các bước sử dụng thuộc tính này như sau, bạn tạo một đối tượng XmlSchemaCollection Phương thức Add(), nằm trong một XmlSchemaCollection, có bốn quá tải Bạn có thể truyền nó cho một đối tượng xuất phát từ XmlSchema, một đối tượng xuất phát từ

XmlSchemaCollection, một chuỗi không gian tên với chuỗi URI của file sơ đồ và một đối tượng xuất phát từ XmlReader chứa trong sơ đồ

Sử dụng lớp XmlTextWriter

Lớp XmlTextWriter cho phép bạn xuất XML thành một chuỗi, một file hoặc một đối tượng a TextWriter Giống như XmlTextReader, nó là một kiểu forward-only,

non-cached XmlTextWriter có thể cấu hình cao, cho phép bạn chỉ rõ những thứ như cho phép thục đầu dòng, số thục đầu dòng, kí tự chỉ dẫn nào được dùng trong các giá trị thuộc tính cho phép không gian tên được hỗ trợ

Hãy xem ví dụ sau, để biết cách sử dụng lớp XmlTextWriter Có thể tìm thấy mã nguồn trong thư mục XmlWriterSample1:

private void button1_Click(object sender, System.EventArgs e)

{

// change to match your path structure

string fileName=" \\ \\ \\booknew.xml";

// create the XmlTextWriter

XmlTextWriter tw=new XmlTextWriter(fileName,null);

// set the formatting to indented

tw.Formatting=Formatting.Indented;

tw.WriteStartDocument();

// Start creating elements and attributes

tw.WriteStartElement("book");

tw.WriteAttributeString("genre","Mystery");

tw.WriteAttributeString("publicationdate","2001");

tw.WriteAttributeString("ISBN","123456789");

tw.WriteElementString("title","The Case of the Missing Cookie");

tw.WriteStartElement("author");

tw.WriteElementString("name","Cookie Monster");

tw.WriteEndElement();

tw.WriteElementString("price","9.99");

tw.WriteEndElement();

Ngày đăng: 07/11/2013, 19:15

TỪ KHÓA LIÊN QUAN