XML中的DTD約束

什么是約束?

在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的子元素有三種可能篱蝇,即nameauthor以及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绍撞、pressdate三個子元素中的一個得院。

PS:對于?傻铣、*以及+這三個符號的含義,可以類比于正則表達(dá)式進(jìn)行記憶祥绞。

DTD屬性聲明

介紹完了元素聲明非洲,下面介紹屬性聲明。最基本的語法為:

  <!ATTLIST 元素名稱 屬性名稱 屬性類型 默認(rèn)值>

下面是W3C對于屬性類型和默認(rèn)值的規(guī)定:

屬性類型與默認(rèn)值

舉個例子蜕径,如果一個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屬性的空元素。如果heightwidth沒有被設(shè)定兜喻,則10080分別是它們的默認(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">

參考資料

http://www.w3school.com.cn/dtd/index.asp

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侯繁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泡躯,更是在濱河造成了極大的恐慌贮竟,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件精续,死亡現(xiàn)場離奇詭異坝锰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)重付,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門顷级,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人确垫,你說我怎么就攤上這事弓颈。” “怎么了删掀?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵纤子,是天一觀的道長控硼。 經(jīng)常有香客問我,道長卡乾,這世上最難降的妖魔是什么缚够? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮谍椅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锁施。我一直安慰自己,他們只是感情好沾谜,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布基跑。 她就那樣靜靜地躺著,像睡著了一般媳否。 火紅的嫁衣襯著肌膚如雪荆秦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天掺逼,我揣著相機(jī)與錄音瓤介,去河邊找鬼。 笑死刑桑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祠斧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼辕漂,長吁一口氣:“原來是場噩夢啊……” “哼吩蔑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起隧期,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤赘娄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后性置,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹏浅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了之碗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片季希。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖博敬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情偏窝,我是刑警寧澤武学,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站链沼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏括勺。R本人自食惡果不足惜曲掰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乱豆。 院中可真熱鬧,春花似錦吊趾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屁奏。三九已至,卻和暖如春勇边,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粒褒。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怕享。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像沙合,于是被迫代替她去往敵國和親跌帐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. XML簡介 以下內(nèi)容來自于http://www.w3school.com.cn/xml 基本知識 XML 和...
    WebSSO閱讀 1,907評論 1 7
  • 經(jīng)過兩天的奮戰(zhàn)谨敛,終于把xml簡略的過了一遍究履。 1.1XML介紹 xml是Extensible Markup lan...
    Ystrator閱讀 809評論 0 2
  • 1、XML的語法 文檔聲明寫法: <?xml version="1.0" ?>文檔聲明必須出現(xiàn)在xml文件...
    來個芒果閱讀 1,275評論 0 1
  • 毛不易,當(dāng)我初看他在某節(jié)目的出場時炕贵,我簡直不敢相信他居然寫出了《消愁》這樣的歌。年級輕輕野崇,其貌不揚(yáng),嘴角總是掛著一...
    阿塔瑪閱讀 306評論 0 0
  • 最近蕪湖的天氣一直很晴朗鳖轰,等了一個星期的周六終于到來。手術(shù)室繼續(xù)著繁忙的手術(shù)焰轻,在十一點(diǎn)半到來之前老師就讓我們回去...
    尋找_5b84閱讀 536評論 2 2