DTD約束簡介

 

DTD約束簡介

文檔類型聲明網絡

文檔類型聲明就是DOCTYPE,它告訴解析器,XML文檔必須遵循DTD定義。同時,他也告訴解析器,到哪裏找到文檔定義的其他內容。在前邊的例子裏DOCTYPE很簡單:編輯器

<!DOCTYPE students[]>spa

文檔類型聲明以<!DOCTYPE開始,而後是根標籤的名字,咱們這裏根標籤是students因此寫的是students,注意<!DOCTYPE和students之間有一個空格,這個空格必須有。這裏聲明之後就意味着文檔中根標籤必須是students。code

在根元素的後邊有幾種不一樣的狀況,上邊的例子裏,緊跟在跟標籤的是一對[]咱們全部DTD都是在[]中間編寫的。orm

還有一種狀況DTD是單獨保存到一個外部文件中的,咱們須要在聲明中引入外部的DTD文件。引入外部的DTD文件主要有兩種方式:系統標識符、公共標識符。xml

系統標識符圖片

利用系統標識符咱們能夠聲明一個外部DTD文件的位置,它由兩部分組成:關鍵字SYSTEM和指向文檔位置的URI引用。URI能夠是硬盤上的一個文件,也能夠是網絡中的一個文件。ip

<!DOCTYPE students SYSTEM 「students.dtd」 []>開發

 

<!DOCTYPE students SYSTEM 「file:///c:/students.dtd」 []>文檔

 

<!DOCTYPE students SYSTEM 「http://www.xxx.com/xx.dtd」 >

上邊三種都是使用系統標識符的例子,SYSTEM關鍵字後邊能夠根的是一個硬盤上文件的地址,也能夠是一個網絡中的地址,最後一個例子沒有[]這個也是徹底能夠的。

公共標識符

公共標識符是定義外部DTD的第二種方法:

<!DOCTYPE students PUBLIC 「-//ATGUIGU//DTD students//EN」 「students.dtd」>

和系統標識符相似,公共標識符以PUBLIC開始,其後緊跟一個專用標識符,可是公用標識符不是用來表示文件的引用,而是表示目錄中的一個記錄。

根據XML規範公共標識符能夠採用任意格式,可是常常採用的一種格式是正式公共標識符(Formal Public Identifier,FPI)。

FPI語法結構:-//全部人//文件描述//語言//版本。

可是大多數的解析器是不能解析公共標識符的,因此咱們通常還會在公共標識符後邊加一個系統標識符,如上公共標識符」-//ATGUIGU//DTD students//EN」後邊咱們加了一個空格,空格後邊的」students.dtd」就是一個系統標識符。

這一段的意思就是解析器先會嘗試經過公共標識符尋找DTD文件,若是找不到在經過系統標識符獲取。

外部DTD文件

接下來咱們嘗試建立一個外部DTD約束文件,並將它引入到當前文檔中。利用外部的DTD約束文件能夠很方便的將經常使用的約束信息和他人共享,而再也不須要重複定義。

這裏咱們嘗試將剛纔的students的約束定義爲一個外部的DTD約束,首先咱們建立一個純文本文件,名稱保存爲students.dtd。內容以下:

<!ELEMENT students (student)*>

<!ELEMENT student (name , age , gender , address)>

<!ATTLIST student id CDATA #REQUIRED>

在建立一個新的xml文件,並經過公共標識符的方式將以上約束引入:

<!DOCTYPE students PUBLIC 「//ATGUIGU//DTD students//EN」 「students.dtd」>

重複上邊的步驟對編寫後的文檔進行驗證,咱們會發現當文檔內容不符合咱們定義的規則時,一樣會報錯,而且若是使用的帶有自動提示功能的編輯器時(如Eclipse)在輸入XML標籤時還會彈出提示。

2.3.2 DTD聲明

一個完整的DTD聲明由三個基本部分組成:元素聲明、屬性聲明、實體聲明。

元素聲明

當咱們用DTD定義一個XML文檔的內容是,必須用DTD定義文檔裏的每個元素。讀者將會明白,DTD也能夠對可選元素進行聲明。可選元素是指在XML文檔中可能出現,也可能不出現的元素。

<!ELEMENT students (student)*>

