在講解DTD文件以前,我要說說一份合格的XML應該符合怎麼樣的規則?java
就我總結一下幾點,你們看看就行了:python
1.一份XML有且僅有一個根元素。編碼
2.XML是嚴格區分大小寫的,<book>元素和<Book>元素是不相同的。spa
3.若是一個元素不須要子內容的話,它就是一個空元素,應寫成:<元素名 />,就不要寫成這樣了:<元素名><元素名 />code
4.XML文檔開頭聲明:xml
<?xml version="1.0" encoding="UTF-8"?>
聲明以"<?"開頭,以"?>"結束,中間version屬性是必須的,是指該文檔遵照XML1.0的規範,encoding是XML進行解碼的時候所用的字符集,注意是解碼不是編碼,默認是用utf-8,該屬性是可選的,此外還可能接觸到一個standalone,它指定的是是否引用其餘資源,它的值只有yes跟noblog
5.若是元素中有空白字符的話,XML會原樣保留,而HTML會把多個刪除成一個再輸出圖片
6.XML預留了幾種實體引用::<:表明着小於號,>表明着大於號,&:表明and符號,'表明英文的單引號,"表明英文的雙引號,經過這些內置的實體引用,能夠避免文檔符號的衝突,保持良好的文檔規範。utf-8
7.CDATA標記:在CDATA標記下,裏面的內容都是當作字符串來處理,即便是合法的字符,也會當作字符來處理。資源
<?xml version="1.0" encoding="UTF-8"?> <book> <describe> <![CDATA[ <a> author:xujianguo </a> ]]> </describe> </book>
輸出<a>xujianguo</a>
8.註釋格式:<!-- 註釋內容 -->
下面正式講解一下DTD文件:
DTD文件爲何存在?
一份XML文件下來,若是你沒有添加約束條件的話,你要怎麼寫就怎麼寫,很不規範,同時也意味着別人不熟悉你的XML文件的條件下也能夠操做你的XML文件,而經過DTD約束文件,能夠約束每一個元素內部能夠出現哪些子元素,能夠支持什麼屬性,這個就是DTD存在的理由了。
引入的DTD:
方法一:內部DTD - 就是將DTD與XML數據定義放在同一個文檔中,格式以下:
<?xml version="1.0" encoding="UTF-8"?> <! DOCTYPE 根元素名[ 元素描述 ]> XML文檔主體部分
由上面咱們也能夠看出一個引入DTD最開始的格式了:
<! DOCTYPE 根元素名[ 元素描述 ]>
方法二:外部DTD - 就是將外部DTD的地址告訴XML,因此在XML中要說明一下地址在哪裏。格式:<! DOCTYPE 根元素名 SYSTEM "外部DTD的URI">
如今假設在本身XML文檔的相同路徑下有個book.dtd文件,就能夠這樣引入:
<?xml version="1.0" encoding="UTF-8"?> <! DOCTYPE book SYSTEM "book.dtd"> <book> <describe> <![CDATA[ <a> author:xujianguo </a> ]]> </describe> </book>
定義元素:
格式:<!ELEMENT 元素名 元素類型描述>
元素類型描述主要有以下幾種:
類型 | 描述 | 語法 |
任意類型 | 這種元素便可以是字符串,也能夠是其餘子元素 | <!ELEMENT 元素名 ANY> |
字符串值 | 這種元素只能是字符串,不能包含其餘子元素 | <!ELEMENT 元素名 (#PCDATA)> |
空元素 | 這種元素只能爲空元素,空元素前面有介紹 | <!ELEMENT 元素名 EMPTY> |
包含子元素 | 元素中能夠出現子元素 | <!ELEMENT 父元素 (子元素)> |
混合類型 | 能夠出現以上的類型 | <!ELEMENT 父元素 (#PCDATA|子元素|子元素|子元素...)> |
如今咱們就利用上面所學的知識簡單的寫一個DTD:
language.dtd:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language ANY> <!ELEMENT codeLanguage (#PCDATA | Java | C | Python)* > <!ELEMENT Java (#PCDATA)> <!ELEMENT C EMPTY> <!ELEMENT Python EMPTY>
language.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "language.dtd"> <language> <C /> <codeLanguage> <C /> <Python /> <Java> I am Java </Java> </codeLanguage> <codeLanguage> Other Language </codeLanguage> </language>
下面講解的是有關子元素的一些知識點:
定義有序的子元素:若是使用引文英文逗號(,)做爲子元素之間的分隔符,則子元素之間必須遵照定義的順序。
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language (codeLanguage)> <!ELEMENT codeLanguage (Java, C, Python)> <!ELEMENT Java (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT Python (#PCDATA)>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "test.dtd"> <language> <codeLanguage> <Java/> <C/> <Python/> </codeLanguage> </language>
上面的Java、C、Python是按照定的順序來的
定義互斥的子元素:互斥的子元素表名一系列子元素之間只能出現其中的一個,互斥的子元素用豎線(|)分隔
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language (codeLanguage)*> <!ELEMENT codeLanguage (Java | C | Python)> <!ELEMENT Java (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT Python (#PCDATA)>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "test.dtd"> <language> <codeLanguage> <Java> I am Java </Java> </codeLanguage> <codeLanguage> <C> I am C </C> </codeLanguage> <codeLanguage> <Python> I am Python </Python> </codeLanguage> </language>
子元素出現的頻率:
符號表:
符號 | 表示頻率 |
+ | 代表子元素能夠出現1次或者屢次 |
* | 代表子元素能夠出現0次或者屢次 |
? | 代表子元素能夠出現0次或者1次 |
定義無序的子元素:DTD沒有專門爲定義無序的子元素提供特定的語法,若是但願定義無序的元素的話,經過前面的語法和頻率組合來實現
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language (codeLanguage)*> <!ELEMENT codeLanguage (Java | C | Python)+> <!ELEMENT Java (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT Python (#PCDATA)>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "test.dtd"> <language> <codeLanguage> <Java> I am Java </Java> <Python> I am Python </Python> </codeLanguage> <codeLanguage> <Python> I am Python </Python> <C> I am C </C> </codeLanguage> <codeLanguage> <Python> I am Python </Python> <C> I am C </C> <C> I am C </C> </codeLanguage> </language>
定義元素屬性:
DTD爲XML添加屬性提供了支持,DTD中定義屬性的語法格式:<!ATTLIST 屬性所屬的元素 屬性名 屬性類型 [元素對屬性的約束][默認值]>
元素對屬性的約束介紹表:
約束 | 描述 |
#REQUIRED | 必需的屬性,意味着必須爲該元素指定該屬性 |
#IMPLIED | 該屬性無關緊要 |
#FIXED | 該屬性的值是固定的,定義時必須指定固定值 |
DTD支持的屬性類型:
類型 | 說明 |
CDATA | 該屬性值只能是字符串數據 |
(en1 | en2 | en3) | 該屬性值是一系列枚舉值之一 |
ID | 該屬性值必須是有效的標示符,且該屬性值可用於表示該元素,在XML中必須惟一 |
IDREF | 該屬性值必須引用自另外一個已有的ID屬性值 |
IDREFS | 該屬性值必須引用自多個已有的ID屬性值,多個ID屬性值之間用空格隔開 |
NMTOKEN | 該屬性值必須是一個合法的XML名稱,它也指定了該屬性值是字符串數據,但比CDATA具備更強的約束,它 代表屬性值只能由字母、數字、英文下劃線、英文中劃線、英文點號、英文冒號等組成 |
NMTOKENS | 該屬性值能夠是多個NMTOKEN,過個NMTOKEN之間用空格隔開 |
ENTITY | 該屬性值是一個外部實體,例如圖片文件 |
ENTITIES | 該屬性值是多個外部實體,多個實體之間用空格隔開 |
NOTATION | 該屬性值是在DTD聲明過的符號(NOTATION),這是個將要過時的規範看,避免使用 |
xml: | 該屬性值是一個預約義的XML值 |
下面一個例子演示一個有關枚舉類型、ID、IDREF、IDREFS、NMTOKEN和NMTOKENS類型的使用:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language (codeLanguage)*> <!ELEMENT codeLanguage (Java | C | Python)+> <!ELEMENT Java (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT Python (#PCDATA)> <!ATTLIST Java type (JavaSE | JavaEE | JavaME) #REQUIRED> <!ATTLIST C id ID #REQUIRED> <!ATTLIST Python ref IDREF #IMPLIED> <!ATTLIST Python refs IDREFS #IMPLIED> <!ATTLIST codeLanguage author NMTOKEN #IMPLIED>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "test.dtd"> <language> <codeLanguage author="xujianguo"> <Java type="JavaEE"> I am JavaEE </Java> <C id="c"> I am C </C> <C id="ccc"> I am C </C> <Python ref="c"> I am Python </Python> <Python refs="c ccc"> I am Python </Python> </codeLanguage> </language>
下面你們來看看怎麼定義實體:
語法格式:<!ENTITY 實體名 "實體值">
使用實體的語法格式:&實體名;
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT language (codeLanguage)*> <!ELEMENT codeLanguage (Java | C | Python)+> <!ELEMENT Java (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT Python (#PCDATA)> <!ATTLIST Java type (JavaSE | JavaEE | JavaME) #REQUIRED> <!ATTLIST C id ID #REQUIRED> <!ATTLIST Python ref IDREF #IMPLIED> <!ATTLIST Python refs IDREFS #IMPLIED> <!ATTLIST codeLanguage author NMTOKEN #IMPLIED> <!ENTITY java "I am Java"> <!ENTITY c "I am C"> <!ENTITY python "I am Python">
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "test.dtd"> <language> <codeLanguage author="xujianguo"> <Java type="JavaEE"> &java; </Java> <C id="c"> &c; </C> <C id="ccc"> &c; </C> <Python ref="c"> &python; </Python> <Python refs="c ccc"> &python; </Python> </codeLanguage> </language>