在XML中使用DTD
使用DTD知識總結
DTD介紹
- DTD( Document Type Definition)文件型別定義。在XML標準中,描述瞭如何建立DTD,以及如何將它與根據它的規則所編寫的XML文件相關聯,並且還定義了XML處理器應該如何對DTD進行處理,有了DTD就可以檢測XML文件的結構是否正確。
- DTD在實際應用中的作用主要包括:
- 可以驗證XML文件資料的有效性
- 可以為某類XML文件提供統一的格式和相同的結構
- 可以保證在一定範圍內,XML文件資料的交流和共享
- 一個程式設計人員根據DTD就能夠知道對應的XML文件邏輯結構,從而編寫出相應的處理應用程式。
- 第一個DTD例子:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 根元素名稱 [ <!ELEMENT 根元素名稱(第一個子元素, 第二個子元素)> <!ELEMENT 第一個子元素(#PCDATA)> <!ELEMENT 第二個子元素(#PCDATA)> <!ATTLIST 第一個子元素 屬性一 CDATA #REQUIRED> ]> <根元素名稱> <第一個子元素 屬性一="任意內容"> 文字內容1 </第一個子元素> <第二個子元素> 文字內容1 </第二個子元素> </根元素名稱>
DTD的基本語法
- DTD內部可以包含下列語句:
- 元素型別宣告語句<!ELEMENT ......>
- 屬性列表宣告語句<!ATTLIST ......>
- 實體宣告語句<!ENTITY .......>
- 符號宣告語句<!NOTATION ......>
- 註釋語句
- 一個DTA即可以是獨立的文件,該文件的副檔名為.dtd。DTD也可以存在於文件內部,如果存在於XML文件內部,則DTD的內容放置於
- 例如:demodtd.dtd如下:
<?xml version="1.0" encoding="UTF-8" ?> <!-- root元素中包含了兩個子元素 --!> <!ELEMENT root (sub1, sub2)> <!ELEMENT sub1(#PCDATA)> <!ELEMENT sub2(#PCDATA)> <!ATTLIST root param1 NOTATION(Jpeg | Png) # REQUIRED param2 CDATA # IMPLIED> <!ENTITY NAME "ENTITY VALUE"> <!NOTATION Jpeg SYSTEM "Image/jpeg"> <!NOTATION Png SYSTEM "Image/png">
引入在XML文件中,程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYE root SYSTEM "demodtd.dtd">
<root param1 = "Jpeg">
<sub1>&NAME;</sub1>
<sub2>any word </sub2>
</root>
直接內置於XML文件中時,程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!--root元素中包含了2個子元素-->
<!ELEMENT root (sub1,sub2)>
<!ELEMENT sub1 (#PCDATA)>
<!ELEMENT sub2 (#PCDATA)>
<!ATTLIST root param1 CDATA #REQUIRED
param2 CDATA #IMPLIED>
<!ENTITY NAME1 "ENTITY VALUE">
<!ENTITY PIC SYSTEM "Sunset.jpg" NDATA jpr>
<!NOTATION jpr SYSTEM "mspaint.exe">
]>
<root param1="PIC">
<sub1>&NAME1;</sub1>
<sub2>any word</sub2>
</root>
引入DTD的方式
- 外部DTD
外部DTD的引用須事先已有一個dtd檔案,將DTD的約束寫到檔案中,然後在XML文件中按以下語法格式新增:
<!DOCTYPE (根元素名稱) SYSTEM "外部DTD的URL地址">
SYSTEM關鍵字表示文件使用的是私有DTD檔案,“外部DTD檔案的URI”可以是相對URI或者絕對URI,相對URI是相對於文件型別宣告所在文件的位置。“外部DTD檔案的URI”這部分也被稱為系統識別符號(system identifier). - 內部DTD
使用DTD的最簡單的方式,內部DTD就是指將語義約束與XML文件的內容放在同一個XML文件中。緊跟在XML宣告和處理指令之後,以<!DOCTYPE[開始,以]>結束語法格式如下:
<!DOCTYPE 根元素名稱 [ 元素描述 ]>
- 公用DTD
公用DTD與外部DTD類似,但是該DTD引用公用的DTD的語法格式如下:
<!DOCTYPE (根元素名稱) PUBLIC "DTD的標識名" "公用DTD的URL地址">
公共DTD名稱要遵循一些約定。如果一項DTD是ISO標準,它的名字要以字串“ISO”開始,如果是一個非ISO的標準組織批准的DTD,它的名字以“+”開始。如果不是標準組織批准的DTD,它的名字以連字元“-”開始。這些開始字元或字串後面接//和DTD所有者的名字,之後是另一個雙斜槓和DTD描述的文件型別,接著又是一個雙斜槓後接ISO 639語言識別符號,如EN表示英語,ZH表示中文。
例如:
-
自定義的dtd
//tanglin //DTD STUDENT1.0/ZH
<!DOCTYPE HR PUBLIC "//tanglin //DTD STUDENT1.0/ZH " "http://city.dlut.edu.cn/xml/dtds/students.dtd">
-
HTML網頁的文件型別宣告
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
DTD中的元素
- 元素定義語法
語法如下所示:
<!ELEMENT 元素名 元素型別描述>
語法詳細說明:
- 元素名:即文件中元素的名稱。
- 元素型別描述:元素型別描述用於指定元素本身是否為對空元素,如果不為空元素元素的內容包括哪些。
- 元素型別
元素型別具體包括以下5類:
-
字串型別:即#PCDATA,表示該元素的內容只能是字串。
-
空元素:EMPTY,表示該元素只能是空元素。
-
包含子元素:表示該元素內部巢狀其它元素,具體包含子元素可能有:有序子元素、無序互斥子元素、無序組合子元素。子元素出現的次數也會根據實際的定義而不同。
-
混合型別:即內容中即包括字串型別又包括子元素,但混合型別在實際應用中不建議使用。
-
任意型別:即ANY,表示該標記對於元素內容沒有限制,該標記的內容可以是字串型別、也可以包含子元素、即包含字串又包括自元素的混合型別、該標記也可以是空元素。在實際應用中儘量避免。
-
子元素如下:
- 有序子元素
用逗號分隔,表示子元素的出現順序必須與宣告時一致,並且不能被省略。 - 無序互斥子元素
用豎線(|)分隔,表示任選其一,即多個子元素在文件定義中只能出現一個。 - 無序組合子元素
子元素出現頻率可以根據不同的符號進行設定這些符號的含義如表2-2所示:
子元素出現頻率符號及其含義
修飾符 含義
+ 一次或多次
? 0次或一次
* 0次或多次
預設 一次
這些修飾符可以限制元素出現的次數,也可以結合圓括號( )批量設定
- 混合型別
混合型別定義的子元素即可以包含字串又可以包含子元素,其定義方法稍微複雜一些,典型的混合型別定義方法形如<!ELEMENT root (#PCDATA|sub1|sub2)*>。但在實際用該型別使用較少,也不建議使用。
- DTD中的屬性
在DTD中宣告元素屬性的語法:
<!ATTLIST 元素名稱 [屬性名 屬性型別 [約束] [預設值]]+>
在一個ATTLIST 中可以定義同一個元素下的一個或多個屬性。如果包含多個屬性宣告,屬性宣告之間使用空格間隔。
- 元素名稱:屬性所屬的元素名稱
- 屬性名:屬性名稱
- 屬性型別:屬性的值型別,
- 約束:元素對屬性的約束
修飾符 | 含義 |
---|---|
#REQUIRED | 表示該屬性是必需的,不能沒有 |
#IMPLIED | 表示該屬性可以有也可以沒有 |
#FIXED | 表示在XML文件中只會給出一個元素屬性所定義的固定值。只有當約束為該值時,才能給出預設值,注意預設值必須給出 |
- 定義示例:
<? xml version="1.0" encoding="UTF-8"?>
<! DOCTYPE root[
<!ELEMENT root (#PCDATA)>
<!ATTLIST root reqParam CDATA #REQUIRED>
<!ATTLIST root impParam CDATA #IMPLIED
fixParam CDATA #FIXED "default value">
]>
<root reqParam = "required value">
</root>
- DTD中的ENTITY實體
- ENTITY 實體,在一個甚至多個XML文件中頻繁使用某一條資料,我們可以預先定義一個這條資料的“別名”,即一個ENTITY,然後在這些文件中需要該資料的地方呼叫它。
- 實體分類關係圖
-
通用內部解析實體
內部實體是最簡單的一種實體,該實體的內容為字串的文字內容。所有的內部實體都是解析實體。內部實體的語法格式如下:<!ENTITY 實體名稱 "實體內容">
例如:
<!ENTITY one "one">
<!ENTITY two "&one; I am two">
- 實體名稱:實體名稱由DTD程式設計師自己定義,但必須滿足唯一性,即不能重名。同時滿足XML的命名規範。
- 實體內容:所需要表達的文字內容。
-
通用外部解析實體
定義外部解析實體的語法如下:
<!ENTITY 實體名稱 SYSTEM|PUBLIC ["公共實體識別符號"] "URI/URL">
- URI/URL:所引用的外部檔案的路徑地址,被引用的外部檔案必須是可以被解析的,副檔名沒有限制。
- 實體為PUBLIC時才會有相應的“公共實體識別符號” ,如果為SYSTEM則沒有“公共實體識別符號”.
例項如下:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE aa[ <!ELEMENT aa (#PCDATA)> <!ELEMENT copyright SYSTEM "outer.txt"> ]> <aa>©right; </aa>
-
通用外部未解析實體:
<!ENTITY 實體名稱 SYSTEM “URL/URL” NDATA 標記名>
URI/URL:所引用的外部檔案的路徑地址
標記名:被定義的符號的名稱。
例項程式碼:
<!ENTITY PICTURE SYSTEM 'pic.jpg' NDATA msp>
-
引數內部解析實體
引數實體和普通實體只能在XML文件中引用,如果需要在DTD中使用實體則必須使用引數實體
宣告引數內部解析實體的語法:
<!ENTITY % 引數實體名稱 "實體內容">
引數實體名稱:實體名稱由DTD程式設計師自己定義,但必須滿足唯一性,即不能重名。同時滿足XML的命名規範。
實體內容:所需要表達的文字內容。 -
引數外部解析實體
宣告引數外部解析實體的語法:
<!ENTITY % 引數實體名稱 SYSTEM “URL/URL”>
URI/URL:所引用的外部檔案的路徑地址
引用引數實體的語法:
%引數實體名稱;
-
- DTD符號
普通符號的語法格式:
<!NOTATION 符號名稱 SYSTEM | PUBLIC ["公共符號識別符號"] "URI\URL">
- 符號名稱:名稱由DTD程式設計師自己定義,但必須滿足唯一性,即不能重名。同時滿足XML的命名規範
- URI\URL:外部來處理這些未解析資料的程式路徑
- 符號為PUBLIC時才會有相應的“公共符號識別符號” ,如果為SYSTEM則沒有“公共符號識別符號”
DTD定義格式缺點
- DTD本身是基於正則表示式的,描述能力相對較弱。
- DTD不支援資料型別,對資料的約束不夠準確。
- DTD約束能力不足,無法對語義作出更精細的語義限制。
- DTD的結構不夠好,可重用性較差。