前面介紹了XML的作用和基本的格式,今天我給大家分享的是關於XML的約束。廢話不多說,我們直接來正題!
一、DTD簡介
1.1、DTD概述
DTD(Document Type Definition,文檔類型定義)
1)DTD是一套關於標記符的語法規則。它是XML1.0版規格的一部分,是XML文件的驗證機制,屬於XML文件組成的一部分。
2)XML文件提供應用程序一個數據交換的格式,DTD正是讓XML文件能夠成為數據交換的標准,因為不同的公司只需定義好標准的DTD,
各公司都能夠依照DTD建立XML文件,並且進行驗證,如此就可以輕易的建立標准和交換數據,這樣滿足了網絡共享和數據交互。
4)DTD中的所有約束都是針對 與某個標簽的子標簽進行約束的
注意:除了DTD約束,其實還有其他的約束。Schema(模式)約束:用xml寫的文件,然后用來約束xml文件
1.2、DTD的目的
驗證XML文檔是不是一個有效的XML文檔。
有效:如果一個良構的XML文檔滿足了dtd的聲明,就是一個有效的XML文檔。
有效一定良構,良構不一定有效。
1.3、XML文檔引入DTD的方式
1)引入內部DTD
<!DOCTYPE 根元素[ DTD驗證規則/實體定義... ]>
2)引入外部DTD
當引用的文件在本地時:<!DOCTYPE 根元素 SYSTEM "DTD文件路徑">
當引用文件是一個公共文件(DTD文件存在於遠程服務器上)時:<!DOCTYPE 根元素 PUBLIC "DTD名稱" "DTD文件的URL">
1.4、DTD約束原理
注:通過DTD約束,XML就能在DTD的約束下進行自定義了,不過DTD有個缺點,那就是不能對數據進行數值約束這種范圍約束。
二、DTD的分類
2.1、內部DTD
DTD代碼與XML代碼在同一個文件中
例如:帶有DTD的XML文檔實例

<?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note>
分析:
!DOCTYPE note (第二行)定義此文檔是 note 類型的文檔。
!ELEMENT note (第三行)定義 note 元素有四個元素:"to、from、heading,、body"
!ELEMENT to (第四行)定義 to 元素為 "#PCDATA" 類型
!ELEMENT from (第五行)定義 frome 元素為 "#PCDATA" 類型
!ELEMENT heading (第六行)定義 heading 元素為 "#PCDATA" 類型
!ELEMENT body (第七行)定義 body 元素為 "#PCDATA" 類型
2.2、外部DTD
DTD約束與xml文檔不在同一個文件中,XML文檔需引入外部DTD文件
例如:外部DTD實例,需要將DTD文件引入到XML文件中

<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
note.dtd文件的內容

<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
2.3、混合DTD
既有外部DTD,又有內部DTD
三、DTD在元素中的聲明
3.1、元素約束
格式:<!ELEMENT 元素名 (內容模式)> 同一元素不允許出現兩次聲明
1)內容模式:可以對元素內容進行約束也可以對元素中的子元素進行約束,大小寫敏感,內容模式的括號有意義
1.1)(#PCDATA) :元素內容為任何字符或者空,但不允許有子元素, 不可省略()
1.2)EMPTY :元素內容為空,不允許有任何文本數據(包括空格換行)與子元素,可以有屬性,不可加()
1.3)ANY :元素可以包含任何數據,包括文本數據和子元素,不可加()

