<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 是什么類型的語言?::分析和概述

    級別: 初級

    Michael H. Kay

    2001 年 2 月 01 日

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

    我撰寫本文的初衷是為一篇關于 Saxon 的技術文章提供必要的背景知識,打算提供在傳統 XSLT 處理器中使用的實現技巧內幕,從而幫助用戶使其樣式表的性能達到最大化。但 developerWorks 的編輯們勸說我:這篇介紹應該吸引更廣泛的讀者,值得作為 XSLT 語言的獨立說明而單獨發表。

    什么是 XSLT?

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





    回頁首


    XSLT 的角色

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

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


    清單 1. 表示足球錦標賽結果的 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 瀏覽器顯示這些足球賽的結果,不要指望系統會產生合理的布局。需要其它一些機制來告訴系統如何在瀏覽器屏幕、電視機、WAP 電話或真正在紙張上顯示數據。這就是使用樣式表的目的。樣式表是一組說明性的規則,它定義了應如何表示源文檔中標記標識的信息元素。

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

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

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

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





    回頁首


    XSLT 作為語言

    就某些方面而言,XSLT 作為一種語言來說是非常古怪的。我不打算在本文中討論已做出的設計決策的基本原理,盡管可以通過它們在邏輯上追溯到語言設計者確定的對 XSLT 的要求。如需更完整的說明,請參閱拙作的第 1 章。

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

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

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





    回頁首


    XSLT 處理器的操作

    XSLT 處理器使用樹狀結構作為其輸入,并生成另一個樹狀結構作為輸出。圖 1 中顯示了這一點。


    圖 1. XSLT 輸入和輸出的樹狀結構
    XSLT 處理器的操作

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

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

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





    回頁首


    示例樣式表

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


    清單 2. 足球賽結果的基本樣式表
    												<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>


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

    該轉換的結果就是一個 HTML 文檔,該文檔在瀏覽器中的表示如圖 2 所示。


    圖 2. 清單 2 中樣式表的結果
    以上樣式表的結果

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


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


    這里沒有足夠的篇幅來完整地說明這個樣式表,簡而言之,它為球隊聲明了一個變量,變量值是一個節點集合,其中每個參賽球隊都有一個實例。然后它計算每支球隊的勝、平或負的比賽場次總數,以及球隊進球或失球的總數。圖 3 顯示了它在瀏覽器中的最終輸出結果。


    圖 3. 清單 3 中名次樣式表的結果
    以上樣式表的結果

    這個示例的目的是說明 XSLT 不單單能夠對源文檔中出現的文本指定字體和布局。它是一個完整的編程語言,能夠以任何方式轉換源數據以供顯示,或者輸入另一個應用程序。





    回頁首


    XSLT 的優點

    您為什么考慮使用 XSLT?

    XSLT 給了您傳統高級聲明編程語言的所有好處,特別是對于轉換 XML 文檔的任務。

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

    當然與所有聲明性語言一樣,XSLT 也會降低性能。但是對于大多數應用程序,今天的 XSLT 處理器的性能已經完全能夠滿足應用程序的需要,并且它會變得越來越好。在我的第二篇文章中,我將討論 XSLT 處理器中使用的一些優化技巧,如我自己的 Saxon 產品。





    回頁首


    結束語

    我想要在本文中展示的是 XSLT 是一種用于操作 XML 文檔的完整高級語言,就如同 SQL 是操作關系表的高級語言一樣。應該注意到 XSLT 不僅是一種樣式設計語言,它比 CSS(或者甚至 CSS2)的功能更強大。

    我見到過一些應用程序,它們的所有商務邏輯都用 XSLT 編碼。在一個三層在線銀行系統中,我看到:

    • 從后端操作系統以 XML 消息的形式檢索所有數據。
    • 在聯機會話的持續時間內,用戶的帳戶數據在內存中以 XML DOM 形式表示。
    • 所有給用戶的信息首先封裝成 XML 消息,然后用服務器或客戶機附帶的 XSLT 轉換根據瀏覽器的性能將這些消息轉換成 HTML。

    該應用程序的數據都是 XML 格式的,并且邏輯(包括數據訪問邏輯、商務邏輯和顯示邏輯)都由 XSLT 來實現。我建議每個項目都采用那種體系結構,但這還需要很長時間,我認為我們會在幾年之內見到那種系統。

    作為一種編程語言,XSLT 有許多特性 -- 從它使用 XML 語法到其功能性編程原理的基礎 -- 還不為一般 Web 程序員所熟悉。那意味著一條陡峭的學習曲線和通常遇到許多挫折。當初對于 SQL 也是如此,所有這些表示 XSLT 與以前的編程語言有著本質的區別。但不要放棄:它是功能非常強大的技術,值得努力學習。





    回頁首


    參考資料

    • 您可以參閱本文在 developerWorks 全球站點上的 英文原文.

    • 同一個作者撰寫的 Wrox 書籍 XSLT Programmer's Reference。XSLT 語言的綜合指南。

    • W3C 出版的 XSLT 1.0 Recommendation。XSLT 語言的權威性規范。

    • W3C 出版的 XPath 1.0 Recommendation 。XSLT 樣式表中使用的 XPath 表達式語法的權威性規范。

    • XSL-List ,一個有關 XSLT 所有事物的繁忙郵件列表,它附帶有可搜索檔案,由 MulberryTech 進行管理。

    • www.xslinfo.com ,一個很好的網絡中央頁面,帶有到 XSLT 資源的鏈接,內容包括軟件、書籍、教程和其它內容。




    回頁首


    關于作者

    Michael Kay 在 XML 界非常著名,他是 Saxon XSLT 處理器和 Wrox 書籍 XSLT Programmer's Reference 的作者。多年以前,他就獲得了博士學位,他的研究領域是數據庫技術。自那時起,他設計了 Codasyl 數據庫、關系數據庫、面向對象數據庫和自由文本數據庫軟件。

    在寫作時,Michael 還兼了幾份工作(并沒有休息)。他剛結束了在 ICL(一家英國 IT 服務公司)24 年的工作,并投奔 Software AG 成為體系結構小組的一員,該小組負責掌控未來 XML 產品的方向。

    作者選擇這張照片來證明他并非總是象他在 Wrox 書籍中所表現得那樣嚴肅。


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

    主站蜘蛛池模板: 亚洲日韩精品国产3区| 亚洲av无码成h人动漫无遮挡| 亚洲激情电影在线| 久久国产精品免费网站| 亚洲国产精品VA在线观看麻豆| 人体大胆做受免费视频| 亚洲国产精品成人久久蜜臀 | 亚洲欧洲自拍拍偷综合| 免费国产高清毛不卡片基地| 日本不卡在线观看免费v| 亚洲丝袜美腿视频| CAOPORN国产精品免费视频| 亚洲v国产v天堂a无码久久| 亚洲综合激情五月色一区| 久操视频免费观看| 亚洲日韩aⅴ在线视频| 国产成人无码免费看片软件 | 免费无遮挡无遮羞在线看| 女人18毛片免费观看| 色老板亚洲视频免在线观| 青青青免费国产在线视频小草| 久久久无码精品亚洲日韩按摩| 日本一卡精品视频免费| 亚洲VA中文字幕无码一二三区| 另类免费视频一区二区在线观看| 亚洲中文字幕在线观看| 精品乱子伦一区二区三区高清免费播放 | 久久99精品免费一区二区| 亚洲中文字幕成人在线| 特a级免费高清黄色片| 77777亚洲午夜久久多人| 精选影视免费在线 | 亚洲国产一区国产亚洲| 久久免费观看国产99精品| 精品无码一区二区三区亚洲桃色 | 亚洲免费无码在线| 免费观看国产精品| 亚洲国产精品ⅴa在线观看| 啦啦啦www免费视频| 亚洲av无码专区在线电影| 亚洲一区无码中文字幕|