Khi chúng ta đã có một tài liệu XML, chúng ta sẽ tự hỏi: sử dụng nó như thế nào và làm thế nào để truy cập đến một tập tin XML. Một vǎn bản XML có thể hiểu được ở
bất kỳ đâu trong hệ thống nhờ thông tin trong phần meta-data của nó mang theo. Vì vậy việc truy cập thông tin trong vǎn bản XML này là hoàn toàn khả thi (parsible), hơn nữa cách thức truy cập hoàn toàn có thểđược sử dụng cho các vǎn bản XML khác nhau.
Hai giải pháp mở cho người lập trình sử dụng để đọc thông tin XML là DOM (Document Object Model) và SAX (Simple API for XML). Đây là hai bộ giao diện lập trình chuẩn và mở cho phép người lập trình xử lý thông tin XML mà không phải tạo ra các module xử lý riêng rẽ cho từng dữ liệu cụ thể. Người lập trình chỉ cần tạo ra những module đơn giản gọi là parser sử dụng các hàm của SAX hoặc DOM để truy cập bất kỳ
từng phần tử của vǎn bản XML. Chúng ta có khá nhiều lựa chọn ngôn ngữ lập trình để
viết bộ parser này như Java, C++, Perl, Python, Microsoft cũng phát triển các thành phần để hỗ trợ XML cho VB, VC, ASP.NET, .NET ... Cụ thể hơn, bạn có thể viết client bằng C++ trên Linux sử dụng DOM để làm việc với XML và gửi dữ liệu XML đến server, server này được viết bằng VB.NET và sử dụng SAX để làm việc với dữ liệu XML client gửi đến.
DOM là công nghệ lưu trữ dữ liệu của vǎn bản XML dưới dạng cây (hierarchical object model) với các node là các thành phần dữ liệu của vǎn bản. Sử dụng mô hình cây cho phép dựng bất kỳ một vǎn bản XML phức tạp nào và việc thao tác dữ liệu chính là thao tác với các node tương ứng của cây.
SAX sử dụng kiểu xử lý hướng sự kiện (event), khác với DOM là dựng cây model trước tiên rồi mới cho phép thao tác dữ liệu. SAX xử lý ngay khi đọc vǎn bản và tạo ra các object tương ứng (custom object) để chứa dữ liệu, quá trình lặp lại cho đến khi kết thúc vǎn bản. Mọi thứđược giải phóng trừ các objects mới được tạo ra đã chứa toàn bộ
dữ liệu của vǎn bản XML. Với những vǎn bản đơn giản và chỉ đọc một lần mà không cần cập nhật thì SAX là lựa chọn đầu tiên vì nó nhanh hơn rất nhiều so với DOM.
Mặc dù SAX và DOM có chung một mục đích là truy cập thông tin trong vǎn bản XML nhưng mỗi pháp pháp có một cách tiếp cận riêng và sử dụng phương pháp nào cho hiệu quả lại phụ thuộc vào từng hoàn cảnh cụ thể.
Sau đây, là một số kỹ thuật được sử dụng trong mội trường Visual Studio.NET để
làm việc với tập tin XML.
2.2.8.1. Đọc và phân tích tài liệu XML
2.2.8.1.1. Sử dụng lớp XMLTextReader
Lớp XMLTextReader cung cấp một cursor được sử dụng để lấy dữ liệu từ một tài liệu XML. Chúng ta khai báo như sau:
XmlTextReader myRdr = new XmlTextReader(Server.MapPath("catalog2.xml"));
Khi một thể hiện được tạo ra, con trỏ cursor sẽđược đặt ởđầu tài liệu. Chúng ta có thể
sử dụng phương thức Read() để lấy những phần dữ liệu một cách tuần tự. Mỗi phần dữ
liệu tương tự như một nút trong cây XML. Thuộc tính NodeType sẽ lấy kiểu của phần dữ liệu, thuộc tính Name sẽ lấy tên của nút, và Value sẽ lấy giá trị của nút. Vì thế, khi một phần dữ liệu được đọc, chúng ta có thể sử dụng câu lệnh sau để hiện thị tên, giá trị
và kiểu của nút.
Response.Write(myRdr.NodeType.ToString() +" " + myRdr.Name + ":" + myRdr.Value);
Nếu muốn kiểm tra nút đó có thuộc tính hay không, chúng ta có thể sử dụng phương thức HasAttributes. Nếu giá trị trả về của phương thức HasAttributes là true, chúng ta áp dụng phương thức MoveToAttribute(i) để lặp qua các thuộc tính của nút.
if (myRdr.HasAttributes) {
for( int i = 0; i< myRdr.AttributeCount-1;i++) { myRdr.MoveToAttribute(i); Response.Write(myRdr.NodeType.ToString()+":"+ myRdr.Name + ": " + myRdr.Value + "</br>"); } myRdr.MoveToElement(); } 2.2.8.1.2. Sử dụng mô hình DOM
Bên cạnh XMLTextReader thì mô trường Visual Studio.NET cũng hỗ trợ mô hình DOM (Document Object Module) đểđọc và trình bày nội dung của một tập tin XML. Việc sử dụng mô hình DOM sẽ thông qua một số đối tượng như XMLDocument, XMLDataDocument. Khi một XMLDocument được tạo ra, nó tổ chức nội dung của một tập tin XML thành một cây. Trong khi đối tượng XMLTextReader cung cấp một cursor
định vị theo một hướng, thì XMLDocument cung cấp việc truy xuất nhanh và trực tiếp
đến một nút. Tuy nhiên, việc sử dụng mô hình DOM rất tốn bộ nhớđể lưu trữ thành một cây, và thật sự sẽ khó khăn khi tài liệu XML có kích thước lớn. Có nhiều cách khác nhau để tạo một đối tượng XMLDocument. Sau đây chúng ta sử dụng đối tượng XMLTextReader để tạo một XMLDocument.
private void Page_Load(object sender, System.EventArgs e) {
if(!Page.IsPostBack) {
XmlDocument myDoc = new XmlDocument();
XmlTextReader myRdr = new XmlTextReader(Server.MapPath("Catalog2.xml"));
myDoc.Load(myRdr);
Session("sessionDoc") = myDoc;
//khi cây được tạo ra, chúng ta có thể hiển thị lênlistbox //với thuộc tính InnerText của những node ProductName int i=0; for(i=0;i<myDoc.DocumentElement.ChildNodes.Count-1;i++) { lstProducts.Items.Add (myDoc.DocumentElement. ChildNodes[i].ChildNodes[i].InnerText); } myRdr.Close(); } }
2.2.8.2. Định hướng qua tài liệu XML để rút trích dữ liệu:
2.2.8.2.1. Sử dụng lớp XMLTextReader
Trong phần trên, chúng ta đã biết cách để đọc vào một tài liệu XML, phần này chúng ta sẽđịnh hướng qua tài liệu XML và chỉ lấy những dữ liệu nào cần thiết cho ứng dụng của mình. Ví dụ như nếu nút đó là ProductName chúng ta sẽđọc và hiển thị thông tin trên một listbox, cụ thể như sau:
while (myRdr.Read()) { if(XmlNoteType.Element) { if (myRdr.Name="ProductName") { myRdr.Read(); stProducts.Items.Add(myRdr.ReadString); } } } myRdr.Close(); 2.2.8.2.2. Sử dụng mô hình DOM
Một cây được tạo thành từ nhiều nút. Và một nút cũng là một cây chứa những nút khác. Nút lá thì không có nút con, vì thế nút này dùng để hiển thị dữ liệu văn bản. Lớp XmlDataDocument kế thừa từ lớp XmlDocument, vì thế nó cũng có một số phương thức như lớp XmlDocument. Điều thú vị nhất của XmlDataDocument là nó cung cấp hai cách nhìn trên cùng một dữ liệu đó là XML view và relational view. XmlDataDocument có một thuộc tính tên là DataSet, thông qua DataSet, XmlDataDocument trình bày dữ liệu như một hoặc nhiều bảng (DataTable) có quan hệ
hoặc không có quan hệ. Khi chúng ta sử dụng phương thức Load() để tải một đối tượng XmlDataDocument, chúng ta có thể xem nó như một cây hoặc như một bảng (hoặc nhiều bảng). Sau đây là hình minh hoạ cho hai cách nhìn về một tài liệu XML khi sử
Mô hình DOM trong .NET 2.2.9. Nhận xét về XML
XML được xây dựng như là một chuẩn cho việc trình bày và trao đổi dữ liệu trên web. Tập đoàn W3C đã xây dựng chuẩn XML và những công nghệ liên quan bao gồm XML DOM, XPath, XSL, và XML Schema. Trong đó XML DOM được sử dụng để tạo, thay đổi, và duyệt qua tài liệu XML. Xpath là ngôn ngữ dùng để truy vấn trên tài liệu XML. XSL dùng để chuyển đổi tài liệu XML từ dạng này sang dạng khác. XML Schema định nghĩa cấu trúc và kiểu dữ liệu cho những nút trong một tài liệu XML. Tất cả những công nghệ này đã tạo nên sức mạnh cho XML. Vì thế, XML ngày nay đang
được sử dụng rất phổ biến và tương lai sẽ là một chuẩn duy nhất được dùng trên web.
XML không phải là:
• XML không là ngôn ngữ lập trình
Không có một trình biên dịch nào có thểđọc tập tin XML và tạo ra mã co thể thực thi được. Có lẽ chúng ta có thểđịnh nghĩa một ngôn ngữ kịch bản, ngôn ngữđó sử
dụng định dạng mã máy XML, và được thông dịch bằng một chương trình nhị phân, nhưng các chương trình này sẽ hiếm khi được sử dụng. XML có thểđược sử dụng như một dạng chỉ dẫn cho những chương trình, giống như các chương trình truyền thống có thểđọc một tập tin văn bản config và thực thi những hành động khác nhau phụ thuộc và những gì mà nó đọc được trong tập tin config. Gần đây nhiều chương trình đang bắt đầu sử dụng những tập tin XML config.
• XML không phải là giao thức truyền tải trên mạng (network transport protocol)
XML sẽ không gửi dữ liệu qua mạng. Dữ liệu gửi trên mạng thông qua giao thức HTTP, FTP, NFS hoặc một số giao thức khác có thể ngẫu nhiên được mã hóa bằng
định dạng XML.
• XML không là cơ sở dữ liệu
Việc XML có phải là cơ sở dữ liệu hay không là một câu hỏi mà nhiều nguời không trả lời được. Vì XML cũng giống như mọi ngôn ngữ khác đó là nó cũng có ưu điểm và khuyết điểm. Ưu điểm của XML như chúng ta đã biết ở trên nhưng khuyết điểm của XML ởđây là XML dài dòng và truy xuất chậm. Việc truy xuất chậm là do việc lưu trữ tài liệu XML trong bộ nhớđể phục vụ cho vấn đề truy vấn như chúng ta đã
đề cập trong mô hình DOM. Vì vậy, sau đây chúng ta sẽ quan tâm đến một khía cạnh khác của XML. Đó là XML có gần gũi như một Cơ sở dữ liệu (CSDL) hay
không? Câu trả lời là “chỉ một phần nào”. Vì XML cũng có một sốđiểm giống như
CSDL. Đó là nó cũng có khả năng lưu trữ, có hỗ trợ một số lược đồ như DTD, hay Schema (tương tự như bảng trong CSDL quan hệ). Và trên XML ta cũng có thể thực hiện thao tác truy vấn bằng cách sử dụng XPath, XQuery, XQL,…, và XML cũng có hỗ trợ lập trình trên giao diện. Nhưng một số vấn đề mà XML chưa hỗ trợ như
một CSDL. Đó là không có chỉ mục, vấn đề bảo mật không cao, tính toàn vẹn dữ
liệu chưa đáp ứng, không hỗ trợ các trigger, việc truy cập đa người dùng cũng hạn chế, và cuối cùng là không cho truy vấn thông qua nhiều tài liệu. Một cơ sở dữ liệu có thể chưa dữ liệu XML, có thể như một VARCHAR hoặc như một số kiểu dữ liệu XML tùy chỉnh nhưng cơ sở dữ liệu không phải là một tài liệu XML. Chúng ta có thể lưu trữ dữ liệu XML vào trong cơ sở dữ liệu trên server hoặc nhận dữ liệu từ cơ
sở dữ liệu in định dạng XML, nhưng để làm được như vậy, chúng ta cần một phần mềm được viết bằng ngôn ngữ lập trình như là C, C++,C# hay Java… Để lưu trữ
XML trong cơ sở dữ liệu, phần mềm ở phía client sẽ gửi dữ liệu tới server sử dụng một giao thức mạng nhu là TCP/IP. Phần mềm phía server sẽ nhận dữ liệu XML, phân tích nó, và lưu trữ vào cơ sở dữ liệu.Để nhận một tài liệu XML từ một cơ sở dữ
liệu, chúng ta sẽ cần một phần mềm trung gian (middleware) như Enhydra, phần mềm này sẽ thực hiện các truy vấn SQL trên cơ sở dữ liệu và đưa ra tập kết quả theo
định dang XML trước khi trả về cho client. Một số cơ sở dữ liệu có thể tích hợp mã lệnh phần mềm này vào server của họ hoặc cung cấp plug-ins để xử lý. XML là một dạng thức chuyển tải độc lập hệ thống nền, tuy nhiên việc lưu trữ dữ liệu XML như
một cơ sở dữ liệu là không khả thi.
2.3. DTD (Document Type Definition)
DTD là từ viết tắt của Document Type Definition – định nghĩa kiểu tư liệu. Định nghĩa kiểu tư liệu DTD làm cho tài liệu XML trở nên hợp khuôn dạng và có giá trị.
2.3.1. Tạo khai báo và định nghĩa kiểu tư liệu DTD:
2.3.1.1. Chỉ thị bắt đầu khai báo DTD:
Cách khai báo DTD phụ thuộc vào khái niệm standalone trong chỉ thị xml đầu tiên. Khái niệm này cho ta biết định nghĩa kiểu tư liệu DTD trong tài liệu XML được định nghĩa ởđâu (nằm trong tài liệu XML hay nằm bên ngòai). Cụ thể:
Giá trị Mô tả
Yes DTD được khai báo bên trong tài liệu XML.
No DTD được khai báo bên ngòai tài liệu XML với tên mở rộng là “.dtd”
Có nhiều mẫu khai báo, nhưng để bắt đầu ta dùng thẻ <!DOCTYPE>
Khai báo Mô tả
<!DOCTYPE rootname [DTD] > Đây là tham chiếu nội.
<!DOCTYPE rootname SYSTEM URL> Đây là tham chiếu ngoại riêng tư, URL
được dùng để tham chiếu đến các DTD ngoại.
<!DOCTYPE rootname SYSTEM URL
[DTD]> Tham chingọai riêng tếu nư. ội kết hợp với tham chiếu <!DOCTYPE rootname PUBLIC FPI
URL>
Tham chiếu ngoại dùng chung, URL được dùng để tham chiếu đến các DTD ngoại.
<!DOCTYPE rootname PUBLIC FPI URL
[DTD] > Tham chingọai dùng chung. ếu nội kết hợp với tham chiếu
∗ Chú ý: nếu 1 phần tử được định nghĩa trong tài liệu cục bộ và trong file tham chiếu ngoại thì về mặt lý thuyết định nghĩa nội bộ sẽđược ưu tiên trước. Nhưng thực tế các trình kiểm tra đều báo lỗi khi phát hiện có 2 định nghĩa trùng nhau.
2.3.1.2. Khai báo Element:
Sau khi khai báo phần bắt đầu của kiểu tư liệu, ta định nghĩa các kiểu tư liệu cho phần tử thẻ bằng khai báo <!ELEMENT>. Cú pháp:
<!ELEMENT NAME CONTENT_MODEL>
Name Tên của phần tử muốn định nghĩa. Content_Model Dạng nội dung trong phần tử Name. Nó có thể là EMPTY, ANY, các phần tử con hoặc dữ liệu văn bản thô…
Trong Content_Model ta có thể định nghĩa nội dung mà nó chứa có thể bắt buộc xuất hiện hoặc không, hoặc có thể xuất hiện nhiều lần bằng cách dùng ký tự *, +, ?, |
a* Không có hoặc có nhiều phần tử a giống nhau a+ Có ít nhất 1 phần tử a.
a? Có 1 phần tử a hoặc không có phần tử a nào hết. a,b Phần tử b sẽ xuất hiện ngay sau phần tử a. a|b Lựa chọn 1 trong hai phần tử a hoặc b Các khái niệm trong Content_Model:
- ANY: cho biết phần tử khai báo có thể chứa bất kỳ kiểu nội dung nào và sẽ
không bị kiểm tra bởi trình phân tích.
- Danh sách các phần tử con: cho biết phần tử mà bạn khai báo có chứa những phần tử con khác. Ví dụ: <!ELEMENT DOCUMENT (CUSTOMER)*>
- #PCDATA: chỉ biễu diễn dữ liệu thô ( có thể là số nguyên hoặc số chấm động nhưng phải ở dạng text).
- Làm việc với nhiều phần tử con: ta sử dụng ký tựđại diện cho phép làm việc và khao báo sử dụng nhiều phần tử con.
- DTD sequences: trong 1 phần tửđể liệt kê các phần tử con xuất hiện tuần tự, ta sử dụng kí tự “,”. Và trong phần khai báo, khỏang trắng không quan trọng.
- Nhóm 1 tập các định nghĩa DTD con bằng “ () ”.
2.3.2. Định nghĩa DTD ngoại:
Mục đích là định nghĩa DTD cho phần tử thẻ dựa trên phần định nghĩa sẵn từ các XML trước đó. Ngòai ra, nó sẽ giúp cho các ứng dụng có thể dễ dàng chia sẻ. Định nghĩa DTD ngoại có 2 cách: private DTDs và public DTDs ( tham chiếu ngoại dùng riêng và tham chiếu ngoại dùng chung).
Để sử dụng tham chiếu ngoại ta cần khai báo standalone = “no” trong chỉ thị khai báo xml đầu tiên.
2.3.2.1 Sử dụng DTD với URL:
Thông thường trình phân tích sẽ tìm các file tham chiếu ngoại trong thư mục cùng cấp với file tài liệu XML. Nhưng để mở rộng hơn, bạn có thể sử dụng DTD của 1 tổ
chức hay cá nhân nào đó ở bất cứđâu trên thế giới bằng cách chỉđịnh file tham chiếu ngoại theo địa chỉ tuyệt đối URL và có khai báo với tư cách là tham chiếu ngọai dùng chung. Ví dụ:
<!DOCTYPE DOCUMENT SYSTEM
"http://www.starpowder.com/dtd/order.dtd">
2.3.2.2. Tham chiếu ngoại dùng riêng:
Tham chiếu ngoại riêng dùng cho 1 nhóm người họăc mang tính cá nhân – không dùng cho mục đích dùng chung. Khai báo và định nghĩa tham chiếu ngoại ta dùng từ
khóa SYSTEM trong chỉ thị khai báo <!DOCTYPE>.Cú pháp: <!DOCTYPE rootname SYSTEM URL>
2.3.2.3. Tham chiếu ngọai dùng chung:
Tương tự cú pháp của tham chiếu ngọai dùng riêng, nhưng ta thay SYSTEM thành PUBLIC và thêm khái nhiệm FPI. Cú pháp:
<!DOCTYPE rootname PUBLIC FPI URL> Trong đó, FPI có 4 trường, và FPI có những quy tắc sau:
- Trường thứ nhất: xác định kết nối của DTD đến 1 formal standard (chuẩn hình thức). Nếu là tài liệu thì trường này sẽ là ký tự “-”. Đối với DTD không đúng chuẩn thì ta dùng ký tự “+”. Đối với formal standard, trường này sẽ tham chiếu