<!--1.EMPTY:指的是該標簽中不能有其他任何的子標簽--> <!-- <!ELEMENT students EMPTY> --> <!-- 2.(#PCDATA:表示在該標簽中只能出現字符內容,不能出現任何的標簽) --> <!-- <!ELEMENT students (#PCDATA)> --> <!--3.ANY:表示在該標簽中可以出現任何數據 --> <!-- <!ELEMENT students ANY> --> <students> </students>
1.4)(childElements) 由內容模式部件指定:“, | ? + *”
對內部子元素進行約束,均不能添加其他子元素以及文本(可以空格換行)
“,”:表示指定子元素必須順序出現,不多不少
例如:<!ELEMENT EleName (a,b,c)>
解讀:<!-- 表示a、b、c三個元素按照順序並且每個只能出現一次 -->
“|”:表示在指定的多個子元素中選擇出現1個,只能1次
例如:<!ELEMENT EleName (a|b|c)>
解讀:<!-- 表示a、b、c三個元素任選其一只能出現一次 -->
“ ”:元素必須且只能出現一次
例如:<!ELEMENT EleName (a)>
解讀:<!-- 表示a必須出現並且只能出現一次 -->
“?”:指定元素要出現0次或1次
例如:<!ELEMENT EleName (a)?>
解讀:<!-- 表示a能夠出現0次或1次 -->
“+”:指定元素要出現1次或多次
例如:<!ELEMENT EleName (a)+>
解讀:<!-- 表示a能夠出現1次或多次 -->
“*”:指定元素要出現0次或多次
例如:<!ELEMENT EleName (a)*>
解讀:<!-- 表示a能夠出現0次或多次 -->
2)混合模式(Mixed)
元素中既可有文本數據又可有子元素
<!ELEMENT EleName (#PCDATA|a|b)*>
表示元素中即可以有字符又可以有指定元素,字符數據與指定元素可以出現任意次數,順序不限。
注意:優先寫#PCDATA,如(#PCDATA|a)*正確,(a|#PCDATA)*錯誤。
瀏覽器是非驗證解析器,不會校驗xml文檔的有效性。
3.2、屬性約束
1)語法:
<!ATTLIST 元素名 屬性名 屬性類型 屬性默認值
屬性名 屬性類型 屬性默認值
......
>
2)屬性類型
ID 屬性值唯一,且屬性值必須符合命名規則——不能以數字開頭
(v1|v2|v3) 枚舉,屬性值從中選擇一個
CDATA 屬性值為字符
3)屬性默認值
#REQUIRED 屬性必須出現,屬性值沒有限制
#IMPLIED 屬性值可以出現可以不出現
attribute_vlaue 屬性類型后跟屬性值,表示屬性如果不出現,則屬性值為默認的attribute_value
#FIXED value #FIXED value表示屬性可出現可不出現,顯示出現則屬性值必須為指定的value,不出現,則值默認value
注:ID屬性類型只能使用#REQUIRED或#IMPLIED;枚舉類型后跟默認值必須為匹配值之一
四、DTD文檔的實例
4.1、內嵌

<!DOCTYPE 根元素[ <!ENTITY 實體名 "實體內容"> <!ELEMENT 元素名 (內部模式)> <!ATTLIST 元素名 屬性名 屬性類型 屬性默認值/屬性特點 屬性名 屬性類型 屬性默認值/屬性特點 ... > ]>
4.2、外部引用

<!DOCTYPE 根元素 SYSTEM "dtd文件路徑"> <!DOCTYPE 根元素 PUBLIC "dtd文件的描述信息" "dtd的url">
4.3、內嵌與外部引用同時使用

<!DOCTYPE 根元素 SYSTEM "dtd文件路徑" [ <!ENTITY 實體名 "實體內容"> <!ELEMENT 元素名 (內部模式)> <!ATTLIST 元素名 屬性名 屬性類型 屬性默認值 屬性名 屬性類型 屬性默認值 ... > ]>
一個實例:班級約束
XMLClass.dtd

<!ENTITY % sex "男|女"> <!ELEMENT 班級 (學生+,作者)> <!ATTLIST 班級 班次 CDATA "1班" 編號 ID #REQUIRED > <!ELEMENT 學生 (名字,年齡,介紹)> <!ELEMENT 作者 (#PCDATA)> <!ATTLIST 學生 地址 CDATA #IMPLIED 授課方式 CDATA #FIXED "面授" 學號 ID #REQUIRED 班級編號 IDREF #REQUIRED 朋友 IDREFS #IMPLIED 性別 (%sex;) #REQUIRED > <!ELEMENT 名字 (#PCDATA)> <!ELEMENT 年齡 (#PCDATA)> <!ELEMENT 介紹 (#PCDATA)>
XMLtest.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- 引入DTD --> <!DOCTYPE 班級 SYSTEM "XMLClass.dtd" [<!ENTITY writer "Switch">]> <班級 編號="C1" 班次="1班"> <學生 地址="湖南" 授課方式="面授" 學號="n1" 班級編號="C1" 朋友="n2" 性別="男"> <名字>張三</名字> <年齡>20</年齡> <介紹>不錯</介紹> </學生> <學生 授課方式="面授" 學號="n2" 班級編號="C1" 朋友="n1 n3" 性別="女"> <名字>李四</名字> <年齡>18</年齡> <介紹>很好</介紹> </學生> <學生 授課方式="面授" 學號="n3" 班級編號="C1" 朋友="n2" 性別="男"> <名字>王五</名字> <年齡>22</年齡> <介紹>非常好</介紹> </學生> <作者>&writer;</作者> </班級>
覺得不錯的點個推薦“”哦!