Một tài liệu XML với đặc tính có khả năng mở rộng, cho phép chính tác giả tự định nghĩa các elements, attributes và các quy định khác trong tài liệu XML.
Bằng cách nào để đưa ra các mô tả chính xác định dạng tài liệu XML cho đối tác hoặc các ứng dụng có thể xác minh dữ liệu bên trong? Để giải quyết vấn đề, khái niệm về document type definition (DTD) được đưa ra.
Document Type Definition (DTD)
DTD là gì?
Document type definition (DTD) là một tập hợp các khai báo để mô tả ràng buộc các tài liệu được viết bằng ngôn ngữ đánh dấu như SGML, XML, HTML.
Tạo và sử dụng DTD
Cấu trúc của một DTD bao gồm 3 phần
- Element Declarations: khai báo tên và nội dung của
element
. - Attribute Declarations: khai báo
attribute
này thuộcelement
nào, tên gọi, kiểu dữ liệu và giá trị mặc định củaattribute
. - Entity Declarations: khai báo tên, giá trị và vị trí của
entity
.
DTD có 2 dạng tùy thuộc vào vị trí đặt DTD
- Dạng 1: đặt ngay bên trong tài liệu XML (internal).
- Dạng 2: đặt tại một file riêng có địng dạng
*.dtd
(external).
Các dạng khai báo cơ bản trong DTD
Khai báo element
Element
rỗng:<!ELEMENT element-name EMPTY>
Element
chứa dữ liệu dạngPCDATA
:<!ELEMENT element-name (#PCDATA)>
Element
dạng bất kì:<!ELEMENT element-name ANY>
Element
có các thẻ con, theo thứ tự:<!ELEMENT element-name(child1, child2, …)>
Một số kí hiệu mô tả số lần xuất hiện của element:
- Tên
element
đứng 1 mình (element
): chỉ xuất hiện 1 lần. - Dấu
+
(element+
): xuất hiện nhiều lần (1..n). - Dấu
*
(element*
): xuất hiện nhiều lần (0..n). - Dấu
?
(element?
): xuất hiện nhiều lần (0..1).
Khai báo attribute
Khai báo 1 attribute
theo cú pháp:
<!ATTLIST element-name attribute-name attribute-type default-value>
Khai báo Entity
<!ENTITY entity-name value>
Trong bài viết này sẽ từng bước phân tích và xây dựng DTD (internal) cho tài liệu XML sau:
<?xml version="1.0" encoding="UTF-8"?> <channel> <name><![CDATA[ C/C++ ]]></name> <article author="Kevin La" > <title><![CDATA[ C++11 - OOP - override ]]></title> <link>http://www.stdio.vn/articles/read/58-c11-oop-override</link> <description><![CDATA[ <p>Giao cho máy móc giúp con người kiểm tra chặt chẽ để giảm rủi ro cho phần mềm là một ý tưởng hay, vì máy móc sẽ luôn làm theo nguyên tắc mà nó được con người định ra. Ở C++11, cũng đưa ra thêm khái niệm về <span class="article_code">override</span> để giúp lập trình viên kiểm soát các sơ sót trong override.</p> ]]></description> <copyright>&stdio; </copyright> </article> <article author="Kevin La" editor="Larige Thai" > <title> <![CDATA[ C++11 - nullptr ]]> </title> <link>http://www.stdio.vn/articles/read/57-c11-nullptr</link> <description><![CDATA[ <p>Thông thường ta sử dụng <span class="article_code">NULL</span> để đánh dấu cho một con trỏ đang "không trỏ tới đâu cả", và bên dưới của <span class="article_code">NULL</span> chính là giá trị <span class="article_code">0</span>. Ở C++11 chúng ta có thêm một lựa chọn mới đó là <span class="article_code">nullptr</span>.</p> ]]></description> <copyright> &stdio; </copyright> </article> …. </channel>
PHÂN TÍCH TÀI LIỆU XML
Root element: channel
Trong root element
:
- 1
element name
- Ít nhất 1
element article
.- Trong
element article
có 2attribute author
(bắt buộc) vàeditor
(có thể có). - Ngoài ra
element
này còn bao gồm cácelement
con theo thứ tự:title
,link
,description
,copyright
.
- Trong
Entity
thường xuyên xuất hiện trong tài liệu là “http://www.stdio.vn/
”.
XÂY DỰNG DTD
Dựa vào phần phân tích có thể dễ dàng xây dựng DTD của tài liệu XML trong ví dụ trên như sau:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE channel[ <!ELEMENT channel (name,article*)> <!ELEMENT name (CDATA)> <!ELEMENT article (title, link, description, copyright)> <!ELEMENT title (CDATA)> <!ELEMENT link (#PCDATA) > <!ELEMENT description (CDATA)> <!ELEMENT copyright (#PCDATA) > <!ATTLIST article author CDATA #REQUIRED> <!ATTLIST article editor CDATA #IMPLIED> <!ENTITY stdio "http://www.stdio.vn/"> ]> <channel> <name><![CDATA[ C/C++ ]]></name> <article author="Kevin La" > <title><![CDATA[ C++11 - OOP - override ]]></title> <link>http://www.stdio.vn/articles/read/58-c11-oop-override</link> <description><![CDATA[ <p>Giao cho máy móc giúp con người kiểm tra chặt chẽ để giảm rủi ro cho phần mềm là một ý tưởng hay, vì máy móc sẽ luôn làm theo nguyên tắc mà nó được con người định ra. Ở C++11, cũng đưa ra thêm khái niệm về <span class="article_code">override</span> để giúp lập trình viên kiểm soát các sơ sót trong override.</p> ]]></description> <copyright>&stdio; </copyright> </article> <article author="Kevin La" editor="Larige Thai" > <title> <![CDATA[ C++11 - nullptr ]]> </title> <link>http://www.stdio.vn/articles/read/57-c11-nullptr</link> <description><![CDATA[ <p>Thông thường ta sử dụng <span class="article_code">NULL</span> để đánh dấu cho một con trỏ đang "không trỏ tới đâu cả", và bên dưới của <span class="article_code">NULL</span> chính là giá trị <span class="article_code">0</span>. Ở C++11 chúng ta có thêm một lựa chọn mới đó là <span class="article_code">nullptr</span>.</p> ]]></description> <copyright> &stdio; </copyright> </article> …. </channel>
DTD trong ví dụ được khai báo ở dạng internal nên tất cả khai báo đều phải đặt trong thẻ <!DOCTYPE >
.