元素聲明的基本語法:<!ELEMENT 元素名 元素內容模型>,使用!ELEMENT聲明一個元素,接下類是元素名也就是標籤名,元素內容模型跟在元素名的後邊。一個元素的內容模型定義了可容許的元素內容。一個元素可能包含一個子元素、一段文本或子元素域文本的組合,也容許元素內容爲空。這正是DTD的核心,這樣就能夠定義文檔的結構。就XML推薦標準而言,有四類內容文檔,它們是:元素內容、混合內容、空內容、任意內容。

在XML中元素中能夠有子元素,咱們能夠經過DTD來定義某個元素中能夠包含哪些子元素,爲了頂一個元素中能夠包含哪些子元素,咱們只需將子元素名寫在父元素後邊的()中。例如若是一個students標籤中只容許有一個student元素,則定義以下:

<!ELEMENT students (student)>

事實上在students元素中是能夠出現多個student的,只須要在()後邊多加一個*,以下:

<!ELEMENT students (student)*>

還可使用其餘符合?表示一次或零次,+表示一次或屢次,*表示零次或屢次。

在student標籤中能夠有name、age、gender、address,則能夠在()中編寫都給元素名,使用,分割。以下:

<!ELEMENT student (name , age , gender , address)>

使用,分割表明子元素必須按照這樣的順序出現,即age必須在name後,gender必須在age後,address必須在gender後。若是不要求子元素的順序可使用|分割子標籤:

<!ELEMENT student (name|age|gender|address)>

若是元素中的內容是純文本的內容,使用#PCDATA定義:

<!ELEMENT name #PCDATA>

若是元素僅僅是一個空元素,也稱爲自結束標籤咱們可使用EMPTY來定義:

<!ELEMENT br EMPTY>

ANY表示在元素中能夠定義任意內容:

<!ELEMENT test ANY>

屬性聲明

使用ATTLIST關鍵字聲明元素中的屬性

<!ATTLIST student id CDATA #REQUIRED>

上邊這個例子爲student元素聲明一個id屬性。

ATTLIST聲明包括三部分的基本內容:ATTLIST關鍵字、相應的元素名、屬性列表。一個ATTLIST能夠定義任意個屬性,每一個屬性由三部分組成屬性名、屬性類型、屬性值聲明。咱們來看一個下咱們聲明的id屬性:

id CDATA #REQUIRED

這個屬性聲明裏,屬性名是id,關鍵字CDATA是屬性類型,它表示id屬性的值是字符數據,最後的#REQUIRED關鍵字,表示屬性時必須的。

屬性名這裏沒有什麼好說的,就是要注意屬性名要符合XML的規範。主要說一下屬性的類型,在聲明屬性時,咱們必須說明處理器如何處理屬性值中的字符數據。屬性主要有以下幾個類型:

類型

描述

CDATA

字符數據。

ID

惟一肯定的屬性值

IDREF

屬性值是一個ID的引用,引用一個標識的惟一元素

IDREFS

屬性值爲一個用空格分隔的IDREF列表

ENTITY

屬性值是一個外部非解析實體(圖片、mp3)

ENTITIES

屬性值是一個用空格分隔的ENTITY列表

NMTOKEN

屬性值是一個名稱標記

NMTOKENS

屬性值是一個有空格分隔的NMTOKEN列表

Enumerated List

枚舉類型

在聲明屬性時,須要說明屬性值的取值方式。一般,咱們但願在聲明屬性時,指定一個默認值;有時,咱們但願在文檔中給屬性賦值;而在其餘時候,咱們要求屬性值爲某個固定值。聲明屬性時必須說明這些特性。根據XML推薦標準,屬性值能夠有4種,默認值、固定值、必須值、隱含值(或可選值)。

默認值就是元素沒有設置屬性,或者某個屬性沒有設置值時,也但願該屬性有某個值,這個值就是默認值。可是若是一旦爲屬性設置了一個值則默認值再也不有效。設置默認值很是簡單,只需在屬性類型後插入一個引號表示的值便可:

<!ATTLIST student duty (班長|組長|學生) 「學生」>

這裏咱們爲student標籤增長了一個duty的必須屬性,這個屬性有三個可選值,班長、組長、學生。當咱們沒有指定該屬性時,默認認爲duty爲學生。

注意不能爲ID類型的屬性指定默認值。

在某些情形中,屬性值是固定不變的。若是某個屬性值固定不變,那麼是使用#FIXED關鍵字,以後緊跟着這個固定值。固定值在許多方面與默認值類似。當解析器正則解析文檔時,遇到一個固定值屬性時,就把這個固定值插入到這個屬性裏。

