給XML檔案定義DTD
DTD是Document Type Definition(文件型別定義)的縮寫。它通過定義元素、屬性、標記以及文件中的實體及其相互關係等規則來保證XML文件的合法性。
1.DTD的宣告方式分為內部宣告與外部宣告
內部宣告的格式是
<!ELEMENT 根元素 (元素1,元素2)>
<!ELEMENT 元素1 (#PCDATA)>
<!ELEMENT 元素2 (#PCDATA)>
]>
外部宣告的格式分兩種,對應的關鍵字為"SYSTEM"與"PUBLIC"
<!-- 這裡的外部DTD檔案,若不指明 絕對路徑,則必須是和xml檔案在同一目錄,否則無效 -->
"PUBLIC"宣告的DTD檔案通常是一個由權威機構制訂的,提供給特定行業或公眾使用的DTD。
2.元素型別宣告
DTD中使用的元素內容型別有:EMPTY、ANY、Mixed、Elements
EMPTY是指元素不能有任何的內容,但可以有屬性:
<!ELEMENT 元素1 EMPTY>
<!ATTLIST 元素1 性別 (男|女) "男">
<!-- XML檔案部分 -->
<元素1 性別="女" />
<!-- 這裡若是以<元素1></元素1>的形式出現,即使裡面沒有任何資料,也會產生錯誤 -->
ANY說明元素可以有任何型別的子元素,也可以是純文字,還可以為空
這裡需要特別注意的是,雖然用ANY定義的元素可以包含其它元素,但必須遵循XML檔案的"有效的"原則,即XML檔案規定檔案中所使用的任何元素都必須在DTD中給出定義
看下面這段非法的檔案:
<!DOCTYPE 圖書資訊 [
<!ELEMENT 圖書資訊 ANY>
]>
<圖書資訊>
<書名>新概念英語</書名>
</圖書資訊>
編譯器會提示這樣一條錯誤資訊
"This file is not valid: Element '書名' has not been declared."
就是提示"書名"這個元素沒有經過定義,要糾正這個錯誤,只要在DTD定義部分加入定義語句"<!ELEMENT 書名 (#PCDATA)>"就可以了
Mixed允許混合內容使得字元資料和其他元素能在元素內共存,它並不是以關鍵字的形式存在的
<!DOCTYPE 圖書資訊 [
<!ELEMENT 圖書資訊 (#PCDATA|書名|價格)*>
<!ELEMENT 書名 (#PCDATA)>
<!ELEMENT 價格 (#PCDATA)>
]>
<圖書資訊>
今日新到圖書:
<書名>
XML實用教程
</書名>
<價格>
¥26.00
</價格>
</圖書資訊>
Elements規定特定子元素必須按規則與順序出現,子元素後可以用各種元字元來說明出現的次數
<!ELEMENT 元素4 (子元素1,子元素2,子元素3)>
可能出現的元字元:
元字元 | 含義 |
+ | 出現1次或多次 |
* | 出現0次或多次 |
? | 出現0次或1次 |
無符號 | 只能出現1次 |
下面的例子中,"IT求職"的各項子元素必須按順序和元字元說明的次數來出現
<!DOCTYPE IT求職 [
<!ELEMENT IT求職 (招聘資訊)+>
<!ELEMENT 招聘資訊 (公司名,招聘職位+,公司網站?,聯絡方式*)>
<!ELEMENT 公司名 (#PCDATA)>
<!ELEMENT 招聘職位 (#PCDATA)>
<!ELEMENT 公司網站 (#PCDATA)>
<!ELEMENT 聯絡方式 (#PCDATA)>
]>
<IT求職>
<招聘資訊>
<公司名>中興通訊</公司名>
<!--這裡招聘職位出現了2次-->
<招聘職位>1.Java高階工程師</招聘職位>
<招聘職位>2.C++高階工程師</招聘職位>
<!--這裡公司網站出現了1次-->
<公司網站>http://www.zte.com.cn/</公司網站>
<!--這裡聯絡方式出現了2次-->
<聯絡方式>地址:深圳市南山區高新技術產業園科技南路中興通訊大廈</聯絡方式>
<聯絡方式>電話:0755-26770000</聯絡方式>
</招聘資訊>
<招聘資訊>
<公司名>
阿里巴巴
</公司名>
<!--這裡招聘職位出現了1次-->
<招聘職位>軟體測試工程師</招聘職位>
<!--沒有出現公司網站-->
<!--沒有出現聯絡方式-->
</招聘資訊>
</IT求職>
3.定義有效的元素屬性
在DTD中定義屬性時,我們採用下面的格式:
<!ATTLIST 元素名 屬性名 (屬性值 屬性型別 預設值)*>
例如:
<!ATTLIST 作者
姓名 CDATA #REQUIRED
性別 (男|女) "男"
聯絡方式 CDATA #IMPLIED
>
根據XML檔案是否必須為一個屬性提供取值,屬性的預設值又可以分為以下四類:
- 必須賦值的屬性REQUIRED
- 屬性值可有可無的屬性IMPLIED
- 固定取值的屬性FIXED
- 自定義的預設值
下面用一個例子來說明這四類預設屬性
<!DOCTYPE 圖書資訊 [
<!ELEMENT 圖書資訊 (書名,作者,價格)*>
<!ELEMENT 書名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 價格 (#PCDATA)>
<!ATTLIST 作者
姓名 CDATA #REQUIRED
性別 (男|女) "男"
聯絡方式 CDATA #IMPLIED
分類 CDATA #FIXED "WEB程式設計技術"
>
]>
<圖書資訊>
<書名>ASP.NET案例開發集錦</書名>
<作者 姓名="趙輝、楊麗敏"/>
<價格>37.00</價格>
<書名>C#高階程式設計</書名>
<作者 姓名="wrox" 聯絡方式="http://www.wrox.com"/>
<價格>128.00</價格>
<書名>HTML XHTML CSS基礎教程(第6版)</書名>
<作者 姓名="Elizabeth Castro" 分類="WEB程式設計技術"/>
<價格>50.00</價格>
<書名>ASP.NET 2.0 應用開發技術</書名>
<作者 姓名="孟憲會(net_lover)" 性別="男"/>
<價格>59.00</價格>
</圖書資訊>
上面的例子為子元素"作者"定義了4個屬性,分別是"姓名"(#REQUIRED型別)、"聯絡方式"(#IMPLIED型別)、"分類"(#FIXED型別)、"性別"(自定義型別)
在第一本書《ASP.NET案例開發集錦》中,只出現了"姓名",但其實際屬性有兩項,還有一個是#FIXED型別的"分類"
在第二本書《C#高階程式設計》中,除了必須出現的"姓名",還出現了#IMPLIED型別的"聯絡方式",算上#FIXED型別的"分類",實際屬性有三項
在第三本書《HTML XHTML CSS基礎教程(第6版》中,除了"姓名",還顯式出現了#FIXED型別的"分類",它的實際屬性與第一本書相同
在第四本書《ASP.NET 2.0 應用開發技術》中,"姓名"後出現了自定義屬性"性別",它只有兩個值"男"和"女",預設為"男",出現其他值將顯示錯誤
屬性型別分為以下10種:
- CDATA
- Enumerated
- ID
- IDREF
- IDREFS
- ENTITY
- ENTITIES
- NMTOKEN
- NMTOKENS
- NOTATION
CDATA和Enumerated(列舉型別)在上面的例子中已有所說明,主要研究一下其他的屬性型別:
·ID屬性型別
每個ID型別的屬性必須有不同的值,大多數ID屬性使用#REQUIRED,且ID型別和#FIXED不相容.屬性不能既是固定的,又有ID型別.這是因為#FIXED屬性只能有一個值
看下面的錯誤示例:
<!DOCTYPE 職員資訊 [
<!ELEMENT 職員資訊 (普通職員)*>
<!ELEMENT 普通職員 (#PCDATA)>
<!ATTLIST 普通職員 編號 ID #REQUIRED>
]>
<職員資訊>
<普通職員 編號="8">張三</普通職員>
<普通職員 編號="E8">李四</普通職員>
<普通職員 編號="E8">王五</普通職員>
</職員資訊>
上面的檔案有2個錯誤,一個是 編號="8" 這裡,ID屬性不能是純數字,必須要以字母或下劃線開頭;另一個是出現了兩個"E8"的編號,這與ID屬性的定義是相違背的.
·IDREF屬性型別
具有IDREF型別的屬性的值是文件中另一個元素的ID
<!DOCTYPE 武將資訊 [
<!ELEMENT 武將資訊 (姓名)*>
<!ELEMENT 姓名 (#PCDATA)>
<!ATTLIST 姓名 編號 ID #REQUIRED>
<!ATTLIST 姓名 君主 IDREF #IMPLIED>
]>
<武將資訊>
<姓名 編號="P1">曹操</姓名>
<姓名 編號="P2">劉備</姓名>
<姓名 編號="P3">孫權</姓名>
<姓名 編號="P4" 君主="P1">許楮</姓名>
<姓名 編號="P5" 君主="P2">關羽</姓名>
<姓名 編號="P6" 君主="P3">甘寧</姓名>
</武將資訊>
上面的例子中,由於"君主"屬性指定為IDREF,所以其內容必須為ID屬性的"編號"裡的值
·IDREFS屬性型別
IDREF屬性的值只能為一個.但如果要描述一對多的關係,例如三國裡所有人都只有一個君主,但卻會有多個子女.這時候就要用到IDREFS屬性了
<!DOCTYPE 武將資訊 [
<!ELEMENT 武將資訊 (姓名)*>
<!ELEMENT 姓名 (#PCDATA)>
<!ATTLIST 姓名 編號 ID #REQUIRED>
<!ATTLIST 姓名 子女 IDREFS #IMPLIED>
]>
<武將資訊>
<姓名 編號="C1">關平</姓名>
<姓名 編號="C2">關興</姓名>
<姓名 編號="C3">孫策</姓名>
<姓名 編號="C4">孫權</姓名>
<姓名 編號="C5">孫尚香</姓名>
<姓名 編號="F1" 子女="C1 C2">關羽</姓名>
<姓名 編號="F2" 子女="C3 C4 C5">孫堅</姓名>
</武將資訊>
·ENTITY屬性型別
ENTITY型別屬性使人們能把外部二進位制資料(即外部未解析的普通實體)連結到文件,ENTITY屬性的典型例子是一幅影像,該影像由來自與另一個URL的二進位制資料組成
<!DOCTYPE 影像 [
<!ELEMENT 影像 EMPTY>
<!ATTLIST 影像 來源 ENTITY #REQUIRED>
<!ENTITY Logo SYSTEM "logo.gif">
]>
<影像 來源="&Logo;"/>
·ENTITIES屬性型別
ENTITIES是ENTITY的複數形式.ENTITIES型別的屬性值由空格分隔多個未解析的實體名稱組成.每個實體名稱引用一個外部的非XML資料來源.這個方法的一個用途是輪流顯示不同圖片的幻燈片,如下所示:
<!DOCTYPE 幻燈片 [
<!ELEMENT 幻燈片 EMPTY>
<!ATTLIST 幻燈片 來源 ENTITY #REQUIRED>
<!ENTITY PIC1 SYSTEM "picture1.jpg">
<!ENTITY PIC2 SYSTEM "picture2.gif">
<!ENTITY PIC3 SYSTEM "picture3.jpg">
]>
<幻燈片 來源="&PIC1; &PIC2; &PIC3;"/>
·NMTOKEN屬性型別
NMTOKEN屬性型別限制有效的XML名稱記號的屬性值,除了空格,任何字元都被認為是有效的.
<!DOCTYPE 客戶資料 [
<!ELEMENT 客戶資料 (聯絡地址)*>
<!ELEMENT 聯絡地址 (#PCDATA)>
<!ATTLIST 聯絡地址 城市 NMTOKEN #REQUIRED>
]>
<客戶資料>
<聯絡地址 城市="London">張三</聯絡地址>
<聯絡地址 城市="010北京">李四</聯絡地址>
<聯絡地址 城市="New York">王五</聯絡地址>
</客戶資料>
上面的例子,"010北京"雖然是以數字開頭,但由於是NMTOKEN型別,所以它也是合法的.但最後的"New York"為非法,因為NMTOKEN型別限制了空格的使用
·NMTOKENS屬性型別
NMTOKENS是NMTOKEN的複數形式,它允許出現一組值,同NMTOKEN的規則一樣,不限制符號的使用。它可以出現空格,但空格的作用是分割不同的記號
<!DOCTYPE 註冊資訊 [
<!ELEMENT 註冊資訊 (使用者資料)*>
<!ELEMENT 使用者資料 (#PCDATA)>
<!ATTLIST 使用者資料 愛好 NMTOKENS #REQUIRED>
]>
<註冊資訊>
<使用者資料 愛好="足球 籃球">張三</使用者資料>
<使用者資料 愛好="唱歌 跳舞">李四</使用者資料>
<使用者資料 愛好="Play the Piano">王五</使用者資料>
</註冊資訊>
上面的例子雖然沒有錯誤,但最後的"play the piano"本來想表達的意思是"彈鋼琴",但由於NMTOKENS的限制,被拆解成了"play"、"the"、"Piano"三個部分。所以在遇到NMTOKENS型別屬性時,要特別注意空格的使用。
·NMTOKENS屬性型別
NOTATION對於使用非XML格式的資料非常有用。現實世界中存在很多無法或不易用XML格式組織的資料,例如圖象、聲音、影像等等。對於這些資料,XML應用程式常常並不提供直接的應用支援。通過為它們設定NOTATION型別的屬性,可以嚮應用程式指定一個外部的處理程式
<!DOCTYPE 檔案 [
<!ELEMENT 檔案 (聲音檔案)>
<!ELEMENT 聲音檔案 (#PCDATA)>
<!NOTATION MP SYSTEM "mplayer32.exe">
<!NOTATION ST SYSTEM "soundtool">
<!NOTATION SM SYSTEM "Sound Machine">
<!ATTLIST 聲音檔案 處理程式 NOTATION (MP|SM|ST) #REQUIRED>
]>
<檔案>
<聲音檔案 處理程式="MP">Lydia.mp3</聲音檔案>
</檔案>
相關文章
- 探索 DTD 在 XML 中的作用及解析:深入理解文件型別定義XML型別
- XML Schema定義XML
- xml檔案XML
- 如何給PDF檔案設定密碼?密碼
- AndroidMainfest.xml檔案AndroidAIXML
- python XML 檔案解析PythonXML
- jdom解析xml檔案XML
- xml是什麼格式的檔案 xml檔案怎麼開啟XML
- java 語音用xml檔案實現圖形介面 xml檔案JavaXML
- 死磕Spring之IoC篇 - 解析自定義標籤(XML 檔案)SpringXML
- 使用 Java 解析XML檔案JavaXML
- Go xml檔案處理GoXML
- Go 專案配置檔案的定義和讀取Go
- DTD
- Python解析XML檔案生成HTMLPythonXMLHTML
- nodejs xmlreader 讀寫xml檔案NodeJSXML
- C#讀取Xml檔案C#XML
- ajax與XML檔案互動XML
- 使用xml檔案配置SSM整合XMLSSM
- 清單檔案 AndroidManifest.xmlAndroidXML
- Java系列:讀取XML檔案JavaXML
- Spring 定時器的使用—Xml、Annotation、自定義Spring定時器XML
- Spring 定時器的使用---Xml、Annotation、自定義Spring定時器XML
- 面向切面的Spring(二) xml中定義aopSpringXML
- activiti7 獲取流程定義的xmlXML
- 在 MotionScene 檔案中定義場景約束
- Vivado使用技巧(13):CSV檔案定義IO Ports
- 為什麼不在標頭檔案做定義
- 【SSM框架整合】專案xml檔案、properties等檔案的配置SSM框架XML
- Mybatis 學習筆記(一)——配置檔案SqlMapConfig.xml和對映檔案Mapper.xmlMyBatis筆記SQLXMLAPP
- No grammar constraints (DTD or XML Schema) referenced in the document.的兩種解決辦法AIXML
- Linux shell格式化XML檔案LinuxXML
- 使用C#讀寫xml檔案C#XML
- XML 檔案解析實踐 (DOM 解析)XML
- 匹配 XML 檔案正規表示式XML
- 前端如何處理xml配置檔案?前端XML
- php獲取xml檔案內容PHPXML
- Maven的settings.xml檔案配置MavenXML