實用數據綁定: 使用 XPath 作為數據綁定工具,第 2 部分:使用 JAXP API 執行 XPath 查詢
級別: 中級
Brett McLaughlin, 作家,編輯, O'Reilly Media, Inc.
2006 年 1 月 23 日
一 旦理解了 XPath 語法和位置路徑,避開 DOM 和 SAX 的開銷訪問 XML 就是可能的了,而且很容易。對于 Java? 開發人員來說,幸運的是 Java API for XML Processing(JAXP)為創建 XPath 表達式和在應用程序中使用查詢結果提供了原生的 Java 解決方案。本系列文章包括兩部分,這是第 2 部分,介紹如何創建 XPath 請求、執行請求和處理得到的節點集,都在 Java 環境中輕松地完成。
本系列的 第 1 部分 介紹了 XPath 語言及其語法。對于不熟悉 XSLT 的 Java 程序員來說可能有一點兒壓力。XPath 語法可能看起來有點兒奇怪,和基于 XML 的語法相比更像是 UNIX 的目錄路徑 —— 又稍微增加了一點兒東西。但是您很快就看到了 XPath 使得選擇 XML 文檔的特定部分非常容易。
![]() |
|
在實用數據綁定 系列文章中討論 XPath,原因就在于這些選擇都使用邏輯名(請參閱 突出的邏輯性)。比方說,不必選擇根元素第二個子元素的第一個屬性,可以使用 XPath 表達式 /cds/cd[@title='August and Everything After']
。從一定意義上說,這就是 數據綁定,因為可以使用 XML 標記而不是結構來訪問數據。
本文主要討論使用 XPath 作為通過邏輯名從 XML 中訪問數據的方法,如 cd
、table
或 person
,而不用 firstElement
或 parent.getChildren(2)
。最終得到的代碼非常類似于數據綁定,使用邏輯名而非語義名,但是又沒有傳統數據綁定解決方案的初始類生成和類路徑問題。
第 1 部分 中提到,XPath 選擇總是返回一個節點 集。和其他任何集合一樣,其中可能有零個、一個或多個成員。這里重要的概念是節點。節點可以是一段文本(比如元素的內容)、一個元素、一條處理指令或者注釋。當然,節點集就是這類事物的任意組合。
如果您是一位 DOM 程序員,就不會被節點這個概念難倒。DOM 根據其 Node
接口看待一切事物,因此您也就習慣于通過 Node
接口來處理注釋、元素和文本數據。如果不習慣 DOM,應該花點兒時間來熟悉節點。節點對于使用 XPath 至關重要。執行 XPath
表達式時,對表達式結果進行操作的代碼必須對節點操作,而不深究 XML 語義。文檔內的導航是用 XPath 表達式進行的,而不是使用 DOM
樹轉移方法從一個子節點移動到另一個。
![]() ![]() |
![]()
|
Java 編程語言的最新版本 Java 5.0 中,對 Java API for XML Processing(JAXP)和 XPath 的支持已成為標準。您可能已經熟悉 JAXP 以及 SAX、DOM 和 XSL 編程中使用的 javax.xml.parsers
和 javax.xml.transform
包。(如果不熟悉的話,請參閱本文后面列出的一些 參考資料。)對 XPath 的支持主要來自于一個新的包 javax.xml.xpath
。
JAXP 1.3 包含在所有的 Java 5.0 下載包中。為了確保安裝了 JAXP 1.3,請在命令提示符下輸入以下命令:
|
應該看到類似于 清單 1 所示的結果。
清單 1. 命令行提示符下的 Java 5.0
|
如果版本是 1.5 或更高,則已經有了 JAXP 1.3,可以確信您有了本文中使用的 XPath API。
還需要一些供操作的 XML。本文中所有的例子都將使用 清單 2 中所示的簡單 XML 文檔。這個文檔并不復雜,但是足以說明 90% 的 XPath 編程中所需要的各種 XPath 函數。
清單 2. XPath 代碼中使用的 XML 示例文檔
|
將該文檔保存在本地機器上便于從 Java 代碼中訪問的地方(請參閱 下載)。如果希望使用自己的 XML 文檔也完全可以,只要調整示例代碼和文檔的結構與邏輯名匹配即可。
![]() ![]() |
![]()
|
DOM 程序員已經熟悉了節點的概念,這是理解 XPath 表達式和這些表達式的返回值不可或缺的。使用 XPath 時,DOM 程序員還有一個優勢,即在應用任何 XPath 表達式之前實際使用 DOM 獲得對 XML 文檔的訪問。這毫不奇怪:XPath 現在是 JAXP 的核心部分,而 JAXP 也提供了完整的 DOM 支持。
使用 XPath 的第一步是將目標 XML 文檔作為 DOM 樹讀入,如 清單 3 所示。
清單 3. 將 XML 加載到 DOM 樹中
|
清單 3 中的代碼沒有多少值得注意的地方。它僅僅從命令行接收 XML,然后使用 JAXP DOM API 將其加載到 DOM 樹中。如果曾經使用過 JAXP,或者在沒有 JAXP helper 類的情況下使用過 DOM,就會非常熟悉這種操作。(如果這些代碼看起來有些嚇人,那么可能需要查閱一下 參考資料 中列出的 DOM 文章,然后再回到本文。)
第 1 部分 中提到,在對任何 XPath 表達式求值之前,必須知道開始的上下文。比方說,選擇 ID 為 23
的 artist
節點,XPath 表達式取決于上下文是 XML 文檔的根節點,還是第三個 cd
元素的第二個 track
元素。
![]() |
|
顯然,需要能夠在 XML 文檔中移動來設置上下文,并相應地修改 XPath 表達式。從這里開始,真正的數據綁定 API 和 XPath 的界線漸漸分明了。在 XPath 中,雖然表達式是純邏輯性的(使用 cd
或 artist
之類的名稱),但是仍然需要使用 DOM 在 XML 中移動位置。這意味著仍然需要使用 Element
、Text
這樣的 XML 結構成分,仍然需要適當的樹遍歷。當然,如果讀入 XML 文檔,像 清單 3 那樣,那么最初的上下文就是文檔根節點,如果從根開始編寫表達式就不用太擔心樹的遍歷。
有些讀者可能已經在撓頭了。本文是討論如何將 XPath 用于數據綁定的,但是到現在說的一直是 DOM 和結構。XPath 是數據綁定很好的替身,但是這種 API 天生具有一定程度的結構。事實上,甚至位置路徑也在某種程度上使用結構://cds/cd[@title='This Desert Life']
假設 cds
元素是目標文檔的根元素,cd
元素是根的子元素。這和使用 getCDs().getCD("This Desert Life")
之類的代碼沒有多少差別。這兩種數據綁定方法沒有顯著的不同。
至于更明顯的差異,就是在 XPath 代碼中必須處理 DOM。但是,這點不同也能夠在很大程度上隱藏起來。再看一看 清單 3,加載文檔過程中所有和 DOM 有關的工作都通過 buildDocument()
方法抽象出來。返回的 DOM Document
對象是 DOM 專有的,但是沒有多少地方需要直接操作這個對象。因此,不需要傳統數據綁定方法所需要的一些類生成代碼,XPath 就提供了數據綁定的多數 好處:
- 從 DOM 和 SAX 這樣的 API 中抽象出來
- 使用邏輯命名法而不是結構命名法
- XML 文檔和 Java 對象之間的寬松映射
這就使其成為 XML 編程中一種非常輕量的數據綁定方法。
![]() ![]() |
![]()
|
您已經看到,稍微了解一點兒 DOM 知識可以大大方便對 XPath 的學習。如果在 DOM 的基礎上再熟悉 JAXP API,那么您就遙遙領先了。比方說,在 JAXP 中無論是用 SAX 還是 DOM ,基本步驟都是:
- 創建新的解析器工廠。
- 創建新的解析器或者文檔構造器(builder)。
- 解析/構造目標 XML。
同樣的步驟也適用于 XPath 編程:
- 創建新的 XPath 工廠。
- 創建新的 XPath 求值程序(evaluator)。
- 創建和計算 XPath 表達式。
如果掌握了這些 SAX 或 DOM 背景知識,可能只需看一眼 XPath API 就能開始編程了。不過先等一等。還需要知道 XPath 一些特殊的地方,雖然您會發現本節的內容熟悉而且非常簡單。
如果不熟悉 JAXP 或者使用時間不長,可能就不會理解在這種 API 中工廠模式的重要性和價值。JAXP 實際上不是一種 API
而更像是一種抽象,它允許不必編寫廠商專用的代碼,就可以使用特定廠商的 SAX、DOM 和 XPath 實現。為此,需要加載一個工廠實例,如 SAXParserFactory
或 DocumentBuilderFactory
,然后 JAXP 就會把這個類連接到這些結構的廠商實現。因此雖然在代碼中直接使用 SAXParserFactory
,JAXP 必須在幕后使用 Apache Xerces 來處理真正的文檔解析。
同樣的抽象在 XPath 中更具有高瞻遠矚的性質。和豐富的 XML 解析與轉換工具相比,目前還沒有很多 XPath
處理程序。但是,通過使用工廠模式,就會發現以后如果需要可以更方便地替換 XPath 實現。具體來說,XPath
工廠允許使用不同的對象模型。默認情況下,節點集是從 DOM Node
和 NodeSet
中的 XPath 表達式返回的(在稍后的 使用 XPath 表達式
一節中將會看到)。但是,有可能希望使用 JDOM 結構或者 dom4j 提供的對象模型。雖然這些 Java/XML API 還沒有用于
JAXP 的 XPath 引擎,但是可能很快就會出現。JAXP
工廠模型意味著很容易插入這些模型。因此不要為使用工廠模式所要求的額外步驟感到惱火,它們的存在為了提供便利,增加靈活性。
![]() |
|
您已經知道,使用 XPath 時最主要的包是 javax.xml.xpath
。毫不奇怪,我們需要的工廠被稱作 XPathFactory
,也在這個包中。JAXP 老兵可能已經猜到,要使用 newInstance()
創建新的工廠,如 清單 4 所示(添加到 清單 3 中所示的代碼中)。
清單 4. 創建新的 XPath 工廠
|
清單 4 中沒有什么特別之處。僅僅使用默認的對象(即 DOM,至少在 1.3 版中如此,而且近期不大可能改變)創建了一個新的 XPath 工廠實例。
因為 JAXP 已經開始接受其他 XML 對象模型,您可能希望不使用 JAXP 默認的 DOM 模型。這種情況下可以為 newInstance()
指定一個字符串統一資源標識符(Uniform Resource Identifier,URI),如 清單 5 所示。
清單 5. 指定字符串 URI
|
默認情況下,該 URI 被指定為 javax.xml.xpath.XPathConstants.DOM_OBJECT_MODEL
中的 http://java.sun.com/jaxp/xpath/dom
。因此 清單 5 中的代碼等價于 清單 6 中所示的代碼。
清單 6. 創建新的 XPath 工廠,比較麻煩的方法
|
無論采用何種方法創建,工廠都是使用 XPath 時的第一步。因此測試類中一定要包含工廠創建代碼,以便能夠使用 XPath
類。
![]() ![]() |
![]()
|
創建工廠之后,還需要從工廠轉移到能夠真正計算表達式并與 XPath 環境交互的對象。XPathFactory
不能 讓您計算表達式(至少不能直接計算),它僅僅是從代碼中獲得廠商的 XPath 引擎和對象模型,而不需要很多廠商專用代碼的一種方式。因此,建立這種聯系后,還需要獲得一個能夠 處理 XPath 表達式求值的對象。這并非其他對象,正是 XPath
對象登臺亮相了。
可以使用工廠的 newXPath()
方法創建新的 XPath
。清單 7 表明這個步驟是多么簡單。
清單 7. 創建 XPath 類的新實例
|
如果這些代碼看起來簡單得可笑,那就對了。所有其他的 XPath 處理工作都要從這個類開始,雖然看起來簡單,但是應該習慣于輸入這些代碼。
一旦得到了 XPath
的實例,就可以開始通過改變上下文、處理名稱空間和計算表達式來配置它。其中一些主題超出了本文的范圍,但是如果遇到 XPath 代碼不工作的情況,可能是因為使用了錯誤配置的 XPath
對象。如果是這種情況,或者懷疑是這樣,可以通過調用 xpath.reset()
重新將該對象恢復為初始配置。這樣通常能夠消除看到的問題,在調試過程中非常有用。
![]() ![]() |
![]()
|
現在您可能已經為使用 XPath 表達式作好了充分的準備。所幸的是,到現在為止您做的準備工作使這項任務變得很容易了。只需要用字符串創建一個新的表達式(要記住,這些都只是在 XML 文檔中定位的引用,常常被稱為位置路徑)。
清單 8 將一個 XPath 表達式賦給了一個字符串變量,這里沒有戲法,也沒有特殊的語法。僅僅使用一般的 Java String
,然后將 XPath 表達式賦給它去求值。
清單 8. 創建 XPath 表達式
|
因為 清單 8 沒有包含 XPath 專用的步驟,必須非常小心。其中也沒有任何錯誤檢查。有可能漏掉 title
屬性中的 @
符號(我第一次編寫這段代碼時就這樣做過!),不會顯示任何錯誤,只不過計算表達式時返回值為空。因此在計算和使用表達式之前一定要反復檢查。
得到表達式后必須對其求值。這正是出現 XPath
對象的原因。可以使用 evaluate()
方法計算表達式。這個方法有點兒奇特,因此讓我們看看 清單 9 中的例子,了解每個參數的意義。
清單 9. 計算 XPath 表達式
|
evaluate()
的第一個參數是表達式本身,第二個是表達式求值開始的上下文。清單 9 中,傳入了通過調用 buildDocument()
獲得的 DOM 文檔。如果需要不同的上下文,可以傳入文檔中的某個 Node
。但通常不這樣做,傳入 DOM 文檔元素,然后從這里開始編寫表達式是最簡單的辦法。
最后一個參數看起來有點兒奇怪,除非您非常熟悉 Java Naming and Directory Interface(JNDI)。該參數告訴 XPath 引擎期望表達式返回什么類型的值。XPathConstants
類中定義了幾種可能的值:
-
XPathConstants.BOOLEAN
用于返回布爾數據類型的表達式(映射到 JavaBoolean
數據類型) -
XPathConstants.NODE
用于返回節點數據類型的表達式(映射到 DOMorg.w3c.dom.Node
數據類型) -
XPathConstants.NODESET
用于返回節點集數據類型的表達式(映射到 DOMorg.w3c.dom.NodeList
數據類型) -
XPathConstants.NUMBER
用于返回數值數據類型的表達式(映射到 JavaDouble
數據類型) -
XPathConstants.STRING
用于返回字符串數據類型的表達式(映射到 JavaString
數據類型)
這些類型涵蓋了所有表達式。清單 9 中的表達式(//cds/cd[@title='August and Everything After']
)應該返回一個且只有一個節點,因此類型指定為 XPathConstants.NODE
。如果表達式返回多個節點,比如 //cds/cd
返回所有 cd
元素,應該使用 XPathConstants.NODESET
。
evaluate()
的返回值是一個 Java Object
,因此需要將其強制轉換成指定的類型。然后可以對 Node
、NodeSet
或者返回的其他類型進行操作。
![]() |
|
在討論不同類型的 XPath 表達式之前,有必要提一提 XPath
對象的另一種特性。如果準備反復使用同一個 XPath 表達式,無論是一個 XML 文檔還是具有相同結構的多個文檔,當然不希望重復編譯表達式的字節碼版本。
為了避免重復這一過程,XPath
提供了一個 compile()
方法,只有一個參數,即字符串 XPath 表達式。它編譯該表達式并將其作為 XPathExpression
類的實例返回。然后這個實例就代替了 XPath
,可以對 XPathExpression
實例而不是 XPath
調用 evaluate()
。XPathExpression
版本的 evaluate()
有兩個參數,即上下文(多數情況下就是 DOM 文檔對象)和返回類型,操作和 XPath
對象的版本一樣。請看 清單 10 中的簡單例子。
清單 10. 預編譯 XPath 表達式
|
經過這樣簡單的修改,您的工作有很好的回報。因為無論如何都要付出將表達式編譯成字節碼的代價,所以修改后實際增加的成本只是多了一個需要管理的對象,程序流稍微變得不那么直觀。(強調的是稍微,只要略有 Java 和 JAXP 經驗,這些代碼仍然很清晰。)除非確信表達式只使用一次,否則對表達式進行預編譯總是有益的。
處理 XPath 表達式結果的方法僅受限于您的編程知識。得到結果集后,可以做任何需要的處理。比方說,為了驗證 清單 9 和 清單 10 中的代碼確實檢索到了正確的 CD,可以增加 清單 11 中所示的代碼。
清單 11. 檢查結果
|
返回的結果本身沒有多少用處,但關鍵是可以使用 DOM 對 XPath 表達式求值返回的 Node
進行操作。也可將其轉化成其他 Java/XML 格式(如 SAX)并提供事件處理程序,或者將節點序列化到磁盤中。也可將數據提取出來供應用程序的其他部分處理、迭代其跟蹤路徑或者想到的其他方法。XPath 專用的處理已經完成,因此不需要再擔心了。
當然也可將返回的這個 Node
作為新 XPath 表達式的上下文,如 清單 12 所示。
清單 12. 多表達式求值
|
這就是使用上下文可能非常有意義的地方,可以從前一個表達式的結果開始新的 XPath 表達式,不 需要編寫大量的 DOM 代碼就能非常方便地在文檔中導航。
![]() ![]() |
![]()
|
如果理解了 XPath 并能使用不同類型的表達式,事情就更有趣了。第 1 部分 已經介紹了 XPath 必須提供的大多數功能。現在我們將在 Java 代碼中使用這些功能。
最常見的操作之一是處理表達式返回的節點集。再看一看 清單 2 中的示例 XML,假設需要查看 Counting Crows 的所有唱片。只要兩個 XPath 表達式就能很容易地實現,如 清單 13 所示。
清單 13. 處理節點集
|
清單 13
中使用幾種不同返回類型的 XPath
表達式。首先使用返回字符串(實際上是一個數字,不過從文本轉化成數字并沒有什么好處,因為后面的代碼還要將其作為字符串使用)的 XPath
表達式檢索 Counting Crows 的 ID。然后使用該表達式的結果創建一個新的表達式,選擇具有此 ID 的所有 cd
元素。
第二個表達式的結果是一個節點集,映射到 DOM org.w3c.dom.NodeList
類型。循環遍歷 org.w3c.dom.NodeList
非常簡單,很容易將列表中的每個 Node
強制轉換成 org.w3c.dom.Element
,然后獲取子元素(文本節點)并輸出該文本節點的值。還使用了另外一個 XPath 表達式,這僅僅是為了強調 XPath 的方便性,說明 XPath 能夠多么輕易地避開基本上任何 DOM 樹遍歷代碼。該表達式取得當前節點的 title
屬性(要記住,在這里上下文很重要)并返回其值,然后輸出這個值。通過使用 NodeList
中的當前 Node
作為上下文,可以很好地代替 DOM 獲取每個 CD 的標題。
細心的讀者可能注意到清單 13 中的一句代碼:
|
這個版本的
evaluate()
也需要上下文參數,但是不 需要返回類型,它似乎返回一個字符串。情況確實如此,這個版本的 evaluate()
在任何情況下都返回一個字符串。有時候,比如計算的表達式返回一個節點集或者一個節點,這可能造成很大的混亂。不過在其他時候,如果確實需要一個文本表達式,這是一種很好的縮寫形式。
XPath 的另一個特點是能夠計算布爾表達式。比如,可使用 清單 14 中的代碼來實現和 清單 13 類似的效果,這一次在迭代全部 CD 的過程中使用了 XPath 布爾表達式。
清單 14. 用 XPath 表達式返回布爾值
|
清單 13 和 清單 14 無所謂優劣,僅僅是獲得同樣信息的不同方法。不過,這兩個例子說明了 XPath 的靈活性。這些例子以及本文中的其他例子,說明了 XPath 如何處理各種數據類型,可以為您自己的編程工作帶來啟迪。
![]() ![]() |
![]()
|
和以前相比 Java 開發人員擁有了更多的 API、技術和工具箱。但是豐富的編程能力也帶來一種危險 —— 某種 API 偏執癥。很容易認定只有那些明確貼上數據綁定標簽的 API 才能用于以邏輯而非語義的方式獲取 XML 數據。貼上 XPath 標簽的 API 只能用于傳統上使用 XPath 的應用程序中,這就是偏執癥的觀念。同樣的問題也適用于其他 API,無論是解析 XML、讀取屬性文件還是在內存中創建樹狀結構的 API。
但是,當稍微創造性地選擇 API 和編程方式時,Java 語言的強大之處常常最明顯。不要被那些隨意的標簽(如數據綁定)所蒙蔽,要看看 API 到底提供了什么。如果發現一種 API 似乎提供了有用的功能,就將其添加到代碼中,無論它是用來干什么的。和遵守所有規則但是笨拙、緩慢、功能有限的應用程序相比,以這種方式使用(或濫用) API 的能夠工作的應用程序更應該受到贊賞。
通過本系列的兩篇文章,您看到了如何將 XPath API 作為一種相對容易的數據綁定 API 來使用,雖然一般認為 XPath 僅在 XSLT 和 XPointer 世界中出現。更好的是,Java 語言在 JAXP 中提供了一種 XPath API。Java 和 XML 程序員有誰能夠抗拒這種誘惑呢?放棄標簽的框框吧,不僅僅 JAXB 能用于數據綁定,XPath 是一個很好的起點。
![]() ![]() |
![]()
|
描述 | 名字 | 大小 | 下載方法 |
---|---|---|---|
Sample code for this article | x-pracdb9_code.zip | 52KB | HTTP |
![]() | ||||
![]() | 關于下載方法的信息 | ![]() | ![]() | Get Adobe? Reader? |
![]() ![]() |
![]()
|
學習
- 您可以參閱本文在 developerWorks 全球站點上的 英文原文。
- “使用 XPath 作為數據綁定工具,第 1 部分”(developerWorks,2005 年 11 月):閱讀本系列的第一期文章,了解如何使用 XPath 選擇 XML 內容。
- XML Path Language (XPath) Version 1.0 和 XML Path Language (XPath) 2.0:XPath 1.0 規范是一種 W3C 推薦標準。XPath 2.0 于 2005 年 11 月成為 W3C 候選推薦標準。
- “XPath 入門”(developerWorks,2004 年 5 月):XPath 新手請參閱 Bertrand Portier 的教程。
- The Extensible Stylesheet Language Family (XSL) 和 XSL Transformations (XSLT) Version 1.0:XPath 是 XSL 的重要組成部分。進一步了解 W3C 的 XSL 規范家族,包括 XSLT 轉換語言。
- XQuery 1.0 and XPath 2.0 Data Model (XDM):伴隨著 XPath 2.0,XQuery 希望定義能同時用于兩種規范的數據模型。
- “Toward an XPath API”:Leigh Dodds 的這篇文章可以幫助您了解最初導致 1.0 XPath API 誕生的原因。
- “SAX,功能強大的 API”(developerWorks,2001 年 8 月):本文詳細介紹了 SAX,這是已成為事實標準的基于事件的 XML 處理 API。
- “理解 DOM”(developerWorks,2003 年 7 月):Nicholas Chase 的這篇教程介紹了 DOM 文檔的結構,說明了如何使用 Java 技術從 XML 文件創建 DOM 文檔、修改文檔和檢索輸出。
- “在 Java 中使用 DOM 和 XPath 進行有效的 XML 處理”(developerworks,2002 年 5 月):Tony Darugar 分析了如何在 Java 編程中高效地使用 DOM。
- Java and XML(O'Reilly Media, Inc.):Brett McLaughlin 的這本書即將出版第三版,其中一章專門討論 XPath。
- XML in a Nutshell(O'Reilly Media, Inc.):Elliotte Rusty Harold 和 W. Scott Means 寫的這本書是非常全面的 XML 參考資料,有一章專門討論 XPath。
- Java API for XML Processing (JAXP):了解 JAXP 如何提供了原生 Java 解決方案來創建 XPath 請求,并在應用程序中使用查詢結果。
- “JAXP 全面介紹,第 1 部分” 和 “JAXP 全面介紹,第 2 部分”(developerWorks,2005 年 5 月):Brett McLaughlin 的這兩篇文章介紹了 JAXP,說明如何利用這種 API 的解析和驗證特性及其對 XSL 轉換的支持。
- “JAXP 驗證”(developerWorks,2005 年 10 月):本文詳細介紹了這種新的 JAXP API,從基礎到更高級的特性。
- Java Naming and Directory Interface (JNDI):這一行業標準為基于 Java 技術的應用程序提供了多種命名和目錄服務的統一接口。
- developerWorks XML 專區:可以找到更多 XML 資源,包括文章、教程、技巧和標準。
- developerWorks Java 技術專區:大量的文章、教程和技巧幫助您充分了解 Java 語言技術和相關應用。
- IBM Certified Solution Developer -- XML and related technologies:了解如何通過認證。
獲得產品和技術
-
使用 IBM 試用軟件 開發您的下一個項目,可直接從 developerWorks 下載。
討論
![]() ![]() |
![]()
|
![]() | ||
![]() | Brett McLaughlin 從 Logo 時代就開始使用計算機。(還記得那個小三角嗎?)近年來他已經成為 Java 技術和 XML 社區最知名的作家和程序員之一。他曾經在 Nextel Communications 實現過復雜的企業系統,在 Lutris Technologies 編寫應用服務器,最近在 O'Reilly Media, Inc. 繼續撰寫和編輯這方面的圖書。在他的新書 Head Rush Ajax 中,Brett 和暢銷書作家 Eric 與 Beth Freeman 為 Ajax 帶來了獲獎的創新方法 Head First。他最近出版的 Java 1.5 Tiger: A Developer's Notebook 是關于 Java 技術最新版本的第一本著作,他的經典之作 Java and XML 仍然是在 Java 語言中使用 XML 技術的最權威的著作之一。 |
![]() ![]() |
![]()
|
![]() |
posted on 2006-03-18 20:44 Vincent.Chen 閱讀(415) 評論(0) 編輯 收藏 所屬分類: AJAX