XML基礎(chǔ)教程第3章_第1頁
XML基礎(chǔ)教程第3章_第2頁
XML基礎(chǔ)教程第3章_第3頁
XML基礎(chǔ)教程第3章_第4頁
XML基礎(chǔ)教程第3章_第5頁
已閱讀5頁,還剩120頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1第3章有效的XML文件2第3章有效的XML文件3.1有效的XML文件的定義3.2如何檢查有效性3.3DTD中的元素3.4DTD的完整性3.5DTD中的屬性3.6DTD中的實體3.7可解析實體與不可解析實體3.8DTD中的參數(shù)實體3.9內(nèi)部DTD3.10IGNORE和INCLUDE3.11DTD的名稱空間3第3章

有效的XML文件

規(guī)范性僅僅是XML語言的基本語法,沒有對XML文件怎樣組織數(shù)據(jù)進(jìn)行具體的限制,對同一問題編寫的XML文件,在數(shù)據(jù)組織結(jié)構(gòu)上就可能有很大的不同。

Time1.xml和Time2.xml

4列車時刻Time1.xml<?xmlversion=“1.0”encoding=“UTF-8”?><火車時刻表> <T28>

開車時間:20點58分

</T28></火車時刻表>Time2.xml<?xmlversion=“1.0”encoding=“UTF-8”?><火車時刻表> <T28>

開車時間:

<hour>20點</hour> <minute>58分</minute> </T28></火車時刻表>5商店營業(yè)時間STime1.xml<?xmlversion=“1.0”encoding=“UTF-8”?><商店營業(yè)時間> <商店><商店名稱>國貿(mào)大廈</商店名稱> <營業(yè)時間>08:30至18:30</營業(yè)時間> </商店> <商店><商店名稱>華聯(lián)商場</商店名稱> <營業(yè)時間>07:30至22:30</營業(yè)時間> </商店></商店營業(yè)時間>6商店營業(yè)時間STime2.xml<?xmlversion=“1.0”encoding=“UTF-8”?><商店營業(yè)時間> <商店> <商店名稱>國貿(mào)大廈</商店名稱> <開門時間>08:30</開門時間> <關(guān)門時間>18:30</關(guān)門時間> </商店> <商店> <商店名稱>華聯(lián)商場</商店名稱> <開門時間>07:30</開門時間> <關(guān)門時間>22:30</關(guān)門時間> </商店></商店營業(yè)時間>73.1有效的XML文件定義

對XML數(shù)據(jù)進(jìn)行約束的主要原因:一是使XML的數(shù)據(jù)組織更加合理,符合系統(tǒng)要求;二是便于維護(hù)XML中的數(shù)據(jù),從而提高整個系統(tǒng)的可維護(hù)性。 針對某些問題,有時可能需要對XML文件怎樣組織數(shù)據(jù),即數(shù)據(jù)結(jié)構(gòu),進(jìn)行必要的限制,以便解析器能更好解析其中的數(shù)據(jù)。83.1有效的XML文件定義

對XML的數(shù)據(jù)結(jié)構(gòu)進(jìn)行限制有兩種方式:使用文檔類型定義(DocumentTypeDefinition,DTD)和XMLSchema模式。但二者最重要的區(qū)別是XMLSchema是一個特殊的XML文件,而DTD是有獨立語法結(jié)構(gòu)的文件。

DTD的使用要早與XMLSchema模式,DTD和XMLSchema模式各有所長,但XMLSchema模式比DTD更為復(fù)雜。本章主要討論DTD,以及怎樣使用它約束XML文件。

一個規(guī)范的XML文件如果和某個DTD文件相關(guān)聯(lián),并遵守DTD文件規(guī)定的限制條件,就稱為有效的XML文件。93.1.1初識DTD

下面用一個簡單例子說明如何使用DTD文件來約束XML文件中的數(shù)據(jù)結(jié)構(gòu)。

需要一個刻畫商店營業(yè)時間的XML文件,但數(shù)據(jù)結(jié)構(gòu)必須符合下列要求:根標(biāo)記名稱為:商店營業(yè)時間根標(biāo)記可以有若干個名稱為“商店”的子標(biāo)記。名稱為“商店”的標(biāo)記順序地包含有名稱為“商店名稱”“開門時間”“關(guān)門時間”的子標(biāo)記。名稱為“商店名稱”的標(biāo)記包含的內(nèi)容只能是文本數(shù)據(jù),不能有子標(biāo)記。名稱為“開門時間”的標(biāo)記包含的內(nèi)容只能是文本數(shù)據(jù),不能有子標(biāo)記。名稱為“關(guān)門時間”的標(biāo)記包含的內(nèi)容只能是文本數(shù)據(jù),不能有子標(biāo)記。103.1.1初識DTD DTD文件是由元素所構(gòu)成的文本文件。在DTD文件中,用關(guān)鍵字ELEMENT來定義一個元素,格式如下:<!ELEMENT標(biāo)記名稱標(biāo)記的約束條件>

