DTD 是文檔類型定義(Document Type Definition)的縮寫。DTD 定義了 XML 文檔的結(jié)構(gòu)以及合法的元素和屬性。
為什么使用 DTD
通過使用 DTD,獨立的團體可以就數(shù)據(jù)交換的標準 DTD 達成一致。
應(yīng)用程序可以使用 DTD 來驗證 XML 數(shù)據(jù)的有效性。
內(nèi)部 DTD 聲明
如果 DTD 在 XML 文件內(nèi)聲明,它必須包裹在 <DOCTYPE>
定義內(nèi):
帶有內(nèi)部 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>
在 XML 文件中,選擇"view source" 以查看 DTD。
上述 DTD 的解釋如下:
-
<!DOCTYPE note>
定義該文檔的根元素為 note -
<!ELEMENT note>
定義 note 元素必須包含四個元素:"to, from, heading, body" -
<!ELEMENT to>
定義 to 元素的類型為 "#PCDATA" -
<!ELEMENT from>
定義 from 元素的類型為 "#PCDATA" -
<!ELEMENT heading>
定義 heading 元素的類型為 "#PCDATA" -
<!ELEMENT body>
定義 body 元素的類型為 "#PCDATA"
外部 DTD 聲明
如果 DTD 在外部文件中聲明,<!DOCTYPE>
定義必須包含對 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>
以下是包含 DTD 的文件 "note.dtd" 的內(nèi)容:
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
DTD - XML 構(gòu)建模塊
XML 和 HTML 文檔的主要構(gòu)建模塊是元素
XML 文檔的構(gòu)建模塊
從 DTD 的角度來看,所有 XML 文檔都由以下構(gòu)建模塊組成:
- 元素
- 屬性
- 實體
- PCDATA
- CDATA
元素
元素是 XML 和 HTML 文檔的主要構(gòu)建模塊。
HTML 元素的示例包括 "body" 和 "table"。XML 元素的示例可能是 "note" 和 "message"。元素可以包含文本、其他元素或為空??盏?HTML 元素的示例包括 "hr"、 "br" 和 "img"。
示例
<body>some text</body>
<message>some text</message>
屬性
屬性提供有關(guān)元素的額外信息。
屬性始終位于元素的開始標記內(nèi)。屬性始終以名稱/值對的形式出現(xiàn)。以下是具有有關(guān)源文件的附加信息的 "img" 元素的示例
<img src="computer.gif" />
實體
一些字符在 XML 中具有特殊含義,例如小于號(<),它定義了 XML 標記的開始。
大多數(shù)人都知道 HTML 實體: "
"。這個 "no-breaking-space" 實體用于在 HTML 文檔中插入額外的空格。實體在 XML 解析器解析文檔時會被展開。
以下實體在 XML 中是預(yù)定義的:
-
<
代表<
-
>
代表>
-
&
代表&
-
"
代表"
-
'
代表'
PCDATA
PCDATA 表示解析的字符數(shù)據(jù)。
將字符數(shù)據(jù)視為 XML 元素的開始標記和結(jié)束標記之間找到的文本。
PCDATA 是解析器將解析的文本。解析器將檢查文本中的實體和標記。
文本內(nèi)的標記將被視為標記,并且實體將被展開。
但是,解析的字符數(shù)據(jù)不應(yīng)包含任何&、<或>字符;這些需要用分別表示為 &
<
和 >
實體。
CDATA
CDATA 表示字符數(shù)據(jù)。
CDATA 是解析器將不解析的文本。文本內(nèi)的標記將不被視為標記,并且實體將不被展開。
DTD - 元素
在 DTD 中,元素通過 ELEMENT 聲明進行聲明
聲明元素
在 DTD 中,XML 元素的聲明具有以下語法:
<!ELEMENT element-name category>
或者
<!ELEMENT element-name (element-content)>
空元素
空元素通過 category 關(guān)鍵字 EMPTY
進行聲明:
<!ELEMENT element-name EMPTY>
示例
<!ELEMENT br EMPTY>
XML 示例
<br />
具有解析字符數(shù)據(jù)的元素
僅包含解析字符數(shù)據(jù)的元素在括號內(nèi)使用 #PCDATA
進行聲明:
<!ELEMENT element-name (#PCDATA)>
示例
<!ELEMENT from (#PCDATA)>
具有任何內(nèi)容的元素
使用 category 關(guān)鍵字 ANY
聲明的元素可以包含任意可解析的數(shù)據(jù)組合:
<!ELEMENT element-name ANY>
示例
<!ELEMENT note ANY>
具有子元素(序列)的元素
具有一個或多個子元素的元素通過在括號內(nèi)聲明子元素的名稱進行聲明:
<!ELEMENT element-name (child1)>
或者
<!ELEMENT element-name (child1,child2,...)>
示例
<!ELEMENT note (to,from,heading,body)>
當子元素按逗號分隔在序列中聲明時,子元素必須按相同的順序出現(xiàn)在文檔中。在完整聲明中,子元素也必須被聲明,并且子元素也可以有子元素。 "note" 元素的完整聲明如下:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
聲明元素的僅出現(xiàn)一次
<!ELEMENT element-name (child-name)>
示例
<!ELEMENT note (message)>
上面的示例聲明了子元素 "message" 必須在 "note" 元素內(nèi)出現(xiàn)一次,且僅一次。
聲明元素至少出現(xiàn)一次
<!ELEMENT element-name (child-name+)>
示例
<!ELEMENT note (message+)>
上面示例中的+號表示子元素 "message" 必須在 "note" 元素內(nèi)出現(xiàn)一次或多次。
聲明元素出現(xiàn)零次或更多次
<!ELEMENT element-name (child-name*)>
示例
<!ELEMENT note (message*)>
上面示例中的*號表示子元素 "message" 可以在 "note" 元素內(nèi)出現(xiàn)零次或更多次。
聲明元素出現(xiàn)零次或一次
<!ELEMENT element-name (child-name?)>
示例
<!ELEMENT note (message?)>
上面示例中的?號表示子元素 "message" 可以在 "note" 元素內(nèi)出現(xiàn)零次或一次。
聲明要么/或內(nèi)容
<!ELEMENT note (to,from,header,(message|body))>
上面的示例聲明了 "note" 元素必須包含一個 "to" 元素、一個 "from" 元素、一個 "header" 元素,以及一個 "message" 或 "body" 元素。
聲明混合內(nèi)容
<!ELEMENT note (#PCDATA|to|from|header|message)*>
上面的示例聲明了 "note" 元素可以包含零個或多個解析字符數(shù)據(jù)、"to"、"from"、"header" 或 "message" 元素的出現(xiàn)。
DTD - 屬性
在 DTD 中,使用 ATTLIST 聲明來聲明屬性
聲明屬性
屬性聲明具有以下語法:
<!ATTLIST element-name attribute-name attribute-type attribute-value>
DTD 示例
<!ATTLIST payment type CDATA "check">
XML 示例
<payment type="check" />
attribute-type
可以是以下之一:
-
CDATA
:值是字符數(shù)據(jù) -
(en1|en2|..)
:值必須是列舉列表中的一個 -
ID
:值是唯一標識符 -
IDREF
:值是另一個元素的標識符 -
IDREFS
:值是其他標識符的列表 -
NMTOKEN
:值是有效的 XML 名稱 -
NMTOKENS
:值是有效的 XML 名稱的列表 -
ENTITY
:值是實體 -
ENTITIES
:值是實體的列表 -
NOTATION
:值是符號的名稱 -
xml:
:值是預(yù)定義的 xml 值
attribute-value
可以是以下之一:
-
value
:屬性的默認值 -
#REQUIRED
:屬性是必需的 -
#IMPLIED
:屬性是可選的 -
#FIXED value
:屬性值是固定的
默認屬性值
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
有效的 XML
<square width="100" />
在上面的示例中,“square”元素被定義為一個帶有類型 CDATA 的空元素。如果未指定寬度,則其默認值為 0。
REQUIRED
語法
<!ATTLIST element-name attribute-name attribute-type #REQUIRED>
示例
<!ATTLIST person number CDATA #REQUIRED>
有效的 XML
<person number="5677" />
無效的 XML
<person />
如果沒有默認值的選項,但仍希望強制屬性存在,請使用 #REQUIRED
關(guān)鍵字。
IMPLIED
語法:
<!ATTLIST element-name attribute-name attribute-type #IMPLIED>
示例
<!ATTLIST contact fax CDATA #IMPLIED>
有效的 XML:
<contact fax="555-667788" />
有效的 XML:
<contact />
如果不想強制作者包含屬性,并且沒有默認值的選項,請使用 #IMPLIED
關(guān)鍵字。
FIXED
語法:
<!ATTLIST element-name attribute-name attribute-type #FIXED "value">
示例
<!ATTLIST sender company CDATA #FIXED "Microsoft">
有效的 XML:
<sender company="Microsoft" />
無效的 XML:
<sender company="W3Schools" />
當希望屬性具有固定值而不允許作者更改時,請使用 #FIXED
關(guān)鍵字。如果作者包含其他值,XML 解析器將返回錯誤。
列舉屬性值
語法
<!ATTLIST element-name attribute-name (en1|en2|..) default-value>
示例
<!ATTLIST payment type (check|cash) "cash">
XML 示例
<payment type="check" />
或
<payment type="cash" />
當希望屬性值是固定一組合法值之一時,請使用列舉屬性值。
XML 元素與屬性
在 XML 中,沒有規(guī)定何時使用屬性,何時使用子元素。
元素與屬性的使用
數(shù)據(jù)可以存儲在子元素中,也可以存儲在屬性中。
請看以下示例
<person sex="female">
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
<person>
<sex>female</sex>
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
在第一個示例中,sex
是一個屬性。在最后一個示例中,sex
是一個子元素。這兩個示例提供了相同的信息。
在何時使用屬性以及何時使用子元素方面,沒有具體的規(guī)則。根據(jù)我的經(jīng)驗,在 HTML 中使用屬性很方便,但在 XML 中應(yīng)該盡量避免使用。如果信息看起來像是數(shù)據(jù),請使用子元素
以下三個 XML 文檔包含完全相同的信息:
- 使用了一個
date
屬性:
<note date="12/11/2002">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
- 使用了一個
date
元素:
<note>
<date>12/11/2002</date>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
- 使用了擴展的
date
元素(這是我喜歡的):
<note>
<date>
<day>12</day>
<month>11</month>
<year>2002</year>
</date>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
避免使用屬性?
是否應(yīng)該避免使用屬性?
一些使用屬性的問題包括:
- 屬性不能包含多個值(子元素可以)
- 屬性不容易擴展(用于未來更改)
- 屬性不能描述結(jié)構(gòu)(子元素可以)
- 屬性更難以通過程序代碼進行操作
- 屬性值不容易與 DTD 進行測試
如果將屬性用作數(shù)據(jù)的容器,最終會得到難以閱讀和維護的文檔。盡量使用元素來描述數(shù)據(jù)。僅在提供與數(shù)據(jù)無關(guān)的信息時使用屬性。
不要像這樣使用 XML(這不是 XML 的正確用法)
<note day="12" month="11" year="2002"
to="Tove" from="Jani" heading="Reminder"
body="Don't forget me this weekend!">
</note>
關(guān)于屬性規(guī)則有一個例外:
有時會為元素分配 ID 引用。這些 ID 引用可以用于訪問 XML 元素,方式類似于 HTML 中的 NAME 或 ID 屬性。這個例子演示了這一點:
<messages>
<note id="p501">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note id="p502">
<to>Jani</to>
<from>Tove</from>
<heading>Re: Reminder</heading>
<body>I will not!</body>
</note>
</messages>
這些示例中的 ID 只是一個計數(shù)器或唯一標識符,用于識別 XML 文件中不同的 note
,并不是 note
數(shù)據(jù)的一部分。
這里想說的是,元數(shù)據(jù)(關(guān)于數(shù)據(jù)的數(shù)據(jù))應(yīng)該存儲為屬性,而數(shù)據(jù)本身應(yīng)該存儲為元素。
實體聲明
實體(Entity)被用來定義對特殊字符的快捷方式。實體可以聲明為內(nèi)部或外部。
內(nèi)部實體聲明
語法
<!ENTITY entity-name "entity-value">
示例
DTD示例
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright W3Schools.">
XML示例
<author>&writer;©right;</author>
注意:一個實體由三部分組成:一個 &
符號、一個實體名和一個分號。
外部實體聲明
語法
<!ENTITY entity-name SYSTEM "URI/URL">
XML示例
<author>&writer;©right;</author>
DTD示例
電視節(jié)目表DTD
<!DOCTYPE TVSCHEDULE [
<!ELEMENT TVSCHEDULE (CHANNEL+)>
<!ELEMENT CHANNEL (BANNER,DAY+)>
<!ELEMENT BANNER (#PCDATA)>
<!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)>
<!ELEMENT HOLIDAY (#PCDATA)>
<!ELEMENT DATE (#PCDATA)>
<!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)>
<!ELEMENT TIME (#PCDATA)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT DESCRIPTION (#PCDATA)>
<!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED>
<!ATTLIST CHANNEL CHAN CDATA #REQUIRED>
<!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED>
<!ATTLIST TITLE RATING CDATA #IMPLIED>
<!ATTLIST TITLE LANGUAGE CDATA #IMPLIED>
]>
報紙文章DTD文章來源:http://www.zghlxwxcb.cn/news/detail-859192.html
<!DOCTYPE NEWSPAPER [
<!ELEMENT NEWSPAPER (ARTICLE+)>
<!ELEMENT ARTICLE (HEADLINE,BYLINE,LEAD,BODY,NOTES)>
<!ELEMENT HEADLINE (#PCDATA)>
<!ELEMENT BYLINE (#PCDATA)>
<!ELEMENT LEAD (#PCDATA)>
<!ELEMENT BODY (#PCDATA)>
<!ELEMENT NOTES (#PCDATA)>
<!ATTLIST ARTICLE AUTHOR CDATA #REQUIRED>
<!ATTLIST ARTICLE EDITOR CDATA #IMPLIED>
<!ATTLIST ARTICLE DATE CDATA #IMPLIED>
<!ATTLIST ARTICLE EDITION CDATA #IMPLIED>
<!ENTITY NEWSPAPER "Vervet Logic Times">
<!ENTITY PUBLISHER "Vervet Logic Press">
<!ENTITY COPYRIGHT "Copyright 1998 Vervet Logic Press">
]>
產(chǎn)品目錄DTD文章來源地址http://www.zghlxwxcb.cn/news/detail-859192.html
<!DOCTYPE CATALOG [
<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "jd@jd-tools.com">
<!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>
<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte"
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>
<!ELEMENT NOTES (#PCDATA)>
]>
## 最后
為了方便其他設(shè)備和平臺的小伙伴觀看往期文章:
微信公眾號搜索:`Let us Coding`,關(guān)注后即可獲取最新文章推送
看完如果覺得有幫助,歡迎點贊、收藏、關(guān)注
到了這里,關(guān)于探索 DTD 在 XML 中的作用及解析:深入理解文檔類型定義的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!