XML解析 DOM(文檔對(duì)象模型)與 SAX(XML簡(jiǎn)易應(yīng)用應(yīng)用程序編程接口) 1.DOM 卻沒(méi)有提供特定的實(shí)現(xiàn),實(shí)際上,它能夠用任何編程語(yǔ)言實(shí)現(xiàn)。例如,為了通過(guò)D O M訪問(wèn)傳統(tǒng) 的數(shù)據(jù)存儲(chǔ),可以將D O M實(shí)現(xiàn)為傳統(tǒng)數(shù)據(jù)訪問(wèn)功能之外的一層包裝。利用D O M中的對(duì)象,開(kāi)發(fā) 人員可以對(duì)文檔進(jìn)行讀取、搜索、修改、添加和刪除等操作。D O M為文檔導(dǎo)航以及操作H T M L 和X M L文檔的內(nèi)容和結(jié)構(gòu)提供了標(biāo)準(zhǔn)函數(shù)。 D O M提供了強(qiáng)大的接口集合,以簡(jiǎn)化對(duì)D O M節(jié)點(diǎn)樹(shù)的操作。
• DOM能夠保證正確的語(yǔ)法和格式正規(guī)性。 • DOM能夠從語(yǔ)法中提取內(nèi)容。 • DOM能夠簡(jiǎn)化內(nèi)部文檔操作。 • DOM能夠貼切地反映典型的層次數(shù)據(jù)庫(kù)和關(guān)系數(shù)據(jù)庫(kù)的結(jié)構(gòu)。 1. DOM能夠保證正確的語(yǔ)法和格式正規(guī)性 由于D O M將文本文件轉(zhuǎn)化為抽象的節(jié)點(diǎn)樹(shù)表示,因此能夠完全避免無(wú)結(jié)束標(biāo)記和不正確的 標(biāo)記嵌套等問(wèn)題。使用D O M操作X M L文檔時(shí),開(kāi)發(fā)人員不必?fù)?dān)心文檔的文本表示—只需要關(guān) 注父子關(guān)系和相關(guān)的信息。另外, D O M能夠避免文檔中不正確的父子關(guān)系。例如,一個(gè)A t t r對(duì) 象永遠(yuǎn)也不能成為另一個(gè)A t t r對(duì)象的父對(duì)象。 2. DOM能夠從語(yǔ)法中提取內(nèi)容 由D O M創(chuàng)建的節(jié)點(diǎn)樹(shù)是X M L文件內(nèi)容的邏輯表示—它顯示了文件提供的信息,以及它們 之間的關(guān)系,而不受限于X M L語(yǔ)法。例如,節(jié)點(diǎn)樹(shù)蘊(yùn)含的信息可以用于更新關(guān)系數(shù)據(jù)庫(kù),或者 創(chuàng)建H T M L頁(yè)面—開(kāi)發(fā)人員不必糾纏于X M L語(yǔ)法規(guī)范。 3. DOM能夠簡(jiǎn)化內(nèi)部文檔操作 就修改X M L文件的結(jié)構(gòu)而言,使用D O M比使用傳統(tǒng)的文件操作機(jī)制更加簡(jiǎn)單。正如我們?cè)?/p> 前面的例子中所描述的,利用D O M在文檔中增加元素非常簡(jiǎn)便。另外,你可以通過(guò)幾條命令執(zhí) 行全局性操作(例如:從文檔中刪除具有特定標(biāo)記名稱的所有元素),而不必采用繁瑣的方法 —首先對(duì)文件進(jìn)行掃描,然后刪除相關(guān)的標(biāo)記。 4. DOM能夠貼切地反映典型的層次數(shù)據(jù)庫(kù)和關(guān)系數(shù)據(jù)庫(kù)的結(jié)構(gòu) D O M表示數(shù)據(jù)元素關(guān)系的方式非常類似于現(xiàn)代層次型和關(guān)系型數(shù)據(jù)庫(kù)表示信息的方法。這 使得利用D O M在數(shù)據(jù)庫(kù)和X M L文件之間移動(dòng)信息變得相當(dāng)簡(jiǎn)單。 大部分?jǐn)?shù)據(jù)庫(kù)都使用“雪花”結(jié)構(gòu)表示層次型信息,數(shù)據(jù)庫(kù)中的信息從中心“頂級(jí)”表向 外輻射,類似于車輪的車條(參見(jiàn)圖5 - 3)。 圖5-3 注意,每個(gè)客戶可能有多張發(fā)票,而且每張發(fā)票可能包含多個(gè)行式項(xiàng)目。為了支持這種行 為,X M L允許我們包含一個(gè)子元素的多個(gè)拷貝。上圖中的每個(gè)元素基本上都對(duì)應(yīng)著一張表,每 張表都包含多列(這些列在X M L中作為屬性出現(xiàn))。 上圖的結(jié)構(gòu)等價(jià)于以下X M L文件: 2.SAX
S A X的接口風(fēng)格完全不同于文檔對(duì)象模型。文檔對(duì)象模型應(yīng)用程序通過(guò)遵循內(nèi)存中的對(duì)象 參照來(lái)要求文檔中的內(nèi)容;使用S A X ,解析器通過(guò)向應(yīng)用程序報(bào)告解析事件流來(lái)告知應(yīng)用程序文 檔的內(nèi)容。 S A X即X M L簡(jiǎn)易應(yīng)用程序編程接口,全稱是擴(kuò)展標(biāo)記語(yǔ)言簡(jiǎn)易應(yīng)用程序編程接口。 從程序中讀取X M L文檔基本上有三種方式: • 把X M L只當(dāng)做一個(gè)文件讀取,然后自己挑選出其中的標(biāo)簽。這是黑客們的方法,我們不推 薦這種方式。你很快會(huì)發(fā)現(xiàn)處理所有的特殊情況(包括不同的字符編碼,例外約定,內(nèi)部 和外部實(shí)體,缺省屬性等)比想象的困難得多;你可能不能夠正確地處理所有的特殊情況, 這樣你的程序會(huì)接收到一個(gè)非常規(guī)范的X M L文檔,卻不能正確地處理它。要避免這種想法: X M L解析器似乎并不昂貴(大多數(shù)是免費(fèi)的)。 • 可以用解析器分析文檔并在內(nèi)存里創(chuàng)建對(duì)文檔內(nèi)容樹(shù)狀的表達(dá)方式:解析器將輸出傳遞給 文檔對(duì)象模型,即D O M。這樣程序可以從樹(shù)的頂部開(kāi)始遍歷,按照從一個(gè)樹(shù)單元到另一 個(gè)單元的引用,從而找到需要的信息。 • 也可以用解析器讀取文檔,當(dāng)解析器發(fā)現(xiàn)標(biāo)簽時(shí)告知程序它發(fā)現(xiàn)的標(biāo)簽。例如它會(huì)告知它 何時(shí)發(fā)現(xiàn)了一個(gè)開(kāi)始標(biāo)簽,何時(shí)發(fā)現(xiàn)了一些特征數(shù)據(jù),以及何時(shí)發(fā)現(xiàn)了一個(gè)結(jié)束標(biāo)簽。這 叫做事件驅(qū)動(dòng)接口,因?yàn)榻馕銎鞲嬷獞?yīng)用程序它遇到的有含義的事件。如果這正是你需要 的那種接口,可以使用S A X。 1. SAX 的優(yōu)點(diǎn) 下面的部分簡(jiǎn)述了S A X接口最顯著的一些優(yōu)點(diǎn)。 (1) 可以解析任意大小的文件 因?yàn)镾 A X不需要把整個(gè)文件加載到內(nèi)存,所以對(duì)內(nèi)存的占用一般比D O M小得多,而且不隨 著文件大小的增加而增加。當(dāng)然D O M使用的實(shí)際內(nèi)存數(shù)量要視解析器而定,但在大多數(shù)情況下 一個(gè)1 0 0 K b的文檔至少要占用1 M b的內(nèi)存。 但是有一點(diǎn)要注意:如果S A X應(yīng)用程序自身在內(nèi)存中創(chuàng)建文檔的表達(dá),它會(huì)占用和允許 解析器創(chuàng)建空間一樣大小的內(nèi)存。 (2) 適合創(chuàng)建自己的數(shù)據(jù)結(jié)構(gòu) 應(yīng)用程序可能會(huì)想用如書、作者以及出版者這樣的高級(jí)對(duì)象而不是一些低級(jí)元素、屬性和 處理指令來(lái)創(chuàng)建數(shù)據(jù)結(jié)構(gòu)。這些“交易對(duì)象”可能只是和X M L文件內(nèi)容有一點(diǎn)關(guān)系;例如它們 可能只是組合X M L文件和其他數(shù)據(jù)源的數(shù)據(jù)。在這種情況下,如果想在內(nèi)存中創(chuàng)建面向應(yīng)用的 數(shù)據(jù)結(jié)構(gòu),首先創(chuàng)建一個(gè)低級(jí)D O M結(jié)構(gòu)然后毀壞它是很不合算的??梢詢H在每個(gè)事件發(fā)生時(shí)處 理它,這樣保證商務(wù)對(duì)象模型合理地增加變動(dòng)。 (3) 適合小信息子集 如果僅對(duì)計(jì)算本周圖書館購(gòu)進(jìn)的書籍?dāng)?shù)量或確定它們的平均價(jià)s格感興趣,那么把不需要的 全部數(shù)據(jù)和需要的少量數(shù)據(jù)一起讀入內(nèi)存是非常低效和不必要的。SAX 一個(gè)非常好的特點(diǎn)就是 可以非常容易地忽略不感興趣的數(shù)據(jù)信息。 (4) 簡(jiǎn)單 如題所示, S A X非常易于使用。 (5) 快速 如果可以從經(jīng)由文檔的簡(jiǎn)單序列中獲取你需要的信息, S A X幾乎一定是最快的方法。 2. SAX 的缺點(diǎn) 在論述完其優(yōu)點(diǎn)之后應(yīng)該指出使用S A X時(shí)可能遇到的不足之處。 (1) 不能對(duì)文檔做隨機(jī)存取 因?yàn)槲臋n并不加載到內(nèi)存,所以必須按照數(shù)據(jù)提交的次序進(jìn)行處理。對(duì)于文檔中包含許多 內(nèi)部交叉引用如使用I D和I D R E F屬性的情況,S A X使用起來(lái)會(huì)困難一些。 (2) 難以實(shí)現(xiàn)復(fù)雜的查詢 復(fù)雜的查詢對(duì)程序而言是非常凌亂的,因?yàn)楸仨氉约壕S護(hù)含有你所需要保留信息的數(shù)據(jù)結(jié) 構(gòu),如當(dāng)前元素祖先的屬性。 (3) 不能使用文檔類型定義( D T D) S A X 1 . 0不會(huì)告知D T D的任何內(nèi)容。實(shí)際上D O M也不會(huì)告知太多內(nèi)容什么,盡管有些提供商 已經(jīng)擴(kuò)展了D O M接口以支持這種功能。這對(duì)大多數(shù)應(yīng)用程序來(lái)說(shuō)并不是個(gè)問(wèn)題: D T D主要是解 析器感興趣的問(wèn)題;而且在本章末尾可以看到這個(gè)問(wèn)題在SAX 2.0中得到了解決。 (4) 不可獲取詞法信息 S A X的設(shè)計(jì)原理是它不提供詞法信息。S A X設(shè)法告知文檔作者想要說(shuō)明什么,而不是讓你 忙于研究他們說(shuō)明方式的細(xì)節(jié)。例如: 第6章SAX 1.0: XML簡(jiǎn)易API使用147 下載 • 你不能查明原始文檔中是否包含“& # x a ; " 或" & # 1 0或 ; ”它是否包含一個(gè)換行字符:所有這三 種情況以相同的方式報(bào)告給應(yīng)用程序。 • 你不會(huì)被告知文檔中的注釋說(shuō)明: S A X假設(shè)注釋是為方便作者而不是讀者設(shè)計(jì)的。 • 你不會(huì)得知屬性書寫的順序:這被認(rèn)為是無(wú)關(guān)緊要的。 只有當(dāng)你考慮到以后可能會(huì)需要編輯文檔,想按照文檔原先書寫的方式重新創(chuàng)建它時(shí),這 些限制才會(huì)導(dǎo)致一些問(wèn)題。例如你需要編寫這樣一個(gè)應(yīng)用程序,它用來(lái)在完整無(wú)缺地保留文檔 原有內(nèi)容的基礎(chǔ)上,從另外一個(gè)文檔添加某些額外信息到原文檔中。這樣如果你隨意改變了屬 性的順序或丟棄了所有的注釋,原文檔作者會(huì)不滿意的。實(shí)際上,大多數(shù)限制和D O M是一樣的, 盡管D O M的確在某些方面提供了稍多一些的信息:例如它保留了注釋。此外,很多這樣的限制 在SAX 2.0里得到改進(jìn);盡管沒(méi)有完全解決,例如屬性的順序和分割符(單引號(hào)或雙引號(hào))的選 D O M可以從X M L原文件中讀取文檔,也可以創(chuàng)建和修改內(nèi)存中的文檔。相比較而言, S A X 是用來(lái)讀取X M L文檔而不是書寫文檔。 實(shí)際結(jié)果是S A X接口可以很容易地和讀取X M L文檔一樣書寫文檔。稍后可以看到,解析器 讀取X M L文檔時(shí)發(fā)送給應(yīng)用程序的事件流同樣可以被應(yīng)用程序發(fā)送到文檔生成器以創(chuàng)建文檔。 (6) 當(dāng)前的瀏覽器不支持S A X 盡管有許多支持S A X接口的X M L解析器。在編寫本書時(shí)還沒(méi)有一個(gè)主流的We b瀏覽器內(nèi)置 X M L解析器以支持S A X接口。你當(dāng)然可以把兼容S A X的解析器合成到一個(gè)Java applet程序中去, 但是從服務(wù)器下載a p p l e t的開(kāi)銷會(huì)使低速接入Internet 的用戶失去耐心。實(shí)際上客戶端X M L編程 可選擇的接口是相當(dāng)有限的。
|
聯(lián)系客服