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
attributenày thuộcelementnà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
Elementrỗng:<!ELEMENT element-name EMPTY>Elementchứa dữ liệu dạngPCDATA:<!ELEMENT element-name (#PCDATA)>Elementdạng bất kì:<!ELEMENT element-name ANY>Elementcó 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.iostream.co/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.iostream.co/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: channelTrong root element:
- 1
element name - Ít nhất 1
element article.- Trong
element articlecó 2attribute author(bắt buộc) vàeditor(có thể có). - Ngoài ra
elementnày còn bao gồm cácelementcon 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.iostream.co/”.
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.iostream.co/"> ]> <channel> <name><![CDATA[ C/C++ ]]></name> <article author="Kevin La" > <title><![CDATA[ C++11 - OOP - override ]]></title> <link>http://www.iostream.co/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.iostream.co/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 >.