2020久久超碰欧美精品最新亚洲欧美日韩久久精品,国产福利电影一区二区三区,亚洲欧美日韩一区在线观看,亚洲国产欧美日韩欧美特级,亚洲欧美日韩成人一区久久,欧美日韩精品一区二区三区不卡,国产欧美日韩va另类影音先锋,亚洲欧美日韩久久精品,亚洲欧美日韩国产成人精品影院,亚洲国产欧美日韩精品一区二区三区,欧美日韩国产成人高清视频,日韩久久精品国产免费观看频道,久久人人爽人人爽从片av高清,国产精品综合一区二区

首頁技術文章正文

DTD語法詳細介紹【黑馬程序員】

更新時間:2020-12-29 來源:黑馬程序員 瀏覽量:

在編寫XML文檔時,需要掌握XML語法。同理,在編寫DTD文檔時,也需要遵循一定的語法。DTD的結構一般由元素類型定義、屬性定義、實體定義、記號(notation)定義等構成,一個典型的文檔類型定義會把將來要創建的XML文檔的元素結構、屬性類型、實體引用等預先進行定義。接下來,針對DTD結構中所涉及到的語法進行詳細講解。

一、元素定義

元素是XML文檔的基本組成部分,在DTD定義中,每一條<!ELEMENT…>語句用于定義一個元素,其基本的語法格式如下所示:

<!ELEMENT 元素名稱 元素內容>

在上面元素的定義格式中,包含了“元素名稱”和“元素內容”。其中,“元素名稱”是自定義的名稱,它用于定義被約束XML文檔中的元素,“元素內容”是對元素包含內容的聲明,包括數據類型和符號二部分,它共有五種內容形式,具體如下:

(1)#PCDATA:表示元素中嵌套的內容是普通文本字符串,其中,關鍵字PCDATA是Parsed Character Data的簡寫。例如<!ELEMENT 書名 (#PCDATA)>表示書名所嵌套的內容是字符串類型。

(2)子元素:說明元素包含的元素。通常用一對圓括號()將元素中要嵌套的一組子元素括起來,例如,<!ELEMENT 書 (書名,作者,售價)>表示元素書中要嵌套書名、作者、售價等子元素。


(3)混合內容:表示元素既可以包含字符數據,也可以包含子元素。混合內容必須被定義零個或多個,例如,<!ELEMENT 書 (#PCDATA|書名)*>表示書中嵌套的子元素書名包含零個或多個,并且書名是字符串文本格式。


(4)EMPTY:表示該元素既不包含字符數據,也不包含子元素,是一個空元素。如果在文檔中元素本身已經表明了明確的含義,就可以在DTD中用關鍵字EMPTY表明空元素。例如,<!ELEMENT br EMPTY>,

其中br是一個沒有內容的空元素。

(5)ANY:表示該元素可以包含任何的字符數據和子元素。例如,<!ELEMENT 聯系人 ANY>表示聯系人可以包含任何形式的內容。但在實際開發中,應該盡量避免使用ANY,因為除了根元素外,其它使用ANY的元素都將失去DTD對XML文檔的約束效果。


需要注意的是,在定義元素時,元素內容中可以包含一些符號,不同的符號具有不同的作用,接下來,針對一些常見的符號進行講解,具體如下:


● 問號[?]:表示該對象可以出現0次或1次。


●星號[*]:表示該對象可以出現0次或多次。


●加號[+]:表示該對象可以出現1次或多次。


● 豎線[|]:表示列出的對象中選擇1個。


●逗號[,]:表示對象必須按照指定的順序出現。


● 括號[()]:用于給元素進行分組。


二、屬性定義

在DTD文檔中,定義元素的同時,還可以為元素定義屬性。DTD屬性定義的基本語法格式如下所示:


<!ATTLIST 元素名
      屬性名1 屬性類型 設置說明
屬性名1 屬性類型 設置說明
......
>

在上面屬性定義的語法格式中,“元素名”是屬性所屬元素的名字,“屬性名”是屬性的名稱,“屬性類型”則是用來指定該屬性是屬于哪種類型,“設置說明”用來說明該屬性是否必須出現。關于“屬性類型”和“設置說明”的相關講解,具體如下:


1、設置說明

定義元素的屬性時,有四種設置說明可以選擇,具體如下:


1)#REQUIRED