注意:在DTD文件中,元素的定義用“<!ELEMENT”開始,以“>”結(jié)束。要特別注意的是“<!ELEMENT”中的“<、!、ELEMENT”間不要有空格。11limitShop.dtd<!ELEMENT商店營業(yè)時間(商店*)><!ELEMENT商店(商店名稱,開門時間,關(guān)門時間)><!ELEMENT商店名稱(#PCDATA)><!ELEMENT開門時間(#PCDATA)><!ELEMENT關(guān)門時間(#PCDATA)>12商店營業(yè)時間STime2.xml<?xmlversion=“1.0”encoding=“UTF-8”?><商店營業(yè)時間> <商店> <商店名稱>國貿(mào)大廈</商店名稱> <開門時間>08:30</開門時間> <關(guān)門時間>18:30</關(guān)門時間> </商店> <商店> <商店名稱>華聯(lián)商場</商店名稱> <開門時間>07:30</開門時間> <關(guān)門時間>22:30</關(guān)門時間> </商店></商店營業(yè)時間>13注意:

某些書將XML文件中的標(biāo)記也稱為元素,本書為符合WEB設(shè)計中的習(xí)慣,沒有在XML文件使用元素這一術(shù)語,而使用標(biāo)記這一術(shù)語。

需要特別提到的是,DTD中的元素和XML文件中的標(biāo)記的語法格式有很大不同。

143.1.2DTD文件的保存DTD文件由元素構(gòu)成的文本文件,需用文本編輯器編寫保存。DTD文件擴(kuò)展名為.dtd。在保存DTD文件時,DTD文件的編碼必須和其關(guān)聯(lián)的XML文件一致。也就是如果XML文件的編碼為UTF-8,那么XML關(guān)聯(lián)的DTD文件也必須依照UTF-8編碼保存。153.1.3XML與DTD的關(guān)聯(lián)形式

一個XML文件只有和某個DTD文件相關(guān)聯(lián),才會受到該DTD文件的約束。

XML文件使用文檔類型聲明與一個DTD相關(guān)聯(lián),有兩種形式的關(guān)聯(lián):SYSTEM和PUBLIC。SYSTEM關(guān)聯(lián)表明所關(guān)聯(lián)的DTD文件由個人或工作小組所定義且認(rèn)可。PUBLIC關(guān)聯(lián)表明所關(guān)聯(lián)的DTD文件已經(jīng)得到某一領(lǐng)域的認(rèn)可,是經(jīng)過許多人討論得到認(rèn)可的DTD文件。16SYSTEM關(guān)聯(lián)

SYSTEM關(guān)聯(lián)型的文檔類型聲明格式:<!DOCTYPE根標(biāo)記的名稱

SYSTEM"DTD文件的URI">例如:<!DOCTYPE商店營業(yè)時間SYSTEM“l(fā)imitShop.dtd">SYSTEM關(guān)聯(lián)表明所關(guān)聯(lián)的DTD文件由個或工作小組所定義且認(rèn)可

17PUBLIC關(guān)聯(lián)

PUBLIC關(guān)聯(lián)型的文檔類型聲明格式:<!DOCTYPE根標(biāo)記的名稱

PUBLIC"正式公用標(biāo)識符""DTD文件的URI">例如:<!DOCTYPE商店營業(yè)時間PUBLIC"-//ISO123456/Daxian/ForXML/EN"“l(fā)imitShop.dtd">PUBLIC關(guān)聯(lián)表明所關(guān)聯(lián)的DTD文件已經(jīng)得到某一領(lǐng)域的認(rèn)可,是經(jīng)過許多人討論得到認(rèn)可的DTD文件。

18FPI正式公用標(biāo)識符FPI的格式為:“-//ISO認(rèn)證//單位名稱//DTD說明//所用語言”

FPI中不可以含有非ASII碼字符。

19DTD文件的位置SYSTEM和PUBLIC格式的文檔類型聲明中提到的:“DTD文件URI”DTD文件的URI必須是一個有效的資源,如果URI是一個文件的名字,該文件必須和當(dāng)前XML文件在同一目錄中;如果URI是一個鏈接,該鏈接地址必須是可訪問的,使用URI可以使許多組織的XML文件共享同一個DTD文件。20example3_2.xml<?xmlversion=“1.0”encoding=“UTF-8”?><!DOCTYPE“商店營業(yè)時間”

SYSTEM“l(fā)imtShop.dtd”><商店營業(yè)時間> <商店> <商店名稱>國貿(mào)大廈</商店名稱> <開門時間>08:30</開門時間> <關(guān)門時間>18:30</關(guān)門時間> </商店> <商店> <商店名稱>華聯(lián)商場</商店名稱> <開門時間>07:30</開門時間> <關(guān)門時間>22:30</關(guān)門時間> </商店></商店營業(yè)時間>21現(xiàn)在看一個簡單的DTD文件以及它是怎樣約束XML文件的數(shù)據(jù)結(jié)構(gòu)。假設(shè)編寫一個關(guān)于學(xué)生的入學(xué)時間、畢業(yè)時間信息的XML文件,其中根標(biāo)記是“學(xué)生”。<!ELEMENT學(xué)生(張三,李四)><!ELEMENT張三(入學(xué)時間,畢業(yè)時間)><!ELEMENT李四(入學(xué)時間,畢業(yè)時間)><!ELEMENT入學(xué)時間(#PCDATA)><!ELEMENT畢業(yè)時間(#PCDATA)>#PCDATA表示文本數(shù)據(jù),可以含有普通字符、字符引用、實體引用或者是CDATA段的內(nèi)容。22例子1dtdFile.dtd<!ELEMENT列車時刻表

(T28次,T226次)><!ELEMENTT28次

(開車時間,終到時間)><!ELEMENTT226次

(開車時間,終到時間)><!ELEMENT開車時間

(hour,minute)><!ELEMENT終到時間

(hour,minute)><!ELEMENThour(#PCDATA)><!ELEMENTminute(#PCDATA)>23Cha3_1.xml

<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE列車時刻表

PUBLIC"-//ISO88/China/xml/CH""dtdFile.dtd"><列車時刻表><T28次><開車時間><hour>23點</hour><minute>12分</minute></開車時間><終到時間><hour>23點</hour><minute>12分</minute></終到時間></T28次><T226次><開車時間><hour>08點</hour><minute>45分</minute></開車時間><終到時間><hour>19點</hour><minute>36分</minute></終到時間></T226次></列車時刻表>243.2怎樣檢查有效性

瀏覽器的XML解析器只檢查XML文件是否是規(guī)范的。當(dāng)用瀏覽器打開一個有效的XML文件時,瀏覽器的XML解析器僅僅檢查XML文件所關(guān)聯(lián)的DTD文件是否有語法錯誤,并不檢查XML文件是否遵守該DTD規(guī)定的約束條件。 可以使用DOM解析器來檢查一個XML文件是否是有效的。

25TestValidate.javaimportjavax.xml.parsers.*;importorg.xml.sax.helpers.*;importorg.xml.sax.*;importjava.io.*;importorg.w3c.dom.*;importjava.util.Scanner;publicclassTestValidate{publicstaticvoidmain(Stringargs[]){StringfileName=null;try{Scannerreader=newScanner(System.in);System.out.println("請輸入要驗證有效性的文件名字:");fileName=reader.nextLine();DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();

例子226 factory.setValidating(true);DocumentBuilderbuilder=factory.newDocumentBuilder();MyHandlerhandler=newMyHandler();builder.setErrorHandler(handler);Documentdocument=builder.parse(newFile(fileName));if(handler.errorMessage==null){System.out.println("XML文件是有效的");}else{System.out.println("XML文件不是有效的");}}catch(Exceptione){System.out.println(e);}}}27classMyHandlerextendsDefaultHandler{StringerrorMessage=null;publicvoiderror(SAXParseExceptione)throwsSAXException{errorMessage=e.getMessage();System.out.println("一般錯誤:"+errorMessage);}publicvoidfatalError(SAXParseExceptione)throwsSAXException{errorMessage=e.getMessage();System.out.println("致命錯誤:"+errorMessage);}}283.3DTD中的元素

DTD中的元素(ELEMENT)是用來約束XML文件中的標(biāo)記,在DTD中使用元素聲明來定義一個元素,元素的聲明格式為:<!ELEMENT標(biāo)記名稱

標(biāo)記的約束條件

>

例如:<!ELEMENT列車時刻表

(T28次,T29次)>

約束標(biāo)記“列車時刻表”

只可以有且必須有兩個子標(biāo)記“T28次”和“T29次”。特別強調(diào)的2點:DTD文件中元素的作用與其在DTD文件中的書寫位置無關(guān)。在DTD文件中不能使用多個元素約束同一個標(biāo)記,即使它們的約束條件相同。293.3.1約束標(biāo)記只包含文本數(shù)據(jù)如果約束一個標(biāo)記沒有子標(biāo)記,也就是說約束標(biāo)記只能包含文本數(shù)據(jù)。<!ELEMENT標(biāo)記名稱(#PCDATA)>下列3個標(biāo)記符合要求:<姓名>張三</姓名><姓名></姓名><姓名/>30限制標(biāo)記只有文本數(shù)據(jù)

關(guān)鍵字#PCDATA約束標(biāo)記的文本數(shù)據(jù)中可以有:普通字符,CDATA段中的內(nèi)容字符引用實體引用。 當(dāng)一個標(biāo)記使用這樣的約束時,該標(biāo)記的文本數(shù)據(jù)也可以只由一個“空字符”組成。31例如<!ELEMENTHello(#PCDATA)>下列“Hello”標(biāo)記都是符合約束條件標(biāo)記:<Hello>

你好</Hello><Hello>你好</Hello><Hello></Hello>而下列不符合約束條件:<Hello>

你好

<a>hello</a></Hello>323.3.2規(guī)定標(biāo)記的子標(biāo)記

如果想約束XML文件中某個標(biāo)記可以有怎樣的子標(biāo)記,比如,標(biāo)記必須有哪些子標(biāo)記,子標(biāo)記是否允許重復(fù)出現(xiàn)、出現(xiàn)的順序如何等,那么

DTD中元素聲明的“標(biāo)記的約束條件”是用小括號括起的子標(biāo)記列表,格式為<!ELEMENT標(biāo)記名稱

(子標(biāo)記列表)>

333.3.2規(guī)定標(biāo)記的子標(biāo)記<!ELEMENT標(biāo)記名稱

(子標(biāo)記列表)> XML文件中的標(biāo)記可以含有文本數(shù)據(jù)和子標(biāo)記,如果在DTD文件中使用上述約束條件的元素,這樣的元素將約束XML文件中相應(yīng)的標(biāo)記只可以有子標(biāo)記,不可以含有能顯示的文本數(shù)據(jù),即文本數(shù)據(jù)僅僅可以由空白類字符所組成。

“子標(biāo)記列表”約束標(biāo)記可以有哪些子標(biāo)記及它們在父標(biāo)記中出現(xiàn)的先后順序。“子標(biāo)記列表”是用逗號分隔列出的若干個標(biāo)記,每個標(biāo)記稱做“子標(biāo)記列表”的一個分項。34例如:<!ELEMENT開車時間

(hour,minute)>

要求標(biāo)記“開車時間”

恰好有兩個子標(biāo)記“hour”和“minute”,不可以有能顯示的文本數(shù)據(jù),并且子標(biāo)記在父標(biāo)記“開車時間”中出現(xiàn)的順序必須是“hour”、“minute”而不是

“minute”、“hour”.

35<開車時間> <hour> 04點

</hour> <minute> 58分

</minute></開車時間>不可以將T28標(biāo)記寫成<開車時間> <minute> 58分

</minute> <hour> 04點

</hour></開車時間>不可以將“開車時間”標(biāo)記寫成含有可顯示文本“特快列車”<開車時間>

特快列車

<hour> 04點

</hour> <minute> 58分

</minute></開車時間>36子標(biāo)記出現(xiàn)的次數(shù)

子標(biāo)記列表中的每個子標(biāo)記的后面可以尾加限定符號來限定該子標(biāo)記出現(xiàn)的次數(shù)。不尾加限定符號的子標(biāo)記必須出現(xiàn)且只能出現(xiàn)一次。限定符號有:+:尾加該限定符號的子標(biāo)記必須出現(xiàn)一次或多次。*:尾加該限定符號的子標(biāo)記可出現(xiàn)零次或多次。?:尾加該限定符號的子標(biāo)記可出現(xiàn)零次或一次。例如:<!ELEMENT庫存商品(商品名稱+,管理員?)>37分項的或運算子標(biāo)記列表的分項也可以是幾個標(biāo)記的“或運算”,而且或運算必須用小括號括起來。例如:<!ELEMENT應(yīng)聘者(姓名,(本科|碩士|博士),(男|女))><!ELEMENT應(yīng)聘者(姓名,(獎勵|處分)*,(男|女))>38例子3dtdFile.dtd<!ELEMENT應(yīng)聘信息(應(yīng)聘者*)><!ELEMENT應(yīng)聘者(姓名,(本科|碩士|博士),(獎勵|處分)*,(性別))><!ELEMENT本科(#PCDATA)><!ELEMENT碩士(#PCDATA)><!ELEMENT博士(#PCDATA)><!ELEMENT獎勵(#PCDATA)><!ELEMENT處分(#PCDATA)><!ELEMENT性別(#PCDATA)><!ELEMENT姓名(#PCDATA)>39Cha3_3.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE應(yīng)聘信息SYSTEM"dtdFile.dtd"><應(yīng)聘信息><應(yīng)聘者><姓名>張林將</姓名><碩士>北京大學(xué)計算機理學(xué)碩士</碩士><獎勵>獲2005年度光華獎學(xué)金</獎勵><獎勵>獲2003年度一等獎學(xué)金</獎勵><處分>2004被一次警告處分</處分><性別>男</性別></應(yīng)聘者><應(yīng)聘者><姓名>李小黎</姓名><博士>清華大學(xué)自動化專業(yè)工學(xué)博士</博士><獎勵>獲2003年度光華獎學(xué)金</獎勵><性別>女</性別></應(yīng)聘者><應(yīng)聘者><姓名>王勁勁</姓名><本科>南京大學(xué)文學(xué)系文學(xué)學(xué)士</本科><性別>女</性別></應(yīng)聘者></應(yīng)聘信息>403.規(guī)定標(biāo)記的混合內(nèi)容

一個標(biāo)記的內(nèi)容可以有兩部分構(gòu)成:文本數(shù)據(jù)和標(biāo)記,其中的標(biāo)記稱做該標(biāo)記的子標(biāo)記。 格式如下:<!ELEMENT標(biāo)記名稱

(#PCDATA|子標(biāo)記1|子標(biāo)記2…|子標(biāo)記m)*>

41錯誤的寫法(#PCDATA|子標(biāo)記1|子標(biāo)記2…|子標(biāo)記m)其錯誤是未用“*”字符結(jié)尾;(#PCDATA|子標(biāo)記1|子標(biāo)記2…|子標(biāo)記m)+其錯誤是使用“+”字符結(jié)尾;(#PCDATA|子標(biāo)記1|子標(biāo)記2…|子標(biāo)記m)?其錯誤是使用“?”字符結(jié)尾;(#PCDATA,子標(biāo)記1,子標(biāo)記2…,子標(biāo)記m)子標(biāo)記列表不能有“#PCDATA”分項。

約束標(biāo)記的混合內(nèi)容元素的缺點是:只能約束該標(biāo)記可以有哪些子標(biāo)記,不能約束這些子標(biāo)記出現(xiàn)的次數(shù)和出現(xiàn)的順序。另外,約束條件中也不能使用限制符號,下列寫法是錯誤的。(#PCDATA|子標(biāo)記1+|子標(biāo)記2*…|子標(biāo)記m?)42fiveDTD.dtd<!ELEMENT學(xué)生列表(姓名*)><!ELEMENT姓名(#PCDATA|出生日期|性別)*><!ELEMENT出生日期(#PCDATA)><!ELEMENT性別(#PCDATA)>43<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE學(xué)生列表PUBLIC"-//ISO88//school//ForXML//Ch"“fiveDTD.dtd"><學(xué)生列表><姓名>張三

<出生日期>1993-12-12</出生日期><性別>男</性別></姓名><姓名>孫翠花

<出生日期>1992-01-31</出生日期><性別>女</性別></姓名></學(xué)生列表>44例子4dtdFile.dtd<!ELEMENT列車時刻表(車次)*><!ELEMENT車次(#PCDATA|開車時間|終到時間)*><!ELEMENT開車時間(#PCDATA)><!ELEMENT終到時間(#PCDATA)>45Cha3_4.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE列車時刻表PUBLIC"-//ISO88//raiway//ForXML//Ch""dtdFile.dtd"><列車時刻表><車次>K83次特快列車

<開車時間>20點36分</開車時間> <開車時間>20點36分</開車時間> <開車時間>16點36分</開車時間><終到時間>07點12分</終到時間></車次><車次><終到時間>09點16分</終到時間> K18次特快列車

</車次><車次><終到時間>09點16分</終到時間> K18次特快列車

<開車時間>16點36分</開車時間></車次><車次></車次></列車時刻表>464.

EMPTY和ANY

如果準(zhǔn)備約束一個標(biāo)記是空標(biāo)記,或者是只含有空字符的非空標(biāo)記,元素的“標(biāo)記的約束條件”可以是關(guān)鍵字“EMPTY”;<!ELEMENTspeakEMPTY> 如果不準(zhǔn)備對一個標(biāo)記有任何約束,元素的“標(biāo)記的約束條件”可以是關(guān)鍵字“ANY”。例如:<!ELEMENThelloANY>47<!ELEMENTspeakEMPTY>下列標(biāo)記都是符合約束條件的標(biāo)記<speak/><speak></speak><hello>qweqwe</hello><!ELEMENThelloANY>而下列標(biāo)記都是不符合約束條件的標(biāo)記<speak>Howareyou</speak><speak></speak><speak></speak>48493.4DTD的完整性

一個DTD文件必須是完整的,即滿足:(1)不允許無窮嵌套如果一個DTD元素約束某個標(biāo)記可以出現(xiàn)某個子標(biāo)記,那么對該子標(biāo)記進(jìn)行約束的DTD元素就不能約束該標(biāo)記的子標(biāo)記是它的父標(biāo)記。下列是錯誤的。<!ELEMENT商品名稱(name,price)><!ELEMENTprice(商品名稱,unit)><!ELEMENT學(xué)生(姓名,性別)><!ELEMENT姓名(學(xué)生,拼音)>3.4DTD的完整性

(2)XML文件中的每個標(biāo)記都必須在DTD中有相應(yīng)元素進(jìn)行約束。下列DTD文件是不完整的。<!ELEMENT列車時刻表(T28次,T29次)><!ELEMENTT28次(hour,minute)><!ELEMENTT29次(minute,hour)><!ELEMENT商店營業(yè)時間(商店*)><!ELEMENT商店(商店名稱,開門時間,關(guān)門時間)><!ELEMENT商店名稱(#PCDATA)>50513.5DTD中的屬性約束列表

屬性是指標(biāo)記的屬性,可以為標(biāo)記添加附加信息。屬性是一個名值對,即屬性必須由名字和值組成。屬性必須在非空標(biāo)記的開始標(biāo)記或空標(biāo)記中聲明,用“=”為屬性指定一個值。例如,我們可為標(biāo)記“桌子”添加三個屬性:<桌子width=“300”height=“600”length=“1000”>

一個信息是否作為一個標(biāo)記的附加信息或作為該標(biāo)記的子標(biāo)記,這取決于具體的問題。一個基本的原則:不要因為屬性的頻繁使用而破壞穩(wěn)當(dāng)?shù)慕Y(jié)構(gòu)。523.5.1ATTLIST屬性約束列表 DTD中的屬性列表(ATTLIST)可用來約束XML文件中標(biāo)記的屬性,在DTD中屬性列表的聲明格式為:<!ATTLIST標(biāo)記名稱

屬性名稱

屬性類型

默認(rèn)值情況屬性名稱

屬性類型

默認(rèn)值情況…

…>例如:<!ATTLIST桌子

widthCDATA“0” heightCDATA“0” lengthCDATA“0”>注意:對于有效的XML文件,對于標(biāo)記中添加的每個屬性,在DTD中都必須有相應(yīng)的ATTLIST聲明給予約束。例6sixDTD.dtd<!ELEMENT教學(xué)樓(教室*)><!ELEMENT教室(號碼,用途)><!ELEMENT號碼(#PCDATA)><!ELEMENT用途(#PCDATA)><!ATTLIST教室widthCDATA“8m”><!ATTLIST教室lengthCDATA“15m”>53example3-6.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE教學(xué)樓SYSTEM"sixDTD.dtd"><教學(xué)樓><教室><號碼>A101</號碼><用途>自習(xí)室</用途></教室><教室width=“10m”length=“16m”><號碼>A606</號碼><用途>語音室</用途></教室></教學(xué)樓>

瀏覽器的解析器認(rèn)為它有名字為width和length的屬性,且屬性值是DTD文件中屬性列表約束給出的默認(rèn)值。5455屬性名稱”、“屬性類型”和“默認(rèn)值情況”

在ATTLIST聲明中,涉及到“屬性名稱”“屬性類型”和“默認(rèn)值情況”,其意義分別闡述如下:<!ATTLIST標(biāo)記名稱屬性名稱屬性類型默認(rèn)值情況>(1)屬性名稱屬性名稱的命名規(guī)則和標(biāo)記的命名規(guī)則相同,可以由字母、數(shù)字、下劃線(“_”)、點(“.”)或連字符(“-”)組成,但必須以字母或下劃線開頭。屬性的名稱區(qū)分大小寫。(2)屬性類型

我們已經(jīng)知道屬性值一定是一個字符串,那么屬性類型就決定了屬性可以用怎樣的字符串作為屬性的值。無論何種類型的屬性,其屬性值中都不能含有左尖括號,右尖括號,與符號,單引號和雙引號。如果想用這些值,可以使用實體引用。屬性值區(qū)分大小寫。(3)默認(rèn)值情況

ATTLIST聲明中關(guān)于屬性的“默認(rèn)值情況”是對XML文件中標(biāo)記的屬性進(jìn)行約束的細(xì)節(jié)條件。562.屬性的默認(rèn)值 <!ATTLIST>聲明中包括“屬性名稱”、“屬性類型”和“默認(rèn)值情況”,其中的“默認(rèn)值情況”含有約束的細(xì)節(jié)條件。

“默認(rèn)值情況”對標(biāo)記中的屬性的約束意義的表述。

默認(rèn)值情況約束意義字符串標(biāo)記必須有該屬性,且有默認(rèn)值#IMPLIED標(biāo)記可以沒有該屬性,沒有默認(rèn)值#REQUIRED標(biāo)記必須有該屬性,沒有默認(rèn)值#FIXED“字符串”標(biāo)記可以沒有該屬性,但如果有該屬性,那么屬性值固定不變57以下就“默認(rèn)值情況”的幾種情況詳細(xì)討論如下

(1)字符串如果某個屬性的“默認(rèn)值情況”是一個字符串,

XML中對應(yīng)標(biāo)記必須有該屬性,但標(biāo)記可以不明顯地添加該屬性。如果不明顯地添加該屬性,解析器也認(rèn)為該標(biāo)記有這個屬性,并且默認(rèn)值為DTD文件中ATTLIST聲明給定的字符串。<!ATTLIST張山heightCDATA"160"><!ATTLIST桌子colorCDATA"red">

58舉例5dtdFile.dtd<!ELEMENTroom(桌子)*><!ELEMENT桌子(#PCDATA)><!ATTLIST桌子

widthCDATA"100"heightCDATA"100"lengthCDATA"100">Cha3_5.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEroomSYSTEM"dtdFile.dtd"><room><桌子width="123"height="200"length="5555">

紅桌子

</桌子><桌子>

大小如何?

</桌子></room>舉例7sevenDTD.dtd<!ELEMENT商品列表(商品*)><!ELEMENT商品(名稱,價格)><!ELEMENT名稱(#PCDATA)><!ELEMENT價格(#PCDATA)><!ATTLIST商品類別CDATA"食品">example3_7.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE商品列表SYSTEM"sevenDTD.dtd"><商品列表><商品

類別=“家電"> <名稱>電視機</名稱><價格>2678元/臺</價格>

</商品><商品> <名稱>東北大米</名稱><價格>5.9元/斤</價格>

</商品></商品列表>

5960(2)#IMPLIED

當(dāng)屬性的“默認(rèn)值情況”是關(guān)鍵字“#IMPLIED”時,該屬性就沒有默認(rèn)值,而且相應(yīng)的標(biāo)記里可以不使用該屬性。當(dāng)認(rèn)為一個屬性可有可無,且沒有默認(rèn)值時,就可以將屬性的“默認(rèn)值情況”設(shè)置為“#IMPLIED”。

<!ATTLIST顧客heightCDATA#IMPLIED>61(3)#REQUIRED當(dāng)屬性的“默認(rèn)值情況”是關(guān)鍵字“#REQUIRED”時,該屬性沒有默認(rèn)值,相應(yīng)的標(biāo)記必須要添加該屬性并給出屬性的值。

當(dāng)我們不想為某個屬性設(shè)置默認(rèn)值,但要求標(biāo)記里必須有該屬性時,就可以將屬性的“默認(rèn)值情況”設(shè)置為“#REQUIRED”。<!ATTLIST顧客

heightCDATA#REQUIRED>62(4)#FIXED

當(dāng)屬性的“默認(rèn)值情況”是關(guān)鍵字“#FIXED”和一個字符串時,該屬性的默認(rèn)值就是關(guān)鍵字“#FIXED”后面指定的那個字符串。

在編寫XML文件時,即使被約束的標(biāo)記不顯示的附加該屬性,解析器也認(rèn)為該標(biāo)記有這個屬性,而且屬性值是關(guān)鍵字“#FIXED”

指定的字符串。但如果標(biāo)記顯示添加該屬性,那么不可以改變屬性的值,即該屬性的值必須是關(guān)鍵字“#FIXED”

指定的字符串。<!ATTLIST消防車

顏色

CDATA#FIXED"紅色"><!ATTLIST報警電話號碼CDATA#FIXED“110">

63

目前,瀏覽器內(nèi)置的XML解析器只檢查XML關(guān)聯(lián)的DTD文件本身是否有錯,但不檢查XML文件是否遵守了DTD文件的約束條件。

如果你只想檢查有效性,也可以使用3.2節(jié)中的解析器。例8eightDTD.dtd<!ELEMENT教學(xué)樓(教室*,休息室*)><!ELEMENT教室(#PCDATA)><!ELEMENT休息室(#PCDATA)><!ATTLIST教室號碼CDATA#REQUIRED><!ATTLIST休息室號碼CDATA#IMPLIED>example3_8.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE教學(xué)樓SYSTEM"sevenDTD.dtd"><教學(xué)樓><教室號碼=“2109”

>物理系專用</教室><教室號碼=“5509”>英語系專用</教室><休息室號碼=“T5”>老師課間休息專用</休息室><休息室>學(xué)生課間休息專用</休息室></教學(xué)樓>64例9nineDTD.dtd<!ELEMENT重要電話簿(報警電話,火警電話,急救電話)><!ELEMENT報警電話(#PCDATA)><!ELEMENT火警電話(#PCDATA)><!ELEMENT急救電話(#PCDATA)><!ATTLIST報警電話號碼CDATA#FIXED“110”><!ATTLIST火警電話號碼CDATA#FIXED“119”><!ATTLIST急救電話號碼CDATA#FIXED“120”>6566例子6dtdFile.dtd<!ELEMENT車(汽車*,驢車*)><!ELEMENT汽車(#PCDATA)><!ATTLIST汽車車牌CDATA#REQUIRED><!ELEMENT驢車(#PCDATA)><!ATTLIST驢車車牌CDATA#IMPLIED>Cha3_6.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE車SYSTEM"dtdFile.dtd"><車><汽車車牌="汽A1234567">

交通工具

</汽車><驢車車牌="驢A7654321">

農(nóng)用車

</驢車></車>67TestAttsOne.javaimportjavax.xml.parsers.*;importorg.xml.sax.helpers.*;importorg.xml.sax.*;importjava.io.*;publicclassTestAttsOne{publicstaticvoidmain(Stringargs[]){try{SAXParserFactoryfactory=SAXParserFactory.newInstance();factory.setValidating(true);factory.setNamespaceAware(true);SAXParsersaxParser=factory.newSAXParser();MyHandlerOnehandler=newMyHandlerOne();saxParser.parse(newFile("cha3_6.xml"),handler);}catch(Exceptione){System.out.println(e);}}}68classMyHandlerOneextendsDefaultHandler{publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesatts){System.out.print("<"+localName+">");System.out.println("該標(biāo)記的屬性:");for(intk=0;k<atts.getLength();k++){System.out.print("屬性名稱:");System.out.print(atts.getLocalName(k)+"");System.out.print("屬性類型:");System.out.print(atts.getType(k)+"");System.out.print("屬性的值:");System.out.print(atts.getValue(k)+"");}}publicvoidendElement(Stringuri,StringlocalName,StringqName){System.out.println("</"+localName+">");}publicvoiderror(SAXParseExceptione)throwsSAXException{StringerrorMessage=e.getMessage();System.out.println("一般錯誤:"+errorMessage);}}69例子7dtdFile.dtd<!ELEMENT電話薄(報警電話,火警電話)><!ELEMENT報警電話(#PCDATA)><!ATTLIST報警電話號碼CDATA#FIXED"110"><!ELEMENT火警電話(#PCDATA)><!ATTLIST火警電話號碼CDATA#FIXED"119">Cha3_7.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE電話薄SYSTEM"dtdFile.dtd"><電話薄><報警電話號碼="110">

不要亂打報警電話。

</報警電話><火警電話號碼="119">

一旦發(fā)生火災(zāi),請及時撥打119。

</火警電話></電話薄>70TestAttsTwo.javaimportjavax.xml.parsers.*;importorg.xml.sax.helpers.*;importorg.xml.sax.*;importjava.io.*;importorg.w3c.dom.*;publicclassTestAttsTwo{publicstaticvoidmain(Stringargs[]){OutContentoutContent=newOutContent();try{DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();factory.setValidating(true);DocumentBuilderbuilder=factory.newDocumentBuilder();builder.setErrorHandler(newMyHandlerTwo());Documentdocument=builder.parse(newFile("cha3_7.xml"));Elementroot=document.getDocumentElement();StringrootName=root.getNodeName();System.out.println("XML文件根節(jié)點的名字:"+rootName);NodeListnodeList=root.getChildNodes();outContent.output(nodeList);}catch(Exceptione){System.out.println(e);}}}71classOutContent{publicvoidoutput(NodeListnodeList){intsize=nodeList.getLength();for(intk=0;k<size;k++){Nodenode=nodeList.item(k);if(node.getNodeType()==Node.ELEMENT_NODE){ElementelementNode=(Element)node;Stringname=elementNode.getNodeName();System.out.print(name); //獲取標(biāo)記的全部屬性

NamedNodeMapmap=elementNode.getAttributes(); for(intj=0;j<map.getLength();j++){AttrattrNode=(Attr)map.item(j);StringattName=attrNode.getName();StringattValue=attrNode.getValue();System.out.println("屬性名稱及值:"+attName+"="+attValue);}NodeListnodes=elementNode.getChildNodes();output(nodes);}}}}72classMyHandlerTwoextendsDefaultHandler{publicvoiderror(SAXParseExceptione)throwsSAXException{StringerrorMessage=e.getMessage();System.out.println("一般錯誤:"+errorMessage);}}733.屬性類型

屬性類型決定了屬性可以用怎樣的字符串作為屬性的值。屬性的常用類型有:CDATAEnumeratedNMTOKENNMTOKENSIDIDREFIDREFS以下分別來介紹這些屬性類型。74(1)CDATA類型

對于CDATA(CharacterData)類型的屬性,該屬性的值可以是任何一個字符串,但是,字符串中不能含有左尖括號、右尖括號、與符號、單引號和雙引號,如果想使用這些字符,可以使用字符引用或?qū)嶓w引用。 下面的例子10說明了CDATA類型屬性的用法??捎美?中的解析器驗證XML文件是否有效。75例子10tenDTD.dtd<!ELEMENT通訊錄(姓名*)><!ELEMENT姓名(#PCDATA)><!ATTLIST姓名電話CDATA#REQUIREDEmailCDATA#REQUIRED

住址CDATA#IMPLIED>example3_10.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE通訊錄SYSTEM"tenDTD.dtd"><通訊錄><姓名電話="12345678"Email=“zhangfei@">

張飛

</姓名><姓名電話=“98765432"Email=“l(fā)ikui@"住址="北京海淀區(qū)">

李奎

</姓名></通訊錄>76(2)Enumerated類型

如果屬性的類型是Enumerated類型,那么該屬性只可以取枚舉出的值。Enumerated不是關(guān)鍵字,是指類型定義的格式,其格式是將屬性可以取的值用符號“|”分隔,Enumerated類型的定義格式如下:<!ATTLIST標(biāo)記名稱

屬性名稱

(屬性值1|屬性值2|…|屬性值n)

默認(rèn)值情況>

對于Enumerated類型,屬性值可以由字母、數(shù)字、下劃線、點或連字符組成,并允許首字符是數(shù)字字符。77例子9dtdFile.dtd<!ELEMENT學(xué)生(姓名*)><!ELEMENT姓名(#PCDATA)><!ATTLIST姓名性別(1男|女)#REQUIRED>Cha3_9.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE學(xué)生SYSTEM"dtdFile.dtd"><學(xué)生><姓名性別=“1男">

張三

</姓名><姓名性別="女">

翠花

</姓名></學(xué)生>例11elevenDTD.dtd<!ELEMENT道路(路燈*)><!ELEMENT路燈(編號,位置)><!ELEMENT位置(#PCDATA)><!ELEMENT編號(#PCDATA)><!ATTLIST路燈狀態(tài)(亮|滅)#REQUIRED>example3_11.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE道路SYSTEM“elevenDTD.dtd"><道路><路燈狀態(tài)=“亮”><編號>10010</編號><位置>中山路</位置>

</路燈><路燈狀態(tài)=“滅"><編號>20011</編號><位置>長江路</位置>

</路燈></道路>7879(3)NMTOKEN類型

如果屬性的類型是NMTOKEN類型的屬性,屬性值可以由字母、數(shù)字、下劃線(“_”)、點(“.”)或連字符(“-”)組成,屬性值中不能含有空格字符(屬性值也可以用數(shù)字、點或連字符開頭)。dtdFile.dtd<!ELEMENT文件(Java文件,XML文件)><!ELEMENTJava文件(#PCDATA)><!ATTLISTJava文件文件名NMTOKEN#REQUIRED><!ELEMENTXML文件(#PCDATA)><!ATTLISTXML文件文件名NMTOKEN#REQUIRED>80Cha3_10.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE文件SYSTEM"dtdFile.dtd"><文件><Java文件文件名="Hello.java">

<![CDATA[classHello{publicstaticvoidmain(Stringargs[]){System.out.println("ok");}}]]></Java文件><XML文件文件名="First.xml">

<![CDATA[<?xmlversion="1.0"?><職員><姓名>張小三</姓名></職員>]]></XML文件></文件>例子10例12twelveDTD.dtd<!ELEMENT作家名單(姓名*)><!ELEMENT姓名(#PCDATA)><!ATTLIST姓名筆名NMTOKEN#IMPLIED>example3_12.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE作家名單SYSTEM"twelveDTD.dtd"><作家名單><姓名筆名=“仙山”>

張三

</姓名><姓名筆名=“桃李">

李陶</姓名></作家名單>8182(4)NMTOKENS類型

我們已經(jīng)知道,對于NMTOKEN類型的屬性,其屬性值中不能含有空白類字符。如果需要某個屬性的屬性值含有空白類字符,而且被空白分隔開的子字符串符合NMTOKEN類型屬性的屬性值之規(guī)定,那么就可以將屬性的類型取為NMTOKENS類型。

83例子11dtdFile.dtd<!ELEMENT成果(論文*)><!ELEMENT論文(#PCDATA)><!ATTLIST論文關(guān)鍵字NMTOKENS#REQUIRED>Cha3_11.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE成果SYSTEM"dtdFile.dtd"><成果><論文關(guān)鍵字="拓?fù)潇鼗煦缬成?>

本論文詳細(xì)討論了線段自映射的拓?fù)潇睾蚅i-yorke混沌之間的關(guān)系

</論文><論文關(guān)鍵字="XMLSOAP">

本論文詳細(xì)討論了基于SOAP通信中XML文件的作用。

</論文></成果>例13thirteenDTD.dtd<!ELEMENT圖書列表(圖書*)><!ELEMENT圖書(名稱,出版社)><!ELEMENT名稱(#PCDATA)><!ELEMENT出版社(#PCDATA)><!ATTLIST圖書關(guān)鍵字NMTOKENS#REQUIRED>example3_13.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE圖書列表SYSTEM"thirteenDTD.dtd"><圖書列表><圖書關(guān)鍵字=“XML可擴(kuò)展語言解析器"><名稱>XML基礎(chǔ)教程</名稱><出版社>清華大學(xué)出版社</出版社>

</圖書><圖書關(guān)鍵字=“JAVA類對象線程"> <名稱>Java程序設(shè)計</名稱><出版社>清華大學(xué)出版社</出版社>

</圖書></圖書列表>8485(5)ID類型 ID類型的屬性的屬性值具有互斥性,即所有ID類型的屬性的屬性值必須互不相同。如果希望某個屬性的屬性值具有專用性,即不允許其他類型相同(ID類型)的屬性再使用這個屬性值,那么就可以將屬性的類型取為ID類型。

需要注意的是,ID類型的屬性值可以由字母、數(shù)字、下劃線、點或連字符組成,但必須以字母或下劃線開頭。

需要特別注意的是ID類型屬性的默認(rèn)值情況只能是“#REQUIRED”和“#IMPLIED”,不可以是“字符串”或#FIXED“字符串”。

一個標(biāo)記的若干屬性中不允許有2個屬性的類型都是ID。86例如,下列ID類型屬性的“默認(rèn)值情況”是錯誤的。<!ATTLIST張山址址ID#FIXED“北京大學(xué)”><!ATTLIST張山地址ID“北京大學(xué)”><!ATTLIST汪想地址IDFIXED“北京市”><!ATTLIST辛望地址ID“清華大學(xué)”>下列ID類型屬性的“默認(rèn)值情況”是正確的。

<!ATTLIST張山地址ID#REQUIRED> <!ATTLIST張山地址ID#IMPLIED><!ATTLIST汪想地址ID#REQUIRED><!ATTLIST辛望地址ID#IMPLIED>87例子12dtdFile.dtd<!ELEMENT出版社(圖書*)><!ELEMENT圖書(名稱*)><!ELEMENT名稱(#PCDATA)><!ATTLIST名稱ISBNID#REQUIRED>Cha3_12.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE出版社SYSTEM"dtdFile.dtd"><出版社><圖書><名稱ISBN="ISBN.7-302-09142-0">Java基礎(chǔ)教程

</名稱>

<!--下面的ISBN屬性的取值是不允許的--><名稱ISBN="ISBN.7-302-09142-0">JSP基礎(chǔ)教程

</名稱></圖書></出版社>ID類型的屬性值的專用性僅限于ID類型的屬性,并不干涉其他類型屬性的屬性值。例14fourteenDTD.dtd<!ELEMENT城市交通(公交電車,公交汽車)><!ELEMENT公交電車(名稱*)><!ELEMENT公交汽車(名稱*)><!ELEMENT名稱(#PCDATA)><!ATTLIST名稱車牌號ID#REQUIRED>example3_14.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE城市交通SYSTEM"fourteenDTD.dtd“><城市交通><公交電車><名稱車牌號=“遼B555”>101無軌電車<名稱><名稱車牌號=“遼B555”>201有軌電車<名稱></公交電車><公交汽車><名稱車牌號=“遼B666”>801快車<名稱><名稱車牌號

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論