隨筆-7  評論-4  文章-0  trackbacks-0
           

          XSLT 是什么類型的語言,其用途是什么,為什么要這樣設(shè)計它?這些問題可以有許多不同的答案,初學(xué)者往往會感到困惑,因為這種語言與他們以前習(xí)慣使用的語言之間有很大差別。本文嘗試說明 XSLT。本文并不試圖教您編寫 XSLT 樣式表,它將說明這種語言的起源,它擅長什么,以及您為什么應(yīng)該使用它。

          什么是 XSLT
          XSLT 語言由萬維網(wǎng)聯(lián)盟 (W3C) 定義,并且該語言的 1.0 版本在 1999 年 11 16 日作為推薦書發(fā)布(請參閱參考資料)。我已經(jīng)在拙作 XSLT Programmers' Reference 中提供了全面的規(guī)范和用戶指南,因此我不打算在本文中涵蓋相同內(nèi)容。確切地講,本文的目的只是使讀者理解 XSLT 適合大規(guī)模事物的哪些位置。

          XSLT 的角色
          XSLT 的最初目的是將信息內(nèi)容與 Web 顯示分離。如其最初定義那樣,HTML 通過按抽象概念(如段落、重點和編號列表)定義顯示來實現(xiàn)設(shè)備獨立性。隨著 Web 變得越來越商業(yè)化,出版人希望其輸出質(zhì)量能達(dá)到與印刷品相同的質(zhì)量。這逐漸導(dǎo)致越來越多地使用具體顯示控件,如頁面上材料的明確字體和絕對位置。然而不幸的是完全可以預(yù)料其副作用,即將相同的內(nèi)容傳遞到替代設(shè)備,如數(shù)字電視機和 WAP 電話(印刷業(yè)的行話再現(xiàn)效果)將會變得日益困難。

          由于吸收了印刷業(yè)使用 SGML 的經(jīng)驗,在 1998 年初定義了一種標(biāo)記語言 XML,它用于表示獨立于顯示的結(jié)構(gòu)化內(nèi)容。與 HTML 使用一組固定概念(如段落、列表和表)不同,XML 標(biāo)記中使用的標(biāo)記完全是用戶定義的,其用意是這些標(biāo)記應(yīng)該與所關(guān)注的對象(如人、地點、價格和日期)相關(guān)。盡管 HTML 中的元素本質(zhì)上都是印刷樣式(雖然處于抽象級別),而 XML 的目標(biāo)是元素應(yīng)該描述實際對象。例如,清單 1 顯示了表示足球錦標(biāo)賽結(jié)果的 XML 文檔。

          清單 1. 表示足球錦標(biāo)賽結(jié)果的 XML 文檔
          <results group="A">
          <match>
          <date>10-Jun-1998</date>
          <team score="2">Brazil</team>
          <team score="1">Scotland</team>
          </match>
          <match>
          <date>10-Jun-1998</date>
          <team score="2">Morocco</team>
          <team score="2">Norway</team>
          </match>
          <match>
          <date>16-Jun-1998</date>
          <team score="1">Scotland</team>
          <team score="1">Norway</team>
          </match>
          <match>
          <date>16-Jun-1998</date>
          <team score="3">Brazil</team>
          <team score="0">Morocco</team>
          </match>
          <match>
          <date>23-Jun-1998</date>
          <team score="1">Brazil</team>
          <team score="2">Norway</team>
          </match>
          <match>
          <date>23-Jun-1998</date>
          <team score="0">Scotland</team>
          <team score="3">Morocco</team>
          </match>
          </results>




          如果要通過 Web 瀏覽器顯示這些足球賽的結(jié)果,不要指望系統(tǒng)會產(chǎn)生合理的布局。需要其它一些機制來告訴系統(tǒng)如何在瀏覽器屏幕、電視機、WAP 電話或真正在紙張上顯示數(shù)據(jù)。這就是使用樣式表的目的。樣式表是一組說明性的規(guī)則,它定義了應(yīng)如何表示源文檔中標(biāo)記標(biāo)識的信息元素。

          W3C 已經(jīng)定義了兩個系列的樣式表標(biāo)準(zhǔn)。第一個是在 HTML 中廣泛使用的 CSS(級聯(lián)樣式表),當(dāng)然它也可以在 XML 中使用。例如,可以使用 CSS 來表示何時顯示發(fā)票,應(yīng)支付的總額應(yīng)該用 16 Helvetica 粗體字顯示。但是,CSS 不能執(zhí)行計算、重新整理或排序數(shù)據(jù)、組合多個源碼中的數(shù)據(jù)或根據(jù)用戶或會話的特征個性化顯示的內(nèi)容。在這個足球賽結(jié)果的例子中,CSS 語言(即使是最新版本 CSS2,尚未在產(chǎn)品中完全實現(xiàn))的功能還不夠強大,不能處理這項任務(wù)。由于這些原因,W3C 已著手開發(fā)更強大的樣式表語言 XSL(可擴展樣式表語言),并采納了 SGML 社區(qū)中開發(fā)的 DSSSL(文檔樣式、語義和規(guī)范語言)中許多好的構(gòu)思。

          XSL 的開發(fā)過程中(這在 DSSSL 中已有所預(yù)示),發(fā)現(xiàn)在準(zhǔn)備 XML 文檔以備顯示的過程中執(zhí)行的任務(wù)可以分成兩個階段:轉(zhuǎn)換和格式化。轉(zhuǎn)換是將一個 XML 文檔(或其內(nèi)存中的表示法)轉(zhuǎn)換成另一個 XML 文檔的過程。格式是將已轉(zhuǎn)換的樹狀結(jié)構(gòu)轉(zhuǎn)換成兩維圖形表示法或可能是一維音頻流的過程。XSLT 是為控制第一階段轉(zhuǎn)換而開發(fā)的語言。第二階段格式化的開發(fā)工作還是進行中。但實際上,大多數(shù)人現(xiàn)在使用 XSL XML 文檔轉(zhuǎn)換成 HTML,并使用 HTML 瀏覽器作為格式化引擎。這是可行的,因為 HTML 實際上只是 XML 詞匯表的一個示例,而 XSLT 可以使用任何 XML 詞匯表作為其目標(biāo)。

          將轉(zhuǎn)換成一種語言和格式化成另一種語言這兩個操作分離經(jīng)證實的確是一種好的決策,因為轉(zhuǎn)換語言的許多應(yīng)用程序經(jīng)證明無法向用戶顯示文檔。隨著 XML 日益廣泛地用作電子商務(wù)中的數(shù)據(jù)互換語法,對于應(yīng)用程序?qū)?shù)據(jù)從一個 XML 詞匯表轉(zhuǎn)換成另一個 XML 詞匯表的需求也在不斷增加。例如,某個應(yīng)用程序可能從電視收視指南中抽取電視節(jié)目的細(xì)節(jié),并將它們插入按次付費客戶的月帳單中。同樣,還有許多實用的數(shù)據(jù)轉(zhuǎn)換,在這些轉(zhuǎn)換中源詞匯表和目標(biāo)詞匯表是相同的。它們包括數(shù)據(jù)過濾,以及商務(wù)操作,如施行漲價。因此,隨著在系統(tǒng)中開始越來越多地以 XML 語法的形式使用數(shù)據(jù),XSLT 就逐漸成為由于處理這些數(shù)據(jù)的隨處可見的高級語言。

          在拙作中,我做了這樣一個比喻:XSLT XML 的關(guān)系,就好象 SQL 與表格化數(shù)據(jù)的關(guān)系一樣。關(guān)系模型的強大功能并非來自用表存儲數(shù)據(jù)的思想,而是源于 SQL 中可行的基于關(guān)系運算的高級數(shù)據(jù)操作。同樣,XML 的層次化數(shù)據(jù)模型對應(yīng)用程序開發(fā)者的幫助實際上也非常小。正是因為 XSLT 作為 XML 數(shù)據(jù)的高級操作語言提供了如此強大的功能。

          XSLT 作為語言
          就某些方面而言,XSLT 作為一種語言來說是非常古怪的。我不打算在本文中討論已做出的設(shè)計決策的基本原理,盡管可以通過它們在邏輯上追溯到語言設(shè)計者確定的對 XSLT 的要求。

          以下概述了 XSLT 語言的部分主要特性。

          XSLT 樣式表是一個 XML 文檔。通過使用 XML 的尖括號標(biāo)記語法來表示文檔的結(jié)構(gòu)。這種語法在某種程度上是比較笨拙的,而此決策可以使該語言變得更羅嗦。但是,它確實有好處。它表示可以自動使用 XML 的所有詞匯設(shè)備(例如,Unicode 字符編碼和轉(zhuǎn)義,使用外部實體等等)。它表示很容易使 XSLT 樣式表變成轉(zhuǎn)換的輸入或輸出,使該語言可以作用于自身。它還使將期望的 XML 輸出塊嵌入樣式表變得很容易。實際上,許多簡單的樣式表基本上可以寫作期望輸出文檔的模板,并且可以將一些特殊指令嵌入文本中,以便插入輸入中的變量數(shù)據(jù)或計算某個值。這就使 XSLT 在這個簡單的級別上非常類似于許多現(xiàn)有的專用 HTML 模板語言。

          基本處理范例是模式匹配。在這方面,XSLT 繼承了文本處理語言(如 Perl)的傳統(tǒng),這種傳統(tǒng)可以一直追溯到 1960 年代的語言,如 SNOBOLXSLT 樣式表包括一組模板規(guī)則,每條規(guī)則都使用以下方式:如果在輸入中遇到此條件,則生成下列輸出。規(guī)則的順序是無關(guān)緊要的,當(dāng)有幾條規(guī)則匹配同一個輸入時,將應(yīng)用沖突解決算法。然而,XSLT 與串行文本處理語言的不同之處是 XSLT 對輸入并非逐行進行處理。實際上,XSLT 將輸入 XML 文檔視為樹狀結(jié)構(gòu),每條模板規(guī)則都適用于樹中的一個節(jié)點。模板規(guī)則本身可以決定下一步處理哪些節(jié)點,因此不必按輸入文檔的原始順序來掃描輸入。

          XSLT 處理器的操作
          XSLT 處理器使用樹狀結(jié)構(gòu)作為其輸入,并生成另一個樹狀結(jié)構(gòu)作為輸出。

          常常通過對 XML 文檔進行語法分析來生成輸入樹狀結(jié)構(gòu),而輸出樹狀結(jié)構(gòu)通常被串行化到另一個 XML 文檔中。但 XSLT 處理器本身操作的是樹狀結(jié)構(gòu),而不是 XML 字符流。這個概念最初給許多用戶的感覺是不切實際的,結(jié)果卻對理解如何執(zhí)行更復(fù)雜的轉(zhuǎn)換起了關(guān)鍵作用。首先,它表示 XSLT 處理器可以理解源文檔中與樹狀結(jié)構(gòu)無關(guān)的特殊之處。例如,無論屬性是包括在單引號中還是在雙引號中,都不可能應(yīng)用不同的處理,因為會將這兩種形式視為同一個基本文檔的不同表示方法。更深入地看,它表示處理輸入元素或生成輸出元素是一個原子操作。不可能將處理元素的開始標(biāo)記和結(jié)束標(biāo)記分成單獨的操作,因為一個元素會自動表示成樹模型的單節(jié)點。

          XSLT 使用叫作 XPath 的子語言來引用輸入樹中的節(jié)點。XPath 本質(zhì)上是與具有層次結(jié)構(gòu)的 XML 數(shù)據(jù)模型相匹配的查詢語言。它可以通過按任何方向瀏覽樹來選擇節(jié)點,并根據(jù)節(jié)點的值和位置應(yīng)用謂詞。它還包括用于基本字符串處理、數(shù)字計算和布爾代數(shù)的工具。例如,XPath 表達(dá)式 ../@title 選擇當(dāng)前節(jié)點的父代元素的標(biāo)題屬性。XPath 表達(dá)式用于選擇要進行處理的輸入節(jié)點、在條件處理期間測試條件,以及計算值以便插入結(jié)果樹中。模板規(guī)則中還使用了 XPath 表達(dá)式的簡化形式模式來定義特定模板規(guī)則適用于哪些節(jié)點。XPath 在單獨的 W3C 推薦書中定義,它允許使用在其它上下文中再使用的查詢語言,特別是用于定義擴展超鏈接的 XPointer

          XSLT 以傳統(tǒng)語言(如 LispHaskell Scheme)中的功能性編程的概念為基礎(chǔ)。樣式表由模板組成,這些模板基本上是單一功能 -- 每個模板將輸出樹的一部分定義成一部分輸入樹的功能,并且不產(chǎn)生副作用。使用無副作用的規(guī)則受到嚴(yán)格控制(除了轉(zhuǎn)義成用類似 Java 的語言編寫的外部代碼)。XSLT 語言允許定義變量,但不允許現(xiàn)有變量更改它的值 -- 即沒有賦值語句。這個策略使許多新用戶感到困惑,其目的是為了允許逐步應(yīng)用樣式表。其原理是如果語言沒有副作用,那么對輸入文檔做很小的改動時,不必從頭執(zhí)行整個轉(zhuǎn)換就應(yīng)該可以計算出對輸出文檔的最后更改。目前必須說這只是理論上的可能,任何現(xiàn)有 XSLT 處理器還不能實現(xiàn)。(注:雖然 XSLT 以功能性編程概念為基礎(chǔ),但它還不是一個完整的功能性編程語言,因為它缺少將函數(shù)當(dāng)作一級數(shù)據(jù)類型進行處理的能力。)

          示例樣式表
          在這個階段,使用示例會使語言變得更清楚。清單 2 顯示了列出足球賽結(jié)果的簡單樣式表。

          清單 2. 足球賽結(jié)果的基本樣式表

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

          <xsl:template match="results">
          <html>
          <head><title>
          Results of Group <xsl:value-of select="@group">
          </title></head>
          <body><h1>
          Results of Group <xsl:value-of select="@group">
          </h1>
          <xsl:apply-templates>
          </body></html>
          </xsl:template>

          <xsl:template match="match">
          <h2>
          <xsl:value-of select="team[1]"> versus <xsl:value-of select="team[2]">
          </h2>
          <p>Played on <xsl:value-of select="date"></p>
          <p>Result:
          <xsl:value-of select="team[1] ">
          <xsl:value-of select="team[1]/@score">,
          <xsl:value-of select="team[2] ">
          <xsl:value-of select="team[2]/@score">
          </p>
          </xsl:template>

          </xsl:transform>





          這個樣式表包括兩個模板規(guī)則,一個匹配 <results> 元素,另一個匹配 <match> 元素。<results> 元素的模板規(guī)則輸出頁面的標(biāo)題,然后調(diào)用 <xsl:apply-templates>,這是一個 XSLT 指令,它將處理當(dāng)前元素的所有子代,對于每個子代都使用其適當(dāng)?shù)哪0逡?guī)則。在本例中,<results> 元素的所有子代都是 <match> 元素,所以會用第二個模板規(guī)則來處理它們。規(guī)則輸出了一個標(biāo)識比賽的次級 HTML 標(biāo)題(以 "Brazil versus Scotland" 的形式),然后生成 HTML 段落,給出了比賽的日期和兩隊的比分。

          該轉(zhuǎn)換的結(jié)果就是一個 HTML 文檔。

          這是一種非常簡單的表示信息的方法。然而,XSLT 的功能比這要強大得多。清單 3 包含了另一個可以操作相同源數(shù)據(jù)的樣式表。這次,樣式表計算一個比賽名次表,用來顯示錦標(biāo)賽結(jié)束時各隊的名次。

          清單3. 計算球隊名次表的樣式表
          <xsl:transform
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          version="1.0">


          <xsl:variable name="teams" select="http://team[not(.=preceding::team)]">
          <xsl:variable name="matches" select="http://match">

          <xsl:template match="results">

          <html><body>
          <h1>Results of Group <xsl:value-of select="@group"></h1>

          <table cellpadding="5">
          <tr>
          <td>Team</td>
          <td>Played</td>
          <td>Won</td>
          <td>Drawn</td>
          <td>Lost</td>
          <td>For</td>
          <td>Against</td>
          </tr>
          <xsl:for-each select="$teams">
          <xsl:variable name="this" select=".">
          <xsl:variable name="played" select="count($matches[team=$this])">

          <xsl:variable name="won"
          select="count($matches[team[.=$this]/@score > team[.!=$this]/@score])">
          <xsl:variable name="lost"
          select="count($matches[team[.=$this]/@score < team[.!=$this]/@score])">
          <xsl:variable name="drawn"
          select="count($matches[team[.=$this]/@score = team[.!=$this]/@score])">
          <xsl:variable name="for"
          select="sum($matches/team[.=current()]/@score)">
          <xsl:variable name="against"
          select="sum($matches[team=current()]/team/@score) - $for">

          <tr>
          <td><xsl:value-of select="."></td>
          <td><xsl:value-of select="$played"></td>
          <td><xsl:value-of select="$won"></td>
          <td><xsl:value-of select="$drawn"></td>
          <td><xsl:value-of select="$lost"></td>
          <td><xsl:value-of select="$for"></td>
          <td><xsl:value-of select="$against"></td>
          </tr>
          </xsl:for-each>
          </table>
          </body></html>
          </xsl:template>

          </xsl:transform>





          這里沒有足夠的篇幅來完整地說明這個樣式表,簡而言之,它為球隊聲明了一個變量,變量值是一個節(jié)點集合,其中每個參賽球隊都有一個實例。然后它計算每支球隊的盛、平或負(fù)的比賽場次總數(shù),以及球隊進球或失球的總數(shù)。

          這個示例的目的是說明 XSLT 不單單能夠?qū)υ次臋n中出現(xiàn)的文本指定字體和布局。它是一個完整的編程語言,能夠以任何方式轉(zhuǎn)換源數(shù)據(jù)以供顯示,或者輸入另一個應(yīng)用程序。

          XSLT 的優(yōu)點
          您為什么考慮使用 XSLT

          XSLT 給了您傳統(tǒng)高級聲明編程語言的所有好處,特別是對于轉(zhuǎn)換 XML 文檔的任務(wù)。

          高級語言帶來的實際好處是開發(fā)生產(chǎn)力。但實際上,真正的價值源自于更改的潛力。與使用低級 DOM SAX 接口編碼的過程性應(yīng)用程序相比,用于轉(zhuǎn)換 XML 數(shù)據(jù)結(jié)構(gòu)的 XSLT 應(yīng)用程序更能適應(yīng)對 XML 文檔細(xì)節(jié)的更改。在數(shù)據(jù)庫世界中,這種特性叫做數(shù)據(jù)獨立性,正是由于數(shù)據(jù)獨立性導(dǎo)致了諸如 SQL 之類聲明性語言的成功,并使舊的引導(dǎo)性數(shù)據(jù)訪問語言走向衰亡。我堅信在 XML 世界中也會這樣。

          當(dāng)然與所有聲明性語言一樣,XSLT 也會降低性能。但是對于大多數(shù)應(yīng)用程序,今天的 XSLT 處理器的性能已經(jīng)完全能夠滿足應(yīng)用程序的需要,并且它會變得越來越好。


          posted on 2008-09-24 09:48 bobby 閱讀(226) 評論(0)  編輯  收藏 所屬分類: XSLT

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
          相關(guān)文章:
           
          主站蜘蛛池模板: 廊坊市| 武陟县| 平塘县| 闸北区| 忻州市| 曲周县| 化州市| 新巴尔虎右旗| 四川省| 四会市| 鹤庆县| 蓝山县| 连江县| 大同市| 新营市| 巫溪县| 樟树市| 报价| 区。| 宁南县| 常州市| 布拖县| 永丰县| 临潭县| 阿坝县| 巨鹿县| 洪江市| 仲巴县| 凤阳县| 宁陕县| 牙克石市| 博白县| 鄂托克旗| 临安市| 荔波县| 昭觉县| 桐梓县| 常宁市| 当雄县| 大渡口区| 芦山县|