表示元素的該屬性是必須的,例如,當定義聯系人信息的DTD時,我們希望每一個聯系人都有一個聯系電話屬性,這時,可以在屬性聲明時,使用REQUIRED。


2)#IMPLIED

表示元素可以包含該屬性,也可以不包含該屬性。比如,當定義一本書的信息時,發現書的頁數屬性對讀者無關緊要,這時,在屬性聲明時,可以使用IMPLIED。


3)#FIXED

表示一個固定的屬性默認值,在XML文檔中不能將該屬性設置為其它值。使用#FIXED關鍵字時,還需要為該屬性提供一個默認值。當XML文檔中沒有定義該屬性時,其值將被自動設置為DTD中定義的默認值。


4)默認值

和FIXED一樣,如果元素不包含該屬性,該屬性將被自動設置為DTD中定義的默認值。不同的是,該屬性的值是可以改變的,如果XML文件中設置了該屬性,新的屬性值會覆蓋DTD中定義的默認值。


2、屬性類型

在DTD中定義元素的屬性時,有十種屬性類型可以選擇,具體如下:


1) CDATA

這是最常用的一種屬性類型,表明屬性類型是字符數據,與元素內容說明中的#PCDATA相同。當然,在屬性設置值中出現的特殊字符,也需要使用其轉義字符序列來表示,例如,用&amp;表示字符(&),用&lt;表示字符(<)等。


2) Enumerated(枚舉類型)

在聲明屬性時,可以限制屬性的取值只能從一個列表中選擇,這類屬性屬于Enumerated(枚舉類型)。需要注意的是,在DTD定義中并不會出現關鍵字Enumerated。接下來通過一個案例來學習如何定義Enumerated類型的屬性,如例1所示。

例1 enum.xml

<?xml version="1.0" encoding="GB2312" standalone="yes">
<!DOCTYPE 購物籃 [
    <!ELEMENT 購物籃 ANY>
    <!ELEMENT 肉 EMPTY>
    <!ATTLIST 肉 品種(雞肉|牛肉|豬肉|魚肉) "雞肉">
]>
    <購物籃>
        <肉 品種="魚肉"/>
        <肉 品種="牛肉"/>
        <肉/>
    </購物籃>

在例1中,“品種”屬性的類型是Enumerated,其值只能為 “雞肉”、“牛肉”“豬肉”和“魚肉”,而不能使用其它值。“品種”屬性的默認值是“雞肉”,所以,即使<購物籃>元素中的第三個子元素沒有顯示定義“品種”這個屬性,但它實際也具有“品種”這個屬性,且屬性的取值為“雞肉”。


3)ID

一個ID類型的屬性用于唯一標識XML文檔中的一個元素。其屬性值必須遵守XML名稱定義的規則。一個元素只能有一個ID類型的屬性,而且ID類型的屬性必須設置為#IMPLIED或#REQUIRED。因為ID類型屬性的每一個取值都是用來標識一個特定的元素,所以,為ID類型的屬性提供默認值,特別是固定的默認值是毫無意義的。接下來通過一個案例來學習如何定義一個ID類型的屬性,如例2所示。


例2 id.xml