固定值常見應用是指定版本號。DTD的做者常常爲某個專用的DTD文件指定一個固定的版本號:

<!ATTLIST students version CDATA #FIXED 「1.0」>

XML文檔中有一些屬性時必須有的這些屬性就叫作必須值,咱們使用#REQUIRED關鍵字將一個屬性設置爲必須值:

<!ATTLIST student id CDATA #REQUIRED>

如上咱們的id屬性就是一個必須值,若是student標籤中沒有id屬性則解析器會報錯。若是一個屬性已經設置爲必須值了,則不能再爲這個屬性指定默認值。

還有一些屬性既不是必需值,也沒有默認值或固定值。這種狀況下該屬性可能會出如今元素裏,也可能不出如今元素裏。咱們一般把這些元素稱爲可選值。使用#IMPLIED聲明一個可選屬性:

<!ATTLIST student class CDATA #IMPLIED>

在同一個ATTLIST中能夠建立多個屬性的聲明也很簡單,以下:

<!ATTLIST student id CDATA #REQUIRED

                  duty (班長|組長|學生) 「學生」>

一樣也可使用多個ATTLIST標籤設置:

<!ATTLIST student id CDATA #REQUIRED>

<!ATTLIST student duty (班長|組長|學生) 「學生」>

實體聲明

若是要把某個特殊字符插入到XML文檔裏,要使用轉義字符或實體應用。XML內置了5個實體,用於在XML文檔裏插入特殊字符。除了這個5個內置實體外,咱們還能夠利用字符引用表示一些難以輸入的字符,例如:咱們可使用’表明單引號,使用 ;表明©等。事實上,在XML文檔裏實體不限於這些簡單字符的引用。在文檔裏,實體能夠是一段要替換的文本,能夠是其餘的XML標記,甚至能夠是外部文件。咱們把實體分爲4大類,每一類均可以插入到XML文檔裏:內置實體、字符實體、通常實體、參數實體。

內置實體,在XML中默承認以使用5個實體:  

實體

字符

&amp;

&

<

<

>

>

這5個是內置實體,這是由於根據XML標準推薦,全部的XML解析器默認時都必須支持這5個實體。它們不須要再DTD裏定義,咱們立刻就要看到,其餘類型的實體,在插入到文檔以前必須如今DTD中定義。

字符實體和內置實體很像,不須要再DTD中聲明。它們能夠直接用在元素內容和屬性內容裏。字符實體引用經常使用來表示不容易出入的字符,或非ASCII字符。

與內置實體同樣,要在文檔中使用字符實體,必須在文檔裏插入字符實體的引用。引用字符實體的語法與引用5個內置實體的語法很是類似。如 ;表明©。實際上字符實體和內置實體最大的區別就是字符實體沒有實體名。第一個個字符時&,而後是一個#,而不是是提名,緊跟其後的是一個數字,本例是169,踏實©字符的Unicode碼。結尾是一個;。

與內置的實體引用同樣,凡是運行使用普通文本的地方,如元素的內容和屬性值,均可以使用字符實體。在DTD定義裏也可使用字符實體。與內置實體同樣,字符實體不能代替實際的XML標記,也不能做爲元素名或屬性名的一部分。

通常實體的做用與5個內置實體的做用很是類似,可是前者必須在XML文檔中使用以前,先在DTD中定義。最多見的情形是,XML開發人員利用普通實體,創建能夠重用的替換文本段。

在XML中聲明普通實體有兩種方式:能夠直接聲明實體的值,或者指向一個外部文件。首先咱們來看在DTD文件中直接定義實體的值:

<!ENTITY wirter 「ATGUIGU lilichao」>

語法:<!ENTITY 實體名 引用內容>,聲明完這個實體咱們就能夠經過&實體名;在文檔中使用實體,好比使用&writer;就表明ATGUIGUI lilichao這句話。

這裏還能夠將實體的值做爲一個外部文件引入,和經過DOCTYPE引如外部的DTD文檔很像:

<!ENTITY wirter SYSTEM 「test.txt」>

或者也可使用公共標識符:

<!ENTITY wirter PUBLIC 「-//ATGUIGU//DTD students//EN」 「test.txt」>

這樣在使用聲明時,就是表明的引用的外部文件中的內容。

相關文章
相關標籤/搜索