XML和Java: 低階或高階的 XML API?

heying1229發表於2007-09-25
XML和Java: 低階或高階的 XML API?[@more@]來自:developerWorks 中國

不久之前,XML 開發主要侷限於 SAX,DOM 和自己開發的 API。儘管今時今日存在大量開發人員友好的 API,但是開發人員是不是也失去了一些處理 XML 的能力呢……

  XML 是關於靈活性的

  不需要詳細研究 XML 起源的長期歷史原因,在開始這個討論話題之前我想再次重申 XML 最初確實是關於靈活性的。XML 提供了一種供應商中立的格式來表示資料。根據對 XML 規範內容和要求的一致理解,應用程式可以輕易生成這種格式,並且其它應用程式也可以方便地使用這種格式。

  以更通俗的語言來說,如果您告訴我您使用的是 XML,然後再告訴我您所使用的元素和屬性,我很快就能寫出能讀取和使用 XML 的程式碼來。反過來也一樣,如果我向您提供了我的約束模型 (constraint model)(通常為 DTD 或者 XML Schema 格式),您就能夠很快地操作我的資料。

  最初的 API 可以維持這種靈活性

  不足為奇,當 XML API 剛開始出現的時候,它們都非常的簡單。最初版本的 Simple API for XML(SAX)和文件物件模型(Document Object Model,DOM)只具備非常基礎的操作。您可以從某個元素中獲得資料,操作其子元素,找出某個屬性的值等,全部都是這方面的操作。除了處理 XML 的詞彙結構之外,這些 API 並未提供大量的特性。

  在 XML 發展的初期,這被認為是件好事。這非常像過去程式設計師對 C 語言和組合語言做的一樣,以對計算機中底層的位元和位元組維持最大控制,SAX 特別適合於處理原始的 XML 文件 — 具有基本格式的資料 — 並允許您的程式完成需要的操作,而不需要花費業餘時間研究這些 XML API。

  然後出現了包裝 API

  首次告別低階控制 — 從理論上說實現了開發人員友好的 API — 的是 JAXP,Sun 公司用於處理 XML 的 Java API。最初,JAXP 的目標是從 SAX 和 DOM 程式碼中移除一些特定於供應商的資訊(涉及到所使用的 XML 解析器)。

  然而,為了努力提供一些便利,JAXP 提供了幾個輔助方法(helper method),從本質上說就是把 SAX 和 DOM 中已有的功能封裝起來。因為 Sun 公司在 Java 市場上影響如此巨大,所以開發人員很快就開始使用這些輔助方法了,並且很少再直接操作 SAX 和 DOM 了 。

  程式設計師仍然需要了解 SAX 的基本原理(如什麼是 ContentHandler 以及如何實現回撥方法),但是 JAXP 抽象出了很多這樣的細節。事實上,要執行特定的動作,如設定一些 SAX 中不常見的詞彙控制程式碼,我們不得不 繞開 JAXP 而直接操作 SAX。

  如今又出現了資料繫結,JDOM 和大量的 API

  差不多在十年之後(取決於您所使用的日期),又出現了許多其它種類的 API。除了 SAX、DOM 和 JAXP 之外,我們還可以使用 JDOM、XOM、dom4j、StAX 和一些其它的變體非常直接地操作 XML。一些資料繫結 API,如 Zeus、Castor 和 JAXB 能允許我們在對 XML 沒有多少了解的情況下處理 XML,而不用操作 XML 文件表示為邏輯資料而不是字串或其他資料的資料。並且 Eclipse 之類的框架將完成所有這些操作,而您只需指定、單擊和修改 XML 就可以了。從字面上看,有數百種方案可供選擇(使用 XSLT 後我甚至不需關心 XML 的轉換了)。

  我們仍然具備靈活性嗎?

  掌握了所有可用於操作 XML 的 API 之後,Java 和 XML 程式設計師似乎具備了前所未有的高度靈活性;那麼選擇就意味著靈活性嗎?我們稍微質疑一下這一斷言,看它是否真的站得住腳。