<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<!DOCTYPE 聯系人列表[
    <!ELEMENT 聯系人列表 ANY>
    <!ELEMENT 聯系人 (姓名,EMAIL)>
    <!ELEMENT 姓名 (#PCDATA)>
    <!ELEMENT EMAIL (#PCDATA)>
    <!ATTLIST 聯系人 編號 ID #REQUIRED>
]>
   <聯系人列表>
        <聯系人 編號="1">
              <姓名>張三</姓名>
              <EMAIL>zhang@itcast.cn</EMAIL>
        </聯系人>
        <聯系人 編號="2">
              <姓名>李四</姓名>
              <EMAIL>li@itcast.cn</EMAIL>
        </聯系人>
 </聯系人列表>

在例2中,將元素為<聯系人>的編號屬性設置為#REQUIRED,說明每個聯系人都有一個編號,同時,屬性編號的類型為ID,說明編號是唯一的。如此一來,通過編號就可以找到唯一對應的聯系人了。


4)IDREF和IDREFS

例2中,雖然張三和李四兩個聯系人的ID編號是唯一的,但是這兩個ID類型的屬性沒有發揮作用,這時可以使用IDREF類型,使這兩個聯系人之間建立一種一對一的關系。接下來通過一個案例來學習IDREF類型的使用,如例3所示。


例3 Idref.xml


<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<!DOCTYPE 聯系人列表[
    <!ELEMENT 聯系人列表 ANY>
    <!ELEMENT 聯系人 (姓名,EMAIL)>
    <!ELEMENT 姓名 (#PCDATA)>
    <!ELEMENT EMAIL (#PCDATA)>
    <!ATTLIST 聯系人
                編號 ID #REQUIRED
               上司 IDREF #IMPLIED>
      ]>
      <聯系人列表>
         <聯系人 編號="1">
             <姓名>張三</姓名>
             <EMAIL>zhang@itcast.org</EMAIL>
         </聯系人>
         <聯系人 編號="2" 上司="1">
              <姓名>李四</姓名>
              <EMAIL>li@itcast.org</EMAIL>
         </聯系人>
     </聯系人列表>

在例3中,為元素<聯系人列表>的子元素<聯系人>增加了一個名稱為上司的屬性,并且將該屬性的類型設置為IDREF,IDREF類型屬性的值必須為一個已經存在的ID類型的屬性值。在第二個<聯系人>元素中,將上司屬性設置為第一個聯系人的編號屬性值,如此一來,就形成了兩個聯系人元素之間的對應關系,即李四的上司為張三。


IDREF類型可以使兩個元素之間建立一對一的關系,但是,如果兩個元素之間的關系是一對多,例如,一個學生去圖書館可以借多本書。這時,需要使用IDREFS類型來指定某個人借閱了哪些書。需要注意的是,IDREFS類型的屬性可以引用多個ID類型的屬性值,這些ID的屬性值需要用空格分隔。接下來通過一個案例來學習IDREFS的使用,如例4所示。


例4 Library.xml

 <?xml version=”1.0” encoding=”GB2312”?>
 <!DOCTYPE library[
     <!ELEMENT libarary (books,records)>
     <!ELEMENT books (book+)>
     <!ELEMENT book (title)>
     <!ELEMENT title (#PCDATA)>
     <!ELEMENT records (item+)>
     <!ELEMENT item (data,person)>
     <!ELEMENT data (#PCDATA)>
      <!ELEMENT person EMPTY>
      <!ATTLIST book bookid ID #REQUIRED>
      <!ATTLIST person name CDATA #REQUIRED>
      <!ATTLIST person borrowed IDREFS #REQUIRED>
  ]>
<library>
      <books>
          <book>
              <book bookid="b0101">
                 <title>Java就業培訓教材</title>
              </book>
              <book bookid="b0102">
                 <title>Java Web開發內幕 </title>
              </book>
              <book bookid="b0103">
                 <title>Java開發寶典</title>
              </book>
      </books>
<records>
        <item>
            <data>2013-03-13</data>
            <person name="張三" borrowed="b0101 b0103"/>
       </item>
        <item>
              <data>2013-05-23</data>
              <person name="李四" borrowed="b0101 b0102 b0103"/>
        </item>
    </records>
</library>


例4中,將元素<book>中屬性名為bookid的屬性設置為ID類型,元素<person>中名為borrowed的屬性設置為IDREFS類型。從Library.xml文檔中可以看出,張三借閱了《Java就業培訓教材》和《Java開發寶典》這兩本書,而李四則借閱了《Java就業培訓教材》、《Java Web開發內幕》和《Java開發寶典》這三本書。


5)NMTOKEN和NMTOKENS


NMTOKEN是Name Token的簡寫,它表示由一個或者多個字母、數字、句點(.)、連字號(-)或下劃線(_)所組成的一個名稱。NMTOKENS關鍵字表示一種列表類型。一個元素的NMOTOKENS類型的屬性設置值可以是同一個XML文件中的另外多個NMTOKEN類型的屬性的設置值,每個NMTOKEN屬性值之間用空格分隔。具體示例如下:

<!ELEMENT 用戶 EMPTY>
<!ATTLIST  用戶 姓名 NMTOKEN #REQUIRED>
<!ELEMENT 數據 (#PCDATA)>
<!ATTLIST  數據 授權用戶 NMTOKENS #IMPLIED>

在上面的示例中,元素<用戶>的“姓名”屬性指定為NMTOKEN類型,元素<數據>的“授權用戶”屬性指定為NMTOKENS,與這段DTD定義語句對應的XML具體如下:

<用戶 姓名="張三">

<用戶 姓名="李四">

<數據 授權用戶="張三 李四">

     這里是一些授權訪問的數據

</數據>


6)NOTATION

現實世界中存在很多無法或不易用XML格式組織的數據,例如圖像、聲音、影像等等。對于這些數據,XML應用程序常常并不提供直接的應用支持,但可以通過設置NOTATION類型的屬性來讓一個外部應用程序進行處理。在DTD文件中,NOTATION定義語句分為兩種情況,具體如下:

第一種情況:<!NOTATION 符號名 SYSTEM "MIME類型">
第二種情況:<!NOTATION 符號名 SYSTEM "URL路徑名">

在上述定義語句中,第一種情況指定數據的MIME類型,第二種情況指定處理程序的URL路徑。當使用NOTATION類型作為屬性的類型時,首先要在DTD中使用<!NOTATION…>語句定義相應的notation,接下來通過一個例來演示NOTATION屬性的使用,如例5所示。


例5 notation.xml

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<!DOCTYPE 文件[
     <!NOTATION mp SYSTEM "movPlayer.exe">
     <!NOTATION gif SYSTEM "Image/gif">
     <!ELEMENT 文件ANY>
     <!ELEMENT 電影 EMPTY>
     <ELEMENT 電影 演示設備 NOTATION (mp|gif) #REQUIRED>
     <文件>
          <電影 演示設備=”mp”/>
     <文件>

在例5中,元素<電影>指定了兩種可選的演示設備,一種是movPlayer.exe,一種是用來繪制GIF圖像的應用程序。


7)ENTITY和ENTITYS

ENTITY對應的中文意思為實體(關于實體定義的細節,將在后面進行介紹)。當某個屬性的類型設置為ENTITY時,表明其屬性值必須為在DTD中使用<!ENTITY …>語句定義的一個實體(entity)的引用。接下來看一段DTD定義的語句,具體如下:


<!ENTITY itcast  "傳智播客論壇交流,www.itcast.cn">
<!ELEMENT 電影 EMPTY>
<!ATTLIST 電影 來源 ENTITY #REQUIRED>

與這段DTD定義語句對應的XML數據片斷如下:

<電影 來源="&itcast;" />

需要注意的是,只有引用實體才可以作為ENTITY類型屬性的設置值,參數實體不能用作ENTITY類型的屬性的設置值。關于參數實體和引用實體的相關講解,將在實體定義中進行詳細講解。


ENTITYS關鍵字用于表示一種列表類型,一個元素的ENTITYS類型的屬性設置值可以是多個實體的引用,每個實體的引用之間用空格分隔,具體示例如下:

<!ENTITY banner SYSTEM "http://www.itcast.cn/images/topword.gif">
<!ENTITY logo SYSTEM "http://www.itcast.cn/images/logo.gif">
<!ATTLIST image src ENTITIES #REQUIRED>

根據上面的DTD語句,如果想通過src屬性引用兩幅圖像,則對應的XML數據如下所示:

<img src="logo banner">


三、實體定義

有時候需要在多個文檔中調用同樣的內容,比如公司名稱,版權聲明等,為了避免重復輸入這些內容,可以通過<!ENTITY…>語句定義一個表示這些內容的實體,然后在各個文檔中引用實體名替代它所表示的內容。實體可分為兩種類型,分別是引用實體和參數實體,接下來,針對這兩種實體類型進行詳細地講解。

1)引用實體

引用實體的語法定義格式有兩種:

(1)<!ENTITY 實體名稱 "實體內容">
(2)<!ENTITY 實體名稱 SYSTEM "外部XML文檔的URL">

引用實體用于解決XML文檔中內容重復的問題,其引用方式方法為:

&實體名稱;

了解了引用實體的語法格式及其在XML文檔中的引用方式,接下來通過一個案例來學習,如例6和例7所示。


例6 book.dtd

<!ENTITY itcast "傳智播客官網,www.itcast.cn">
<!ELEMENT 書架 (書+)>
<!ELEMENT 書 (書名,作者,售價)>
<!ELEMENT 書名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
 <!ELEMENT 售價 (#PCDATA)>


例7 book.xml

 <?xml version="1.0" encoding="GB2312"?>
 <!DOCTYPE 書架 SYSTEM "book.dtd">
 <書架>
    <書>
        <書名>Java就業培訓教程</書名>
        <作者>&itcast;</作者>
        <售價>39.9</售價>
    </書>
    <書>
        <書名>EJB3.0入門經典</書名>
        <作者>黎活明</作者>
        <售價>39.00元</售價>
    </書>
  </書架>

用IE9.0以下的瀏覽器打開book.xml文件,瀏覽器顯示的結果如圖1所示。


1609225008024_01.jpg

圖1提示的錯誤信息是“文本內容中發現無效字符。”這是因為book.dtd文件使用的是本地字符集編碼,即GB2312編碼,而DTD文件應該使用UTF-8或者Unicode編碼。需要注意的是,IE9以上版本的瀏覽器也不會提示錯誤。


接下來我們將book.dtd按照UTF-8編碼方式進行重新保存,保存方式如圖2所示。


1609225020940_02.jpg

按照圖2的方式完成編碼保存后,用IE瀏覽器重新打開book.xml文件或者單擊圖1-10工具欄中的“刷新”按鈕,瀏覽器顯示的結果如圖3所示。


1609225035134_03.jpg

從圖1、3中可以看出,book.xml文件中的“&itcast;”被顯示成“傳智播客官網,www.itcast.cn”。


2)參數實體

參數實體只能被DTD文件自身使用,它的語法格式為:

<!ENTITY % 實體名稱 "實體內容">

需要注意的是,在聲明參數實體時,ENTITY、%、實體名和“實體內容”之間各有一個空格。


引用參數實體的方式是:

%實體名稱;

了解了參數實體的語法格式和引用方式,接下來通過一段示例代碼來演示參數實體的定義,具體如下:

<!ENTITY % TAG_NAME "姓名|EMAIL|電話|地址">
<!ELEMENT 個人信息 (%TAG_NAME; |生日)>
<!ELEMENT 客戶信息 (%TAG_NAME; |公司名)>


在上面的示例中,DTD中定義了兩個元素,分別是“個人信息”和“客戶信息”,這兩個元素的定義中都包含了“姓名| EMAIL|電話|地址”這一相同的部分,因此,可以將相同的部分定義為一個TAG_NAMES的參數實體,然后將“個人信息”和“客戶信息”這兩個元素的定義規則中的“姓名 | EMAIL | 電話 | 地址”部分替換成對TAG_NAMES這個參數實體的引用即可。


參數實體不僅可以簡化元素中定義的相同內容,還可以簡化屬性的定義,具體示例如下:

<!ENTITY % common.attributes
    'id ID #IMPLIED
    account CDATA #REQUIRED'    
>
<!ELEMENT purchaseOrder (item+, manufacturer)>
<!ELEMENT item (price, quantity)>
<!ELEMENT manufacturer (#PCDATA)>
<!ATTLIST purchaseOrder %common.attributes;>
<!ATTLIST item %common.attributes;>
<!ATTLIST manufacturer %common.attributes;>


在上面的示例中,由于多個元素都具有id和account這兩個屬性的相同定義,因此,可以將這兩個屬性的文本內容定義為一個名稱為common.attributes的參數實體。當定義元素的屬性時,通過引用common.attributes 這個參數實體,將該參數實體轉換為id和account 這兩個屬性所定義的文本內容了。


值得一提的是,當DTD的元素和屬性定義中要出現大量相同內容時,參數實體是一種非常不錯的選擇。因為如果需要修改DTD中相同的部分,只需要在參數實體的定義中修改即可。



猜你喜歡:

JDK安裝教程:Jdk怎么安裝?

Dubbo相關面試題附答案

什么是Master選舉?ZooKeeper在集群Master選舉中應用

黑馬程序員java培訓課程

分享到:
在線咨詢 我要報名
和我們在線交談!