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

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

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

    Vincent.Chan‘s Blog

    常用鏈接

    統計

    積分與排名

    網站

    最新評論

    樣式表也能編寫樣式表:由 XSLT 組件制作 XSLT 樣式表

    級別: 初級

    Alan Knox, 軟件工程師, IBM

    2001 年 6 月 01 日

    XSLT 樣式表可用來動態(tài)地將 XML 變換成復雜的瀏覽器顯示標記 -- 但如果顯示復雜,樣式表也復雜。因此需要一種能夠從簡單組件構建復雜樣式表的工具。既然 XSLT 本身就是 XML,因此可以用 XSLT 操縱 XSLT;樣式表也能編寫樣式表。本文演示如何從 XSLT 組件構建一個執(zhí)行某一特定運行時變換的 XSLT 樣式表。

    另一篇 developerWorks 文章 讓你的XML適合所有尺寸的屏幕 討論了編寫與管理那些在很多顯示設備上顯示同一 XML 籃球統計信息的樣式表的問題。該解決方案涉及到編寫一個參數化的樣式表,該樣式表生成具有不同等級的數據內容的 HTML,然后使用 WebSphere Transcoding Publisher 將該樣式表產生的輸出轉換成適合于某個特定設備的代碼。雖然這對于很多情況來說是一種有效和簡單的解決方案,但卻喪失了對出現在用戶屏幕上的內容的某些控制。

    如果要:

    • 完全控制用戶所見的內容
    • 調整應用程序的顯示,以便在每一種設備上實現最佳的可能的效果
    • 利用設備的特定特性

    那么,您必須解決生成無數復雜的樣式表的問題。本文演示了一個使用相同籃球 XML 數據的非折衷解決方案。

    什么是樣式表?

    樣式表描述文檔如何在屏幕上或打印中顯示。通過將樣式表附加到 Web 上的結構化文檔,您可以改變顯示,而無需犧牲設備獨立性或添加新的 HTML 標記。

    什么是 XSL?
    XSL 是可擴展樣式表語言,一種用于表達樣式表的語言。(CSS 是另一種功效較弱的樣式表語言。)

    什么是 XSLT?
    XSLT 代表 XSL 變換,或用于變換 XML 文檔的語言。

    什么是 XML?
    XML 代表用于基于 Web 的文檔的可擴展標記語言??蓪⑺闯?SGML 的縮減版。

    樣式表的難點

    樣式表主要有兩類問題:

    • 復雜性 - 新的應用程序顯示往往需要新的樣式表。隨著標記語言和新設備的激增,所需的樣式表的數量也變得令人生畏。如果使用 XML/XSLT 以外的方法(例如 JavaServer Pages (JSP) 或 JavaBean 體系結構),仍然存在同樣程度的復雜性。然而,生成 JSP 的可使用的工具支持目前比支持 XSLT 樣式表的工具支持要發(fā)達得多。
    • 技能 - 除了理解 XML 數據之外,樣式表作者還必須深入理解多種顯示設備的標記語言。另外,在瀏覽器中生成在外觀吸引人的顯示也需要設計技能。而這種技能組合并非輕易可以獲得。




    回頁首


    解決方案

    上述問題可以通過采用基于組件的方法開發(fā)樣式表來解決。XSLT 是一種聲明性語言,其中,構成樣式表的模板彼此獨立。XSLT 樣式表可以使用 importinclude 機制由其它樣式表構成。只要適當留意,您可以分別開發(fā)一些獨立的 組件樣式表,這些組件樣式表可以一起構成將在運行期間應用于 XML 數據的 顯示樣式表。這些組件將大致分為三種類型,用于處理:

    • 顯示動態(tài) XML 數據(在我的示例中是籃球數據)
    • 可重用的顯示標記部分,例如按鈕欄
    • 頁面殘余部分

    下例演示了這種解決方案。

    用戶界面設計

    您可能希望您的 Web 應用程序看上去和感覺起來設計得更專業(yè)。布局美觀的 HTML 頁面往往意味著復雜標記、具有各種嵌入式 HTML 表的安排以及精確的格式化和間距命令。在本文中,我假設已有某個表示下面所示 頁面設計的靜態(tài) HTML。任務是用一個顯示樣式表重新生成相同的外觀和感覺。


    目標外觀和感覺
    設計 HTML 圖

    雖然這只是一個簡單的示例頁面,但它也有一些嵌入的 HTML 表。它將只是多個頁面中的一個,這些頁面顯示的數據來自生成 XML 形式的籃球統計信息的應用程序。我將用 籃球 XML 中的數據替換 "Dynamic data"(動態(tài)數據),然后使用 "Navigation bar"(導航欄)列出從當前頁開始的鏈接。

    采取的步驟

    要生成顯示樣式表,需要:

    1. 從設計 HTML 制作一個樣式表。
    2. 制作一個將籃球得分格式化成 HTML 的樣式表。
    3. 將二者合并。
    4. 制作一個生成“導航”欄的 XSLT“窗口小部件”。
    5. 具體化這個窗口小部件,以生成頁面的最終樣式表。




    回頁首


    從設計 HTML 制作一個樣式表

    我可以只制作一個 XSLT 樣式表,然后將 HTML 粘貼到適當位置。然而,當用戶界面設計更改時,我希望能相應地快速而輕松地更新顯示樣式表。一種比較好的解決方案是發(fā)明一個可以自動將設計 HTML 轉換成樣式表的過程。如果設計 HTML 和 XML 一樣是有效的(如果不是,可以將它清除),那我就可以用 XSLT 樣式表這樣做。

    頁面骨架

    首先,在設計 HTML 的 <HTML> 標記周圍添加 <layout> 元素。


    帶標記的設計 HTML - skeleton.xml
    												
    														
    <layout match="game">

    <html>

    ...

    </html>




    </layout>

    這不一定使 HTML 變成樣式表,但確實可以讓我使用 <layout> 元素的屬性來存儲那些有助于推動此過程的信息。例如, match="game" 指定了籃球 XML 中的某個元素,我將使用該元素來觸發(fā)此頁面 HTML 的生成。 <layout> 元素內的 HTML 本質上是目標頁面的 HTML 模板。因為 模板一詞在 XSLT 的上下文中有意義,所以,我稱它為目標頁面的 HTML 骨架。

    預處理樣式表

    下面是將 skeleton.xml 中的頁面骨架轉換成樣式表的樣式表。


    pre-process.xsl - 第 1 版
    												<?xml version="1.0"?>

    <xsl:style sheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"




    xmlns:out="http://www.hursley.ibm.com/hsandt/et/compile">



    <xsl:output method="xml" indent="yes"/>




    <xsl:namespace-alias stylesheet-prefix="out" result-prefix="xsl"/>





    <!-- template 1 -->

    <xsl:template match="/layout">




    <out:stylesheet version="1.0">

    <out:output method="html" indent="yes"/>

    <out:template match="{@match}">

    <xsl:apply-templates/>




    </out:template>

    </out:stylesheet>

    </xsl:template>





    <!-- template 2 -->

    <xsl:template match="*|text()">

    <xsl:copy>

    <xsl:copy-of select="@*"/>

    <xsl:apply-templates select="*|text()"/>

    </xsl:copy>

    </xsl:template>





    </xsl:stylesheet>





    該樣式表有兩個模板:

    • template 1 匹配頁面骨架中的 <layout> 元素,并輸出 XSLT 樣式表。
    • template 2 匹配任何其它元素或文本節(jié)點,并只將它匹配的內容不加更改地復制到輸出中。

    因為我希望此樣式表的輸出是一個樣式表,所以必須輸出 XSLT 語句。但是,XSLT 處理器如何區(qū)分要輸出的 XSLT 語句和要執(zhí)行的 XSLT 語句呢?答案是對要復制到輸出的 XSLT 語句使用另一個 XML 名稱空間。

    在上例中,我定義了一個新的名稱空間 ( "http://www.hursley.ibm.com/hsandt/et/compile" ),并將其與名稱空間前綴 out 關聯。因為帶有 out 前綴的 XSLT 語句不在 XSLT ( "http://www.w3.org/1999/XSL/Transform" ) 名稱空間中,所以,XSLT 處理器將按我的需要輸出它們。但這還不夠。我希望輸出是正確的樣式表,XSLT 進程無需作任何進一步更改就可以執(zhí)行它。在示例的這一點處,我將獲得看起來類似于樣式表、而實際上卻不是的東西。

    XSLT 用上面所用的 <xsl:namespace-alias> 元素提供了該問題的解決方案。這將獲取 "http://www.hursley.ibm.com/hsandt/et/compile" ( out ) 名稱空間中的所有內容,并在輸出時將它們移到 "http://www.w3.org/1999/XSL/Transform" ( xsl ) 名稱空間中。

    pre-process.xsl 應用到頁面骨架的結果看起來類似于:


    從 pre-process.xsl 得到的輸出 - skeleton.xsl
    												<?xml version="1.0" encoding="UTF-8"?>

    <out:stylesheet xmlns:out="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <out:output indent="yes" method="html"/>

    <out:template match="game">



    <html>

    ...

    </html>

    </out:template>

    </out:stylesheet>


    請注意,名稱空間前綴仍然是 out 。這并不重要。重要的是名稱空間前綴 out 現在被映射成 XSLT 名稱空間: "http://www.w3.org/1999/XSL/Transform" 。(對 XML 語法分析器很重要的是名稱空間,而不是前綴。前綴是使 XML 便于閱讀的工具)。某些 XSLT 處理器可以在輸出時更改名稱空間前綴和名稱空間。本文示例所用的 Xalan XSLT 處理器不更改。

    現在,可以將 skeleton.xsl 樣式表應用到籃球數據。結果由與數據中 <game> 元素的匹配所觸發(fā),它與原始 設計 HTML 文件是同樣的 HTML。目前這還不是很有用,因為在我希望看到比賽得分的地方仍然顯示字符串 "Dynamic data"。我需要讓 skeleton.xsl 樣式表觸發(fā)那些在適當位置插入得分的模板。我通過找到寫著 "Dynamic data" 的標記,然后將它替換成 <xsl:apply-templates> 調用來實現。 skeleton.xml 文件中的以下標記:

    												...

    <table cellspacing="0" cellpadding="0" border="0" height="100%" width="100%">

    <tbody>

    <tr><td><img src="spacer.gif" width="1" height="50"/></td></tr>

    <tr><td height="100%" align="center" valign="top">




    <h2>Dynamic data</h2>

    </td></tr>

    </tbody>

    </table>

    ...





    變成


    												...

    <table cellspacing="0" cellpadding="0" border="0" height="100%" width="100%">

    <tbody>

    <tr><td><img src="spacer.gif" width="1" height="50"/></td></tr>

    <tr><td height="100%" align="center" valign="top">




    <out:apply-templates select="http://recap"/>

    </td></tr>

    </tbody>

    </table>

    ...





    請注意 out 名稱空間前綴;它將導致 XSLT 處理器將元素作為被輸出,而不是被執(zhí)行的事物對待 -- 與上面對 pre-process.xsl 樣式表中的類似元素的描述完全一樣。正如您將在下一部分中看到的,我只對籃球數據中的 <recap> 元素感興趣,因此,我可以在這里指定選擇標準 select="http://recap" 。

    現在,我所擁有的 XSLT 代碼能夠生成所需的靜態(tài) HTML 布局,并可以觸發(fā)那些插入動態(tài)數據的模板。接下來,我需要從籃球 XML 數據抽取數據的 XSLT 模板。





    回頁首


    籃球數據樣式表

    為簡便起見,我只生成一個在籃球數據的 <recap> 元素中找到的得分數據表,如下所示。


    recap.xsl
    												<?xml version='1.0'?>

    <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>



    <xsl:output method="HTML"/>



    <xsl:template match="/">

    <HTML>

    <HEAD>

    <TITLE>Box Score</TITLE>

    </HEAD>

    <BODY>

    <h1>Testing</h1>

    <xsl:apply-templates select="http://recap"/>

    </BODY>

    </HTML>

    </xsl:template>





    <xsl:template match="recap">

    <TABLE border="0" cellpadding="2" cellspacing="1" width="80%">

    <TR>

    <TD BGCOLOR="#c80000"></TD>

    <TD BGCOLOR="#c80000">

    <CENTER><font color="#FFFFFF"><B>1st</B></font></CENTER>

    </TD>

    <TD BGCOLOR="#c80000">

    <CENTER><font color="#FFFFFF"><B>2nd</B></font></CENTER>

    </TD>

    <TD BGCOLOR="#c80000">

    <CENTER><font color="#FFFFFF"><B>Total</B></font></CENTER>

    </TD>

    </TR>

    <xsl:apply-templates/>

    </TABLE>

    </xsl:template>





    <xsl:template match="recapTeam">

    <TR>

    <TD BGCOLOR="#ffe0e0"><xsl:value-of select="team"/></TD>

    <TD BGCOLOR="#ffe0e0">

    <CENTER><xsl:value-of select="firstHalfScore"/></CENTER>

    </TD>

    <TD BGCOLOR="#ffe0e0">

    <CENTER><xsl:value-of select="secondHalfScore"/></CENTER>

    </TD>

    <TD BGCOLOR="#ffe0e0">

    <CENTER><xsl:value-of select="score"/></CENTER>

    </TD>

    </TR>

    </xsl:template>





    </xsl:stylesheet>


    下面的樣式表挑選出 XML 片斷。


    籃球 XML 中的 <recap> 元素
    												...

    <recap>

    <recapTeam>

    <team>Georgia Tech</team>

    <firstHalfScore> 21 </firstHalfScore>

    <secondHalfScore> 39 </secondHalfScore>

    <score> 60 </score>

    </recapTeam>

    <recapTeam>

    <team>North Carolina State</team>

    <firstHalfScore> 24 </firstHalfScore>

    <secondHalfScore> 48 </secondHalfScore>

    <score> 72 </score>

    </recapTeam>

    </recap>

    ...


    上面的樣式表產生以下輸出:

    Testing


    1st 2nd Total
    Georgia Tech 21 39 60
    North Carolina State 24 48 72




    回頁首


    合并兩個樣式表

    現在,我有兩個樣式表: skeleton.xslrecap.xsl 。我可以通過將這兩個樣式表導入到名為 runtime.xsl 的新樣式表非常方便地合并它們。結果如下所示。


    runtime.xsl
    												<?xml version='1.0'?>

    <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>



    <xsl:import href="recap.xsl"/>

    <xsl:import href="skeleton.xsl"/>



    <xsl:template match="/">

    <xsl:apply-templates/>

    </xsl:template>



    </xsl:stylesheet>

    可以在運行期間將該樣式表作為 Web 應用程序的一部分應用到籃球 XML 數據。樣式表中通過不同 XSLT 模板的流程如下所示:

    • 首先匹配籃球數據的根節(jié)點。 runtime.xsl 中具有 match="/" 的模板具有較高的導入優(yōu)先權,并覆蓋 recap.xsl 中的等價模板。后者只是用于 recap.xsl 的獨立測試中觸發(fā)其它模板,因此,這就是我想要的行為。XSLT 處理器應用這些模板。
    • 要匹配的下一個模板是 skeleton.xsl 中具有 match="game" 的模板。它將持續(xù)輸出 HTML,直到到達要輸出得分數據的 <xsl:apply-templates> 元素為止。
    • 接下來要觸發(fā)的模板是 recap.xsl 中具有 match="recap" 的模板。它構建得分表標題行,然后應用模板來匹配用于構建表數據行的 <recapTeam> 元素。
    • 構建得分表之后,就沒有更多要匹配的輸入 XML 節(jié)點了。此時,控制返回到 match="game" 模板,該模板輸出 HTML 的其余部分。

    現在,我已經實現了具有目標視覺和感覺效果的動態(tài)數據部分。下一步是實現導航欄。





    回頁首


    導航欄

    假設在實際站點上,導航欄在站點上的所有頁面中出現,并具有特定于當前頁面的標題。在導航欄上有一些從該頁出發(fā)的固定鏈接,對于該站點的不同頁面,這些鏈接可能相同,也可能不同。這些鏈接只取決于當前頁面的內容。導航欄不依賴于籃球 XML 數據。

    這一功能的實現與我剛剛對動態(tài)數據所執(zhí)行的操作類似:將 skeleton.xml 文件中 HTML 標記的 "Navigation bar" 部分替換成觸發(fā) XSLT 代碼的某個標記。然而這一次,XSLT 將不由籃球數據觸發(fā),并且我希望用于構建導航欄的所有 XSLT 代碼在預處理階段執(zhí)行,而不要保留到運行期間。

    導航窗口小部件

    首先,我將在 skeleton.xml 文件中希望出現導航欄的位置上放一個標記。我采用以下片斷:


    												<layout match="game">

    ...

    <table cellspacing="0" cellpadding="0" border="0" height="100%" width="145">

    <tr><td><img src="spacer.gif" width="100" height="100"/></td></tr>

    <tr>

    <td align="center" valign="top">




    <font color="white"><h2>Navigation bar</h2></font>

    </td>

    </tr>

    </table>

    ...





    并將它編輯成:


    												<layout id="Recap" match="game" 


    xmlns:widget="http://www.hursley.ibm.com/widget" >

    ...

    <table cellspacing="0" cellpadding="0" border="0" height="100%" width="145">

    <tr><td><img src="spacer.gif" width="100" height="100"/></td></tr>

    <tr>

    <td align="center" valign="top">




    <widget:navbar/>

    </td>

    </tr>

    </table>

    ...





    我在這里發(fā)明了 navbar 標記,并在新的 widget 名稱空間中指定它。通常,當發(fā)明標記來以某種新方式標記已有 XML 時,最好將新標記放在新的名稱空間中,以防止可能發(fā)生的名稱沖突。這樣做的更有利的原因是:可以通過在 XSLT 模板中指定 match="widget:*" 來以類的形式查找和操縱頁面骨架中的“窗口小部件”。

    還要注意添加到 <layout> 元素的 id="Recap" 屬性。它標識這個頁面骨架應用于哪個特定頁面。此信息用于確定在那個頁面的導航欄上出現的內容。

    接下來,我編寫了一個 XSLT 樣式表,該樣式表將由 <widget:navbar/> 標記觸發(fā),并將該標記替換成正確的 HTML,以形成所期望的頁面導航欄。這樣的樣式表看起來可能類似于下例。


    navbar.xsl
    												<?xml version='1.0'?>

    <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'

    xmlns:widget="http://www.hursley.ibm.com/widget">



    <xsl:template match="/">

    <xsl:apply-templates/>

    </xsl:template>





    <xsl:template match="widget:navbar">

    <!-- Get the "id" attribute from the page skeleton <layout> tag -->

    <xsl:variable name="page" select="ancestor::layout[1]/@id" />

    <!-- Navigation bar title: -->

    <tr>

    <td align="center">

    <h2><font color="white"><xsl:value-of select="$page"/></font></h2>

    </td>

    </tr>

    <!-- Navigation bar links: -->

    <xsl:apply-templates select="document('')//widget:page[@id=$page]"/>

    </xsl:template>





    <xsl:template match="widget:page">

    <xsl:apply-templates/>

    </xsl:template>





    <xsl:template match="widget:link">

    <tr>

    <td align="center">

    <a href="{@to}"><xsl:value-of select="@title"/></a>

    </td>

    </tr>

    </xsl:template>





    <!--

    A lookup table of navbar links out from each page:

    -->

    <widget:linkData>



    <widget:page id="Recap">

    <widget:link to="nowhere1" title="Team stats"/>

    <widget:link to="nowhere2" title="Player stats"/>

    <widget:link to="nowhere3" title="etc."/>

    </widget:page>



    <widget:page id="someOther">

    <!-- and so on for the other pages in the application -->

    </widget:page>



    </widget:linkData>





    </xsl:stylesheet>


    此樣式表獲取在其中找到 <widget:navbar/> 標記的 <layout> 元素的 id 屬性值,并在查表期間使用該屬性作為鍵,以發(fā)現導航欄應該包含哪些源自該頁面的鏈接。然后,構造并返回導航欄的 HTML。

    最后一步是更新 pre-process.xsl 樣式表,以利用 navbar 窗口小部件。我需要添加 XSLT 代碼,如下所示:


    pre-process.xsl - 第 2 版
    												<?xml version="1.0"?>

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"

    xmlns:out="http://www.hursley.ibm.com/hsandt/et/compile"




    xmlns:widget="http://www.hursley.ibm.com/widget">



    <xsl:output method="xml" indent="yes"/>

    <xsl:namespace-alias stylesheet-prefix="out" result-prefix="xsl"/>






    <xsl:import href="navbar.xsl"/>



    <xsl:template match="/layout">

    <out:stylesheet version="1.0">

    <out:output method="html" indent="yes"/>

    <out:template match="{@match}">

    <xsl:apply-templates/>

    </out:template>

    </out:stylesheet>

    </xsl:template>





    <xsl:template match="*|text()">

    <xsl:copy>

    <xsl:copy-of select="@*"/>

    <xsl:apply-templates select="*|text()"/>

    </xsl:copy>

    </xsl:template>








    <xsl:template match="widget:*">

    <xsl:apply-imports/>

    </xsl:template>





    </xsl:stylesheet>





    現在,可以對 skeleton.xml 文件重新運行 pre-process.xsl 樣式表,以創(chuàng)建新版的 skeleton.xsl 。 runtime.xsl 中的 <xsl:import> 獲得新的 skeleton.xsl 。對籃球數據應用 runtime.xsl 后產生:

    最后的結果
    運行時 HTML 圖





    回頁首


    結束語

    runtime.xsl 樣式表由其它三個樣式表 skeleton.xsl 、 recap.xslnavbar.xsl 得到。構建這三個樣式表所需的技能如下:

    • 通過對 skeleton.xml 文件應用自動過程來構建 skeleton.xsl 。從靜態(tài) HTML 構建 skeleton.xml 文件非常簡單,無需任何特殊的 XML 或 XSLT 技能。HTML 需要 Web 設計技能。
    • recap.xsl 需要有關的 XSLT 和應用 XML 的知識。它輸出一些 HTML 標記,但不需要太多 HTML 技能,因為靜態(tài) HTML 可能包括一個樣本數據表(它將全面指定表單元顏色、邊框寬度等),而不是 "Dynamic data" 字符串。
    • navbar.xsl 需要 XSLT 知識,并且在更現實的示例中,可能還需要深入了解目標標記語言。

    可以仔細地說明、開發(fā)和單獨地測試樣式表。生成動態(tài)數據的樣式表和生成顯示的樣式表之間是有區(qū)別的。雖然 XSLT 程序員們需要同時理解顯示標記和基本的商業(yè) XML,但對于單獨的 XSLT 程序員來說,無需同時理解二者。在本例的三個樣式表中,技術要求最高的是 navbar.xsl ,但不管怎樣,編寫可重用的 XSLT 組件正是您施展才華的所在。

    When to use sidebars

    請記住,在運行期間也要管理生成的樣式表,并確保對每個給定請求,都應用了正確設備的正確樣式表。

    IBM WebSphere Transcoding Publisher 可以替您這樣做,這樣,應用程序的 XSLT 變換在邏輯上(如果您愿意,也可以在物理上)就與產生 XML 的商業(yè)邏輯分隔開。

    更進一步

    pre-process.xsl 樣式表獨立于它所處理的頁面骨架文件中的標記語言。在生成其它設備(例如,用于 WAP 電話的 WML deck)的標記時,也可以應用完全相同的技術。創(chuàng)建新的窗口小部件只需編寫一個適當的 XSLT 樣式表,然后將一個 <import> 元素添加到 pre-process.xsl 即可。

    隨著要支持的頁面骨架和窗口小部件數目的增加,管理和操縱所有這些組件的問題也隨之成倍增加,因此需要一些工具來管理這種復雜的局面。但是,因為每個組件都是 XML,所以,這些工具本身也可以使用 XML。可以將頁面骨架和窗口小部件存儲在關系數據庫中,并使用 document() 函數從 XSLT 訪問它們。在構建這種開發(fā)工具方面,具有 Java API 的 XSLT 處理器(例如 Xalan)將特別有用。





    回頁首


    參考資料





    回頁首


    關于作者

    author

    Alan Knox 是英國漢普郡 Hursley Park 的一名 IBM 軟件工程師。Alan 于 1997 年從 Civil Service 跳槽到 IBM。從那時起,他參與了一些使現有 Web 應用程序適用于交互式電視和 WAP 電話的項目??梢酝ㄟ^ knox@uk.ibm.com 與 Alan 聯系

    posted on 2006-03-21 23:49 Vincent.Chen 閱讀(477) 評論(0)  編輯  收藏 所屬分類: XML

    主站蜘蛛池模板: 亚洲欧洲视频在线观看| 亚洲免费无码在线| 97在线观免费视频观看| 香港经典a毛片免费观看看| 午夜亚洲www湿好大| 亚洲国产精品狼友中文久久久 | 毛片a级毛片免费观看品善网| a毛片在线免费观看| 少妇亚洲免费精品| 亚洲精品自偷自拍无码| 亚洲成a人片在线观看中文!!!| 国产偷国产偷亚洲清高动态图| 免费大片在线观看网站| 成年男女免费视频网站| 国产成人免费在线| 久久国产精品免费视频| 中文字幕在线免费观看视频| 五级黄18以上免费看| 久久久久亚洲精品无码网址色欲 | 成人爽a毛片免费| 国产精品综合专区中文字幕免费播放| 亚洲第一成年网站视频| 亚洲一区无码中文字幕乱码| 亚洲黄色在线播放| 亚洲精品无码不卡| 亚洲免费精彩视频在线观看| 亚洲av日韩av不卡在线观看 | 久久免费精品视频| 中文字幕免费观看全部电影| 在线免费视频你懂的| 亚洲精品视频免费| 三上悠亚在线观看免费| 在线观看免费视频一区| free哆拍拍免费永久视频| v片免费在线观看| 亚洲免费在线观看| 99re8这里有精品热视频免费| 久久成人永久免费播放| 日韩精品无码免费专区午夜不卡| a级毛片视频免费观看| 三年片在线观看免费观看大全动漫 |