[摘錄]:http://www.javafan.net/article/20051229115558915.html
概述
Java Server Pages (JSP) 標準標記庫 (JSTL)的版本的發布對于JSP/servlet開發者來說是一個重大的進展。有了一個表達語言(EL)和一組四種強大的、易于學習的標準標記庫,JSTL極有可能不久后成為實現動態的、基于Java的站點的主要方法。
1996年對JSP servlet的介紹使得Java成為動態網頁開發的合理的選擇。隨后出現的Java服務器頁(JSP)是走向快速的、可維護的Java網頁實現過程的合理進化的一步,緊接著就出現了JSP標記的支持。但是2002中期的JSTL(JSP標準標記庫)的發布才是進一步加速和簡化開發過程最大的一步。
在本文中,我解釋了JSTL的功能,也涵蓋了你啟動JSTL所需的每件事情。假設你有了對Java、JSP、XML和安裝一個Web容器的基本理解。如果你對這些主題感到陌生,你可以在Resources(http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources)上瀏覽一下背景參考。在下面的闡述中,假定你有XML和SQL的知識。
安裝JSTL支持
對于我們的JSTL安裝例子來說,我們使用Tomcat 4.1(盡管任意支持Servlet 2.3和JSP1.2說明的servlet容器都應該能工作)。首先,下載Tomcat 4.1并且按指示進行安裝(注意:JSTL需要一個JSP1.2 Web容器)。
用tomcat4 start程序啟動Tomcat,并且運行index.html頁來確保Tomcat是激活的、且運行良好。
接下來,安裝JSTL支持,你可以從Jakarta站點下載JSTL支持,(http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources)并按照下面步驟:
1.從Jakarta站點下載JSTL檢索、解壓/脫檔該文件。(http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resources)
2.復制你已經解壓為common/lib的jar文件到你的Tomcat安裝路徑中(盡管我們的項目不需要所有的jar文件);這使得JSTL文件適用于你的任意Web應用。
3.對于任意你想使用JSTL的Web應用來說,復制.tld文件到你的Web應用的WEB-INF目錄下。
4.對于你的JSTL的Web應用,編輯web.xml并添加下列輸入:
<taglib>
<taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>
<taglib-location>/WEB-INF/fmt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/sql</taglib-uri>
<taglib-location>/WEB-INF/sql.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/x</taglib-uri>
<taglib-location>/WEB-INF/x.tld</taglib-location>
</taglib> |
這些輸入讓你的Web應用可使用JSTL標記庫的表達語言(EL)版本。這些輸入的位置有關系!如果你不肯定將他們輸入到何處,關于web.xml選項和順序的權威性指導在文檔類型定義(DTD)中定義過:
http://java.sun.com/j2ee/dtds/web-app_2_2.dtd。
5.當你創建了一個使用JSTL的JSP頁時,將他輸入到你的Web應用的主目錄下,就像其它JSP和HTML頁一樣。你可以為該頁任意取名,但是它必須有一個.jsp的擴展名。
基礎原理 首先,所有的JSTL也是JSP頁,JSTL只是JSP功能的一個超集。
同樣,所有的JSTL標記是有效的XML。這意味著:如果你將JSTL標記之外的內容當作臨時文本(通常是HTML)時,剩下的JSTL標記必須當作合法的XML來解釋。這里有一些隱含的規則,它要求大部分XML語法都是正確的。
JSTL提供一組四個標準標記庫(core核心、internationalization/format國際標準化/格式、XML和SQL)并支持EL。JSTL和EL的基本設計目的是簡化網頁開發和實現。
在本文中,我們遵循JSTL說明書的命名規則,并且把JSTL標記當作動作。一個JSTL標記對應于某個動作;調用動作明確的提醒我們:他們添加動態行為到一個另外的靜態頁上。
JSTL標記庫有兩個版本:一個用你以前使用的方法將JSP表達式插入,如<%= . . . %>,另一個使用一個JSTL EL.我會在后面進一步討論在JSTL中的EL支持。
EL支持 要理解當前JSTL對EL支持的狀態,讓我們檢查相關的說明書是怎樣處理的。Java說明書請求(JSR)專家組成員決定:由于某種原因,EL規范說明應該是JSP說明書的一部份,而不是JSTL說明書的一部分。EL完整的說明書成為JSP2.0的一部分。因為JSTL1.0在JSP1.3之前已經完成,JSTL作者不得不對用于JSTL1.0的EL支持實現做一個合理的猜測(結果可能是相當好的)。一個JSTL維護版本將與JSP1.3說明書保持一致,并為了使EL適合JSP1.3說明書,JSTL維護版本做了一些修正。
本文描述的EL概要可能在即將發布的JSTL版本中有一點改動,但是任何改動都是微小的。
EL用于簡單的語法定義了一套功能強大的語言,它很容易學習。它融合著JavaScript語言和Perl語言較好的部分的一些風格。EL表達式,集成了來自四種標準標記庫的JSTL標記,提供了一個巨大的、靈活的屬性集。
所有的EL表達式都被${}括起來。JSTL中的表達式總是JSTL標記中的屬性值的一部分。表達式可以是屬性的一部分或者合并和嵌入到一個字符串直接量中。JSTL屬性也可以包含簡單的字符串直接量。在接下來的JSTL中,我們在一個來自核心庫的c:out動作中說明每種情況,這個核心庫將它的value屬性值送到JSP輸出上:
<c:out value="${anExpression}"/>
<c:out value="literalText${anExpression}${anotherExpression}"/>
<c:out value="literalText"/> |
EL也定義了一套規則用于強制表達式中的值轉換為上下文相對應的類型。我們在這里不詳細討論這些規則;然而,它的方法與用Perl語言定義的方式非常相似(就像Perl語言中的做法一樣,該方法理所當然的運行良好,但是,偶爾,也會出現可能不是你十分想要的那種結果,但你可以接受)。
EL為訪問對象屬性、集合元素、一組隱藏對象以及使用相關的、邏輯的和算術的操作符提供了支持。對于索引的屬性來說,包括數組和java.util.List類在內,元素可用下列語法訪問:
${alist[4]}
${aList[someVariable]} |
JavaBean屬性和java.util.Map元素(它代表一系列名字/值對)都可以使用下列方法的一個訪問得到。在以下的開頭兩個表達式里,我們可以訪問到一個用JavaBean語言命名為aProperty的屬性或者用關鍵字aProperty訪問到一個Map實體。在第三個表達式中(注意:我已經省略了引號),我們用保存在變量aVariableContainingPropertyName中的一個名字訪問了在anObject之內的一個元素:
${anObject.aProperty}
${anObject["aPropertyName"]}
${anObject[aVariableContainingPropertyName]} |
在EL中定義了許多隱藏變量:
● pageContext:用于該網頁的pageContext對象
● pageScope, requestScope, sessionScope, 和 applicationScope:這些是映射這些范圍的每一個變量到值上的Map集。
● param 和 paramValues:用頁訪問傳遞的參數,與在JSP中一樣
● header 和 headerValues:用頁請求傳遞的頭,與在JSP中一樣
● cookie:Map映射cookie程序到特定的cookie對象上
EL定義了全套與你在Java中非常熟悉的那些完全對應的操作符。算法操作符包括+、 -、 *、 / (或 div)、 和% (或 mod)。相關的操作符包括==、!=、<、>、<=、>=,它分別對應于eq、ne、lt、gt、le、和ge。我不想詳細闡述這些操作符,因為他們都能自我說明。
JSTL標記庫
至此,我已經解釋了一些基本原理并且涵蓋了EL語法。我要專門討論四種JSTL標記庫。我主要討論核心庫,因為它是你一定要使用的;但是,我也會詳細的討論其余幾個,以便你能啟動它。
首先,盡管我應該更多地談論JSTL標記庫的兩種風格,我上面提到的每個JSTL標記庫以兩個版本出現:一個支持使用EL的表達式;另一個支持標準JSP表達式。當你引入任何標記庫到一個JSP頁時,你要定義一個前綴,該前綴指定了與庫中標記相對應的命名空間。
四種標準標記庫,和他們的JSTL規范定義的前綴常規,列表如下。記住:你可以定義自己的前綴,但是這絕對沒有什么好處。
四種標準標記庫
為了使用頁中的核心標記庫( 實際上,你使你的頁對標記庫的命名空間可見),在你的頁首包含下列例子中的指令:
<%@ taglib prefix="c" uri=http://java.sun.com/jstl/core %> |
為了使用該標記庫的標記,用你在你的包含語句中設計好的前綴,在你的頁中給每個標記加上前綴:
<c:out value="${anExpression}"/> |
核心數據庫 讓我們更詳細的測試核心數據庫,先看看他最通用的功能。
顯示/設定值和異常處理 核心庫的最基本的標記是c:out標記,它在頁中顯示一個EL表達式的值。一個使用c:out的表達式通常是這樣:
We have <c:out value="${applicationScope.product.inventoryCount}"
escapeXml="true" default="0" /> of those items in stock. |
上例中,value屬性是我們送到頁輸出的表達式。我也說明了選項escapeXml的屬性和默認屬性。escapeXml的屬性指定了XML字符(<、>、 &、 和 .)是否應該轉化為相應的字符實體代碼(這樣他們可以讓這些字符出現在一個HTML頁中);默認屬性用于EL不能估算出數值或者數值計算出來為空的情況。
注意:當EL支持完全貫穿整個JSP2.0的時候,你不需要使用c:out動作;你可以僅嵌套JSP表達式直接在頁中。
另一個普遍使用的核心動作是c:set,它在頁中設定一個變量。你可以用兩種方法使用c:set動作,第一種方法設定在var屬性中定義的變量到在value屬性中定義的值上,方法如下:
<c:set var="customerID" value="$param:customerNumber" scope="session" /> |
上述的選擇項scope屬性指定了我們要在會話期范圍內設定變量customerID;如果范圍沒有制定,范圍默認為頁。
c:set另一個強大的用途就是將c:set標記的體的內容賦給一個指定的變量:
<c:set var="cellContents">
<td>
<c:out value="${myCell}"/>
</td>
</c:set> |
在上例中,c:set動作定義了名為cellContents(在頁的范圍內)的變量,該變量擁有在標記的體中定義的內容。在這種情況下,體定義了一個HTML表格單元格元素,計算體中的c:out動作,并且該計算的結果包括在體中的字符串直接量值。
就像你預想的那樣,JSTL進行異常處理有點早。在典型的JSP頁中,你有兩種異常處理的方法:試圖/捕捉直接嵌入到頁中的小腳本代碼中的塊;或者用一個JSP errorPage指令。JSP errorPage指令提供一個良好的捕捉所有異常的方法來處理頁中任何可能的異常。JSTL用一個c:catch動作提供一個好的可選擇的方式。這個c:catch動作提供一個更細粒度的有效方法來處理異常。而且沒有嵌入Java代碼到頁中。一個c:catch動作是這樣的:
<c:catch>
<!--. . . some set of nested JSTL tags below which would be hit on an exception-->
</c:catch> |
c:catch動作有一個可選的屬性,即一個指向拋出異常的變量。
你可能不怎么愿意使用c:remove標記。這個標記有用于變量名和范圍的屬性,并且可從指定的范圍內刪除指定的變量。
流程控制
讓我們轉為討論JSTL的流程控制和條件標記。如果你已經用任何一種語言使用了條件和流程控制語句,理論上這里沒什么新鮮的東西。
c:if動作處理簡單條件語句的測試。計算測試屬性中的Boolean表達式的值,如果表達式為真的話,計算體的內容。在下面的動作中,我們也說明了備選項var屬性。為了以后的使用,var屬性保存測試結果在頁(如果沒有指定其他scope屬性的話)中。
<c:if test="${status.totalVisits == 1000000}" var="visits">
You are the millionth visitor to our site! Congratulations!
</c:if> |
下面我們展示了用c:choose、 c:when、 和 c:otherwise交換邏輯的JSTL的支持。一組c:when動作可能包括在一個備選的標記內,如果在c:when塊中任何表達式計算值為真的話,就不用計算c:choose動作內的測試。如果c:when塊中沒有一個測試計算值為真的時候:如果出現c:otherwise動作內容時,則計算c:otherwise動作的內容:
<c:choose>
<c:when test="${item.type == 'book'}">
...
</c:when>
<c:when test="${item.type == 'electronics'}">
...
</c:when>
<c:when test="${item.type == 'toy'}">
...
</c:when>
<c:otherwise>
...
</c:otherwise>
</c:choose> |
c:foreach動作提供一個容易的方法來迭代一個集合的元素。如果你想只迭代集合的一部分的話,你可以分別用begin、 end、 和 step屬性指定起點、終點和一個遞增值。在下面的例子中,我們在變量customerNames中迭代一個集合的內容;在每個循環中,下一個元素輸入到變量名內并在c:foreach動作的體內計算:
<table>
<c:forEach var="name" items="${customerNames}">
<tr><td><c:out value="${name}"/></td></tr>
</c:forEach>
</table> |
記得Java的StringTokenizer類嗎?有了c:forTokens動作,你可以用JSTL獲得類似的功能。這個程序片斷可使用在delims屬性中定義的定界符通過items String屬性中的條目迭代。注意,items 屬性不必是一個字符直接量;它可以是任何有效的EL表達式:
<table>
<c:forTokens items="47,52,53,55,46,22,16,2" delim="," var="dailyPrice">
<tr><td><c:out value="${dailyPrice}"/></td></tr>
</c:forTokens>
</table> |
在接下來的完整的JSTL頁中,我列出了已經傳遞到該頁的所有參數。param 和paramValues對象是映射關鍵字到一個或多個值的Java Map集。在本例中,我們找出了用于集合的每個MapEntry的關鍵字即參數名,并且使用關鍵字來查找所有與關鍵字關聯的參數值:
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<body>
<head>
<title>Parameter Listing Example</title>
</head>
<br>
<b>Parameter values passed to this page for each parameter: </b>
<table border="2">
<c:forEach var="current" items="${param}">
<tr>
<td>
<b><c:out value="${current.key}" /></b>
</td>
<c:forEach var="aVal" items="${paramValues[current.key]}">
<td>
<c:out value="${aVal}" />
</td>
</c:forEach>
</tr>
</c:forEach>
</table>
</body>
</html> |
其他動作
我們也需要討論一些其他重要的核心標記庫動作。在網頁實現中一個潛在的問題范圍與URL編碼有關。沒有URL編碼,在網頁中傳遞的URL的某個字符如空格,可能會迷惑Web服務器。URL編碼確保這些特殊的字符用不引起迷惑的字符代替。下列例子在變量myUrl中定義了一個URL,該變量myUrl由一個URL和一系列參數組成。URL動作(注意,這里只在JSTL意義上的動作)保證所有字符都正確的編碼:
<c:url value="http://acme.com/exec/register" var="myUrl">
<c:param name="name" value="${param.name}"/>
<c:param name="country" value="${param.country}"/>
</c:url>
<a href='<c:out value="${myUrl}"/>'>Register</a> |
在上面的代碼中,param動作簡單的定義了一組名值對。
JSP允許設計者用 <JSP:INCLUDE></JSP:INCLUDE>
<JSP:INCLUDE>指令包括其他頁的內容。JSTL用JSTL c:import動作擴展了這個概念。c:import的主要優勢是:你能指定一個任意的URL;也可以包含你的Web應用之外(W3C的任何地方)的頁的內容或者你的服務器上的另一個Web應用內的頁的內容。
對于一組與HTTP相關的標記來說,沒有一個方法處理HTTP重定向是不完整的。JSTL用c:redirect動作支持它。
國際化標記庫
在討論了JSTL支持國際化中,我假設你已經有了對下列主題的合理的理解:
●資源包和Java如何找到它們
●Locale類
●資源包查找和MessageFormat類
●局部編碼以及它與Java國際化的關系
●Java文本和數據格式化
如果你需要這些主題的更多的信息,請閱讀Resources (http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl-p4.html#resources#resources)上的參考部分與國際化有關的參考文章。
我在下面的兩個部分討論了國際化標記庫。在第一部分,我包括了你可能使用的格式化和解釋相關的動作(它最初對應于java.text封裝包中的類),盡管你沒有開發過完全的國際化應用程序,可能你也要用到它。在第二部分,我說明了更針對于國際化的動作。
如果存在一個遠程的可能性,你的應用程序會在你本國之外使用。如果你從一開始就建立在國際化的支持上,那么開發就會更加容易。無論你使用何種方法來開發,即使像JSTL一樣容易使用的方法,一開始建立在國際化支持上也是十分有益的。
格式標記庫:格式動作
如果你已經使用了Java的 DateFormat 和NumberFormat類,在下面的標記中使用的方法應該看起來眼熟,因為JSTL格式化動作是在這些類之上建立的。這些Java類普遍提供一個format( )函數,它將一個Java類型轉化為一個格式化的String和創建對應于該String的Java對象。
fmt:formatNumber動作有一個value屬性和一個pattern屬性。value屬性是一個與我們看到的其它value屬性類似的EL表達式或者變量。pattern屬性與在NumberFormat類中定義的模式一樣。下列動作發送一個格式化的String到JSP頁的輸出上:
<fmt:formatNumber value="1000.001" pattern="#,#00.0#"/> |
在這個fmt:formatNumber動作里,我們使用了type屬性來指定:格式化我們需要格式化的值為一個貨幣值。我們保存格式化的結果在一個變量名為dollars中。在一個美國的locale類中,下面的程序生成一個字符串$3456.79(注意,它將使用的貨幣值四舍五入了):
<fmt:formatNumber value="3456.789" type="currency" var="dollars"/> |
用于上面的type屬性的可能值包括currency、 number、 和percent。
在例中,我們使用了另一種方法——使用了一個包括在value屬性中的一個格式化的域(currency,每type屬性)的一個文本字符串。并且解析它來獲取一個數字。結果儲存在由var屬性指定的一個變量內。盡管這個屬性是可選的,還是會經常使用它。另外,解析的值送到頁輸出上:
<fmt:parseNumber value="${currencyInput}" type="currency"
var="parsedNumber"/>
fmt:formatDate動作有一個value屬性、一個format屬性、
一個指向處理格式化的格式類的屬性(典型的,如java.util.Date):
<jsp:useBean id="now" class="java.util.Date" />
<fmt:formatDate value="${now}" timeStyle="long"
dateStyle="long"/> |
像數字格式化一樣,JSTL頁提供一個機制來解析一個代表日期的、進入Date對象的字符串:
<fmt:parseDate value="${dateInput}" pattern="MM dd, YYYY" /> |
查看java.util.DateFormat類,了解如何處理格式化和模式的更多詳細的資料。
格式標記庫:國際化動作 Java本地化的一個關鍵點是ResourceBundle類。JSTL動作允許你用這個類簡單的工作。這個例子使用了fmt:bundle動作來得到與當前Locale 和 fmt:message動作對應的一個ResourceBundle動作,從而查看該資源包中的本地化的字符串:
<fmt:bundle basename="myBundle">
<%-- Use values in myBundle --%>
<fmt:message key="Introduction">
<fmt:param value="${loginName}"/>
<fmt:param value="${loginCount}"/>
</fmt:message>
<fmt:formatDate value="${now}" var="parsedDate"/>
</fmt:bundle> |
經常,fmt:message動作簡單的查看了對應于一個關鍵詞的字符串。在上面的例子中,在ResourceBundle中的字符串包含了取代兩個值的占位符。這些值在fmt:param動作中定義過,這就像Java MessageFormat類使用的方法。
有一些類似的動作可指定一個時區,時區可應用到在標記的體中計算的任何事上:
<fmt:timeZone value="someTimeZone">
<!-- actions in this context will be evaluated using someTimeZone -->
</fmt:timeZone> |
上述的fmt:bundle 和 fmt:timeZone動作有分別對應的fmt:setBundle和fmt:setTimeZone的動作。這些動作添加了可選的scope屬性;因此,你可以使用這些動作在任何等同于應用范圍的范圍內設定一個資源捆綁或者一個時區。
如果你用非歐洲的locale類工作的話,你可能得擔心編碼的問題,JSTL支持用fmt:requestEncoding動作編碼。
SQL標記庫 JSTL 允許容易的數據庫的集成。但是,值得注意的是:沙箱之外的JSTL的執行有一些限制。主要的問題與連接池有關。建立并維護到數據庫的連接是很消耗資源的。JSTL SQL動作使得許多數據庫連接建立起來,通常的,每個用戶至少有一個。因此,JSTL SQL標記對于原型開發的或低容量的、基于Web的應用程序意義重大。但是它不適合于大規模的應用程序。一個可縮放的產品應用程序一般是在一個頁面內處理數據庫訪問如隱藏數據庫訪問和處理像連接池之類的細節。但是,還是有方法允許你實現連接池和用一點自定義碼來使用JSTL SQL動作(請看:"JSTL 1.0: What JSP Applications Need, Part 2" in Resources :http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl-p5.html#resources#resources).
我們看一些簡單的例子。這些例子使用來自SQL庫的JSTL標記。如果你熟悉SQL基礎的話,你應該能夠改編這些例子用在你的應用程序上。
在下面的程序片斷中,我們建立了一條到一個數據庫的連接,選擇一組匹配一個訂單ID的訂單項目,并且在一個表格中顯示item屬性:
<sql:setDataSource
driver="com.cheapDrivers.jdbcDriver"
url="jdbc:cheapDrivers:."
user="guest"
password="password"
var="dataSource" />
<sql:query var="orderItems" dataSource="${dataSource}">
SELECT * FROM items
WHERE order_id = <cout value="${orderID}"/>
ORDER BY price
</sql:query>
<table>
<c:forEach var="row" items="${orderItems.rows}">
<tr>
<td><c:out value="${row.itemName}"/></td>
<td><c:out value="${row.price}"/></td>
<td><c:out value="${row.weight}"/></td>
</tr>
</c:forEach>
</table> |
在下一個例子中,我會說明JSTL是如何支持數據庫事務的,在數據庫中,許多包含對表格多個改動的操作必須是對所有的,或者什么也不做:如果出現一個問題時,改動必須為空操作。在下面例子中,sql:update動作包含在一個sql:transaction動作內,如果在事務處理過程中,存在任何SQL錯誤的話,在事務范圍內執行的所有操作都得重來。
sql:update動作的命名有一點誤導:除了SQL UPDATE外,sql:update也支持INSERT 和 DELETE,甚至是SQL CREATE。實際上,它支持不產生結果的任何一條SQL操作。在下面的例子中,sql:update通過插入變量值到一個PreparedStatement中來執行一個UPDATE動作。在這個代碼片斷中,我們在兩個賬戶之間傳送錢(需要預先包裝在一個事務中的某些東西的一個經典的例子):
<sql:transaction dataSource="${dataSource}">
<sql:update>
UPDATE account
SET account_balance =account_balance -?
WHERE accountNo = ?
<sql:param value="${transferAmount}"/>
<sql:param value="${sourceAccount}"/>
</sql:update>
<sql:update>
UPDATE account
SET account_balance =account_balance +?
WHERE accountNo = ?
<sql:param value="${transferAmount}"/>
<sql:param value="${destAccount}"/>
</sql:update>
</sql:transaction> |
XML標記庫 使用標準的XML標記庫,你所能做的完整的處理,特別是可擴展性單一語言變換說明(XSLT)的處理,對于另一篇文章來說是一個很好的主題。下面我會涵蓋足夠的讓你開始的知識。
在JSTL的XML支持遵循XPath規范。XPath的重要功能之一是為訪問XML著名的分層的信息提供一個清晰的語法。也許看到每件是如何工作的最容易的方法就是看看我們如何使用來自于一個真實JSTL頁的一個片斷里的標記:
!-- Find and parse our XML document (somewhere on the WWW) -->
<c:import url="http://www.cheapstuff.com/orderStatus?id=2435" var="xml"/>
<x:parse xml="${xml}" var="doc"/>
<!-- access XML data via XPath expressions -->
<x:out select="$doc/name"/>
<x:out select="$doc/shippingAddress"/>
<x:out select="$doc/deliveryDate"/>
<!-- Set a scoped variable -->
<x:set var="custName" scope="request" select="$doc/name"/> |
在上面的輸入和解析動作中,我們裝載和解析了一個指定的XML文檔到一個變量doc里。在上面的每個x:out動作中,我們使用了一個XPath表達式訪問了解析的XML文檔的元素,并且發送結果到JSP頁輸出中。
上面的設置表達式計算了一個XPath表達式并且將結果輸入到一個限定范圍的變量里(在上述例子中,它指在一個請求范圍內)。
x:out 和x:set動作可以輸出一個JspTagException。如果他們沒有成功的話(極有可能因為XPath表達式指向并不存在的標記),你的頁,像在所有其他情況下一樣,應該智能的處理這些異常(要么通過傳統的JSP errorPage指令,要么使用JSTL的c:catch動作),
JSTL容易處理XSLT轉換。在下面的示范頁中,我們使用來自XML標記庫中的x:transform動作,用一個XSLT stylesheet創建一個來自于XML源文檔的一個格式化的頁。x:transform動作最重要的屬性是XML和XSLT屬性,在下面的例子中,我們設置了一個來自于我們在同一頁初始化的變量的xslt屬性;我們也在動作的體中設置了XML屬性。該動作默認為x:transform動作。
默認的,轉換的結果送到頁輸出上;你也可以保存結果到一個帶x:var屬性的變量內:
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/xml" prefix="x" %>
<c:set var="xsltSource">
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="music">
<html>
<head></head>
<body marginheight="0" marginwidth="0" topmargin="0" leftmargin="0">
<table cellpadding="0" cellspacing="0" border="1" bgcolor="#ffffff">
<tr>
<td><STRONG>Artist</STRONG></td>
<td><STRONG>Album</STRONG></td>
<td><STRONG>Year</STRONG></td>
<td><STRONG>Genre</STRONG></td>
</tr>
<!---Set up for loop to collect all the artist information //-->
<!-- <xsl:for-each select="./*[name()='artists']"> -->
<xsl:for-each select="artists">
<tr>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="album"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="genre"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
</c:set>
<x:transform xslt="${xsltSource}" >
<music>
<artists>
<artist>Jonny B</artist>
<album>Feedback and Distortion</album>
<year>2001</year>
<genre>Rock</genre>
</artists>
<artists>
<artist>Harmony's Nieces</artist>
<album>Sappy Pop Ballads</album>
<year>2002</year>
<genre>Pop</genre>
</artists>
</music>
</x:transform> |
你也能使用c:import動作再定義一個額外的源文檔和stylesheet,就好像在這個示范的代碼片斷展示的一樣::
<c:import var="${xmlSource}" url="${someDocumentURL}" />
<c:import var="${xsltSource}" url="${anotherDocumentURL}" />
<x:transform xml="${xmlSource}" xslt="${xsltSource}" > |
結束語 至此,你應該對JSTL、它的四種標準標記庫、和它如何使網頁開發更為容易 有了很好的理解。現在你開始寫一些JSTL!
posted on 2006-01-10 12:07
kelven 閱讀(221)
評論(0) 編輯 收藏 所屬分類:
其它