1.內(nèi)部DTD
最簡單的使用DTD的方法是在XML文件的序言部分加入一個DTD描述曹步,加入的位置是緊接在XML處理指示之后战虏。一個包含DTD的XML文件的結(jié)構(gòu)為:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?>
<!DOCTYPE 根元素名[
元素描述
]>
文件體
一個完整的XML文件為:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?>
<!DOCTYPE 聯(lián)系人列表[
<!ELEMENT 聯(lián)系人列表 (聯(lián)系人)*>
<!ELEMENT 聯(lián)系人 (姓名,ID,公司,EMAIL,電話,地址)>
<!ELEMENT 地址 (街道,城市,省份)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT 公司 (#PCDATA)>
<!ELEMENT EMAIL (#PCDATA)>
<!ELEMENT 電話 (#PCDATA)>
<!ELEMENT 街道 (#PCDATA)>
<!ELEMENT 城市 (#PCDATA)>
<!ELEMENT 省份 (#PCDATA)>
]>
<?xml-stylesheet type="text/xsl" href="mystyle.xsl"?>
<聯(lián)系人列表>
<聯(lián)系人>
<姓名>張三</姓名>
<ID>001</ID>
<公司>A公司</公司>
<EMAIL>zhang@aaa.com</EMAIL>
<電話>(010)62345678</電話>
<地址>
<街道>五街1234號</街道>
<城市>北京市</城市>
<省份>北京</省份>
</地址>
</聯(lián)系人>
<聯(lián)系人>
<姓名>李四</姓名>
<ID>002</ID>
<公司>B公司</公司>
<EMAIL>li@bbb.org</EMAIL>
<電話>(021)87654321</電話>
<地址>
<街道>南京路9876號</街道>
<城市>上海市</城市>
<省份>上海</省份>
</地址>
</聯(lián)系人>
</聯(lián)系人列表>
2.外部DTD
一個DTD既可以是內(nèi)部的凛虽,包含在一個“形式良好的”XML文件中(standalone=“yes”)鉴未;也可以是外部的业汰,作為一個外部文件被引用(standalone=“no”)猾封。
外部DTD的好處是:它可以方便高效地被多個XML文件所共享。你只要寫一個DTD文件抛丽,就可以被多個XML文件所引用谤职。事實上,當(dāng)許多組織需要統(tǒng)一它們的數(shù)據(jù)交換格式時亿鲜,它們就是通過外部DTD來完成的允蜈。這樣做不僅簡化了輸入工作,還保證當(dāng)你需要對DTD做出改動時蒿柳,不用一一去改每個引用了它的XML文件饶套,只要改一個公用的DTD文件就足夠了.
為了引用一個外部DTD,必須修改XML聲明和DOCTYPE聲明垒探。XML聲明中必須說明這個文件不是自成一體的妓蛮,即standalone屬性的屬性值不再是yes了。
<?xml version = "1.0"
encoding="GB2312"
standalone = "no"?>
在DOCTYPE聲明中叛复,應(yīng)該加入SYSTEM屬性:
<!DOCTYPE 根元素名
SYSTEM "外部DTD文件的URL">
例如:
<!DOCTYPE 聯(lián)系人列表
SYSTEM "http://www.mydomain.com/dtds/fclml.dtd
">
上面的URL是一個絕對路徑仔引,除此以外扔仓,它還可以是一個相對路徑褐奥,如:
<!DOCTYPE 聯(lián)系人列表
SYSTEM "fclml.dtd">
它說明這個DTD文件和引用它的XML文件在同一個目錄下∏檀兀或者撬码,這個DTD文件還可能在XML文件的父目錄的子目錄DTD下,表示為:
<!DOCTYPE 聯(lián)系人列表
SYSTEM "../dtds/fclml.dtd">
使用這種方法版保,你可以方便地把DTD文件從你的XML文件中分離出來呜笑,粘貼到另一個文件fclml.dtd中。這樣彻犁,你就得到一個DTD文件和一個有效的XML文件叫胁。
仍然回到前面那個包含客戶聯(lián)系方式信息的XML文件,如果使用外部DTD汞幢,其形式應(yīng)該變?yōu)橄旅孢@個樣子驼鹅。DTD文件fclml.dtd:
<?xml version="1.0" encoding="GB2312"?>
<!ELEMENT 聯(lián)系人列表 (聯(lián)系人)*>
<!ELEMENT 聯(lián)系人 (姓名,ID,公司,EMAIL,電話,地址)>
<!ELEMENT 地址 (街道,城市,省份)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT 公司 (#PCDATA)>
<!ELEMENT EMAIL (#PCDATA)>
<!ELEMENT 電話 (#PCDATA)>
<!ELEMENT 街道 (#PCDATA)>
<!ELEMENT 城市 (#PCDATA)>
<!ELEMENT 省份 (#PCDATA)>
XML文件client.xml:
<?xml version = "1.0" encoding="GB2312" standalone = "no"?>
<!DOCTYPE 聯(lián)系人列表
SYSTEM "fclml.dtd">
<?xml-stylesheet type="text/xsl" href="mystyle.xsl"?>
<聯(lián)系人列表>
<聯(lián)系人>
<姓名>張三</姓名>
<ID>001</ID>
<公司>A公司</公司>
<EMAIL>zhang@aaa.com</EMAIL>
<電話>(010)62345678</電話>
<地址>
<街道>五街1234號</街道>
<城市>北京市</城市>
<省份>北京</省份>
<ZIP>100001</ZIP>
</地址>
</聯(lián)系人>
<聯(lián)系人>
<姓名>李四</姓名>
<ID>002</ID>
<公司>B公司</公司>
<EMAIL>li@bbb.org</EMAIL>
<電話>(021)87654321</電話>
<地址>
<街道>南京路9876號</街道>
<城市>上海</城市>
<省份>上海</省份>
<ZIP>200002</ZIP>
</地址>
</聯(lián)系人>
</聯(lián)系人列表>
3. 公用DTD
使用外部DTD時,要在DOCTYPE中使用關(guān)鍵字SYSTEM。實際上输钩,SYSTEM不是引用外部DTD的唯一方法豺型,這個關(guān)鍵字主要用于引用一個作者或組織所編寫的眾多XML文件中通用的DTD。還存在一種外部DTD买乃,它是一個由權(quán)威機構(gòu)制訂的姻氨,提供給特定行業(yè)或公眾使用的DTD。因此剪验,另一個引用外部DTD的辦法是使用關(guān)鍵字PUBLIC肴焊,引用這一類公開給公眾使用的DTD。 引用公共DTD的形式為:
<!DOCTYPE 根元素 PUBLIC "DTD名稱" "外部DTD的URL">
4.元素的定義
一個DTD不僅要告訴語法分析器它所關(guān)聯(lián)的XML文件的根元素是什么功戚,而且還要告訴語法分析器文件的內(nèi)容和結(jié)構(gòu)抖韩,說清文件結(jié)構(gòu)中的每一個細節(jié)。為了定義這些細節(jié)疫铜,我們必須展開DTD中元素說明部分茂浮,使用元素類型聲明(ETD)來聲明所有有效的文件元素。ETD應(yīng)該采用如下的結(jié)構(gòu):
<!ELEMENT 元素名 元素內(nèi)容描述>
一個具體例子:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?>
<!DOCTYPE 聯(lián)系人列表[
<!ELEMENT 聯(lián)系人列表 ANY>
<!ELEMENT 聯(lián)系人(姓名)>
<!ELEMENT 姓名(#PCDATA)>
]>
<聯(lián)系人列表>
<聯(lián)系人>
<姓名>張三</姓名>
</聯(lián)系人>
</聯(lián)系人列表>
元素定義是由它們的元素內(nèi)容模型(ECM)來描述的壳咕,也就是說席揽,是由緊跟元素后面的括號中的內(nèi)容來定義的。元字符的定義:
元 字 符 | 含 義 |
---|---|
+ | 出現(xiàn)一次或多次 |
* | 出現(xiàn)零次或多次 |
谓厘? | 可選幌羞,不出現(xiàn)或出現(xiàn)一次 |
() | 一組要共同匹配的表達式 |
OR,或 | |
竟稳, | AND属桦,要求嚴(yán)格遵從順序要求 |
元素A元素B元素C | 元素列表,無須遵從順序要求 |
注意:在一個組中他爸,只允許使用一種連接符(例如“聂宾,”或“|”)。因此诊笤,像下面這樣定義的DTD是不合法的:
<!ELEMENT 聯(lián)系人(姓名系谐,電話|EMAIL)>
要想使用多種連接符,只有通過創(chuàng)建子組的方式讨跟,使用:
<!ELEMENT 聯(lián)系人(姓名纪他,(電話|EMAIL))>
5.元素的屬性
在DTD中定義屬性時,我們使用下面的格式:
<!ATTLIST 元素名 (屬性名 屬性類型 缺省值)*>
- 必須賦值的屬性
關(guān)鍵字REQUIRED說明XML文件中必須為這個屬性給出一個屬性值晾匠。例如茶袒,假設(shè)你想定義一個"頁面作者"元素,并把這個元素加入所有網(wǎng)站中的每一個頁面凉馆。之所以定義這個元素薪寓,是為了頁面編輯者能夠提供他的聯(lián)系信息乾巧,以便當(dāng)發(fā)現(xiàn)頁面錯誤或無效鏈接時,可以及時地通知他预愤。在這種情況下沟于,每個頁面作者都有不同的個人信息,所以你無法事先知道應(yīng)該用什么作為缺省值植康,但你又的確需要提供每個人的信息旷太。這時候,你就可以把與聯(lián)系信息相關(guān)的屬性定義為必須的(REQUIRED)销睁,而且不用提供缺省值供璧。
-
屬性值可有可無的屬性
當(dāng)使用IMPLIED關(guān)鍵字時,文法解釋器不再強行要求你在XML文件中給該屬性賦值冻记,而且也無須在DTD中為該屬性提供缺省值睡毒。可以說冗栗,這是對屬性值有無的最低要求演顾,現(xiàn)實中經(jīng)常用到。 -
固定取值的屬性
還有一種特殊情況隅居,你需要為一個特定的屬性提供一個缺省值钠至,并且不希望XML文件的編寫者把你的缺省值替代掉。這時候胎源,就應(yīng)該使用FIXED關(guān)鍵字棉钧,同時為該屬性提供一個缺省值。 -
定義缺省值的屬性
如果不使用上面任何一種關(guān)鍵字的話涕蚤,該種屬性就是屬于這種類型宪卿。對于這種屬性,你需要在DTD中為它提供一個缺省值万栅。而在XML文件中可以為該屬性給出新的屬性值來覆蓋事先定義的缺省值佑钾,也可以不另外給出屬性值,后一種情況下它就默認為采用DTD中給出的缺省值申钩。
視實際情況而選擇次绘,給出一個實際的例子:
<!ATTLIST 頁面作者
姓名 #CDATA #IMPLIED
年齡 #CDATA #IMPLIED
聯(lián)系信息 #CDATA #REQUIRED
網(wǎng)站職務(wù) #CDATA #FIXED "頁面作者"
個人愛好 #CDATA "上網(wǎng)">
另外還有屬性的類型:
- CDATA
- Enumerated
- ID
- IDREF
- IDREFS
- ENTITY
- ENTITIES
- NMTOKEN
- NMTOKENS
- NOTATION
參數(shù)實體專門用在DTD中瘪阁。定義方式是:
<!ENTITY % 實體名 "實體內(nèi)容">
或
<!ENTITY % 實體名 SYSTEM "外部文件名">
引用方式為: %實體名
撒遣;
使用參數(shù)實體,可以方便元素和屬性的聲明管跺。例如:
<!ENTITY % TAG_NAMES "姓名 | EMAIL | 電話 | 地址">
<!ELEMENT 個人聯(lián)系信息 (%TAG_NAMES; | 生日)>
<!ELEMENT 客戶聯(lián)系信息 (%TAG_NAMES; | 公司名)>