Vincent.Chan‘s Blog

          常用鏈接

          統(tǒng)計(jì)

          積分與排名

          網(wǎng)站

          最新評(píng)論

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

          級(jí)別: 初級(jí)

          Alan Knox, 軟件工程師, IBM

          2001 年 6 月 01 日

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

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

          如果要:

          • 完全控制用戶所見的內(nèi)容
          • 調(diào)整應(yīng)用程序的顯示,以便在每一種設(shè)備上實(shí)現(xiàn)最佳的可能的效果
          • 利用設(shè)備的特定特性

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

          什么是樣式表?

          樣式表描述文檔如何在屏幕上或打印中顯示。通過將樣式表附加到 Web 上的結(jié)構(gòu)化文檔,您可以改變顯示,而無需犧牲設(shè)備獨(dú)立性或添加新的 HTML 標(biāo)記。

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

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

          什么是 XML?
          XML 代表用于基于 Web 的文檔的可擴(kuò)展標(biāo)記語言。可將它看成 SGML 的縮減版。

          樣式表的難點(diǎn)

          樣式表主要有兩類問題:

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




          回頁首


          解決方案

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

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

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

          用戶界面設(shè)計(jì)

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


          目標(biāo)外觀和感覺
          設(shè)計(jì) HTML 圖

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

          采取的步驟

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

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




          回頁首


          從設(shè)計(jì) HTML 制作一個(gè)樣式表

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

          頁面骨架

          首先,在設(shè)計(jì) HTML 的 <HTML> 標(biāo)記周圍添加 <layout> 元素。


          帶標(biāo)記的設(shè)計(jì) HTML - skeleton.xml
          												
          														
          <layout match="game">

          <html>

          ...

          </html>




          </layout>

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

          預(yù)處理樣式表

          下面是將 skeleton.xml 中的頁面骨架轉(zhuǎn)換成樣式表的樣式表。


          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>





          該樣式表有兩個(gè)模板:

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

          因?yàn)槲蚁M藰邮奖淼妮敵鍪且粋€(gè)樣式表,所以必須輸出 XSLT 語句。但是,XSLT 處理器如何區(qū)分要輸出的 XSLT 語句和要執(zhí)行的 XSLT 語句呢?答案是對(duì)要復(fù)制到輸出的 XSLT 語句使用另一個(gè) XML 名稱空間。

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

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

          pre-process.xsl 應(yīng)用到頁面骨架的結(jié)果看起來類似于:


          從 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>


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

          現(xiàn)在,可以將 skeleton.xsl 樣式表應(yīng)用到籃球數(shù)據(jù)。結(jié)果由與數(shù)據(jù)中 <game> 元素的匹配所觸發(fā),它與原始 設(shè)計(jì) HTML 文件是同樣的 HTML。目前這還不是很有用,因?yàn)樵谖蚁M吹奖荣惖梅值牡胤饺匀伙@示字符串 "Dynamic data"。我需要讓 skeleton.xsl 樣式表觸發(fā)那些在適當(dāng)位置插入得分的模板。我通過找到寫著 "Dynamic data" 的標(biāo)記,然后將它替換成 <xsl:apply-templates> 調(diào)用來實(shí)現(xiàn)。 skeleton.xml 文件中的以下標(biāo)記:

          												...

          <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>

          ...





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

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





          回頁首


          籃球數(shù)據(jù)樣式表

          為簡(jiǎn)便起見,我只生成一個(gè)在籃球數(shù)據(jù)的 <recap> 元素中找到的得分?jǐn)?shù)據(jù)表,如下所示。


          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>

          ...


          上面的樣式表產(chǎn)生以下輸出:

          Testing


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




          回頁首


          合并兩個(gè)樣式表

          現(xiàn)在,我有兩個(gè)樣式表: skeleton.xslrecap.xsl 。我可以通過將這兩個(gè)樣式表導(dǎo)入到名為 runtime.xsl 的新樣式表非常方便地合并它們。結(jié)果如下所示。


          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>

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

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

          現(xiàn)在,我已經(jīng)實(shí)現(xiàn)了具有目標(biāo)視覺和感覺效果的動(dòng)態(tài)數(shù)據(jù)部分。下一步是實(shí)現(xiàn)導(dǎo)航欄。





          回頁首


          導(dǎo)航欄

          假設(shè)在實(shí)際站點(diǎn)上,導(dǎo)航欄在站點(diǎn)上的所有頁面中出現(xiàn),并具有特定于當(dāng)前頁面的標(biāo)題。在導(dǎo)航欄上有一些從該頁出發(fā)的固定鏈接,對(duì)于該站點(diǎn)的不同頁面,這些鏈接可能相同,也可能不同。這些鏈接只取決于當(dāng)前頁面的內(nèi)容。導(dǎo)航欄不依賴于籃球 XML 數(shù)據(jù)。

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

          導(dǎo)航窗口小部件

          首先,我將在 skeleton.xml 文件中希望出現(xiàn)導(dǎo)航欄的位置上放一個(gè)標(biāo)記。我采用以下片斷:


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

          還要注意添加到 <layout> 元素的 id="Recap" 屬性。它標(biāo)識(shí)這個(gè)頁面骨架應(yīng)用于哪個(gè)特定頁面。此信息用于確定在那個(gè)頁面的導(dǎo)航欄上出現(xiàn)的內(nèi)容。

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


          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/> 標(biāo)記的 <layout> 元素的 id 屬性值,并在查表期間使用該屬性作為鍵,以發(fā)現(xiàn)導(dǎo)航欄應(yīng)該包含哪些源自該頁面的鏈接。然后,構(gòu)造并返回導(dǎo)航欄的 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>





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

          最后的結(jié)果
          運(yùn)行時(shí) HTML 圖





          回頁首


          結(jié)束語

          runtime.xsl 樣式表由其它三個(gè)樣式表 skeleton.xslrecap.xslnavbar.xsl 得到。構(gòu)建這三個(gè)樣式表所需的技能如下:

          • 通過對(duì) skeleton.xml 文件應(yīng)用自動(dòng)過程來構(gòu)建 skeleton.xsl 。從靜態(tài) HTML 構(gòu)建 skeleton.xml 文件非常簡(jiǎn)單,無需任何特殊的 XML 或 XSLT 技能。HTML 需要 Web 設(shè)計(jì)技能。
          • recap.xsl 需要有關(guān)的 XSLT 和應(yīng)用 XML 的知識(shí)。它輸出一些 HTML 標(biāo)記,但不需要太多 HTML 技能,因?yàn)殪o態(tài) HTML 可能包括一個(gè)樣本數(shù)據(jù)表(它將全面指定表單元顏色、邊框?qū)挾鹊龋皇? "Dynamic data" 字符串。
          • navbar.xsl 需要 XSLT 知識(shí),并且在更現(xiàn)實(shí)的示例中,可能還需要深入了解目標(biāo)標(biāo)記語言。

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

          When to use sidebars

          請(qǐng)記住,在運(yùn)行期間也要管理生成的樣式表,并確保對(duì)每個(gè)給定請(qǐng)求,都應(yīng)用了正確設(shè)備的正確樣式表。

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

          更進(jìn)一步

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

          隨著要支持的頁面骨架和窗口小部件數(shù)目的增加,管理和操縱所有這些組件的問題也隨之成倍增加,因此需要一些工具來管理這種復(fù)雜的局面。但是,因?yàn)槊總€(gè)組件都是 XML,所以,這些工具本身也可以使用 XML??梢詫㈨撁婀羌芎痛翱谛〔考鎯?chǔ)在關(guān)系數(shù)據(jù)庫(kù)中,并使用 document() 函數(shù)從 XSLT 訪問它們。在構(gòu)建這種開發(fā)工具方面,具有 Java API 的 XSLT 處理器(例如 Xalan)將特別有用。





          回頁首


          參考資料





          回頁首


          關(guān)于作者

          author

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

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

          主站蜘蛛池模板: 无极县| 阳信县| 丰镇市| 定西市| 南昌县| 临湘市| 天门市| 枞阳县| 宁乡县| 阿图什市| 舒兰市| 祁东县| 大冶市| 清远市| 惠东县| 秭归县| 杨浦区| 章丘市| 广汉市| 漯河市| 安化县| 霞浦县| 清苑县| 广南县| 射阳县| 广西| 石首市| 车致| 石棉县| 呼伦贝尔市| 义马市| 陵水| 鄂伦春自治旗| 东台市| 龙州县| 定边县| 股票| 涿州市| 翼城县| 萝北县| 沭阳县|