級別: 初級
Doug Tidwell, 計算機傳道士, eveloperWorks
2001 年 6 月 01 日
讓
我們看看 developerWorks 是如何使用基于 Java 的開放源碼工具來生成定制的 XSLT 應用程序,這些工具對生成
developerWorks 基于 HTML 的教程所需的單調冗長的工作進行了自動化處理。它也稱為
Toot-O-Matic,目前適用于任何開發者,可以作為一個 XSLT 樣本來進行觀察也可以對它進行適當修改以滿足您的培訓需求。Doug
Tidwell 解釋了其設計目標和 XML 文檔設計。他還描述了 13 個代碼樣本來演示如何從一個 XML
源文檔生成大量的包含定制圖形、ZIP 文件以及兩個 PDF 文件的 HTML 面板時使用的技術。
在 developerWorks,我們非常高興地公開 Toot-O-Matic 的源代碼,
這是一個基于 XML 的工具,用來制作我們的教程。在本文中,
將討論當構建工具時我們所做的設計決定,介紹如何使用它來
編寫您自己的教程,還介紹了一些源代碼的組織結構。希望這個工具
能對您有所幫助,并為您在如何使用 XML 和 XSLT 樣式表通過各種有用方法
來操縱結構化數據方面提供一些建議。
Toot-O-Matic
設計目標
Toot-O-Matic 項目是從以下幾個設計目標開始的:
- 更方便地制作 developerWorks 教程
- “自食其力”(表示我們實際使用的都是我們倡導的技術)
- 了解通過 XSLT 樣式表能實現的程度
首先,我將詳細說明這些目標,然后將論述教程的實際設計。
更方便地制作教程
好幾年前,在 developerWorks
構建我們的第一個教程時,創建的工作量是難以置信的
單調冗長。作者和編輯需要在類似 Microsoft Word
的工具中編寫和編輯內容, 然后再開始發布過程。通常第一步是創建教程的
PDF 版本。高質量的可打印版 教程是很受歡迎的,并且很容易從 Microsoft
Word 的格式化文檔中創建 (比從大量的 HTML
文件中創建要容易得多)。
一旦完成了字處理文檔,就將教程轉換成 HTML。我們將那個單一的 HTML
文件分割成小段, 然后將標準的 IBM
頁眉和頁腳添加到每個小段中。這就產生了多個 HTML 文件 (通常是 50 到
100 個),而我們需要將這些文件鏈接在一起。鏈接到一起后,
如果您正在查看某一章節的第三個面板,那么單擊
Next
會進入第四個面板, 而單擊
Previous
會進入第二個面板。然后還需要創建一個菜單面板;
從這個菜單面板中,可以直接鏈接到任何特定章節的第一個面板。最后,
每個面板還有必須測試的鼠標經過的效果。
在作者和編輯忙于編寫實際內容的同時,我們的圖形設計人員在創建章節標題
和教程自身面板的圖形。為了確保標題文本的一致性外觀,設計人員創建了包含那些文本的圖形,
并將它們繪制在適當的背景上。對于某些標題,設計人員還同時制作了
鼠標經過時的普通版本和突出顯示版本。
正如您可能預想到的一樣,構建教程的大量過程是手工編碼并且很容易出錯
(特別是當您在清晨 5:30
興奮地完成編碼以便趕在日出前放上網站時)。我們
希望能夠盡量多地自動完成這些步驟,這樣既可以節省時間又可以將錯誤
的幾率降到最低。
自食其力
另一個設計目標是真正使用我們所倡導的技術。當然我們確實也意識到具有諷刺意義的一點是:
我們極力倡導開放的、基于標準的計算技術,但又不得不使用封閉源碼的專有工具
(例如 Microsoft Word)來創建內容。(注:直到出版時,我們還未聽到
有關 Microsoft Office Linux 版本的任何聲明。)從 XML 文檔和 XSLT
樣式表 構建工具的另一個引人之處是可以使我們向世界展示 XML 和 XSLT
在今天可以做到的
有用工作。選擇這些技術來操縱結構化數據對我們來說是毫不費力之事。
了解通過 XSLT
樣式表能實現的程度
在實現最后一個目標時(即了解通過 XSLT 樣式表究竟能實現多少功能),
Toot-O-Matic 運用了 XSLT 的所有高級功能,包括多個輸入文件、
多個輸出文件和擴展功能。通過樣式表,它將單個 XML 文檔轉換成:
- Web 化的相互鏈接的 HTML 文檔
- 整個教程的菜單
- 教程每個章節的目錄
- 包含所有章節標題和教程標題的 JPEG 圖形
- letter 大小的 PDF 文件
- A4 大小的 PDF 文件
- 包含用戶在其機器上運行教程所需的所有文件的 ZIP 文件
教程布局
XML 文檔結構在過去的 18 個月中不斷完善,在我們真正走近它之前,
先來看一下教程的布局。由于我們不需要從舊的使用 XML 標記的
教程著手,因此能夠專注于想要的最終結果,
然后設計自己 的 XML
文檔結構,這樣就便于將符合 XML 的文檔轉換為我們所需的輸出格式。
菜單面板
用戶首先看到的部分就是菜單面板。菜單面板看上去如下:
圖 1.
教程菜單面板
在本例中,字符串 "Building tutorials with the Toot-O-Matic"
以及所有章節標題 ("1. Installing and configuring Toot-O-Matic"
等等)都是由工具創建的 JPEG 圖形。如果將
鼠標移動到給定章節上,那么其背景色會更改:
圖 2.
鼠標經過菜單項時的效果
在圖 2
中,注意出現了一個作為工具提示的菜單項文本。這對于視力不佳的用戶很有用,
并且與 W3C 定義并由 IBM 擴充的 Web Accessibility Guidelines
一致。
還請注意到面板頂部和底部的導航控件。主頁眉和頁腳是根據 IBM
的公司網站標準定義的; 當您使用 Toot-O-Matic
創建自己的教程時可能要更改這個區域。導航欄中包含了 諸如 "Main
menu"、"Section menu"、"Feedback"、"Previous" 和 "Next"
這些項。盡管
在這個面板中禁用了某些項,但它們是出現在教程的所有面板中。
在導航控件上方是四個圖標,允許用戶下載教程的替代版本或將教程作為電子郵件發送給朋友:
圖 3. 教程圖標
從左到右,這些圖標依次允許用戶:下載包含本地運行教程所需的所有文件的
ZIP 文件, 下載 letter 大小的 PDF 文件,下載 A4 大小的 PDF
文件,以及向朋友發送推薦這個教程
的電子郵件。所有這些圖標在教程的每個面板上都會出現,它們的位置和相關鏈接
是由 Toot-O-Matic 生成的。
單個面板
單個面板看上去如下:
圖 4.
教程信息面板
教程中的大多數面板都使用這種設計。注意,在面板的頂部包含文本
page 1 of 6。導航欄 中還包含到主菜單和章節菜單的活動鏈接。
章節菜單
單擊 "Section menu" 鏈接會顯示當前章節中所有標題的列表:
圖 5.
教程章節索引面板
可以單擊任何面板標題直接轉到該面板。通過樣式表的神奇功能,
會自動出現每個面板的標題以及到每個面板的超鏈接。
Feedback 面板
Toot-O-Matic 會自動生成 feedback
面板。面板包含一段簡要的文字,然后是一個反饋意見表。當用戶 單擊
"Submit feedback"
按鈕時,用戶的意見和建議會自動進入我們的反饋意見數據庫。以下是 一個
feedback 面板示例:
圖 6. Feedback
面板
一旦將某個給定面板標識為 feedback
面板后,就會在教程的每個面板的導航欄中顯示到該面板的鏈接。
E-mail 面板
相對較新的一個添加功能是 "e-mail a friend"
面板。這允許用戶與朋友們一起分享喜愛的教程。單擊 "e-mail it!" 圖標
顯示的面板類似下圖:
圖 7. E-mail
面板
ZIP 文件
教程的 ZIP 文件版本包含了查看教程所需的所有 HTML 文件,
以及所有支持圖形和其它文件。當 Toot-O-Matic 構建這個文件時,
它會包含所有生成的 HTML 和 JPEG 文件,以及在教程 XML 源文件
中引用的任何資源。
PDF 文件
教程的 PDF
版本支持高質量的打印輸出,以供想要脫機閱讀教程的用戶使用。教程首
頁包含了教程的標題和目錄:
圖 8. PDF
文件的首頁
在目錄中,章節標題和頁號都是超鏈接;如果是在聯機查看 PDF 文件,
則可以使用這些鏈接直接轉到特定章節。如果是在閱讀打印出來的 PDF
文件, 那么目錄也仍然很有用。除目錄中的鏈接之外,教程中的交叉引用和
對 Web 頁面的任何引用也都是超鏈接。
教程主體中的頁面中包含了每個面板的文本及其說明,它們之間用一條水平線分隔。
圖 9.
教程主體中的某一頁
PDF 文件中的所有格式和布局問題都是由 Toot-O-Matic 處理的。
XML
文檔設計
好了,我已經全面介紹了 developerWorks 教程出現的所有不同形式,
下面討論將會成為我們的教程的 XML 文檔結構。首先,要介紹一下我們使用
的一些顯而易見的結構化原則:
- 一個
<tutorial>
應該包含一個
<title>
和一個或多個
<section>
。
- 一個
<section>
應該包含一個
<title>
和一個或多個
<panel>
。
- 一個
<panel>
應該包含一個
<title>
和一個
<body>
,
然后可能一個
<body>
再包含面板中一列或兩列內容的標記。
這些決定是顯而易見的,因為我們的教程一直是用這種方式構成的。
單獨的面板
第一個主要的設計決定就是確定應該如何標記一個單獨的
<panel>。我們決定了以下結構:
清單 1.
教程文檔結構
<panel> <title>Title of the panel</title> <body> <image-column> -or- <example-column> (one or the other or neither) <text-column> Basic HTML markup (<p>, <ol>, <li>, <b>, <i>, <u>, <a>, etc.) </text-column> </body> </panel>
|
這種結構允許教程作者使用他們熟悉的大多數標記,
同時又可將教程內容轉換成各種格式。
<image-column>
和
<example-column>
元素
定義了左邊列的內容(如果存在的話)。Toot-O-Matic 文檔
(Toot-O-Matic 軟件包附帶的教程)描述了該工具支持的所有元素和屬性;
其中大多數都與你們知道并喜歡使用的 HTML 元素類似。
文件名
目標是要將單個 XML 文件轉換為 Web 化的相互鏈接的 HTML
文檔。要實現這一點,
需要一些標準方法來命名所有作為輸出創建的文件。將文件名屬性添加到
<tutorial>
元素
中就定義了文件名的基本部分。如果文件名屬性是 "xyz",那么第 1
章節中的 HTML 文件就被 命名為
xyz-1-1.html、xyz-1-2.html
等,而第 2
章節中的文件則被命名 為
xyz-2-1.html、xyz-2-2.html
,依此類推。對于鏈接,
如果現在位于第 2 個
<section>
的第 4 個
<panel>
, 那么要知道
Previous
鏈接應該指向文件
xyz-2-3.html
。如果當前面板
不是最后一個,那么
Next 鏈接應該指向文件
xyz-2-5.html
。第 2 章的 章節索引名為
index2.html
,因此 "Section"
菜單應該指向那個文件。當創建 主菜單面板時,如果在教程中有 7 個
<section>
, 則需要創建到
xyz-1-1.html、xyz-2-1.html
直到
xyz-7-1.html
的鏈接。
對于由 ZIP 和 PDF 圖標引用的文件名,我們再次使用
filename
屬性。繼續前一個 示例,ZIP 文件將命名為
xyz.zip
,兩個 PDF 文件將命名 為
xyz-ltr.pdf
和
xyz-a4.pdf
。知道
filename
屬性 的值允許我們在教程的每個 HTML
文件的主頁眉中構建這些鏈接。使用一種一致的命名約定
使得在面板之間構建鏈接成為可能。
Feedback 面板
feedback 面板是由第一個包含 <feedback-form> 元素的
<panel> 確定的。該元素類似于:
清單 2. 生成 feedback
面板的 XML 元素
<feedback-form action-url="http://www9.software.ibm.com/dworks/ratings.nsf/ RateOnlineCourse?CreateDocument" zone="Web" redirect-url="http://www.ibm.com/developerworks/thankyou/feedback-java.html" />
|
如果要將 Toot-O-Matic 用于您自己的需求,可以將
action-url
和
redirect-url
屬性
更改為匹配您站點的值。
E-mail 面板
最近推出的 e-mail 面板需要兩個新字段,它們作為屬性 添加在
<tutorial>
元素中。以下是 XML 源示例:
清單 3. 用于創建 e-mail
面板的屬性
<tutorial filename="tootomatic" . . . email-link="http://xyz.ibm.com/dW-tutorials/education/tootomatic" abstract="developerWorks is proud to present the Toot-O-Matic, an XML-based tool that uses XSLT style sheets and Java code to convert an XML source file into a variety of text and binary outputs. This tutorial is the documentation for the tool, covering installation, a tag guide, troubleshooting, and writing tips.">
|
在這個清單中,
email-link
和
abstract
屬性是由 e-mail 面板 使用的。要構建 e-mail 面板,我們使用標準的
JavaScript 文件
emailfriend.js
來
管理面板。以下是我們生成的使得 e-mail 面板起作用的 HTML 示例:
清單 4. 生成的用于調用
e-mail 面板的 HTML 標記
<a href="javascript:void newWindow()" border="0"> <img alt="E-mail this tutorial to a friend" border="0" src="../i/icon-email.gif"> </a>
|
(我整理了這個清單,這樣您可以看得更清楚。由 Toot-O-Matic 生成的
實際的 HTML 文件中包含的空白字符更少。)
目錄結構的簡要概括是:Toot-O-Matic
在給定的子目錄中生成它的所有文件, 這個目錄可以在命令行或
<tutorial>
元素中指定。所有
公共資源(
emailfriend.js
、標準的鼠標經過圖形等)都
存儲在
../i
目錄中。如果在單個機器上存儲了多個
Toot-O-Matic 生成 的教程,那么公共文件將僅存儲一次。
XSLT
源代碼
好了,我已經論述了在定義 XML 文檔結構時所解決的設計問題,現在我們將
討論如何使用 XSLT 樣式表將 XML 文檔轉換成需要的結果。首先,使用
XSLT mode 屬性 以多種方式處理相同結構的信息:
清單 5. 使用 XSLT mode 屬性
<xsl:template match="/"> <xsl:apply-templates select="tutorial" mode="build-main-index"/> <xsl:apply-templates select="tutorial" mode="build-section-indexes"/> <xsl:apply-templates select="tutorial" mode="build-individual-panels"/> <xsl:apply-templates select="tutorial" mode="generate-graphics"/> <xsl:apply-templates select="tutorial" mode="generate-pdf-file"> <xsl:with-param name="page-size" select="'letter'"/> </xsl:apply-templates> <xsl:apply-templates select="tutorial" mode="generate-pdf-file"> <xsl:with-param name="page-size" select="'a4'"/> </xsl:apply-templates> <xsl:apply-templates select="tutorial" mode="build-zip-file"/> </xsl:template>
|
這個示例顯示了如何使用多種不同方式來處理相同的基本數據。我們使用方式
build-main-index
來 構建教程的主索引頁面,使用
build-individual-panels
方式來構建單獨的面板,等等。
注意:
generate-pdf-file 方式
使用
page-size
參數來正確設置 頁面大小(同時生成 letter 和
A4 兩種大小的 PDF 文件)。
生成主菜單面板
主菜單由標準的頁眉和頁腳組成,
在頁眉和頁腳之間是教程的所有章節列表。單擊任何章節標題
可以轉至該章節的第一個面板。要增強面板的視覺外觀,
可以使用生成的圖形和鼠標經過效果來顯示面板標題。
生成章節列表的樣式表是簡單明了的。頁眉和頁腳是從樣板文本中生成的;章節列表是使用
<xsl:for-each>
元素生成的:
清單 6.
生成菜單面板鏈接的 XPath 語句
<xsl:for-each select="section"> <a> <xsl:attribute name="href"> <xsl:value-of select="concat($fn, '-', position(), '-1.html')"/> </xsl:attribute> ... <img width="335" height="26" border="0"> ... <xsl:attribute name="src"> <xsl:value-of select="concat('imagemaster/menu-', position(), '.jpg')"/> </xsl:attribute> </img> </a> <br/> </xsl:for-each>
|
(為使示例更加簡潔,我除去了某些 XPath 表達式,那些表達式生成各種錨點屬性和圖像標記。)例如,對于第一章
(position()=1)
, 樣式表生成以下 HTML:
清單 7.
菜單面板鏈接樣本
<a href="xyz-1-1.html" onMouseOut="iOut('menu1');" onMouseOver="iOver('menu1'); self.status=menu1blurb; return true;"> <img border="0" height="26" name="menu1" src="imagemaster/menu1.jpg" width="335"/> </a> <br/>
|
在以上清單中,所有黑體的 1 都是由 XPath
position()
函數生成的。
生成單獨的 HTML 面板
下一個任務是生成組成教程的單獨的 HTML
面板。教程的頁眉和頁腳是由樣板生成的,
并且面板主體中的大多數標記實際上等同于它們的 HTML
對應標記。生成單獨面板 的最有趣的事是:我們使用 XSLT
擴展來將轉換的輸出重定向到不同文件。
使用與 Apache XML 項目 的 Xalan 樣式表引擎一起交付的文本重定向擴展來實現這個功能。在使用擴展之前,要先在樣式表的根元素
<xsl:stylesheet>
元素中聲明:
清單 8.
樣式表擴展定義
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect" extension-element-prefixes="redirect">
|
在本例中,
org.apache.xalan.xslt.extensions.Redirect
是 實現了該擴展的 Java 類名,
redirect
是用來調用擴展的名稱空間
前綴。聲明了這個擴展之后,就可以使用它將轉換輸出管道輸出到不同文件。
Redirect
擴展 的一個重要特性就是使用 XPath
表達式來生成文件名:
清單 9.
樣式表擴展調用
<redirect:write select="concat($fn, '-', $sectionNumber, '-', position(), '.html')"> <!-- other processing goes here --> </redirect:write>
|
假設前綴是
xyz
,以上的 XPath
concat
函數調用 將為
<tutorial>
的第 5 個
<section>
的 第 4 個
<panel>
創建名稱
xyz-5-4.html
。
(為簡化處理過程,
<tutorial>
標記的文件名屬性
存儲在變量
fn
中,當前
<section>
的
position()
存儲 在變量
sectionNumber
中。)鏈接點和引用的生成是貫穿在 XML 源文檔
的整個處理過程之中的。這就確保了在源文檔更改時保持引用的正確性和一致性。
生成章節索引
要生成章節索引,需要創建一個 HTML 文件,其中包含給定
<section>
的 所有
<panel>
的排序列表。使用一個簡單的
<xsl:for-each>
語句
檢索出所有面板標題;由于所有文件名都是動態生成的,也可以創建到所有面板
的超鏈接。以下是用于該任務的 XSLT 模板的簡要摘錄:
清單 10.
生成章節索引
<ol> <xsl:for-each select="panel"> <li> <a> <xsl:attribute name="href"> <xsl:value-of select="concat($fn, '-', $sectionNumber, '-', position(), '.html')"/> </xsl:attribute> <xsl:value-of select="title"/> </a> </li> </xsl:for-each> </ol>
|
在上例中,用于生成文件名的
concat
函數調用是用來
生成
<a>
標記上的
href
屬性值。 在
<a>
標記本身中,我們使用
<xsl:value-of>
元素 檢索當前面板的
<title>
。
生成 PDF 文件
將 XML 文檔轉換為 XSL Formatting Objects (XSL-FO)
流也是相當簡單明了的。打印出來的
布局由教程中的圖形和文本組成,再加上頁號、頁眉、頁腳一起創建高質量的打印輸出。
盡管在創作本文時(2001 年 5 月)XSL-FO 規范還未完成,
但我們可以使用 Apache XML Project 的 FOP (Formatting Objects to
PDF) 工具
當前支持的格式化對象。以下是幾個段落被轉換為格式化對象后的示例:
清單 11.
格式化對象樣本
<fo:block font-size="8pt" line-height="10pt" text-align-last="end" space-after.optimum="8pt"> page 1 of 14 </fo:block> <fo:block font-size="16pt" line-height="19pt" font-weight="bold" space-after.optimum="12pt"> Introduction to JavaServer Pages </fo:block> <fo:block space-after.optimum="6pt"> In today's environment, most Web sites want to display dynamic content based on the user and the session. Most content, such as images, text, and banner ads, is most easily built with HTML editors. So we need to mix the "static" content of HTML files with "directives" for accessing or generating dynamic content.
</fo:block> <fo:block space-after.optimum="6pt"> JavaServer Pages meet this need. They provide server-side scripting support for generating Web pages with combined static and dynamic content. </fo:block>
|
生成 JPEG 文件
對于任何教程來說,都需要生成一些圖形來突出顯示教程的某些部分。首先,
為標題頁的主頁眉創建一個圖像。主頁眉的文本來自
/tutorial/title
元素。例如,標記
<tutorial> <title>Building tutorials with the Toot-O-Matic</title>
|
生成的
masthead.jpg
文件類似于:
圖 10.
生成的頁眉圖形
為了創建這個文本,我們使用一個 Java 擴展將
<title>
元素的 文本轉換成一個 JPEG 文件:
清單 12. 調用 JPEG
創建擴展
<xsl:for-each select="/book/chapter"> <xsl:choose> <xsl:when test="function-available('jpeg:createJPEG')"> <xsl:value-of select="jpeg:createJPEG(title, 'bg.jpg', concat('title', position(), '.jpg'), 'Swiss 721 Bold Condensed', 'BOLD', 22, 52, 35)"/> <img> <xsl:attribute name="src"> <xsl:value-of select="concat('title', position(), '.jpg')"/> </xsl:attribute> </img> <br /> </xsl:when> <xsl:otherwise> <h1><xsl:value-of select="title"/></h1> </xsl:otherwise> </xsl:choose> </xsl:for-each>
|
生成 ZIP 文件
最后的任務是要生成 ZIP 文件本身,這也是通過一個擴展來處理的。這
是在文件命名約定可以簡化事情的另一個領域。將 XML
源文件的根元素傳遞給擴展函數:
清單 13. 生成 ZIP
文件
<xsl:template match="tutorial" mode="build-zip-file"> <xsl:choose> <xsl:when test="function-available('zip:buildZip')"> <xsl:value-of select="zip:buildZip(.)"/> </xsl:when> <xsl:otherwise> <xsl:message terminate="yes"> Sorry, we can't build the zip file. </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template>
|
注意:在調用
buildZip
函數時,僅需要傳遞根元素。
buildZip
函數
采用我們提供的節點(文檔節點), 嘗試創建一個 ZIP
文件并用所有必需文件進行填充。這些文件中的某些文件 是由每個
Toot-O-Matic 教程使用的標準資源列表中的一部分,
而其它文件則是由教程引用的資源(JPEG、GIF 和其它類似文件)。添加的
HTML 文件 是由 XML 源文件的結構確定的。如果教程有 4 個或更多章節,
第 4 個章節包含 8 個面板,并且文件名前綴是
tom
, 那么
buildZip
函數需要將文件
tom-4-1.html、tom-4-2.html
等 添加到 ZIP 檔案中。
結束語
Toot-O-Matic 工具的這一討論介紹了可從單個 XML 文件生成
的全范圍輸出。原始的 XML 文檔結構允許我們將普通的文本信息
轉換為各種不同格式,而將所有這些組合在一起就可以用各種有趣和有用的方式
來提供教程內容。使用這個工具,可以縮短并簡化開發過程,使得制作教程的
過程更方便、更快速和更經濟。最重要的是,我們在此討論的一切都是基于
開放標準并且在任何支持 Java 的平臺上使用。Toot-O-Matic 工具
展示了一個簡單而又并不昂貴的開發項目是如何交付有意義的結果的。
參考資料
感謝
developerWorks 教程小組的成員包括 Tom Coppedge、Jeanette
Fuccella、Leah Ketring、Jeanne Murray、Christine Stackel、Doug
Tidwell、Jackie Wheeler 和 Janet Willis。Toot-O-Matic 是從
他們的創意中形成的,并且還汲取了 Lou Shannon、Gretchen Moore
以及其他 Toot-O-Matic 用戶 的出色建議。
關于作者
|
|
|
MC Dug-T 是 developerWorks 的
科學部長,致力于向公眾推廣 XML、Java 和 Web 服務
411。在他的旅途中,
他從自己曾體驗過的視角獲得了極酷的、全新的樣式表的靈感。所有這些讓人著迷的知識很快
會在他撰寫的 XSLT 一書中(ISBN 0596000537,現在就可以在 amazon.com
上預訂) 由 O'Reilly and Associates
出版,這本書很快會在本地書店大賣。 在最近的 dW
面談中論及這本書時,他夸口“我幾乎將我的所有思想都凝聚在這一大本書里了”。
在放松時,他喜歡將雙手向上舉起,
照他的話說是“擺擺手,我一點也不在乎”。在閑暇之余,
他會和任烹飪老師的妻子 CT-ONE,以及他們 6 歲的寶貝女兒 Lily 呆 在
Raleigh 一起享受天倫之樂。可以通過
dtidwell@us.ibm.com
與他聯系。
|