Các phần tử trong [DTD] theo cú pháp trên đều nằm trong tài liệu. Mỗi phần tử đ−ợc định nghĩa bằng thẻ khai báo <!ELEMENT> theo cú pháp sau:
<!ELEMENT Name Content_Model>
Trong đó Name là tên phần tử muốn định nghĩa, Content –Model có thể đặt là EMPTY (thành phần không chứa gì cả) hay ANY (chứa tổ hợp thành phần và văn bản không xác định) hoặc chứa cả hai nội dung (bao gồm dữ liệu có thể dùng phân tích hoặc các phần tử con khác).
Sau đây là một số cụ thể hoá nội dung của phần tử:
a. Phần tử chứa các phần tử con
Trong ví dụ file danhsach.xml, phần tử canbo chứa các phần tử con hoten,
ngaysinh, gioitinh, khoa đ−ợc khai báo là:
<!ELEMENT canbo (hoten, ngaysinh, gioitinh, khoa)>
b. Phần tử chứa dữ liệu văn bản
Tất cả dữ liệu thô không thuộc phần định dạng đ−ợc tham chiếu đến bởi định nghĩa #PCDATA (Parsed Character Data). Cú pháp định nghĩa nh− sau:
<!ELEMENT Name (#PCDATA)>
Trong đó Name là tên phần tử cần định nghĩa.
c. Phần tử chứa nội dung lựa chọn
Cú pháp khai báo: <!ELEMENT Name (Name1⏐Name2)>
Có nghĩa là phần tử Name hoặc chứa thành phần Name1 hoặc chứa thành phần Name2.
d. Phần tử chứa nhiều phần tử con giống nhau
Định nghĩa DTD sử dụng 3 ký tự đại diện qui định số phần tử con giống nhau mà một phần tử chứa. Đó là các ký tự: *, + và ?. Có thể tóm tắt cách sử dụng 3 ký tự này trong bảng sau (giả sử x và y là hai phần tử muốn khai báo và định nghĩa):
Ký tự đại diện ý nghĩa
x* Không có hoặc có nhiều phần tử x giống nhau x+ Có một hoặc có nhiều phần tử x giống nhau x? Phần tử x hoặc không có phần tử nào
x, y Phần tử x tiếp đến là y
x⏐y Phần tử x hoặc phần tử y (loại trừ lẫn nhau)
(expression) Tập các phần tử expression trong cặp ngoặc sẽ ảnh h−ởng bởi các ký tự đại diện *, +, ?
Bảng 2.1: Tóm tắt cách sử dụng các ký tự đại diện
Quay lại ví dụ file danhsach.xml đã có từ tr−ớc, các bổ sung sau đây làm tài liệu hợp khuôn dạng và hợp lệ:
<?xml version=”1.0” standalone=”yes”?> <--Bắt đầu phần định nghĩa DTD--> <!DOCTYPE danhsachCBCNV [
<!ELEMENT danhsachCBCNV (canbo)*>
<!ELEMENT canbo (hoten, ngaysinh, gioitinh, khoa⏐phong)>
<!ELEMENT hoten (#PCDATA)> <!ELEMENT ngaysinh (#PCDATA)> <!ELEMENT gioitinh (#PCDATA)> <!ELEMENT khoa (#PCDATA)> <!ELEMENT phong (#PCDATA)> ]>
<--Bắt đầu tμi liệu XML--> <danhsachCBCNV>
<canbo>
<hoten> Nguyễn Văn A </hoten> <ngaysinh> 21-10-1954 </ngaysinh> <gioitinh> Nam </gioitinh>
<khoa> CNTT </khoa> </canbo>
<canbo>
<ngaysinh> 11-5-1969 </ngaysinh> <gioitinh> Nữ </gioitinh> <phong> Tμi vụ </phong> </canbo> ... </danhsachCBCNV> 2.3.2. Định nghĩa DTD ngoại
Trong tr−ờng hợp tài liệu XML hiện tại có sử dụng các phần tử thẻ đã đ−ợc định nghĩa trong các tài liệu XML tr−ớc đó (các định nghĩa DTD xây dựng sẵn th−ờng chứa trong các file .dtd), ta phải sử dụng định nghĩa DTD ngoại theo cú pháp sau:
<!DOCTYPE rootName SYSTEM URL [DTD]>
Hoặc
<!DOCTYPE rootName PUBLIC FPI URL [DTD]>
Trong đó: rootName là tên phần tử gốc của tài liệu XML đang xét, SYSTEM là từ khoááp dụng cho tham chiếu ngoại riêng, nếu không chỉ ra đ−ờng dẫn thì trình phân tích sẽ tìm các file tham chiếu trong th− mục hiện hành cùng cấp với file tài liệu này. Ta cũng có thể chỉ định file tham chiếu ngoại là một tài liệu có thể truy xuất theo địa chỉ tuyệt đối URLs trên Internet.
Nếu sử dụng từ khoá PUBLIC trong định nghĩa DTD ngoại thì các phần tử DTD có thể đ−ợc dùng chung cho nhiều tài liệu. Tuy nhiên cần phải tạo ra một định dạng chung hình thức FPI (Formal Public Identifier) và tuân theo các qui tắc áp dụng cho FPI.
L−u ý: khi sử dụng định nghĩa DTD ngoại, trong khai báo đầu tài liệu XML thuộc tính standalone có giá trị “no”.
Ví dụ, soạn file data.dtd có nội dung nh− sau:
<!ELEMENT danhsachCBCNV (canbo)*>
<!ELEMENT canbo (hoten, ngaysinh, gioitinh, khoa⏐phong)>
<!ELEMENT hoten (#PCDATA)> <!ELEMENT ngaysinh (#PCDATA)> <!ELEMENT gioitinh (#PCDATA)> <!ELEMENT khoa (#PCDATA)> <!ELEMENT phong (#PCDATA)>
Khi đó nội dung file danhsach.xml sẽ là:
<?xml version=”1.0” standalone=”no”?>
<!DOCTYPE danhsachCBCNV SYSTEM “data.dtd”> <danhsachCBCNV>
<canbo>
<hoten> Nguyễn Văn A </hoten> <ngaysinh> 21-10-1954 </ngaysinh> <gioitinh> Nam </gioitinh>
<khoa> CNTT </khoa> </canbo>
<canbo>
<hoten> Trần Thanh Mai </hoten> <ngaysinh> 11-5-1969 </ngaysinh> <gioitinh> Nữ </gioitinh> <phong> Tμi vụ </phong> </canbo> ... </danhsachCBCNV>
Hơn nữa, ta cũng có thể kết hợp cả định nghĩa DTD nội và định nghĩa DTD ngoại bằng cách: URL chỉ file .dtd tham chiếu ngoại, còn trong [DTD] đ−ợc sử dụng cho định nghĩa DTD nội.
2.3.3. Thực thể và thuộc tính DTD
a. Thực thể là gì?
Thực thể (entity) là cách XML tham chiếu đến một mục dữ liệu, th−ờng là văn bản (text) hoặc cũng có thể là dữ liệu nhị phân. Thực thể đ−ợc khai báo trong phần định nghĩa DTD, sau đó đ−ợc sử dụng bằng cách tham chiếu đến nó trong tài liệu. Có hai loại thực thể: thực thể tổng quát (general entity) và thực thể tham số (parameter entity). Thực thể có thể là nội (đ−ợc định nghĩa hoàn toàn trong tài liệu tham chiếu đến nó) hoặc là ngoại (nội dung của nó đ−ợc định nghĩa từ nguồn dữ liệu bên ngoài, th−ờng đ−ợc tham chiếu bằng địa chỉ URL hoặc URI).
Thực thể có thể ở dạng phân tích hoặc không phân tích. Với thực thể phân tích, nội dung của nó phải hợp khuôn dạng văn bản của XML. Còn với thực thể không phân tích, nội dung của nó gồm các dữ liệu text hoặc nhị phân mà ng−ời sử dụng không muốn trình phân tích XML phân tích chúng.
a1. Thực thể tổng quát
Cú pháp khai báo và định nghĩa thực thể tổng quát:
<!ENTITY Name Definition>
Trong đó: Name là tên thực thể, đ−ợc dùng để tham chiếu đến nội dung của nó; Definition là định nghĩa của thực thể, nội dung định nghĩa đơn giản nhất là các văn bản cần thay thế khi thực thể đ−ợc tham chiếu đến.
Để tham chiếu đến nội dung thực thể có tên Name ta dùng cú pháp: &Name; Để khai báo thực thể ngoại ta dùng cú pháp:
<!ENTITY Name SYSTEM URI>
Hoặc <!ENTITY Name PUBLIC FPI URI>
Trong đó ý nghĩa từ khoá SYSTEM và PUBLIC t−ơng tự nh− trong định nghĩa DTD ngoại.
a2. Thực thể tham số
Cú pháp khai báo thực thể tham số nội và ngoại lần l−ợt nh− sau:
<!ENTITY %Name Definition> <!ENTITY %Name SYSTEM URI>
Hoặc <!ENTITY %Name PUBLIC FPI URI>
Để tham chiếu đến nội dung thực thể tham số có tên Name ta dùng cú pháp: %Name;
a3. Sự khác nhau giữa thực thể tham số và thực thể tổng quát
Ta sử dụng tham chiếu thực thể tổng quát để trình xử lý XML thay thế nội dung tham chiếu bằng chính nội dung của thực thể trong tài liệu. Ta không thể dùng nó trong bản thân các khai báo DTD. Tham chiếu đến các thực thể tham số chỉ có thể sử dụng trong định nghĩa DTD. Thực thể tham số nội chỉ có thể dùng trong phần khai báo DTD chính. Khi sử dụng DTD tham chiếu ngoại, các thực thể tham số có thể dùng ở bất kỳ đâu trong khai báo DTD. Mục đích của việc dùng thực thể tham số là tránh các khai báo lặp đi lặp lại khi định nghĩa DTD, khi cần thiết ta chỉ thay đổi nội dung thực thể thì các định nghĩa DTD sử dụng tham chiếu đến thực thể sẽ tự động thay đổi theo.
Ví dụ, xây dựng lại file data.dtd nh− sau:
<!ENTITY %canbo “(hoten, ngaysinh, gioitinh, khoa⏐phong)”>
<!ELEMENT danhsachCBCNV (giangvien⏐nhanvien)*>
<!ELEMENT giangvien %canbo;> <!ELEMENT nhanvien %canbo;> <!ELEMENT hoten (#PCDATA)> <!ELEMENT ngaysinh (#PCDATA)> <!ELEMENT gioitinh (#PCDATA)> <!ELEMENT khoa (#PCDATA)> <!ELEMENT phong (#PCDATA)>
Khi đó, nội dung file danhsach.xml sử dụng định nghĩa DTD trên là:
<?xml version=”1.0” standalone=”no”?>
<!DOCTYPE danhsachCBCNV SYSTEM “data.dtd”> <danhsachCBCNV>
<giangvien>
<hoten> Nguyễn Văn A </hoten> <ngaysinh> 21-10-1954 </ngaysinh> <gioitinh> Nam </gioitinh>
<khoa> CNTT </khoa> </giangvien>
<nhanvien>
<hoten> Trần Thanh Mai </hoten> <ngaysinh> 11-5-1969 </ngaysinh> <gioitinh> Nữ </gioitinh> <phong> Tμi vụ </phong> </nhanvien> ... </danhsachCBCNV> b. Thuộc tính
Trong phần 2.2.2(b) ta dã nói qua về thuộc tính của các thẻ, ý nghĩa và vị trí đặt chúng. Tuy nhiên, tr−ớc khi đặt thuộc tính cho một thẻ nào đó, ta cần phải định nghĩa thuộc tính sẽ kết hợp với thẻ đó trong DTD. Cú pháp khai báo thuộc tính nh−
sau:
<!ATTLIST Name
attName Type Default_value attName Type Default_value
....
attName Type Default_value>
Trong đó Name là tên phần tử kết hợp thuộc tính, attName là tên thuộc tính, Type là kiểu thuộc tính còn Default_value là giá trị mặc định cho thuộc tính. Hai bảng sau mô tả các kiểu dữ liệu của thuộc tính và các thiết lập mặc định cho thuộc tính.
Kiểu dữ liệu ý nghĩa
CDATA Dữ liệu đơn giản không chứa phần định dạng
ENTITIES Tham chiếu các thực thể (những thực thể này phải đ−ợc khai báo trong DTD)
ENTITY Tên tham chiếu của thực thể (cũng phải khai báo trong DTD) Enumerated Đại diện cho một sanh sách các giá trị mà thuộc tính có thể d−ợc
gán
ID Tên định danh duy nhất trong tài liệu XML
Bảng 2.2: Các kiểu dữ liệu của thuộc tính
Default_value ý nghĩa
Value Chuỗi giá trị văn bản thô bọc trong cặp dấu nháy
#IMPLIED Chỉ định không có giá trị mặc định cho thuộc tính và thuộc tính này không cần phải dùng đến
#REQUIRED Chỉ định không có giá trị mặc định cho thuộc tính nh−ng phải gán giá trị cho thuộc tính khi sử dụng
#FIXED Value
Value là giá trị bắt buộc, cố định và thuộc tính luôn phải mang giá trị này
Bảng 2.3: Các thiết lập mặc định cho thuộc tính
2.4. Không gian tên của XML. L−ợc đồ XML (XML Schema)[5, 7, 10]
2.4.1. Không gian tên của XML
Vì XML cho phép ta định nghĩa và đặt tên thẻ tuỳ theo mục đích sử dụng nên có khả năng hai ứng dụng khi cần tích hợp với nhau sẽ có chung tên thẻ, lúc đó cần phân biệt không gian tên của các thẻ (để phân biệt tên thẻ thuộc ứng dụng nào).
Không gian tên (namespace) đ−ợc nhận diện qua địa chỉ URL. Để tạo không gian tên cho thẻ, ta đ−a thuộc tính xmlns:prefix=”URL” vào phần tử gốc. Trong đó prefix là bí danh của không gian tên, không gian tên là định danh URLs duy nhất. Sau đó, mọi thành phần khác trong tài liệu đều gắn liền với không gian tên theo cú pháp: <prefix:eName> với thẻ mở và </prefix:eName> với thẻ đóng.
2.4.2. L−ợc đồ XML (XML Schema)
Do tính phức tạp của khai báo DTD mà ng−ời ta đã tìm ra giải pháp khai báo và định nghĩa các phần tử trong tài liệu XML theo l−ợc đồ XML (XML Schema). Tuy không đơn giản hơn định nghĩa DTD nh−ng l−ợc đồ XML tỏ ra mạnh mẽ và chính xác hơn.
Trong phần này ta tìm hiểu về l−ợc đồ XML theo mô hình cài đặt của W3C. (Thực tế, XML là đặc tả mới phát triển sau này nên cài đặt l−ợc đồ đầy đủ nhất là IE của Microsoft. Tuy nhiên IE mới chỉ cài đặt một số đặc tả do W3C qui định)
L−ợc đồ là tài liệu XML thuần văn bản với phần mở rộng .xsd theo cấu trúc sau:
<?xml version=”1.0”?>
<xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema"> ...
</ xsd:schema>
Để có thể sử dụng file l−ợc đồ cho tài liệu XML trong IE, ta tham chiếu đến file l−ợc đồ (filename.xsd) nh− sau:
<? xml version=”1.0”?>
<rootName xmlns=”x-schema: filename.xsd”> ....
</rootName>
Còn W3C cho phép khai báo không gian tên cho tài liệu XML tham chiếu đến file l−ợc đồ (filename.xsd):
<? xml version=”1.0”?> <rootName xmlns=”URL”> ...
a. Khai báo phần tử và kiểu dữ liệu
Có hai kiểu phần tử trong l−ợc đồ XML: kiểu đơn giản (simple types) chỉ chứa dữ liệu đơn giản (chuỗi, số, ngày tháng) và kiểu phức hợp (complex types) chứa phần tử con và thuộc tính.
a1. Tạo kiểu đơn giản
Cú pháp tạo kiểu đơn giản nh− sau:
<xsd:simpleType name=”typeName” base=”xsd:type”> </xsd:simpleType>
Trong đó typeName là tên phần tử có kiểu đơn giản, type là kiểu dữ liệu của phần tử.
Tên kiểu Mô tả
Binary Kiểu dữ liệu nhị phân
Boolean Kiểu logic
Byte Kiểu byte
Century Kiểu thế kỷ
Date Kiểu ngày
Demical Kiểu thập phân Double Kiểu số thực 64 bit ENTITY Kiểu thực thể ENTITIES Kiểu đa thực thể
ID Kiểu định danh
Int, Integer Kiểu số nguyên
IDREF Kiểu tham chiếu định danh NOTATION Kiểu ghi chú
NMTOKEN Kiểu token đơn NMTOKENS Kiểu đa token
Month Kiểu tháng
String Kiểu chuỗi
Bảng 2.4: Các kiểu dữ liệu đơn giản nội tại
a2. Tạo kiểu phức hợp
Kiểu phức hợp trong l−ợc đồ XML đ−ợc chia thành 4 loại:
ắ Phần tử rỗng: phần tử không có nội dung nh−ng có thể chứa thuộc tính. Khai
báo chúng trong l−ợc đồ XML theo cú pháp:
<xsd:element name=”eName”>
<xsd:complexType content=”empty”>
<xsd:element name=”Name” type=”xsd:type”/> ...
</xsd: complexType> </ xsd:element >
ắ Phần tử chứa các phần tử khác và thuộc tính: đây là loại phần tử kiểu phức
hợp cơ bản nhất. Cú pháp khai báo loại phần tử này nh− sau:
<xsd:element name=”eName”> < xsd:complexType>
< xsd:element name=”subName” type=”xsd:type”/. ...
<xsd:attribute name=”attName” type=”xsd:type”/> ...
</ xsd:complexType> </xsd:element>
ắ Phần tử có nội dung hỗn hợp: phần tử này có thể chứa cả văn bản và các
phần tử con. Ví dụ tài liệu XML có nội dung:
<?xml version=”1.0”?> <danhsachCBCNV>
Sau đây lμ danh sách CBCNV trong cơ quan <hoten> Nguyễn Văn A </hoten>
<ngaysinh> 21-10-1954 </ngaysinh> <gioitinh> Nam </gioitinh>
<khoa> CNTT </khoa> </danhsachCBCNV>
Phần tử <danhsachCBCNV> chứa nội dung hỗn hợp bao gồm cả văn bản lẫn phần tử con. Trong t−ờng hợp này ta dùng cú pháp sau để khai báo:
<xsd:element name=”eName”>
< xsd:complexType content=”mixed”>
< xsd:element name=”subName” type=”xsd:type”/. ...
<xsd:attribute name=”attName” type=”xsd:type”/> ...
</ xsd:complexType> </xsd:element>
ắ Phần tử chứa văn bản thuần text phi định dạng: các phần tử có nội dung kiểu
đơn giản th−ờng là kiểu phần tử này.
b. Tạo sự lựa chọn và khai báo tuần tự
Trong khai báo DTD ta thấy xuất hiện ký tự ⏐ cho sự lựa chọn và sự xuất hiện tuần tự cùng các ký tự đại diện *, ?, + cho số l−ợng xuất hiện các phần tử. Vậy chúng đ−ợc thay thể nh− thế nào trong l−ợc đồ?
b1. Tạo sự lựa chọn
Trong l−ợc đồ XML, để tạo sự lựa chọn ta dùng khai báo:
<xsd:choice>
<xsd:element name=”eName” type=”xsd:type”/> < xsd:element name=”eName” type=”xsd:type”/> ...
</ xsd:choice>
b2. Tạo khai báo tuần tự
Giả sử a, b, c, d là các phần tử trong tài liệu XML. Sự xuất hiện của chúng cũng nh− số l−ợng xuất hiện trong biểu thức DTD là (a, b?, (c⏐d)+) đ−ợc diễn đạt trong l−ợc đồ nh− sau:
<xsd:sequence>
<xsd:element name=”a”/>
<xsd:element name=”b” minOccurs=”0” maxOccurs=”1”/> <xsd:choice minOccurs=”1”>
<xsd:element name=”c”/> <xsd:element name=”d”/> </ xsd:choice>
Bây giờ quay lại file data.dtd và file danhsach.xml tại mục 3.2. Khi đó ta xây dựng file data.xsd t−ơng ứng với data.dtd nh− sau:
<?xml version=”1.0”?> <xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <xsd:element name=”danhsachCBCNV” <xsd:complexType> <xsd:sequence minOccurs=”0”>
<xsd:element name=”canbo” type=”canbo”/> </xsd:sequence>
</xsd:complexType> </xsd:element>
<xsd:complexType name=”canbo”> <xsd:sequence>
<xsd:element name=”hoten” type=”xsd:String”/> <xsd:element name=”ngaysinh” type=”xsd:Date”/> <xsd:element name=”gioitinh” type=”xsd:String”/> <xsd:choice>
<xsd:element name=”khoa” type=”xsd:String”/> <xsd:element name=”phong” type=”xsd:String”/> </xsd:choice>
</xsd:sequence> </xsd:complexType> </xsd:schema>
So sánh DTD và XML Schema:
ắ Cả DTD và XML Schema đều thực hiện nhiều vai trò khác nhau trong một ứng dụng XML nh−: làm tài liệu, kiểm tra tính hợp lệ, soạn thảo và sinh mã.
ắ Đặc tả DTD gần nh− là một tập con của chuẩn SGML tr−ớc đó, bao gồm cả những giới hạn của nó. Các DTD không thể dễ dàng kết hợp với không gian tên và tiềm năng kiểu dữ liệu bị hạn chế. Mặt khác, các DTD dễ dàng để phát triển các ứng dụng nhỏ và đ−ợc trợ giúp bởi nhiều công cụ phần mềm.
ắ XML Schema bao gồm ngôn ngữ định nghĩa kiểu dữ liệu phong phú, cải thiện sự chính xác của định nghĩa từ vựng và tính hợp lệ của tài liệu. Cả giá trị thuộc tính và nội dung phần tử XML đều có thể đ−ợc kiểm tra tính hợp lệ theo cùng một kiểu định nghĩa kiểu dữ liệu.
ắ XML Schema cho phép định nghĩa kiểu đơn giản và kiểu phức hợp. Khả năng này cung cấp sự phù hợp khái niệm với tính kế thừa của các lớp trong UML tốt hơn khả năng của DTD.
2.5. Bảng định kiểu CSS (Cascading Style Sheet) [5, 7, 10]
CSS là mô hình định nghĩa kiểu định dạng dùng cho việc hiển thị tài liệu. CSS cho phép hiển thị tài liệu XML nh− các trang HTML và cho phép tách rời định dạng với nội dung tài liệu. CSS t−ơng tự một tập mẫu qui định các kiểu định dạng cho các thẻ trong tài liệu. Nó qui định kiểu nh− màu sắc, font, cỡ, lề,...Tài liệu đ−ợc