(本系列文章是我學習的過程中,整理出來的筆記,如有錯漏,看官請一定不吝回復,讓我能認識自己的不足,并改進錯誤。非常感謝!)
本章大概內容:
1、為什么需要DTD
2、XML文檔如何使用DTD
1)內部定義DTD
2)關聯(lián)外部DTD
3、DTD的結構
1)元素類型聲明
2)屬性列表聲明
3)實體聲明
4)記號聲明
對于一個格式良好的XML文檔,我們只能保證這個文檔的格式符合XML規(guī)范,但是元素與元素的關系,元素與屬性的關系,屬性的取值,我們就無法保證了。對于一個格式良好的文檔,如果只是在有限的應用中使用,或者是用于存儲和傳輸,那么它也能能夠很好的滿足我們的應用,但是如果要其它的用戶了解你所寫的XML文檔,或者與其它應用進行數(shù)據(jù)的交換,那么就有必要提供一種機制,來保證我們寫的XML文檔和別人所寫的XML文檔在結構上是相同的,元素與元素之間的關系是正確的,屬性的取值也是符合要求的,那么這種機制在XML規(guī)范中已經為我們提供了,那就是前一章中介紹過的文檔類型聲明中提到的DTD。
DTD(Document Type Definition),文檔類型定義。
在XML標準中,描述了如何創(chuàng)建DTD,以及如何將它與根據(jù)它的規(guī)范所編寫的XML文檔相關聯(lián),并且還定義了XML處理器應該如何對DTD進行處理。有了DTD就可以檢測XML文檔的結構是否正確。
DTD為XML文檔的編寫者與處理者提供了共同遵循的原則,使得與文檔相關的各種工作有了統(tǒng)一的標準。
如何在XML文檔中引入DTD
通過在XML文檔中包含文檔類型聲明,來建立當前文檔和DTD的關聯(lián)。當進行有效性驗證的XML處理器讀到該聲明時,它獲取DTD,并根據(jù)其中定義的規(guī)則對文檔進行檢驗。文檔類型聲明必須位于XML聲明之后,且在根元素(文檔元素)之前。不過,在XML聲明和文檔類型聲明之間可以插入注釋和處理指令。
我們可以直接在XML文檔中定義DTD,也可以通過URI引用外部的DTD文件,或者同時采用這兩種方式。
上一章中,已經學習過如何通過包含文檔類型聲明來建立與DTD的關聯(lián)?,F(xiàn)在來分析一下這兩種包含方式。
在XML文檔內部給出DTD的方式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE OrganizationChart [
<!ELEMENT OrganizationChart (Name,Office)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Office (#PCDATA)>
]>
<OrganizationChart>
<!--OrganizationChart是該XML文檔的document element-->
<Name>Toone,INC.</Name>
<Office>zhuhai</Office>
<!--因為DTD中定義了Name,Office兩個元素的順序,Office元素不能放在Name元素的前面,否則不是有效的XML文檔-->
</OrganizationChart>
文檔類型聲明由<!開始,后面緊跟一個關鍵字DOCTYPE,然后是文檔根元素的名字,接下來是標記聲明塊,標記聲明塊放在中括號[]之間,由一個或者多個標記聲明構成,最后由>結束。
在DTD中,所有的關鍵字都是大寫的。不過,在DTD中定義的元素和屬性的大小寫是可以任意制定的,但是要注意,因為XML文檔是大小寫相關的,所以一旦給一個元素命名,那么在整個文檔中要使用相同的大小寫。例如,organizationchart和OrganizationChart是不同的兩個元素名。
在XML文檔中定義DTD,比較直觀,修改也比較方便,而且不用擔心XML處理器找不到DTD,但是它也有一些缺點:
1、在文檔中定義DTD會導致文檔本身的長度增加,在傳輸數(shù)據(jù)時,即使不需要驗證文檔的有效性,這些聲明也要一起傳輸。
2、如果多個XML文檔要共用同一個DTD,我們就需要在每一個文檔中加入DTD。
引進外部DTD方式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE OrganizationChart SYSTEM "dtdTest.dtd" >
<OrganizationChart>
<Name>Toone,INC.</Name>
<Office>zhuhai</Office>
</OrganizationChart>
對應DTD內容為:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT OrganizationChart (Name,Office)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Office (#PCDATA)>
在文檔類型聲明時,用管間質SYSTEM或PUBLIC來指出外部DTD文件的位置,使用SYSTEM關鍵字的聲明語法如下:
<!DOCTYPE 根元素的名字 SYSTEM "外部DTD文件的URI">
SYSTEM關鍵字表示文檔使用的是私有的DTD文件,“外部DTD文件的URI”可以是相對URI或者絕對URI。例如上面的例子使用的就是相對URI:
<!DOCTYPE OrganizationChart SYSTEM "dtdTest.dtd" >
使用PUBLIC關鍵字的聲明語法如下:
<!DOCTYPE 根元素的名字 PUBLIC "DTD的名字" "外部DTD文件的URI">
PUBLIC關鍵字用于聲明公共的DTD,并且這個DTD還有一個名稱,"DTD的名稱"也稱為公共標識符(public identifier)。這個DTD可以存放在某個公共的地方,XML處理程序會根據(jù)名稱按照某種方式去檢索DTD,如果XML處理器不能根據(jù)名稱檢索到DTD,就會使用"外部DTD文件的URI"來查找該DTD。例如Java web開發(fā)的web.xml中的DTD聲明(版本不同會稍有不同,我們只關注它的結構):
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
'http://java.sun.com/dtd/web-app_2_3.dtd'>
DTD名稱與XML名稱略有不同,他們只能包含ASCII字母和數(shù)字符號、空格、回車符、換行符和一些標點符號:-'()+,/:=?;!#@*$_%.
公共DTD名稱要遵守一些約定。如果一項DTD是ISO標準,它的名稱要以字符串"ISO"開始。如果是一個非ISO的標準組織批準的DTD,它的名字以加號(+)開始。如果不是標準組織批準的DTD,它的名稱以連字符(-)開始。這些開始字符或字符串后接雙斜杠(//)和DTD所有者的名字(比如上面例子的Sun Microsystems,Inc.),之后是另一個雙斜杠和DTD描述的文檔類型,接著優(yōu)勢一個雙斜杠后接ISO 639語言標識符,如EN表示英語,ZH表示中文。例如:
<!DOCTYPE OrganizationChart PUBLIC "-//Jason Chen//DTD organization chart 1.0//ZH" "dtdTest.dtd">
在上一章我們提到,如果我們的文檔不依賴于外部文檔,在XML聲明中,可以通過standalone="yes"來聲明這個文檔是獨立的文檔。如果文檔依賴于外部文檔,可以通過standalone="no"來聲明。當我們使用外部DTD文件時,就需要將屬性standalone的值設置為"no"。
在實際應用中,很少使用standalone屬性,它的主要用途是作為XML處理器行業(yè)其他應用程序的標志,表示是否需要獲取外部內容。如果文檔依賴于外部文檔,即使我們不使用standalone屬性,XML處理器也能很好地進行處理。
DTD的結構:
DTD的結構一般由以下四種聲明構成:
1、元素類型聲明
2、屬性列表聲明
3、實體聲明
4、記號聲明
一個典型的文檔類型定義文件會吧所要創(chuàng)建的XML文檔的元素結構、屬性類型、實體引用等預先進行定義。
下面分別介紹這四種聲明。
1、元素類型聲明:
一個DTD不僅要告訴XML處理器它所對應的文檔根元素,而且還要告知處理器,文檔的內容和結構,描述清楚文檔結構中的每一個細節(jié)。
元素類型聲明不但說明了每一個文檔中可能存在的元素,給出了元素的名稱,而且給出了元素的具體類型。
一個XML元素可以為空,也可以只包含字符數(shù)據(jù),還可以有若干個子元素,而這些子元素同時又可以擁有它們的子元素。
元素類型聲明采用如下的語法格式:
<!ELEMENT 元素名稱 元素內容說明>
元素內容說明可以指明五種可能的元素內容形式:#PCDATA、子元素、混合內容、EMPTY和ANY。
下面詳細說明每一種元素內容說明。
#PCDATA:
關鍵字#PCDATA說明元素包含字符數(shù)據(jù)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE OrganizationChart [
<!ELEMENT OrganizationChart (Name,Office)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Office (#PCDATA)>
]>
<OrganizationChart>
<Name>Toone,INC.</Name>
<Office>ZhuHai</Office>
</OrganizationChart>
子元素:
當一個元素只包含子元素,而沒有字符數(shù)據(jù)時,則稱此元素類型具有元素型內容(element content)。
在該類型的元素聲明時,通過內容模型來指定在其內容上的約束。內容模型是決定子元素類型和子元素出現(xiàn)順序的一種簡單語法。