什么是約束?
在XML技術(shù)里平绩,可以編寫一個文檔來約束一個XML文檔的書寫規(guī)范圈匆,這就是XML約束。約束定義了文檔的結(jié)構(gòu)捏雌,在某種程度上跃赚,也說明了如何在文檔結(jié)構(gòu)中放置數(shù)據(jù)。事實(shí)上性湿,如果用XML作為數(shù)據(jù)的呈現(xiàn)纬傲,文檔就無法與約束相脫離。
約束一般有兩種:DTD和Schema肤频,這里先介紹DTD叹括。
DTD簡介
DTD(Document Type Definition),全稱為文本類型定義着裹,用于定義合法的XML文檔構(gòu)建模塊领猾。
先寫一個簡單的關(guān)于書本信息的XML文檔:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id=“01”>
<name>三體</name>
<author>劉慈欣</author>
<price>23.8</price>
</book>
<book id=“02”>
<name>龍族</name>
<author>江南</author>
<price>19.6</price>
</book>
</books>
DTD元素聲明
在DTD中,XML中的元素要通過元素聲明來聲明骇扇,語法為:
<!ELEMENT 元素名稱 (元素內(nèi)容)>
或:
<!ELEMENT 元素名稱 類別>
下面是四種不同的元素:
-
空元素:語法為:
<!ELEMENT 元素名稱 EMPTY>
例如一個元素為<title></title>
(也可以寫成<title />
)摔竿,則在DTD中它的聲明為<!ELEMENT title EMPTY>
。
-
帶有子元素的元素:語法為:
<!ELEMENT 元素名稱 (子元素名稱)>
或:
<!ELEMENT 元素名稱 (子元素名稱1,子元素名稱2,...)>
以上面的XML文檔為例少孝,在DTD中继低,book
元素的聲明應(yīng)為<!ELEMENT book (name,author,price)>
。需要注意的是稍走,當(dāng)元素?fù)碛卸鄠€子元素時袁翁,這些子元素必須按照由逗號分隔開的序列進(jìn)行聲明并且按照相同的順序出現(xiàn)在XML文檔中。
-
內(nèi)容為文本類型的元素:語法為:
<!ELEMENT 元素名稱 (#PCDATA)>
例如婿脸,name
元素的聲明應(yīng)為<!ELEMENT name (#PCDATA)>
粱胜。
-
帶有任何內(nèi)容的元素:語法為:
<!ELEMENT 元素名稱 ANY>
此外,對于不同的元素內(nèi)容狐树,DTD也規(guī)定了不同的元素聲明(這里的元素內(nèi)容是針對子元素來說的焙压,而聲明都是對父元素的聲明):
-
子元素只出現(xiàn)一次:語法為:
<!ELEMENT 元素名稱 (子元素名稱)>
例如,如果想要聲明book
元素抑钟,則應(yīng)為<!ELEMENT book (name)>
涯曲。需要注意的是,這里的name
必須是book
元素的唯一子元素在塔,而且只能出現(xiàn)一次幻件。當(dāng)然如果子元素有多個且都僅出現(xiàn)一次,就要寫成<!ELEMENT 元素名稱 (子元素名稱1,子元素名稱2,...)>
蛔溃。
-
子元素出現(xiàn)零次或一次:語法為:
<!ELEMENT 元素名稱 (子元素名稱?)>
-
子元素出現(xiàn)零次或多次:語法為:
<!ELEMENT 元素名稱 (子元素名稱*)>
-
子元素出現(xiàn)一次或多次:語法為:
<!ELEMENT 元素名稱 (子元素名稱+)>
-
子元素為多選一類型:語法為:
<!ELEMENT 元素名稱 (子元素名稱1|元素名稱2|子元素名稱3|...)>
例如绰沥,book
的子元素有三種可能篱蝇,即name
、author
以及price
揪利,這時聲明應(yīng)為<!ELEMENT book (name|author|price)>
态兴,即各個子元素之間用豎線隔開。這里則不需要遵循子元素出現(xiàn)的順序來寫聲明疟位,只需包含所有可能出現(xiàn)的子元素即可(也可以添加一些不可能出現(xiàn)的元素瞻润,當(dāng)然這樣寫并沒有必要)。
-
多種類型的子元素混合:舉個例子:
<!ELEMENT book (name,author?,(price|press|date)*)>
這個聲明的含義為:book
元素包含只出現(xiàn)一次的name
子元素甜刻、出現(xiàn)零次或一次的author
子元素以及出現(xiàn)零次或多次的price
绍撞、press
、date
三個子元素中的一個得院。
PS:對于?
傻铣、*
以及+
這三個符號的含義,可以類比于正則表達(dá)式進(jìn)行記憶祥绞。
DTD屬性聲明
介紹完了元素聲明非洲,下面介紹屬性聲明。最基本的語法為:
<!ATTLIST 元素名稱 屬性名稱 屬性類型 默認(rèn)值>
下面是W3C對于屬性類型和默認(rèn)值的規(guī)定:
舉個例子蜕径,如果一個DTD對于元素和屬性的聲明為:
<!ELEMENT frame EMPTY>
<!ATTLIST frame height CDATA "100">
<!ATTLIST frame width CDATA "80">
則一個正確XML實(shí)例應(yīng)為<frame height="200" width="100" />
两踏,frame
為含有CDATA
類型的height
屬性和CDATA
類型的width
屬性的空元素。如果height
和 width
沒有被設(shè)定兜喻,則100
和80
分別是它們的默認(rèn)值 梦染。
#REQUIRED
和#IMPLIED
這兩者是相對的,在沒有默認(rèn)值的情況下朴皆,前者強(qiáng)制作者為元素添加屬性帕识,而后者則不作要求。
#FIXED "value"
則固定了屬性的值遂铡,并不允許被更改肮疗。例如,<!ATTLIST frame width CDATA "150">
表明frame
元素的width
屬性被強(qiáng)制設(shè)置成150
扒接。
以上文的XML文檔為例伪货,對于book
元素,為了避免混淆珠增,使元素含有id
屬性,用數(shù)字來區(qū)分每一本書蒂教,并且這個屬性是不可少的,因此需要屬性聲明為<!ATTLIST book id CDATA #REQUIRED>
脆荷。
此外懊悯,如果屬性的值可能出現(xiàn)多種情況,類似于上面介紹過的屬性聲明炭分,用豎線隔開各個可能的值:
<!ATTLIST 元素名稱 屬性名稱 (值1|值2|值3|...) 默認(rèn)值>
DTD實(shí)體
前面的元素和屬性都是XML中有的概念,大家就比較熟悉剑肯,可實(shí)體是個新概念,它是什么呢让网?實(shí)體是用于定義引用普通文本或特殊字符的快捷方式的變量。簡單地說溃睹,實(shí)體就是能代表一段字符,只要預(yù)先設(shè)置好實(shí)體代表哪段字符因篇,就可以在文檔中直接引用這個實(shí)體而不用輸入這段字符了泞辐,類似于C語言中宏定義的常量。因此竞滓,說到實(shí)體就要介紹實(shí)體聲明和實(shí)體引用咐吼。
實(shí)體聲明
語法為:
<!ENTITY 實(shí)體名稱 "實(shí)體的值">
實(shí)體引用
語法為:
&實(shí)體名稱;
需要注意的是,實(shí)體聲明中實(shí)體的值應(yīng)被引號(單引號或雙引號)包圍虽界,而實(shí)體引用應(yīng)包含開頭的&
和結(jié)尾的;
汽烦。
例如,向上面的XML文檔中的book
元素添加子元素press
以代表書的出版社莉御,由于兩本書都由人民教育出版社出版撇吞,則可以引用實(shí)體。先對實(shí)體進(jìn)行聲明<!ENTITY PRESS "人民教育出版社">
礁叔,再引用實(shí)體<press>&PRESS;</press>
牍颈。
DTD的三種關(guān)聯(lián)方式
說了這么多,DTD既然是用來約束XML文檔的琅关,那么它應(yīng)該如何與XML文檔關(guān)聯(lián)起來呢煮岁?一般有三種關(guān)聯(lián)方式:
使用內(nèi)部DTD
語法為:
<!DOCTYPE 根元素名稱 [聲明]>
這里的聲明包括元素聲明、屬性聲明和實(shí)體聲明:
<!DOCTYPE 根元素名稱 [
<!ELEMENT ...>
...
<!ATTLIST ...>
...
<!ENTITY ...>
...
]>
對于上文的XML文檔涣易,使用內(nèi)部DTD時的文檔應(yīng)為:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE books [
<!ELEMENT books (book+)>
<!ELEMENT book (name,author,price)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT author (#PCDATA)>
]>
<books>
<book>
<name>三體</name>
<author>劉慈欣</author>
<price>23.8</price>
</book>
<book>
<name>龍族</name>
<author>江南</author>
<price>19.6</price>
</book>
</books>
使用外部DTD
當(dāng)使用外部DTD時画机,此時的DTD是作為一個后綴名為.dtd
的文件單獨(dú)存在,且文件存在于本地新症,在寫XML文檔時進(jìn)行聲明:
<!DOCTYPE 根元素名稱 SYSTEM "DTD文件的URL">
如果DTD文件與XML文檔在同 一目錄下步氏,DTD文件的URL
則為DTD文件名。
DTD文件也具有一定的格式:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT ...>
...
<!ATTLIST ...>
...
<!ENTITY ...>
...
這里第一行是XML的文檔聲明徒爹,后面則是元素聲明荚醒、屬性聲明和實(shí)體聲明芋类。
使用公共DTD
還有一種方式是使用網(wǎng)絡(luò)上的DTD文件,方法和使用外部DTD類似界阁,在XML文檔中也要進(jìn)行聲明:
<!DOCTYPE 根元素名稱 PUBLIC "DTD名稱" "DTD文件的URL">