解析程式中的靈活性

  毫無疑問,我們能夠使用所想要的任何 XML 解析器,任何版本和風格的解析器都可以,只要我們具有某些類檔案 — 大多數情況下,這些檔案都捆綁在所選的 API 中。因此要方便地從 XML4J 轉換到 Sun 公司的老式 Crimson 解析器再到 Apache Xerces(版本 1 或版本 2)是非常簡單的。JAXP 之類的 API 可以很輕鬆地實現這個過程(儘管我在側欄中指出在所有新 API 出現之前這在 SAX 或 DOM 中就已經可用),並且在很多資料繫結 API 中,我們甚至完全意識不到正在進行的解析;解析都隱藏在幕後。因此毫無疑問,我們可以馬上使用任何想要的解析器。解析器中的靈活性被證實。

  使用中的靈活性

  大量的 XML API 還為我們提供了很多處理資料的方法。使用 SAX 和 DOM,能輕易地獲得文件中的原始資料;使用 JAXP 也同樣可行,儘管所支援的資料可能會少一點(我之前提到過必須要執行一些操作才能處理 XML 註釋或 DTD 語法之類的資料)。我們在使用某個資料繫結 API 時,可以在根本上操作 XML 文件的資料而不需 XML 的修飾。person 元素變成了Person 物件,並且我們能夠使用 getAge() 獲取 age 屬性的值。在很多方面,您可以根據在 XML 文件中使用資料的方式以及對 XML 的瞭解程度來選擇 API。因此使用中的靈活性證實無誤。

  錯誤處理中的靈活性

  這裡遇到了些許麻煩,高階 API 的一些靈活性造成了一些問題。在一些 API 中,如 Sun 的 JAXB 和所提供的資料繫結 API 中,我們都是在 XML 文件的原始字串、元素和屬性之上的幾個層次上進行操作的。其結果是,如果文件中的內容格式不正確,則處理任何問題都無法具備高度的靈活性。一般而言,在遇到某種編組或非編組錯誤時,我們必須要修復 XML 本身並重新執行該過程(或者向呼叫程式丟擲異常,這在本質上是相同的)。但是在真正地修復錯誤並從解析器中獲得詳細資訊的方面呢?這確實不屬於高階 API 的範圍。因此,此處出現了一個缺陷。

  操作 XML 文件中的靈活性

  上面所提到的使用中的靈活性,看上去可能與操作 XML 文件中的靈活性是一樣的。其實並非如此;在很多新興的(有些人會說是易於使用的)API 中,我們是在 XML 文件中運算元據的 — 然後有時甚至不是作為 XML 而是當作物件或者屬性來進行操作的。操作 XML 文件本身意味著我們能直接更換、修改或者移除文件的一部分,並能直接處理元素名稱、屬性甚至註釋和處理指令。

  最初看來可能並不是真正需要這一級別的處理和靈活性,但是我們想到了與程式設計的類比。正如 C 語言和組合語言使核心編碼器在計算機程式設計的底層進行工作,特別是 SAX 之類的 API,和程度較輕的 DOM,使核心的 Java 和 XML 程式設計師幾乎可以隨心所欲地操作 XML 文件。就像大多數技巧都內建在 C 語言或者組合語言中,由於這種額外的能力轉化成了真正的速度、效能和一些最佳化,比起一些高階的 API(如 JAXB 甚至是 JDOM),使用 SAX 和 DOM 仍然能為有經驗的程式設計師提供更多的支援。因此,雖然這些高階 API 確確實實提供了大量的優勢,但是它們並沒有為直接操作實際的 XML 文件提供很多的靈活性。

  結束語

  就是這樣:我就是想考證究竟有多大的靈活性。顯而易見,這篇文章並不是一篇充滿了執行程式碼的技巧文章,因為我想知道這些天來是否有人確實使用了執行的 XML 程式碼,以及他們所使用的是哪種(或哪些)API。真的有數百計、數千計或者數萬計的讀者仍然堅持使用 SAX 和 DOM 舒適地編寫著 startProcessingInstruction() 方法,或者完全使用資料繫結和輔助 API 取代了 SAX 和 DOM?我對此非常好奇,大多數 developerWork 的編輯人員同樣好奇。

  更重要的是,您是否認為自己仍然能夠控制 XML 呢?我特別要向那些早期就開始處理 XML 的程式設計師提這個問題,那時 SAX 是快速讀取 XML 的惟一選擇,並且 DOM 是以物件的形式處理 XML 文件的惟一選擇。您是否發現您自己在一個更高的級別工作?您是否對此滿意?或者是否我們都已成為 Turbo Pascal 程式設計師,而只有少許人在他們的 ASM 終端上處理堆疊呢?

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-972099/,如需轉載,請註明出處,否則將追究法律責任。

相關文章