<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    即使世界明天毀滅,我也要在今天種下我的葡萄樹。
    posts - 112, comments - 14, trackbacks - 0, articles - 11

    用于XML的簡單API

    Posted on 2007-01-16 16:26 閱讀(430) 評論(0)  編輯  收藏 所屬分類: XML Design

    替換和插入文本

    下面要做的事情就是自定義解析器,你可以知道如何得到通常會(huì)忽略的信息。但是在這之前,先要學(xué)習(xí)一些重要的XML概念。本節(jié)中,要學(xué)習(xí):

    ·?? ??處理特殊字符("<", "&",等等)

    ·?? 使用XML風(fēng)格語法處理文本

    處理特殊字符

    XML中,實(shí)體是具有名字的XML結(jié)構(gòu)(或純文本)。通過名字引用實(shí)體將實(shí)體插入到文檔中實(shí)體引用的位置。創(chuàng)建實(shí)體引用時(shí),使用“&”和分號(hào)將實(shí)體名包圍起來,如下所示:

    ??&entityName;

    后面學(xué)習(xí)如何編寫DTD時(shí),你會(huì)發(fā)現(xiàn)可以自己定義實(shí)體,所以&yourEntityName; 可以變成你定義的實(shí)體的所有文本。現(xiàn)在,主要討論預(yù)定義實(shí)體和不需要任何特殊定義的字符引用。

    預(yù)定義實(shí)體

    類似于&amp; 的實(shí)體引用包含一個(gè)名字,該名字在定界符之間 (本例中就是"amp")。它引用的文本(&)被用來替換名字,類似于C 或 C++程序中的宏。表 6-1 顯示了特殊字符的預(yù)定義實(shí)體。

    6-1 預(yù)定義實(shí)體

    字符

    引用

    &

    &amp;

    <

    &lt;

    >

    &gt;

    "

    &quot;

    '

    &apos;

    字符引用

    類似于&#147; 的字符引用包含散列符號(hào)(#),該符號(hào)后面跟著數(shù)字。數(shù)字是單個(gè)字符的Unicode值,如65代表字母"A",147代表左引號(hào),148表示右引號(hào)。在本例中,實(shí)體的 "name"為散列符號(hào),它后面跟著用來標(biāo)識(shí)字符的數(shù)字。

    注意:XML中最好用十進(jìn)制來表示值。然而 http://www.unicode.org/charts/ 的Unicode表用十六進(jìn)制表示值。所以需要進(jìn)行轉(zhuǎn)換,以便將正確的值插入XML數(shù)據(jù)集中。

    在XML文檔中使用實(shí)體引用

    假設(shè)你想要在你的XML文檔中插入下面一行內(nèi)容:

    ?Market Size < predicted

    直接在XML文件中添加該行的問題是,當(dāng)解析器看到左尖括號(hào)(<)時(shí),它開始查找標(biāo)簽名,這就會(huì)脫離解析。為了解決該問題,在文件中用&lt;替代"<"

    注意:下面的修改結(jié)果包含在 slideSample03.xml中。它的處理結(jié)果在Echo07-03.txt.中。(可瀏覽版本是slideSample03-xml.htmlEcho07-03.html.)

    如果你按照該編程教程進(jìn)行學(xué)習(xí),在r slideSample.xml 文件中添加下面的文本:

    ??<!-- OVERVIEW -->
    ??<slide type="all">
    ????<title>Overview</title>
    ????...
    ??</slide>
    				??<slide type="exec">
    		
    				????<title>Financial Forecast</title>
    		
    				????<item>Market Size &lt; predicted</item>
    		
    				????<item>Anticipated Penetration</item>
    		
    				????<item>Expected Revenues</item>
    		
    				????<item>Profit Margin </item>
    		
    				??</slide>
    				
    				
    				
    				
    		
    </slideshow>

    在XML文件上運(yùn)行該Echo程序時(shí),可以得到下列輸出結(jié)果:

    ELEMENT:????????<item>
    CHARS:????????Market Size < predicted
    END_ELM:????????</item>

    解析器將引用轉(zhuǎn)化為它表示的實(shí)體,并將該實(shí)體傳遞給應(yīng)用程序。

    使用XML-風(fēng)格的語法處理文本

    在處理包含多個(gè)特殊字符的XML或 HTML塊時(shí),使用合適的實(shí)體引用替換每個(gè)特殊字符很不方便。在這種情況下,可以使用CDATA 段。


    注意:修改結(jié)果包含在slideSample04.xml中。處理結(jié)果在Echo07-04.txt中。(可瀏覽版本是 slideSample04-xml.htmlEcho07-04.html.)

    HTMLCDATA 段的功能類似于<pre>...</pre> ,只是—— CDATA 段中的所有空白都很重要,并且不將其中的字符解釋為XML。CDATA 段從<![CDATA[ 開始,并以]]>結(jié)束。將下面的文本添加到slideSample.xml 文件,為虛構(gòu)的技術(shù)幻燈片定義CDATA 段:

    ?? ...
    				??<slide type="tech">
    		
    				????<title>How it Works</title>
    		
    				????<item>First we fozzle the frobmorten</item>
    		
    				????<item>Then we framboze the staten</item>
    		
    				????<item>Finally, we frenzle the fuznaten</item>
    		
    				????<item><![CDATA[Diagram:
    		
    				??????frobmorten <--------------- fuznaten
    		
    				????????| ?? <3>??^
    		
    				????????| <1>????|??<1> = fozzle
    		
    				????????V ????|??<2> = framboze 
    		
    				????????Staten--------------------+??????<3> = frenzle
    		
    				?????????? <2>
    		
    				????]]></item>
    		
    				??</slide>
    		
    </slideshow>

    在新文件上運(yùn)行Echo 程序時(shí),得到下列結(jié)果:

    ??ELEMENT: <item>
    ??CHARS:?? Diagram:
    ?
    frobmorten <--------------fuznaten
    ?????| ?????????<3>??????????^
    ???? | <1>? ????????????????|?? <1> = fozzle
    ????V? ????????????????|?? <2> = framboze 
    ??staten----------------------+?? <3> = frenzle
    ???????????<2>
    ?
    END_ELM: </item>

    可以看到一旦編寫了CDATA 段中的文本,就能夠得到它。由于解析器不將尖括號(hào)作為XML,所以它們不會(huì)產(chǎn)生致命錯(cuò)誤 (因?yàn)椋绻饫ㄌ?hào)不在CDATA段中,文檔的結(jié)構(gòu)就不好)。

    處理CDATA 和其他字符

    CDATA的存在使得正確回送XML非常重要。如果要輸出的文本不在CDATA段中,那么必須使用適當(dāng)?shù)膶?shí)體引用替代文本中的尖括號(hào)、&和其他特殊符號(hào)。(替代左尖括號(hào)和&最重要, 如果不誤導(dǎo)解析器,它就能正確解釋其他字符)

    但是如果輸出結(jié)果在CDATA 段中,那么不用替換,以產(chǎn)生類似于上例中的文本。在類似于Echo這樣的簡單程序中,這并不是一件重要的事情。但是許多XML-過濾應(yīng)用程序希望進(jìn)行跟蹤,確定文本是否出現(xiàn)在CDATA段中,這樣是為了正確處理特殊字符。

    另一處需要留意的地方就是屬性。屬性值的文本中也能包含尖括號(hào)和分號(hào),也需要使用實(shí)體引用來替換它。(屬性文本不能在CDATA段中,所以,這里不會(huì)存在替換問題)

    本教程的后面部分,會(huì)介紹如何使用LexicalHandler 來判斷是否正在處理CDATA 段。然后,會(huì)介紹如何定義DTD。

    創(chuàng)建文檔類型定義 (DTD)

    在XML聲明之后,文檔序言中能引入DTD,通過DTD可以指定XML文檔中可以引入的標(biāo)簽。同時(shí)告訴驗(yàn)證解析器哪些標(biāo)簽是有效的,以及在什么布局下是有效的。DTD告訴驗(yàn)證解析器和非驗(yàn)證解析器希望在哪里出現(xiàn)文本,解析器根據(jù)什么原則判斷空白是不可忽略的還是可以忽略的。

    基本DTD定義

    例如,在解析幻燈片放映時(shí),你會(huì)看到在注釋和幻燈片元素之前和之后多次調(diào)用方法characters 。在這些情況下,空白由行結(jié)束符和標(biāo)簽周圍的縮進(jìn)構(gòu)成。目標(biāo)是使得XML文檔可讀——空白并不總是文檔內(nèi)容的一部分。在開始學(xué)習(xí)DTD定義之前,首先告訴解析器什么地方的空白可以忽略。


    注意:本節(jié)定義的DTD包含在 slideshow1a.dtd中。 (可瀏覽的版本是 slideshow1a-dtd.html.)

    創(chuàng)建文件slideshow.dtd 輸入XML聲明和注釋標(biāo)識(shí)該文件,如下所示:

    <?xml version='1.0' encoding='utf-8'?>
    <!-- 
    ??DTD for a simple "slide show". 
    -->

    然后,添加下面的文本,指定slideshow 元素僅包含slide 元素:

    <!-- DTD for a simple "slide show". -->
    				<!ELEMENT slideshow (slide+)>
    				
    				
    				
    				
    		

    可以看到,DTD標(biāo)簽以<! 開始,接著是標(biāo)簽名 (ELEMENT)。標(biāo)簽名之后是要定義的元素的名字 (slideshow),括號(hào)內(nèi)是一個(gè)或多個(gè)項(xiàng)目,表明元素的有效內(nèi)容。這樣,符號(hào)說明slideshow 包含一個(gè)或多個(gè)slide 元素。

    若沒有+號(hào),該定義則表明slideshow 僅包含單個(gè)slide 元素。表6-2列出了在元素定義中可以使用的符號(hào)。

    6-2 ?DTD 元素限定符

    限定符

    名字

    含義

    ?

    問號(hào)

    可選 (零個(gè)或一個(gè))

    *

    星號(hào)

    個(gè)或多個(gè)

    +

    加號(hào)

    一或多個(gè)

    括號(hào)內(nèi)可以引入多個(gè)元素,使用逗號(hào)分隔,并且可以在每個(gè)元素上使用一個(gè)符號(hào)來表明可能會(huì)出現(xiàn)該元素的多少個(gè)實(shí)例。逗號(hào)分隔列表說明了哪些元素是有效的并說明了它們出現(xiàn)的順序。

    也可以嵌套括號(hào)以分組多個(gè)項(xiàng)目。例如,在定義image 元素后,可以通過((image, title)+)聲明在幻燈片中每個(gè)image 元素必須和title 元素配對使用。這里,在image/title 對上使用加號(hào)表明可以出現(xiàn)一個(gè)或多個(gè)(imagetitle )對。

    定義文本和嵌套元素

    現(xiàn)在,已經(jīng)告訴了解析器哪里不能出現(xiàn)文本,下面來看看如何告訴解析器哪里能夠出現(xiàn)文本。添加下面的文本,以定義slidetitleitemlist 元素:

    <!ELEMENT slideshow (slide+)>
    				<!ELEMENT slide (title, item*)>
    		
    				<!ELEMENT title (#PCDATA)>
    		
    				<!ELEMENT item (#PCDATA | item)* >
    				
    				
    				
    				
    		

    添加的第一行說明幻燈片包含一個(gè)title ,它后面是零個(gè)或多個(gè)元素項(xiàng)。這里沒有新的內(nèi)容了。下一行說明標(biāo)題包含完整的解析字符數(shù)據(jù) (PCDATA)。在該領(lǐng)域中這叫做"文本",但是在XML中,這叫做“解析字符數(shù)據(jù)”。 (這就將它和CDATA 段區(qū)分開來了,CDATA可能包含不需要解析的字符數(shù)據(jù)。) PCDATA后面的"#"號(hào)表明下面跟著的是特殊字,而不是元素名。

    最后一行介紹了垂直條(|),它代表了or 條件。這樣,可能出現(xiàn)PCDATAitem 。結(jié)尾處的星號(hào)表明它們中的任何一個(gè)可以連續(xù)出現(xiàn)零次或多次。該規(guī)范是混合內(nèi)容模型,因?yàn)槿我舛鄠€(gè)item 元素可以包含在文本中。定義這樣的模型時(shí)要先指定#PCDATA ,并使用垂直條分割一些可選項(xiàng),最后以星號(hào)結(jié)束。

    DTD的局限性

    如果能夠指定item 可以包含文本或在項(xiàng)目列表后可以有文本就更好了。但是事實(shí)表明在DTD中很難得到這樣的規(guī)范。例如,可以使用下面的方法定義一個(gè)item

    <!ELEMENT item (#PCDATA | (#PCDATA, item+)) >

    這樣當(dāng)然很精確,但是一旦解析器看到了#PCDATA 和垂直條,它就要求剩下的定義遵守混合內(nèi)容模型。但是該規(guī)范沒有遵守該模型,所以得到錯(cuò)誤:Illegal mixed content model for 'item'. Found &#x28; ..., 'item'使用了非法的混合內(nèi)容模型。找到&#x28; ..., 這里的十六進(jìn)制字符28表示結(jié)束該定義的尖括號(hào)。

    同樣,重復(fù)定義item 元素是沒有用的。運(yùn)行驗(yàn)證解析器的時(shí)候,下面的規(guī)范:

    <!ELEMENT item (#PCDATA) >
    <!ELEMENT item (#PCDATA, item+) >

    會(huì)產(chǎn)生"duplicate definition"(“重復(fù)定義”)警告。實(shí)際上,第二個(gè)定義會(huì)被忽略。所以現(xiàn)在看來定義一個(gè)混合內(nèi)容模型 (它允許item 元素包含在文本中)是目前能用的最好方法。

    除了上面提到的混合內(nèi)容模型的局限性外,沒有其他方法來限制指定的PCDATA 可能出現(xiàn)的文本。它是不是僅能包含數(shù)字?它是不是必須是日期格式的,還是能夠是貨幣格式?在DTD上下文中沒有辦法說明。

    最后,注意DTD不是層次結(jié)構(gòu)的。title 元素定義的應(yīng)用等價(jià)于slide 標(biāo)題和item 標(biāo)題。當(dāng)擴(kuò)展DTD允許使用HTML-風(fēng)格的標(biāo)簽和純文本時(shí),就有必要根據(jù)slide標(biāo)題限制item標(biāo)題的大小。但是這樣做的唯一方法是給它們一個(gè)不同的名字,如“item-title。 由于DTD缺少層次結(jié)構(gòu),最后一行要求在命名空間中引入“字符連接層次結(jié)構(gòu)”(或它的等價(jià)物) 。所有這些局限性都是開發(fā)模式規(guī)范標(biāo)準(zhǔn)的基本動(dòng)機(jī)。

    DTD中的特殊元素值

    最好不要使用括號(hào)擴(kuò)起來的元素列表,元素定義可以使用一或兩個(gè)特殊值: ANYEMPTYANY 規(guī)范表示元素可能包含其他定義的元素或PCDATA。這類規(guī)范通常用在通用的XML文檔(如創(chuàng)建字處理器)根元素中。在這類文檔中原文的元素可以以任何順序出現(xiàn),所以使用ANY 是有意義的。

    EMPTY 規(guī)范表示元素不包含任何內(nèi)容。所以允許你使用<flag/>標(biāo)簽的e-mail消息在DTD中有一行跟下面類似的內(nèi)容:

    <!ELEMENT flag EMPTY>

    引用DTD

    這時(shí),DTD定義跟XML文檔不在同一文檔中。這意味著必須在XML 文檔中引用它,這使得DTD文件成為XML文件完整的文檔類型定義(DTD)的外部子集。后面可以看到,也可以在文檔中引入DTD的一部分。這樣的定義構(gòu)成了DTD的本地子集。


    注意:本節(jié)中編寫的XML包括在slideSample05.xml中。(可瀏覽版本是slideSample05-xml.html)。

    將下面幾行內(nèi)容添加到slideSample.xml 文件中引用DTD文件:

    <!--? A SAMPLE set of slides? -->
    				<!DOCTYPE slideshow SYSTEM "slideshow.dtd">
    				
    				
    				
    				
    		
    <slideshow ?

    同樣,DTD 標(biāo)簽以"<!"開始,在本例中,標(biāo)簽名DOCTYPE說明該文檔是slideshow,意味著文檔包含slideshow 元素和它內(nèi)部的所有內(nèi)容:

    <slideshow>
    ...
    </slideshow>

    該標(biāo)簽將slideshow 元素定義成文檔的根元素。每個(gè)XML文檔必須有一個(gè)根元素。就在這里指定該元素。換句話說,該標(biāo)簽將文檔content 認(rèn)為是slideshow

    DOCTYPE 標(biāo)簽出現(xiàn)在XML聲明之后根元素之前。SYSTEM 標(biāo)識(shí)符指定DTD文件的位置。由于它不以http:/ or file:/這類前綴開始,故路徑跟XML文檔的位置相關(guān)。是否還記得setDocumentLocator 方法?解析器使用該信息查找DTD 文件,這就跟應(yīng)用程序查找和XML文檔相關(guān)的文件一樣。也要使用PUBLIC 標(biāo)識(shí)符指定使用唯一名字的DTD 文件——但是解析器必須能夠處理它。

    DOCTYPE 規(guī)范必須在XML文檔內(nèi)包含DTD 定義。這樣的定義包含在方括號(hào)內(nèi),如下所示:

    <!DOCTYPE slideshow SYSTEM "slideshow1.dtd" [
    				??...local subset definitions here...
    		
    				]>
    				
    				
    				
    				
    		

    后面會(huì)充分利用該功能來定義一些文檔中能使用的實(shí)體。

    DTD對非驗(yàn)證解析器的影響

    在前一節(jié),定義了基本文檔類型,并在XML文件中使用了它。在本節(jié)中,將使用Echo程序說明引入DTD后,數(shù)據(jù)是如何出現(xiàn)在SAX解析器中的。


    注意:本節(jié)中的輸出結(jié)果在Echo07-05.txt中。(可瀏覽版本是Echo07-05.html)


    slideSample.xml 的最新版本上運(yùn)行Echo程序,可以看到許多對characters 方法的多余的調(diào)用消失了。

    以前是:

    ??...
    >
    PROCESS: ...
    				CHARS:
    		
    ??ELEMENT:????????<slide
    ????ATTR: ...
    ??>
    ??????ELEMENT:????????<title>
    ??????CHARS:????????Wake up to ...
    ??????END_ELM:????????</title>
    ??END_ELM:????????</slide>
    				CHARS:
    		
    ??ELEMENT:????????<slide
    ????ATTR: ...
    ??>
    ??...

    現(xiàn)在是:

    ??...
    >
    PROCESS: ...
    ??ELEMENT:????????<slide
    ????ATTR: ...
    ??>
    ??????ELEMENT:????????<title>
    ??????CHARS:????????Wake up to ...
    ??????END_ELM:????????</title>
    ??END_ELM:????????</slide>
    ??ELEMENT:????????<slide
    ????ATTR: ...
    ??>
    ??...

    很明顯,可以看到,解析器不再傳送以前回送到slide 元素旁邊的空白字符,這是因?yàn)镈TD聲明, slideshow 僅僅包含slide 元素:

    ? <!ELEMENT slideshow (slide+)>

    跟蹤可忽略空白

    既然使用了DTD,解析器不再調(diào)用帶有無關(guān)空白的characters 方法。從僅對處理XML數(shù)據(jù)感興趣的應(yīng)用程序的觀點(diǎn)來看,這樣做非常好。應(yīng)用程序不再受到那些僅為增加XML文件可讀性的空白的干擾。

    另外,如果你正在編寫過濾XML數(shù)據(jù)文件的應(yīng)用程序,并且你希望該版本的文件具有相同的可讀性,那么這些空白就不會(huì)是無關(guān)的——它是必需的。要得到這些字符,必須在應(yīng)用程序中添加方法ignorableWhitespace 。下面你就要這樣做。


    注意:本節(jié)中編寫的代碼包含在Echo08.java中。輸出結(jié)果在Echo08-05.txt.中。(可瀏覽版本是Echo08-05.html)


    要處理解析器看到的可忽略的空白,添加下面的代碼,實(shí)現(xiàn)你自己的Echo程序中的ignorableWhitespace 事件處理程序:

    public void characters (char buf[], int offset, int len)
    ... 
    }
    				public void ignorableWhitespace char buf[], int offset, int Len)
    		
    				throws SAXException
    		
    				{
    		
    				??nl(); 
    		
    				??emit("IGNORABLE");
    		
    				}
    				
    				
    				
    				
    		
    public void processingInstruction(String target, String data)
    ...

    該代碼僅僅產(chǎn)生告訴你查看到了可忽略空白的消息。


    注意:同樣,不是創(chuàng)建的所有解析器都是相同的。SAX規(guī)范不要求調(diào)用該方法。只要DTD使得它可能,Java XML實(shí)現(xiàn)就這樣做。

    現(xiàn)在運(yùn)行Echo應(yīng)用程序,輸出結(jié)果如下所示:

    ELEMENT: <slideshow
    ??ATTR: ...
    >
    				IGNORABLE
    		
    				IGNORABLE
    		
    PROCESS: ...
    				IGNORABLE
    		
    				IGNORABLE
    		
    ??ELEMENT: <slide
    ????ATTR: ...
    ??>
    ??IGNORABLE
    ????ELEMENT: <title>
    ????CHARS:?? Wake up to ...
    ????END_ELM: </title>
    ??IGNORABLE
    ??END_ELM: </slide>
    				IGNORABLE
    		
    				IGNORABLE
    		
    ??ELEMENT: <slide
    ????ATTR: ...
    ??>
    ??...

    這里很明顯,在注釋和幻燈片元素之前和之后調(diào)用了可忽略空白,其中這之前調(diào)用的字符是DTD。

    清除

    既然已經(jīng)回送了可忽略空白,從你的Echo程序中刪除該代碼——前面的練習(xí)中已經(jīng)不再需要它們了。


    注意:該變化保存在Echo09.java中。

    文檔和數(shù)據(jù)

    前面,已經(jīng)介紹了同時(shí)存在XML documents和XML data這兩種叫法的原因之一在于,XML不管結(jié)構(gòu)中的元素之間是否允許使用文本,都能能否很好地處理它們。

    在使用的示例文件中,slideshow 元素是數(shù)據(jù)元素(data element)的一個(gè)例子——它僅包含子元素,且沒有插入文本。另外,item 元素可能會(huì)變成文檔元素(document element),因?yàn)樗芤肓宋谋竞妥釉亍?

    在閱讀該教程的過程中,你會(huì)知道如何擴(kuò)展標(biāo)題元素的定義,讓它能引入HTML-風(fēng)格的標(biāo)記,這也會(huì)變成文檔元素。

    修改空元素

    現(xiàn)在你已經(jīng)理解了如何忽略空白的特定實(shí)例,可以修改“空”元素的定義了。現(xiàn)在可以擴(kuò)展該元素以包含

    ? <foo>?? </foo>

    其中標(biāo)簽間有空白并且DTD定義的空白可忽略。

    定義DTD中的屬性和實(shí)體

    目前定義的DTD用于非驗(yàn)證解析器。它說明了文本應(yīng)該出現(xiàn)在哪里不應(yīng)該出現(xiàn)在哪里,這些都是解析器所關(guān)心的。但是在驗(yàn)證解析器的使用中,DTD需要指定不同元素的有效屬性。我們將在本節(jié)中實(shí)現(xiàn)它,然后再定義一個(gè)可以在XML文件中引用的內(nèi)部實(shí)體和外部實(shí)體。

    定義DTD中的屬性

    首先在幻燈片放映中定義元素屬性。


    注意:本節(jié)中編寫的XML包含在slideshow1b.dtd中。 (可瀏覽版本是:slideshow1b-dtd.html)

    添加下面的文本,定義slideshow 元素的屬性:

    <!ELEMENT slideshow (slide+)>
    				<!ATTLIST slideshow 
    		
    				????title??? CDATA??? #REQUIRED
    		
    				????date???? CDATA??? #IMPLIED
    		
    				????author?? CDATA??? "unknown"
    		
    				>
    		
    <!ELEMENT slide (title, item*)>

    DTD標(biāo)簽ATTLIST揭開了屬性定義的序幕。ATTLIST 后面的名字指定了要定義屬性的元素。這里,元素是slideshow 元素。(注意DTD規(guī)范中同樣缺少層次結(jié)構(gòu)) 。

    每個(gè)屬性由被三個(gè)空格隔開的值指定。不允許使用逗號(hào)和其他分隔符,所以如上所述的格式化定義對增強(qiáng)可讀性很有效。每行中的第一個(gè)元素是屬性的名字,這里是:title, dateauthor。 第二個(gè)元素表示了數(shù)據(jù)的類型:CDATA 是字符數(shù)據(jù)——不可解析數(shù)據(jù)。左尖括號(hào)(<)同樣是XML標(biāo)簽的一部分。表 6-3 提供了屬性類型的有效選擇。

    6-3 屬性類型

    屬性類型

    指定了 ...

    (value1 | value2 | ...)

    由垂直條分隔的值的列表 (例子在下面)

    CDATA

    "未解析的字符數(shù)據(jù)"。(對于一般人而言,這是文本字符串)

    ID

    不與其他ID屬性共享的名字

    IDREF

    對文檔其他地方定義的ID的引用

    IDREFS

    包含一個(gè)或多個(gè)ID引用的空格分隔的列表

    ENTITY

    DTD中定義的實(shí)體的名字

    ENTITIES

    空格間隔的實(shí)體的列表

    NMTOKEN

    有效的XML名字,由字母、數(shù)字、連字符、下劃線和冒號(hào)構(gòu)成

    NMTOKENS

    用空格間隔的名字列表

    NOTATION

    DTD指定的符號(hào)名,描述了非XML數(shù)據(jù)格式,比如圖像文件中使用的*

    *這是一個(gè)很快就過時(shí)的規(guī)范,在本節(jié)結(jié)尾處會(huì)詳細(xì)介紹。

    當(dāng)屬性類型包含括號(hào)括起來的由垂直條分隔的選項(xiàng)列表時(shí),屬性必須使用指定值。例如,將下面的文本添加到DTD中:

    <!ELEMENT slide (title, item*)>
    				<!ATTLIST slide 
    		
    				????type?? (tech | exec | all) #IMPLIED
    		
    				>
    		
    <!ELEMENT title (#PCDATA)>
    <!ELEMENT item (#PCDATA | item)* >

    該規(guī)范說明slide 元素的type 屬性必須按如下方式給出:type="tech"type="exec", or type="all"。其他值不能接受。(能理解DTD的XML編輯器可以使用這樣的規(guī)范來表現(xiàn)選項(xiàng)的彈出列表。)

    屬性規(guī)范中的最后一項(xiàng)確定了屬性的默認(rèn)值,并說明了是否需要屬性。表6-4 列出了可用選項(xiàng)。

    6-4 屬性 - 規(guī)范參數(shù)

    規(guī)范

    指定 ...

    #REQUIRED

    文檔中必須指定屬性值

    #IMPLIED

    文檔中不需要指定屬性值。如果沒有指定,它會(huì)使用應(yīng)用程序提供的默認(rèn)值

    "defaultValue"

    如果文檔中沒有指定值,這就是要使用的默認(rèn)值

    #FIXED "fixedValue"

    要使用的值。如果文檔指定了所有值,它們必須相同

    定義DTD中的實(shí)體

    目前,已經(jīng)看到了類似于&amp; 這樣的預(yù)定義實(shí)體,并且看到實(shí)體中可以引用屬性。現(xiàn)在可以開始學(xué)習(xí)如何定義實(shí)體。


    注意:這里定義的XML包含在slideSample06.xml中。輸出結(jié)果在Echo09-06.txt中。 (可瀏覽版本是slideSample06-xml.htmlEcho09-06.html.)


    將下面的文本添加到你的XML文件的DOCTYPE 標(biāo)簽中:

    <!DOCTYPE slideshow SYSTEM "slideshow.dtd" [
    				??<!ENTITY product? "WonderWidget">
    		
    				??<!ENTITY products "WonderWidgets">
    		
    				]>

    ENTITY 標(biāo)簽名說明正在定義一個(gè)實(shí)體。下面是實(shí)體名和它的定義。這里,定義了一個(gè)叫做“product”的實(shí)體,使用它來替代產(chǎn)品名。以后,一旦改變了產(chǎn)品名(通常會(huì)這樣),只需要改變一個(gè)地方的名字,然后,所有的幻燈片就都能夠使用該新值。

    最后一部分是XML文檔中實(shí)體引用時(shí)可以取代實(shí)體名的替換字符串。使用引號(hào)定義替代字符串,當(dāng)將文本插入文檔時(shí)沒有引入它們。

    為方便起見,我們定義了兩個(gè)版本,一個(gè)是單數(shù)一個(gè)是復(fù)數(shù)。當(dāng)市場專家遇到產(chǎn)品名"Wally"時(shí),你將要輸入復(fù)數(shù)"Wallies"并且正確替換它。


    注意:老實(shí)說,這屬于外部DTD的范疇。這樣,當(dāng)名字改變時(shí),所有的文檔能夠引用新的名字。但是,這是一個(gè)例子...


    既然已經(jīng)定義了實(shí)體,下面要在幻燈片放映中引用它們。進(jìn)行下面的修改實(shí)現(xiàn)該功能:

    <slideshow 
    ??title="WonderWidget&product; Slide Show" 
    ??...
    ??<!-- TITLE SLIDE -->
    ??<slide type="all">
    ????<title>Wake up to WonderWidgets&products;!</title>
    ??</slide>
    ?? <!-- OVERVIEW -->
    ??<slide type="all">
    ????<title>Overview</title>
    ????<item>Why <em>WonderWidgets&products;</em> are 
    great</item>
    ????<item/>
    ????<item>Who <em>buys</em> WonderWidgets&products;</item>
    ??</slide>

    這里要注意的是,你定義的實(shí)體被引用時(shí)用到的語法和用于預(yù)定義實(shí)體的相同(&entityName;),并且可以在屬性值和元素的內(nèi)容中引用實(shí)體。

    回送實(shí)體引用

    下面是在該版本的文件上運(yùn)行Echo 程序時(shí)看到的內(nèi)容:

    ELEMENT:????????<title>
    CHARS:????????Wake up to WonderWidgets!
    END_ELM:????????</title>

    注意,已經(jīng)使用了產(chǎn)品名替換了實(shí)體引用。

    其他有用實(shí)體

    下面是編寫XML文檔中可能有用的其他幾個(gè)實(shí)體定義的例子:

    <!ENTITY ldquo? "&#147;"> <!-- Left Double Quote --> 
    <!ENTITY rdquo? "&#148;"> <!-- Right Double Quote -->
    <!ENTITY trade? "&#153;"> <!-- Trademark Symbol (TM) -->
    <!ENTITY rtrade "&#174;"> <!-- Registered Trademark (R) -->
    <!ENTITY copyr? "&#169;"> <!-- Copyright Symbol --> ?

    引用外部實(shí)體

    也可以使用SYSTEMPUBLIC 標(biāo)識(shí)符命名在外部文件中定義的實(shí)體。現(xiàn)在就可以這樣做。


    注意:這里定義的XML包含在 slideSample07.xmlcopyright.xml中。輸出結(jié)果在Echo09-07.txt中。(可瀏覽版本是slideSample07-xml.html, copyright-xml.html Echo09-07.html.)


    為了引用外部實(shí)體,將下面的文本添加到XML文件的DOCTYPE 語句中:

    <!DOCTYPE slideshow SYSTEM "slideshow.dtd" [
    ??<!ENTITY product? "WonderWidget">
    ??<!ENTITY products "WonderWidgets">
    ??<!ENTITY copyright SYSTEM "copyright.xml">
    ]>

    該定義引用了一個(gè)包含在文件copyright.xml 中的版本信息。創(chuàng)建該文件并輸入一些有趣的文本,如下所示:

    ? <!--? A SAMPLE copyright? -->
    This is the standard copyright message that our lawyers
    make us put everywhere so we don't have to shell out a
    million bucks every time someone spills hot coffee in their
    lap...

    最后,將下面的文本添加到slideSample.xml 文件中,以引用外部實(shí)體:

    <!-- TITLE SLIDE -->
    ??...
    </slide>
    				<!-- COPYRIGHT SLIDE -->
    		
    				<slide type="all">
    		
    				??<item>&copyright;</item>
    		
    				</slide>
    				
    				
    				
    				
    		

    也可以使用外部實(shí)體聲明來訪問servlet,該servlet使用類似于下面的定義來產(chǎn)生當(dāng)前日期:

    <!ENTITY currentDate SYSTEM
    ??"http://www.example.com/servlet/CurrentDate?fmt=dd-MMM-
    yyyy"> ?

    可以使用跟引用其他實(shí)體相同的方法引用該實(shí)體:

    ? Today's date is &currentDate;.

    回送外部實(shí)體

    下面是在幻燈片放映的最新版本上運(yùn)行Echo程序時(shí)看到的內(nèi)容:

    ...
    END_ELM: </slide>
    ELEMENT: <slide
    ??ATTR: type????????"all"
    >
    ??ELEMENT: <item>
    ??CHARS: 
    This is the standard copyright message that our lawyers
    make us put everywhere so we don't have to shell out a
    million bucks every time someone spills hot coffee in their
    lap...
    ??END_ELM: </item>
    END_ELM: </slide>
    ...

    注意,文件中注釋后面的新行將作為字符回送,但是忽略注釋本身。這就是為什么版本消息出現(xiàn)在CHARS: 標(biāo)簽后面的下一行中,而不是直接在標(biāo)簽后面——實(shí)際上第一個(gè)回送的字符是注釋后面的新行。

    總結(jié)實(shí)體

    文檔內(nèi)容中引用的實(shí)體,不論是外部的還是內(nèi)部的都一概叫做一般實(shí)體。包含DTD內(nèi)引用的DTD規(guī)范的實(shí)體叫做參數(shù)實(shí)體(后面將會(huì)詳細(xì)介紹)。

    一個(gè)包含XML(文本和標(biāo)記)并且被解析的實(shí)體叫做已析實(shí)體(parsed entity)。一個(gè)包含二進(jìn)制數(shù)據(jù)的實(shí)體 (如圖像)叫做未析實(shí)體(unparsed entity)。(本質(zhì)來講,它必須是外部的)該教程的下一節(jié)主要討論對未析實(shí)體的引用。

    引用二進(jìn)制實(shí)體

    本節(jié)沒有編程練習(xí)。主要討論引用類似于圖像文件和多媒體數(shù)據(jù)文件這樣的二進(jìn)制時(shí)的選項(xiàng)。

    使用MIME數(shù)據(jù)類型

    有兩種方法可以引用類似于二進(jìn)制圖形文件的這類未析實(shí)體。一種方法是使用DTD的NOTATION-規(guī)范機(jī)制。然而,該機(jī)制是一個(gè)復(fù)雜的非直觀機(jī)制,通常用于兼容SGML文檔。在介紹DTDHandler API時(shí)會(huì)進(jìn)一步詳細(xì)地介紹它,但是現(xiàn)在已可以說結(jié)合最近定義的XML命名空間標(biāo)準(zhǔn),以及為電子郵件附件定義的MIME數(shù)據(jù)類型,為引用未析外部實(shí)體提供了一個(gè)更加有用、更易理解、更易擴(kuò)展的機(jī)制。


    注意:這里描述的XML在 slideshow1b.dtd中。我們實(shí)際上沒有回送任何圖像。這超過了本教程的Echo程序的范圍。本節(jié)僅用來理解如何進(jìn)行這類引用。它假設(shè)將要處理XML數(shù)據(jù)的應(yīng)用程序知道如何處理這類引用。


    將下面的文本添加到slideshow.dtd文件中,以便讓幻燈片顯示使用圖像文件:

    <!ELEMENT slide (image?, title, item*)>
    <!ATTLIST slide 
    ????type?? (tech | exec | all) #IMPLIED
    >
    <!ELEMENT title (#PCDATA)>
    <!ELEMENT item (#PCDATA | item)* >
    				<!ELEMENT image EMPTY>
    		
    				<!ATTLIST image 
    		
    				????alt??? CDATA??? #IMPLIED
    		
    				????src??? CDATA??? #REQUIRED
    		
    				????type?? CDATA??? "image/gif"
    		
    				>
    				
    				
    				
    				
    		

    這些改動(dòng)聲明imageslide中的可選元素,將它定義為空元素,并定義它需要的屬性。該image 標(biāo)簽在HTML 4.0 標(biāo)簽img之后,添加了圖像類型標(biāo)識(shí)符type。(img 標(biāo)簽是在HTML 4.0規(guī)范中定義的)

    image 標(biāo)簽的屬性是由ATTLIST 項(xiàng)定義的。alt 屬性定義了在找不到圖像的情況下顯示的替代文本,它接受字符數(shù)據(jù)(CDATA)。這是一個(gè)“隱含”(implied)值,這表明它不是可選的,并且處理數(shù)據(jù)的程序知道如何替代像“圖像沒有找到”這樣的消息。另外,需要src 屬性來指定要顯示的圖像。

    在MIME數(shù)據(jù)類型中需要type 屬性,它定義在ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/.。它的默認(rèn)值為 image/gif


    注意:這里可以知道類型屬性使用的字符數(shù)據(jù)(CDATA)是MIME數(shù)據(jù)類型中的一種。最常見的格式為: image/gifimage/jpeg。這樣,最好在這里指定屬性列表,使用下面的格式:

    type ("image/gif", "image/jpeg")

    然而,這沒有用,因?yàn)閷傩粤斜硎芟抻诿钟浱?hào)(name token)。正斜杠不是名字記號(hào)字符的有效部分,所以該聲明出錯(cuò)。而且,在DTD中創(chuàng)建屬性列表將會(huì)將有效的MIME類型限制于這些定義中。仍然保持CDATA 使得它更加開放,所以定義了其他類型之后,該聲明仍然有效。


    文檔中,對"intro-pic"圖像的引用具有以下格式:

    <image src="image/intro-pic.gif", alt="Intro Pic", 
    type="image/gif" />

    另一選擇:使用實(shí)體引用

    使用MIME數(shù)據(jù)類型作為元素的屬性是一個(gè)非常靈活并可擴(kuò)展的機(jī)制。要使用符號(hào)機(jī)制創(chuàng)建外部ENTITY 引用,對于jpeg和gif數(shù)據(jù)需要DTD NOTATION 元素。當(dāng)然這些都可以從一些中央知識(shí)庫中取得。但是這樣你必須要為你想要引用的每個(gè)圖像定義不同的ENTITY 元素。換句話說,在文檔中添加新的圖像需要在DTD中進(jìn)行新實(shí)體定義也要在文檔中引用它。給定了普遍存在的HTML 4.0規(guī)范,更新的標(biāo)準(zhǔn)要使用MIME數(shù)據(jù)類型和聲明,如image ,它假設(shè)應(yīng)用程序知道如何處理這類元素。

    選擇解析器實(shí)現(xiàn)

    如果沒有指定其他factory類,就使用默認(rèn)的SAXParserFactory 類。使用不同制造商的解析器,可以改變指向它的環(huán)境變量的值。可以在命令行中進(jìn)行該操作,如下所示:

    java -Djavax.xml.parsers.SAXParserFactory=yourFactoryHere ...

    你指定的factory名必須是完全合格的類名(包括所有的包前綴)。如果想獲得更多信息,請查看SAXParserFactory 類中的newInstance()方法的文檔。

    主站蜘蛛池模板: 国产亚洲情侣久久精品| 亚洲av日韩av天堂影片精品| 最好免费观看韩国+日本| 成人性生交大片免费看无遮挡| 最近免费中文字幕大全免费版视频| 久久久久国产精品免费免费不卡| 日本视频免费高清一本18| 久久久国产精品福利免费| 久草免费福利资源站| 99精品免费观看| 久久久久久精品成人免费图片| 国产精品免费网站| 成年美女黄网站18禁免费| 免费鲁丝片一级在线观看| 免费一级毛片正在播放| 亚洲日韩中文字幕日韩在线| 亚洲综合色自拍一区| 亚洲av无码国产精品色午夜字幕| 久久精品夜色国产亚洲av| 亚洲精品高清国产麻豆专区| 亚洲性色高清完整版在线观看| 亚洲jizzjizz在线播放久| 18禁亚洲深夜福利人口| 人妖系列免费网站观看| 国产成人精品无码免费看| 免费在线观看h片| 国产成人免费a在线视频app| 久久精品国产亚洲Aⅴ蜜臀色欲| 亚洲女久久久噜噜噜熟女| 亚洲欧洲尹人香蕉综合| 亚洲日韩一区二区一无码| 久香草视频在线观看免费| AAA日本高清在线播放免费观看| 精品国产无限资源免费观看| 国产大片线上免费看| 亚洲色WWW成人永久网址| 亚洲大香伊人蕉在人依线| 精品国产日韩亚洲一区91| 永久免费AV无码网站国产| 特级做A爰片毛片免费69| 亚洲欧洲精品成人久久曰影片|