JavaWeb學習日記(三)
DTD語法(要求不高,不要求寫,要求會讀)
兩種寫法
引入中寫的:SYSTEM
,表示當前的DTD檔案是本地的
如果寫的是:PUBLIC
,則表示引入的DTD檔案是來自於網路的在XML內部
<?xml version="1.0" encoding="gb2312" standalone="no" ?>
<!DOCTYPE bookstore[
<!ELEMENT bookstore (book+)>
<!ELEMENT book (name,author,price)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookstore>
<book>
<name>thinking in c++</name>
<author>Bruce Eckel</author>
<price>40</price>
</book>
<book>
<name>thinking in java</name>
<author>Bruce Eckel</author>
<price>50</price>
</book>
</bookstore>
瀏覽器除錯如下:
- 從外部引入
參考上一篇文章
DTD元素的組合型別:
DTD中這樣規定:
<!ELEMENT 家庭(人+,家電*)>
- 1
這個DTD規定了家庭元素中可以有1到多個”人”這個子元素,也可以有0到多個”家電”這個子元素。其中的加號”+”和星號”*”的含義與正則表示式中的含義一致。
XML這樣寫:
<家庭>
<人 名字="張曉明" 性別="男" 年齡="25"/>
< 人 名字="李小鋼" 性別="男" 年齡="36" 愛好="作個教育家和偉人"/>
<家電 名稱="彩電" 數量="3"/>
</家庭>
- 1
- 2
- 3
- 4
- 5
關於組合型別,有下述的的修飾符可以使用:
符號 | 用途 | 示例 | 示例說明 |
---|---|---|---|
() | 用來給元素分組 | (古龍|金庸),(王朔|餘傑) | 分成兩組 |
| | 在列出的物件中選擇一個 | (男人|女人) | 表示男人或者女人必須出現,兩者至少選其一 |
+ | 該物件必須出現一次或者多次 | (成員+) | 表示成員必須出現,而卻可以出現多個成員 |
* | 該物件允許出現0次或者多次 | (愛好*) | 愛好可以出現兩次到多次 |
? | 該物件必須出現0次或者1次 | (菜鳥?) | 菜鳥可以出現,也可以不出現,如果出現的話,最多隻能出現一次 |
, | 物件必須按指定的順序出現 | (西瓜,蘋果,香蕉) | 表示西瓜、蘋果、香蕉必須出現,並且按這個順序出現 |
2.4 屬性定義
DTD中屬性的定義(attribute)是這樣的:
<!ATTLIST 元素名稱
屬性名稱 型別 屬性特點
屬性名稱 型別 屬性特點......
>
- 1
- 2
- 3
- 4
其中,屬性的型別有下面5種:
(1) CDATA
(2) ID
(3) IDREF/IDREFS
(4) Enumerated
(5) ENTITY/ENTITIES
屬性的特點有如下4種:
(1) #REQUIRED,表示這個屬性必須給,不給就報錯
(2) #IMPLIED,表示這個屬性可以給也可以不給
(3) #FIXED value,表示這個屬性必須給一個固定的value值
(4) Default value,表示這個屬性如果沒有值,就分配一個預設的value值
比如,我們想在學生這個子元素上加上地址這個屬性,而且這個屬性是必須的,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE 班級 SYSTEM "myClass.dtd">
<班級>
<學生 地址="香港">
<名字>周小星</名字>
<年齡>23</年齡>
<介紹>學習刻苦</介紹>
</學生>
<學生 地址="澳門">
<名字>林曉</名字>
<年齡>25</年齡>
<介紹>是一個好學生</介紹>
</學生>
</班級>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
這個時候相應的DTD檔案也要更新,不然就會報錯,如下:
<!ELEMENT 班級 (學生+)>
<!ELEMENT 學生 (名字,年齡,介紹)>
<!ATTLIST 學生
地址 CDATA #REQUIRED
>
<!ELEMENT 名字 (#PCDATA)>
<!ELEMENT 年齡 (#PCDATA)>
<!ELEMENT 介紹 (#PCDATA)>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.4.1 對於屬性型別的詳細解釋
(1)屬性型別-CDATA,表示屬性值可以是任何字元(包括中文和數字)
<!ATTLIST 木偶
姓名 CDATA #REQUIRED
>
- 1
- 2
- 3
<木偶 姓名="匹諾曹"/>
<木偶 姓名="PiNuocao"/>
<木偶 姓名="123"/>
- 1
- 2
- 3
(2)屬性型別-ID,表明該屬性的取值必須是唯一的,但是屬性的值不能是以數字開頭!
<!ELEMENT 公司職員 ANY>
<!ATTLIST 公司職員
編號 ID #REQUIRED
姓名 CDATA #REQUIRED
>
- 1
- 2
- 3
- 4
- 5
<公司職員 編號="Z001" 姓名="張三"/>
<公司職員 編號="Z002" 姓名="李思"/>
- 1
- 2
(3)屬性型別-IDREF/IDREFS
- IDREF屬性的值指向文件中其它地方宣告的ID型別的值
- IDREFS同IDREF,但是可以具有由空格分開的多個引用。
<!ELEMENT 家庭(人+)>
<!ELEMENT 人 EMPTY>
<!ATTLIST 人
relIDID #REQUIREDparaentIDIDREFS #IMPLIEDnameCDATA #REQUIRED
>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
<家庭>
<人relID="P_1"name="爸爸"/>
<人relID="P_2"name="媽媽"/>
<人relID="P_3"parentID="P_1 P_2"name="兒子"/>
</家庭>
- 1
- 2
- 3
- 4
- 5
(4)屬性型別-Enumerated,事先定義好一些值,屬性的值必須在所列出的值的範圍內。
<!ATTLISTperson
婚姻狀態 (single|married|divorced|widowed) #IMPLIED
>
<!ATTLISTperson
性別 (男|女) #REQUIRED
>
- 1
- 2
- 3
- 4
- 5
- 6
(5)屬性型別-ENTITY,實體
實體定義:
- 實體用於為一段內容建立一個別名,以後在XML文件中就可以使用別名引用這段內容了。
- 在DTD定義中,一條!ENTITY語句用於定義一個實體。
- 實體可分為兩種型別:引用實體和引數實體。引用實體是被XML文件應用的,而引數實體是被DTD檔案本身應用的。
①引用實體:
- 引用實體主要在XML文件中被應用
語法格式如下,引用實體的定義內容最好放在DTD檔案的最後。
<!ENTITY 實體名稱 "實體內容">
- 1
引用方式:&實體名稱; 末尾要帶上分號,這個引用將直接轉變成實體內容
舉例如下:
<!ENTITYcopyright "Iamaprogrammer">
....
©right;
- 1
- 2
- 3
②引數實體:
引數實體被DTD檔案自身使用
語法格式為:
<!ENTITY % 實體名稱 "實體內容">
- 1
引用方式為:%實體名稱
舉例:
<!ENTITY % TAG_NAME "姓名|EMAIL|電話|地址">
<!ELEMENT 個人資訊 (%TAG_NAME;|生日)>
<!ELEMENT 客戶資訊 (%TAG_NAME;|公司名)>
- 1
- 2
- 3
- 4
3.DTD實際案例
學習DTD的目標在於:
(1)要求我們能夠看得懂DTD檔案,
(2)我們可以根據給出的DTD寫出對應的XML檔案
下面我們看一個案例,下述的DTD檔案是從W3School線上教程中的DTD案例中拿過來的,細看每一行,我們都應該能夠看得懂。
<!ENTITYAUTHOR "JohnDoe">
<!ENTITYCOMPANY "JDPowerTools, Inc.">
<!ENTITYEMAIL "jd@jd-tools.com">
<!ELEMENTCATALOG (PRODUCT+)>
<!ELEMENTPRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLISTPRODUCTNAMECDATA #IMPLIEDCATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUMCDATA #IMPLIEDPLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENTSPECIFICATIONS (#PCDATA)>
<!ATTLISTSPECIFICATIONSWEIGHTCDATA #IMPLIEDPOWERCDATA #IMPLIED>
<!ELEMENTOPTIONS (#PCDATA)>
<!ATTLISTOPTIONSFINISH (Metal|Polished|Matte) "Matte"
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENTPRICE (#PCDATA)>
<!ATTLISTPRICEMSRPCDATA #IMPLIEDWHOLESALECDATA #IMPLIEDSTREETCDATA #IMPLIEDSHIPPINGCDATA #IMPLIED>
<!ELEMENTNOTES (#PCDATA)>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
然後我們可以根據該DTD編寫如下最簡單的XML檔案:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE CATALOG SYSTEM "product.dtd">
<CATALOG>
<PRODUCTNAME="康帥傅礦泉水"CATEGORY="Table"PARTNUM="12"PLANT="Chicago">
<SPECIFICATIONSWEIGHT="20"POWER="18">這裡是細節</SPECIFICATIONS>
<PRICE>25</PRICE>
<PRICE>28</PRICE>
</PRODUCT>
</CATALOG>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
然後我們用Microsoft.XMLDOM校驗該XML,會發現沒有任何錯誤。但是要注意編碼。