jenkins + ant + jmeter 集成測(cè)試報(bào)告發(fā)送郵件

一、什么是接口測(cè)試?

  接口測(cè)試是測(cè)試系統(tǒng)組件間接口的一種測(cè)試。接口測(cè)試主要用于檢測(cè)外部系統(tǒng)與系統(tǒng)之間以及內(nèi)部各個(gè)子系統(tǒng)之間的交互點(diǎn)。測(cè)試的重點(diǎn)是要檢查數(shù)據(jù)的交換,傳遞和控制管理過程,以及系統(tǒng)間的相互邏輯依賴關(guān)系等。?

  接口測(cè)試適用于為其他系統(tǒng)提供服務(wù)的底層框架系統(tǒng)和中心服務(wù)系統(tǒng),主要測(cè)試這些系統(tǒng)對(duì)外部提供的接口,驗(yàn)證其正確性和穩(wěn)定性。接口測(cè)試同樣適用于一個(gè)上層系統(tǒng)中的服務(wù)層接口,越往上層,其測(cè)試的難度越大。?

  接口測(cè)試實(shí)施在多系統(tǒng)多平臺(tái)的構(gòu)架下,有著極為高效的成本收益比,接口測(cè)試天生為高復(fù)雜性的平臺(tái)帶來高效的缺陷監(jiān)測(cè)和質(zhì)量監(jiān)督能力。平臺(tái)越復(fù)雜,系統(tǒng)越龐大,接口測(cè)試的效果越明顯。

  基于接口測(cè)試的重要性,以及它比較容易自動(dòng)化的特性,通過持續(xù)集成的接口監(jiān)控能夠及時(shí)的發(fā)現(xiàn)項(xiàng)目中存在的問題,這對(duì)持續(xù)運(yùn)營(yíng)的項(xiàng)目來說,非常重要。

二、接口測(cè)試的流程

  1、 項(xiàng)目啟動(dòng)后,測(cè)試人員要盡早找到開發(fā)人員拿到接口測(cè)試文檔?

  2、 獲取接口測(cè)試文檔后,就可以進(jìn)行接口用例的編寫和調(diào)試?

  3、 接口用例編寫調(diào)試完成后,部署到持續(xù)集成的測(cè)試環(huán)境中,

  4、 設(shè)定腳本運(yùn)行頻率,告警方式等基本參數(shù),進(jìn)行接口的日常監(jiān)控?

  5、 每日進(jìn)行接口腳本的維護(hù)更新,接口異常的處理

三、jenkins + ant + jmeter 集成測(cè)試報(bào)告發(fā)送郵件

環(huán)境準(zhǔn)備

安裝Jdk

JDK是Java語言的軟件開發(fā)工具包,主要用于移動(dòng)設(shè)備、嵌入式設(shè)備上的java應(yīng)用程序。JDK是整個(gè)java開發(fā)的核心,它包含了JAVA的運(yùn)行環(huán)境(JVM+Java系統(tǒng)類庫(kù))和JAVA工具。

鼠標(biāo)右擊計(jì)算機(jī)(此電腦)->屬性->高級(jí)系統(tǒng)設(shè)置->高級(jí)->環(huán)境變量

在系統(tǒng)變量中,點(diǎn)擊新建,新建JAVA_HOME變量,變量的值:JDK的安裝目錄

在系統(tǒng)變量中找到Path變量,雙擊打開,新增兩個(gè)變量%JAVA_HOME%\bin和%JAVA_HOME%\jre\bin,點(diǎn)擊確定

在系統(tǒng)變量中新建CLASSPATH變量,變量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意前面的.),點(diǎn)擊確定,保存退出。

檢查是否配置成功,win+R輸入cmd,然后回車,在黑乎乎的窗口輸入java -version,能夠看到你安裝的jdk版本信息,即環(huán)境配置成功。

安裝Ant

ant 是Apache軟件基金會(huì)JAKARTA目錄中的一個(gè)子項(xiàng)目,它有以下的優(yōu)點(diǎn):?

1、跨平臺(tái)性:Ant是純Java語言編寫的,所以具有很好的跨平臺(tái)性。?

2、操作簡(jiǎn)單:Ant是由一個(gè)內(nèi)置任務(wù)和可選任務(wù)組成的,用ant任務(wù)就像是在dos中寫命令行一樣。Ant運(yùn)行時(shí)需要一個(gè)XML文件(構(gòu)建文件)。 Ant通過調(diào)用target樹,就可以執(zhí)行各種task。每個(gè)task實(shí)現(xiàn)了特定接口對(duì)象。

3、維護(hù)簡(jiǎn)單、可讀性好、集成簡(jiǎn)單:由于Ant構(gòu)建文件 時(shí)XML格式的文件,所以很容易維護(hù)和書寫,而且結(jié)構(gòu)很清晰。Ant可以集成到開發(fā)環(huán)境中。由于Ant的跨平臺(tái)性和操作簡(jiǎn)單的特點(diǎn),它很容易集成到一些開 發(fā)環(huán)境中去。

以下是解壓后的目錄布局。

apache-ant-1.10.8

+--- README, LICENSE, fetch.xml, 其他文本文件. //基本信息

+--- bin // 包含安裝程序腳本

|

+--- lib // 包含Ant JARs plus必要的依賴項(xiàng)

|

+--- manual // Ant文檔 (必讀 ;-)

|

+--- etc // 包含xsl工具:

? ? ? ?? // - 可以從xml輸出的各種任務(wù)中創(chuàng)建一個(gè)增強(qiáng)型的報(bào)告。

? ? ? ?? // - 遷移你的構(gòu)建文件,并擺脫 "已廢棄 "的警告

? ? ? ?? // - ... 更多 ;-)

點(diǎn)擊http://ant.apache.org/bindownload.cgi進(jìn)入ant官網(wǎng),下載對(duì)應(yīng)的安裝包。

將下載的.zip壓縮包解壓到對(duì)應(yīng)文件夾

配置環(huán)境變量

ANT_HOME? H:\Ant\apache-ant-1.10.2

path ? ? ? H:\Ant\apache-ant-1.10.2\bin

classpath ? H:\Ant\apache-ant-1.10.2\lib

驗(yàn)證是否安裝成功

依次選擇:win + R –>cmd,輸入如下命令:ant? ,出現(xiàn)如下圖,則表示安裝成功

安裝jenkins

jenkins有三種安裝方式

第一種:快速安裝選擇windows系統(tǒng)的版本

解壓成功后雙擊jenkins.msi程序

安裝成功后會(huì)顯示如下要你填寫密碼的驗(yàn)證頁面,按照它的提示信息到對(duì)應(yīng)的目錄底下找文件initialAdminPassword,然后將密碼拷貝出來? localhost:8080

第二種:快速安裝 使用命令 java -jar jenkins.war這是依賴于 java環(huán)境和 jenkins.war進(jìn)行搭建這里不多說,因?yàn)楹竺娴陌惭b順序都是和上述一致

第三種方法:

是直接將jenkins.war包安裝在tomcat的webapps目錄下,然后啟動(dòng)tomcatcat就可以了,當(dāng)然Tomcat也有兩種啟動(dòng)方式。但原理都是一樣的。只是看誰比較方便,兼容性比較強(qiáng)而已。關(guān)鍵還是看系統(tǒng) st

startup.sh?

總結(jié):三種安裝方式都使用與Windows系統(tǒng),第二種和第三種可以使用在linux系統(tǒng),但是為求不出錯(cuò),第二種才是最方便的。如果直接將jenkins.war包放到Tomcat的webapps下,那你公司的項(xiàng)目也放到這里,那就好玩了。

此處, 我們選擇第一種方式進(jìn)行安裝

配置jmeter變量

官網(wǎng)下載

解壓任意目錄即可

配置環(huán)境變量

點(diǎn)擊“新建”,建立一個(gè)變量:JMETER_HOME,值為你解壓的jmeter安裝路徑。我的安裝路徑是在C盤,這個(gè)路徑根據(jù)自己實(shí)際安裝路徑進(jìn)行填寫。然后點(diǎn)擊確定保存即可

配置classpath變量 ;

%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib/logkit-2.0.jar

在用系統(tǒng)變量path后面加上%JMETER_HOME%\bin

最后在cmd輸入jmeter 直接打開 如圖

配置jenkins

環(huán)境變量配置

全局系統(tǒng)環(huán)境變量配置JDK

全局系統(tǒng)環(huán)境變量配置Ant

全局系統(tǒng)環(huán)境變量配置Git

配置jenkins報(bào)告支持顯示HTML樣式

首先在jenkins-系統(tǒng)管理,腳本命令行輸入

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","sandbox; default-src 'self';")

保存后,不是立即生效,需要重新構(gòu)建下項(xiàng)目,html報(bào)告就有顯示了

常用插件安裝

由于我們需要顯示報(bào)告、因此需要安裝郵件和第三方報(bào)告插件 ,jenkins管理 ->Manager Plugins

Ant Plugin

Email Extension Plugin

HTML Publisher plugin

Performance Plugin

Manage Jenkins ->Manage plugins

集成jmeter用例集

新建一個(gè)自由風(fēng)格的項(xiàng)目

配置構(gòu)建觸發(fā)器

構(gòu)建執(zhí)行命令: Execute Windows batch command

3.1 此處通過命令行簡(jiǎn)單執(zhí)行 jmeter生成報(bào)告

rd /s/q D:\auto\jtl

rd /s/q D:\auto\report

mkdir jtl

mkdir report

jmeter -n -t? D:\auto\testcase.jmx? -l D:\auto\jtl\result_.jtl -e -o D:\auto\report

exit 0

3.2 再次新建Invoke Ant ,通過ant build文件構(gòu)建生成日志

構(gòu)建后操作:

完整顯示結(jié)構(gòu)如下:

Publish HTML reports : 此處展示 簡(jiǎn)單報(bào)告

結(jié)果如下顯示:

Publish performance test result report 此處展示性能報(bào)告

結(jié)果如下:

集成郵件配置

全局系統(tǒng)配置郵件config system

(1)全局系統(tǒng)管理配置

? (2)全局郵件服務(wù)器設(shè)置


擴(kuò)展郵件配置郵件Extended E-mail Notification


回到項(xiàng)目配置: 添加 構(gòu)建后操作 -> Editable Email Notification

完整 郵件報(bào)告模板

<!DOCTYPE html>

<html> ?

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ?

<title>53在線接口自動(dòng)化-第${BUILD_NUMBER}次構(gòu)建日志</title> ?

</head> ?


<body size="4" leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" ?

?? offset="0"> ?

?? <table width="95%" cellpadding="0" cellspacing="0" ?

? ? ?? style="font-size: 30pt; font-family: Tahoma, Arial, Helvetica, sans-serif"> ?

? ? ?? <tr> ?

? ? ? ? ?? <td>(本郵件是程序每天定時(shí)下發(fā),有問題請(qǐng)聯(lián)系測(cè)試Young?。ü局蟮耐饩W(wǎng)無法打開郵件里的 URL))</td> ?

? ? ?? </tr> ?

? ? ?? <tr> ?

? ? ? ? ?? <td><h2> ?

? ? ? ? ? ? ? ? ?? <font color="#0000FF">構(gòu)建狀態(tài) - ${BUILD_STATUS}</font> ?

? ? ? ? ? ? ?? </h2></td> ?

? ? ?? </tr> ?

? ? ?? <tr> ?

? ? ? ? ?? <td><br /> ?

? ? ? ? ?? <b><font color="#0B610B">構(gòu)建信息</font></b> ?

? ? ? ? ?? <hr size="3" width="100%" align="center" /></td> ?

? ? ?? </tr> ?

? ? ?? <tr> ?

? ? ? ? ?? <td> ?

? ? ? ? ? ? ?? <ul> ?

? ? ? ? ? ? ? ? ?? <li>項(xiàng)目名稱 : ${PROJECT_NAME}</li> ?

? ? ? ? ? ? ? ? ?? <li>構(gòu)建編號(hào) : 第${BUILD_NUMBER}次構(gòu)建</li> ?

? ? ? ? ? ? ? ? ?? <li>觸發(fā)原因: ${CAUSE}</li> ?

? ? ? ? ? ? ? ? ?? <li>構(gòu)建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li> ?

? ? ? ? ? ? ? ? ?? <li >變更集:${JELLY_SCRIPT,template="html"}</a></li> ?

? ? ? ? ? ? ? ? ?? <!-- 下面是報(bào)告的位置,根據(jù)自己項(xiàng)目要求填寫 -->

? ? ? ? ? ? ? ? ?? <li>SummaryReport:${FILE, path="D:/demo/log/html/SummaryReport.html"}

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></a></li> ?

? ? ? ? ? ? ?? </ul> ? ?

? ? ? ? ? ? ? ? ?? <hr size="3" width="100%" align="center" />

? ? ? ? ?? </td> ?

? ? ?? </tr> ?

?? </table> ?

</body> ?

</html>

郵箱顯示報(bào)告如下樣式:

jmeter相關(guān)配置? ?

一: 通過簡(jiǎn)單的命令:構(gòu)建 目錄結(jié)構(gòu)如下

csv? ? &? xml

簡(jiǎn)單結(jié)構(gòu)目錄如下

修改jmeter.properties文件內(nèi)容細(xì)節(jié)

文件地址

設(shè)置運(yùn)行機(jī)器為本機(jī)

設(shè)置報(bào)告方式為csv

禁用ssl模式

二:通過build文件構(gòu)建目錄如下

? 注意!注意!注意!

使用到的jmeter-results-detail-report_21.xsl 文件

將build.xml中的第42行

style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">

拷貝以下內(nèi)容將這個(gè)路徑下的jmeter-results-detail-report_21.xsl文件覆蓋,這個(gè)文件說明了xsl文件裝換為html文件的一些規(guī)則

使用到的:jmeter.results.shanhe.me.xsl 文件

jmeter.results.shanhe.me.xsl

鏈接:https://pan.baidu.com/s/1TQ7VIEXR9SubNEUZZ3a2xQ 提取碼:ne14

文件目錄結(jié)構(gòu)

build文件詳細(xì)內(nèi)容如下:

<?xml version="1.0" encoding="UTF-8"?>

<project name="ant-jmeter-test" default="run" basedir=".">

?? <taskdef resource="net/sf/antcontrib/antlib.xml" />

?? <tstamp>

? ? ?? <!--format property="time" pattern="yyyyMMddkkmm" /-->

? ? ?? <format property="date" pattern="yyyy/MM/dd kk:mm:ss"/>

? ? ?? <!--kk是24小時(shí)制,KK是12小時(shí)制-->

?? </tstamp>

?? <!-- (1)需要改成自己本地的 Jmeter 目錄-->

?? <property name="jmeter.home" value="D:/testinstail/xml-jmeter-5.2.1"/>

?? <property name="report.title" value="report"/>

?? <!-- (2)jmeter生成jtl格式的結(jié)果報(bào)告的路徑-->

?? <property name="jmeter.result.jtl.dir" value="D:/demo/log/jtl"/>

?? <!-- (3)jmeter生成html格式的結(jié)果報(bào)告的路徑-->

?? <property name="jmeter.result.html.dir" value="D:/demo/log/html"/>

?? <!-- 生成的報(bào)告的前綴 -->

?? <property name="ReportName" value="DetailsReport"/>

?? <property name="ReportName2" value="SummaryReport" />

?? <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}.jtl"/>

?? <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}.html"/>

?? <property name="jmeter.result.htmlName2" value="${jmeter.result.html.dir}/${ReportName2}.html" />

?? <!--項(xiàng)目初始化設(shè)置-->

?? <target name="init" description="init" >

? ? ?? <!--刪除jtl文件夾下生成的所有文件及文件夾包括空目錄,但不刪除根目錄-->

? ? ?? <delete verbose="true" includeemptydirs="true" >

? ? ? ? ?? <fileset dir="${jmeter.result.jtl.dir}" >

? ? ? ? ? ? ?? <include name="**/*" />

? ? ? ? ?? </fileset>

? ? ?? </delete>

? ? ?? <!--刪除html文件夾下生成的所有文件及文件夾包括空目錄,但不刪除根目錄-->

? ? ?? <delete>

? ? ? ? ?? <fileset dir="${jmeter.result.html.dir}">

? ? ? ? ? ? ?? <include name="**/*"/>

? ? ? ? ?? </fileset>

? ? ?? </delete>

? ? ?? <!--<delete dir="${classes.home}"/><mkdir dir="${classes.home}"/>-->

?? </target>

?? <target name="run">

? ? ?? <antcall target="test"/>

? ? ?? <antcall target="report"/>

? ? ?? <!--antcall? target="mail"/-->

?? </target>

?? <target name="test" depends="init">

? ? ?? <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>

? ? ?? <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">

? ? ? ? ?? <!-- (4)build.xml的存放的路徑-->

? ? ? ? ?? <testplans dir="D:\demo" includes="*.jmx"/>

? ? ? ? ?? <property name="jmeter.save.saveservice.output_format" value="xml"/>

? ? ?? </jmeter>

?? </target>

?? <path id="xslt.classpath">

? ? ?? <fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/>

? ? ?? <fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/>

?? </path>

?? <target name="report" depends="test">

? ? ?? <tstamp>

? ? ? ? ?? <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm"/>

? ? ?? </tstamp>

? ? ?? <xslt

? classpathref="xslt.classpath"

? force="true"

? in="${jmeter.result.jtlName}"

? out="${jmeter.result.htmlName}"

? style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">


? ? ? ? ?? <param name="dateReport" expression="${date}"/>

? ? ?? </xslt>


? classpathref="xslt.classpath"

? force="true"

? in="${jmeter.result.jtlName}"

? out="${jmeter.result.htmlName2}"

? style="${jmeter.home}/extras/jmeter.results.shanhe.me.xsl">


? ? ? ? ?? <param name="dateReport" expression="${date}"/>

? ? ?? </xslt>


? ? ?? <copy todir="${jmeter.result.html.dir}">

? ? ? ? ?? <fileset dir="${jmeter.home}/extras">

? ? ? ? ? ? ?? <include name="collapse.png"/>

? ? ? ? ? ? ?? <include name="expand.png"/>

? ? ? ? ?? </fileset>

? ? ?? </copy>

?? </target>

?? <path id="lib_classpath">

? ? ?? <fileset dir="${basedir}/">

? ? ? ? ?? <include name="mail*.jar" />

? ? ? ? ?? <include name="activation*.jar" />

? ? ? ? ?? <include name="commons-email*.jar" />

? ? ? ? ?? <include name="ant-contrib*.jar" />

? ? ?? </fileset>

?? </path>

?? <!--target name="mail"><for list="Young@thunisoft.com" param="tmp" ><sequential><echo>message @{tmp}</echo><mail mailhost="smtp.thunisoft.com" mailport="25" ssl="false" subject="ant mail" messagemimetype="text/html" user="Young" password="*******"? tolist="@{tmp}"><from address="Young@thunisoft.com" /><fileset dir="${jmeter.result.html.dir}"><include name="*.html" /><include name="*.png" /></fileset><message>支持多人同時(shí)發(fā)郵件!!<br /><br /></message></mail></sequential></for></target-->

</project>

jmeter.properties文件配置內(nèi)容

文件地址:

設(shè)置運(yùn)行機(jī)器為本機(jī)

設(shè)置禁用ssl

設(shè)置報(bào)告方式為xml

郵件報(bào)告亂碼處理

進(jìn)入jenkins安裝顯示目錄如下:

修改指定編碼運(yùn)行jenkins

運(yùn)行完以后記得重啟生效: https://localhost:8080/restart

查看jenkins 系統(tǒng)信息編碼為UTF-8即操作成功

注意事項(xiàng):

如果修改此處的編碼方式為utf-8那么 ,**.jmx文件必須為英文 否則構(gòu)建時(shí)由于文件編碼不正確會(huì)構(gòu)建失敗

總結(jié)

ANT構(gòu)建腳本 xml

1.jmeter腳本準(zhǔn)備(不說了)

2.新建一個(gè)demo,把jmx腳本放進(jìn)去

3.在demo下新建目錄resultLog,log下新建兩個(gè)子目錄html,jtl

4.將 jmeter的extras目錄中ant-jmeter-1.1.1.jar包拷貝至ant安裝目錄下的lib目錄中

5.修改Jmeter的bin目錄下jmeter.properties文件的配置:jmeter.save.saveservice.output_format=xml

html:存放生成的html報(bào)告

jtl:存放生成的jtl報(bào)告

build.xml配置

<?xml version="1.0" encoding="UTF-8"?>

<project name="ant-jmeter-test" default="run" basedir=".">

?? <taskdef resource="net/sf/antcontrib/antlib.xml" />

?? <tstamp>

? ? ?? <!--format property="time" pattern="yyyyMMddkkmm" /-->

? ? ?? <format property="date" pattern="yyyy/MM/dd kk:mm:ss"/>

? ? ?? <!--kk是24小時(shí)制,KK是12小時(shí)制-->

?? </tstamp>

?? <!-- (1)需要改成自己本地的 Jmeter 目錄-->

?? <property name="jmeter.home" value="D:/testinstail/xml-jmeter-5.2.1"/>

?? <property name="report.title" value="report"/>

?? <!-- (2)jmeter生成jtl格式的結(jié)果報(bào)告的路徑-->

?? <property name="jmeter.result.jtl.dir" value="D:/demo/log/jtl"/>

?? <!-- (3)jmeter生成html格式的結(jié)果報(bào)告的路徑-->

?? <property name="jmeter.result.html.dir" value="D:/demo/log/html"/>

?? <!-- 生成的報(bào)告的前綴 -->

?? <property name="ReportName" value="DetailsReport"/>

?? <property name="ReportName2" value="SummaryReport" />

?? <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}.jtl"/>

?? <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}.html"/>

?? <property name="jmeter.result.htmlName2" value="${jmeter.result.html.dir}/${ReportName2}.html" />

?? <!--項(xiàng)目初始化設(shè)置-->

?? <target name="init" description="init" >

? ? ?? <!--刪除jtl文件夾下生成的所有文件及文件夾包括空目錄,但不刪除根目錄-->

? ? ?? <delete verbose="true" includeemptydirs="true" >

? ? ? ? ?? <fileset dir="${jmeter.result.jtl.dir}" >

? ? ? ? ? ? ?? <include name="**/*" />

? ? ? ? ?? </fileset>

? ? ?? </delete>

? ? ?? <!--刪除html文件夾下生成的所有文件及文件夾包括空目錄,但不刪除根目錄-->

? ? ?? <delete>

? ? ? ? ?? <fileset dir="${jmeter.result.html.dir}">

? ? ? ? ? ? ?? <include name="**/*"/>

? ? ? ? ?? </fileset>

? ? ?? </delete>

? ? ?? <!--<delete dir="${classes.home}"/><mkdir dir="${classes.home}"/>-->

?? </target>

?? <target name="run">

? ? ?? <antcall target="test"/>

? ? ?? <antcall target="report"/>

? ? ?? <!--antcall? target="mail"/-->

?? </target>

?? <target name="test" depends="init">

? ? ?? <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>

? ? ?? <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">

? ? ? ? ?? <!-- (4)build.xml的存放的路徑-->

? ? ? ? ?? <testplans dir="D:\demo" includes="*.jmx"/>

? ? ? ? ?? <property name="jmeter.save.saveservice.output_format" value="xml"/>

? ? ?? </jmeter>

?? </target>

?? <path id="xslt.classpath">

? ? ?? <fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/>

? ? ?? <fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/>

?? </path>

?? <target name="report" depends="test">

? ? ?? <tstamp>

? ? ? ? ?? <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm"/>

? ? ?? </tstamp>

? ? ?? <xslt

? classpathref="xslt.classpath"

? force="true"

? in="${jmeter.result.jtlName}"

? out="${jmeter.result.htmlName}"

? style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">


? ? ? ? ?? <param name="dateReport" expression="${date}"/>

? ? ?? </xslt>


? classpathref="xslt.classpath"

? force="true"

? in="${jmeter.result.jtlName}"

? out="${jmeter.result.htmlName2}"

? style="${jmeter.home}/extras/jmeter.results.shanhe.me.xsl">


? ? ? ? ?? <param name="dateReport" expression="${date}"/>

? ? ?? </xslt>


? ? ?? <copy todir="${jmeter.result.html.dir}">

? ? ? ? ?? <fileset dir="${jmeter.home}/extras">

? ? ? ? ? ? ?? <include name="collapse.png"/>

? ? ? ? ? ? ?? <include name="expand.png"/>

? ? ? ? ?? </fileset>

? ? ?? </copy>

?? </target>

?? <path id="lib_classpath">

? ? ?? <fileset dir="${basedir}/">

? ? ? ? ?? <include name="mail*.jar" />

? ? ? ? ?? <include name="activation*.jar" />

? ? ? ? ?? <include name="commons-email*.jar" />

? ? ? ? ?? <include name="ant-contrib*.jar" />

? ? ?? </fileset>

?? </path>

?? <!--target name="mail"><for list="Young@thunisoft.com" param="tmp" ><sequential><echo>message @{tmp}</echo><mail mailhost="smtp.thunisoft.com" mailport="25" ssl="false" subject="ant mail" messagemimetype="text/html" user="Young" password="*******"? tolist="@{tmp}"><from address="Young@thunisoft.com" /><fileset dir="${jmeter.result.html.dir}"><include name="*.html" /><include name="*.png" /></fileset><message>支持多人同時(shí)發(fā)郵件!!<br /><br /></message></mail></sequential></for></target-->

</project>

1.修改build.xml中的(1)(2)(3)(4)(5)的路徑為自己的響應(yīng)的路徑

2.將build.xml中的第42行

style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">

拷貝以下內(nèi)容將這個(gè)路徑下的jmeter-results-detail-report_21.xsl文件覆蓋,這個(gè)文件說明了xsl文件裝換為html文件的一些規(guī)則

jmeter-results-detail-report_21.xsl 文件內(nèi)容如下:

<?xml version="1.0"?>

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

<!--

? Licensed to the Apache Software Foundation (ASF) under one or more

? contributor license agreements.? See the NOTICE file distributed with

? this work for additional information regarding copyright ownership.

? The ASF licenses this file to You under the Apache License, Version 2.0

? (the "License"); you may not use this file except in compliance with

? the License.? You may obtain a copy of the License at

? ? ? http://www.apache.org/licenses/LICENSE-2.0

? Unless required by applicable law or agreed to in writing, software

? distributed under the License is distributed on an "AS IS" BASIS,

? WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

? See the License for the specific language governing permissions and

? limitations under the License.

-->

<!--

?? Stylesheet for processing 2.1 output format test result files

?? To uses this directly in a browser, add the following to the JTL file as line 2:

?? <?xml-stylesheet type="text/xsl" href="../extras/jmeter-results-detail-report_21.xsl"?>

?? and you can then view the JTL in a browser

-->

<xsl:output method="html" indent="yes" encoding="UTF-8" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />

<!-- Defined parameters (overrideable) -->

<xsl:param ?? name="showData" select="'n'"/>

<xsl:param ?? name="titleReport" select="'Load Test Results'"/>

<xsl:param ?? name="dateReport" select="'date not defined'"/>

<xsl:template match="testResults">

?? <html>

? ? ?? <head>

? ? ? ? ?? <title><xsl:value-of select="$titleReport" /></title>

? ? ? ? ?? <style type="text/css">

? ? ? ? ? ? ?? body {

? ? ? ? ? ? ? ? ?? font:normal 68% verdana,arial,helvetica;

? ? ? ? ? ? ? ? ?? color:#000000;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? table tr td, table tr th {

? ? ? ? ? ? ? ? ?? font-size: 68%;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? table.details tr th{

? ? ? ? ? ? ? ? ?? color: #ffffff;

? ? ? ? ? ? ? ? ?? font-weight: bold;

? ? ? ? ? ? ? ? ?? text-align:center;

? ? ? ? ? ? ? ? ?? background:#2674a6;

? ? ? ? ? ? ? ? ?? white-space: nowrap;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? table.details tr td{

? ? ? ? ? ? ? ? ?? background:#eeeee0;

? ? ? ? ? ? ? ? ?? white-space: nowrap;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? h1 {

? ? ? ? ? ? ? ? ?? margin: 0px 0px 5px; font: 165% verdana,arial,helvetica

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? h2 {

? ? ? ? ? ? ? ? ?? margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? h3 {

? ? ? ? ? ? ? ? ?? margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? .Failure {

? ? ? ? ? ? ? ? ?? font-weight:bold; color:red;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? img

? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ?? border-width: 0px;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? .expand_link

? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ? ? position=absolute;

? ? ? ? ? ? ? ? ? right: 0px;

? ? ? ? ? ? ? ? ? width: 27px;

? ? ? ? ? ? ? ? ? top: 1px;

? ? ? ? ? ? ? ? ? height: 27px;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? .page_details

? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ? ? display: none;

? ? ? ? ? ? ?? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? .page_details_expanded

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? display: block;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? display/* hide this definition from? IE5/6 */: table-row;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? }

? ? ? ? ?? </style>

? ? ? ? ?? <script language="JavaScript"><![CDATA[

? ? ? ? ? ? ? ? ? ? ? ? ? function expand(details_id)

? ? ? ? ? ? ? {

? ? ? ? ? ? ? ?? document.getElementById(details_id).className = "page_details_expanded";

? ? ? ? ? ? ? }

? ? ? ? ? ? ? function collapse(details_id)

? ? ? ? ? ? ? {

? ? ? ? ? ? ? ?? document.getElementById(details_id).className = "page_details";

? ? ? ? ? ? ? }

? ? ? ? ? ? ? function change(details_id)

? ? ? ? ? ? ? {

? ? ? ? ? ? ? ?? if(document.getElementById(details_id+"_image").src.match("expand"))

? ? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ? ? ? document.getElementById(details_id+"_image").src = "collapse.png";

? ? ? ? ? ? ? ? ? ? expand(details_id);

? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ? ?? else

? ? ? ? ? ? ? ?? {

? ? ? ? ? ? ? ? ? ? document.getElementById(details_id+"_image").src = "expand.png";

? ? ? ? ? ? ? ? ? ? collapse(details_id);

? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ?? ]]></script>

? ? ?? </head>

? ? ?? <body>

? ? ? ? ?? <xsl:call-template name="pageHeader" />

? ? ? ? ?? <xsl:call-template name="summary" />

? ? ? ? ?? <hr size="1" width="95%" align="center" />

? ? ? ? ?? <xsl:call-template name="pagelist" />

? ? ? ? ?? <hr size="1" width="95%" align="center" />

? ? ? ? ?? <xsl:call-template name="detail" />

? ? ?? </body>

?? </html>

</xsl:template>

<xsl:template name="pageHeader">

?? <h1><xsl:value-of select="$titleReport" /></h1>

?? <table width="100%">

? ? ?? <tr>

? ? ? ? ?? <td align="left">Date report: <xsl:value-of select="$dateReport" /></td>

? ? ? ? ?? <td align="right">Designed for use with <a >JMeter</a> and <a >Ant</a>.</td>

? ? ?? </tr>

?? </table>

?? <hr size="1" />

</xsl:template>

<xsl:template name="summary">

?? <h2>Summary</h2>

?? <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">

? ? ?? <tr valign="top">

? ? ? ? ?? <th># Samples</th>

? ? ? ? ?? <th>Failures</th>

? ? ? ? ?? <th>Success Rate</th>

? ? ? ? ?? <th>Average Time</th>

? ? ? ? ?? <th>Min Time</th>

? ? ? ? ?? <th>Max Time</th>

? ? ?? </tr>

? ? ?? <tr valign="top">

? ? ? ? ?? <xsl:variable name="allCount" select="count(/testResults/*)" />

? ? ? ? ?? <xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::s='false'])" />

? ? ? ? ?? <xsl:variable name="allSuccessCount" select="count(/testResults/*[attribute::s='true'])" />

? ? ? ? ?? <xsl:variable name="allSuccessPercent" select="$allSuccessCount div $allCount" />

? ? ? ? ?? <xsl:variable name="allTotalTime" select="sum(/testResults/*/@t)" />

? ? ? ? ?? <xsl:variable name="allAverageTime" select="$allTotalTime div $allCount" />

? ? ? ? ?? <xsl:variable name="allMinTime">

? ? ? ? ? ? ?? <xsl:call-template name="min">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="nodes" select="/testResults/*/@t" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </xsl:variable>

? ? ? ? ?? <xsl:variable name="allMaxTime">

? ? ? ? ? ? ?? <xsl:call-template name="max">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="nodes" select="/testResults/*/@t" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </xsl:variable>

? ? ? ? ?? <xsl:attribute name="class">

? ? ? ? ? ? ?? <xsl:choose>

? ? ? ? ? ? ? ? ?? <xsl:when test="$allFailureCount > 0">Failure</xsl:when>

? ? ? ? ? ? ?? </xsl:choose>

? ? ? ? ?? </xsl:attribute>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:value-of select="$allCount" />

? ? ? ? ?? </td>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:value-of select="$allFailureCount" />

? ? ? ? ?? </td>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:call-template name="display-percent">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$allSuccessPercent" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </td>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$allAverageTime" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </td>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$allMinTime" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </td>

? ? ? ? ?? <td align="center">

? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$allMaxTime" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </td>

? ? ?? </tr>

?? </table>

</xsl:template>

<xsl:template name="pagelist">

?? <h2>Pages</h2>

?? <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">

? ? ?? <tr valign="top">

? ? ? ? ?? <th>URL</th>

? ? ? ? ?? <th># Samples</th>

? ? ? ? ?? <th>Failures</th>

? ? ? ? ?? <th>Success Rate</th>

? ? ? ? ?? <th>Average Time</th>

? ? ? ? ?? <th>Min Time</th>

? ? ? ? ?? <th>Max Time</th>

? ? ? ? ?? <th></th>

? ? ?? </tr>

? ? ?? <xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">

? ? ? ? ?? <xsl:variable name="label" select="@lb" />

? ? ? ? ?? <xsl:variable name="count" select="count(../*[@lb = current()/@lb])" />

? ? ? ? ?? <xsl:variable name="failureCount" select="count(../*[@lb = current()/@lb][attribute::s='false'])" />

? ? ? ? ?? <xsl:variable name="successCount" select="count(../*[@lb = current()/@lb][attribute::s='true'])" />

? ? ? ? ?? <xsl:variable name="successPercent" select="$successCount div $count" />

? ? ? ? ?? <xsl:variable name="totalTime" select="sum(../*[@lb = current()/@lb]/@t)" />

? ? ? ? ?? <xsl:variable name="averageTime" select="$totalTime div $count" />

? ? ? ? ?? <xsl:variable name="minTime">

? ? ? ? ? ? ?? <xsl:call-template name="min">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </xsl:variable>

? ? ? ? ?? <xsl:variable name="maxTime">

? ? ? ? ? ? ?? <xsl:call-template name="max">

? ? ? ? ? ? ? ? ?? <xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t" />

? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ?? </xsl:variable>

? ? ? ? ?? <tr valign="top">

? ? ? ? ? ? ?? <xsl:attribute name="class">

? ? ? ? ? ? ? ? ?? <xsl:choose>

? ? ? ? ? ? ? ? ? ? ?? <xsl:when test="$failureCount > 0">Failure</xsl:when>

? ? ? ? ? ? ? ? ?? </xsl:choose>

? ? ? ? ? ? ?? </xsl:attribute>

? ? ? ? ? ? ?? <td>

? ? ? ? ? ? ?? <xsl:if test="$failureCount > 0">

? ? ? ? ? ? ? ?? <a><xsl:attribute name="href">#<xsl:value-of select="$label" /></xsl:attribute>

? ? ? ? ? ? ? ?? <xsl:value-of select="$label" />

? ? ? ? ? ? ? ?? </a>

? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ? ? ?? <xsl:if test="0 >= $failureCount">

? ? ? ? ? ? ? ?? <xsl:value-of select="$label" />

? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="center">

? ? ? ? ? ? ? ? ?? <xsl:value-of select="$count" />

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="center">

? ? ? ? ? ? ? ? ?? <xsl:value-of select="$failureCount" />

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="right">

? ? ? ? ? ? ? ? ?? <xsl:call-template name="display-percent">

? ? ? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$successPercent" />

? ? ? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="right">

? ? ? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$averageTime" />

? ? ? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="right">

? ? ? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$minTime" />

? ? ? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="right">

? ? ? ? ? ? ? ? ?? <xsl:call-template name="display-time">

? ? ? ? ? ? ? ? ? ? ?? <xsl:with-param name="value" select="$maxTime" />

? ? ? ? ? ? ? ? ?? </xsl:call-template>

? ? ? ? ? ? ?? </td>

? ? ? ? ? ? ?? <td align="center">

? ? ? ? ? ? ? ? ? <a href="">

? ? ? ? ? ? ? ? ? ?? <xsl:attribute name="href"><xsl:text/>javascript:change('page_details_<xsl:value-of select="position()" />')</xsl:attribute>

? ? ? ? ? ? ? ? ? ?? <img src="expand.png" alt="expand/collapse"><xsl:attribute name="id"><xsl:text/>page_details_<xsl:value-of select="position()" />_image</xsl:attribute></img>

? ? ? ? ? ? ? ? ? </a>

? ? ? ? ? ? ?? </td>

? ? ? ? ?? </tr>

? ? ? ? ? ? ? ? ? ? ?? <tr class="page_details">

? ? ? ? ? ? ? ? ? ? ? ? ? <xsl:attribute name="id"><xsl:text/>page_details_<xsl:value-of select="position()" /></xsl:attribute>

? ? ? ? ? ? ? ? ? ? ? ? ? <td colspan="8" bgcolor="#FF0000">

? ? ? ? ? ? ? ? ? ? ? ? ? ?? <div align="center">

? ? ? ? ? ? ? ? ? ? <b>Details for Page "<xsl:value-of select="$label" />"</b>

? ? ? ? ? ? ? ? ? ? <table bordercolor="#000000" bgcolor="#2674A6" border="0"? cellpadding="1" cellspacing="1" width="95%">

? ? ? ? ? ? ? ? ? ? <tr>

? ? ? ? ? ? ? ? ? ? ?? <th>Thread</th>

? ? ? ? ? ? ? ? ? ? ?? <th>Iteration</th>

? ? ? ? ? ? ? ? ? ? ?? <th>Time (milliseconds)</th>

? ? ? ? ? ? ? ? ? ? ?? <th>Bytes</th>

? ? ? ? ? ? ? ? ? ? ?? <th>Success</th>

? ? ? ? ? ? ? ? ? ? </tr>

? ? ? ? ? ? ? ? ? ? <xsl:for-each select="../*[@lb = $label and @tn != $label]">

? ? ? ? ? ? ? ? ? ? ?? <tr>

? ? ? ? ? ? ? ? ? ? ? ? ? <td><xsl:value-of select="@tn" /></td>

? ? ? ? ? ? ? ? ? ? ? ? ? <td align="center"><xsl:value-of select="position()" /></td>

? ? ? ? ? ? ? ? ? ? ? ? ? <td align="right"><xsl:value-of select="@t" /></td>

? ? ? ? ? ? ? ? ? ? ? ? ? <!--? TODO allow for missing bytes field -->

? ? ? ? ? ? ? ? ? ? ? ? ? <td align="right"><xsl:value-of select="@by" /></td>

? ? ? ? ? ? ? ? ? ? ? ? ? <td align="center"><xsl:value-of select="@s" /></td>

? ? ? ? ? ? ? ? ? ? ?? </tr>

? ? ? ? ? ? ? ? ? ? </xsl:for-each>

? ? ? ? ? ? ? ? ? ? </table>

? ? ? ? ? ? ? ?? </div>

? ? ? ? ? ? ? ? ? ? ? ? ? </td>

? ? ? ? ? ? ? ? ? ? ?? </tr>

? ? ?? </xsl:for-each>

?? </table>

</xsl:template>

<xsl:template name="detail">

?? <xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::s='false'])" />

?? <xsl:if test="$allFailureCount > 0">

? ? ?? <h2>Failure Detail</h2>

? ? ?? <xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">

? ? ? ? ?? <xsl:variable name="failureCount" select="count(../*[@lb = current()/@lb][attribute::s='false'])" />

? ? ? ? ?? <xsl:if test="$failureCount > 0">

? ? ? ? ? ? ?? <h3><xsl:value-of select="@lb" /><a><xsl:attribute name="name"><xsl:value-of select="@lb" /></xsl:attribute></a></h3>

? ? ? ? ? ? ?? <table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">

? ? ? ? ? ? ?? <tr valign="top">

? ? ? ? ? ? ? ? ?? <th>Response</th>

? ? ? ? ? ? ? ? ?? <th>Failure Message</th>

? ? ? ? ? ? ? ? ?? <xsl:if test="$showData = 'y'">

? ? ? ? ? ? ? ? ? ? ? <th>Response Data</th>

? ? ? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ? ? ?? </tr>

? ? ? ? ? ? ?? <xsl:for-each select="/testResults/*[@lb = current()/@lb][attribute::s='false']">

? ? ? ? ? ? ? ? ?? <tr>

? ? ? ? ? ? ? ? ? ? ?? <td><xsl:value-of select="@rc | @rs" /> - <xsl:value-of select="@rm" /></td>

? ? ? ? ? ? ? ? ? ? ?? <td><xsl:value-of select="assertionResult/failureMessage" /></td>

? ? ? ? ? ? ? ? ? ? ?? <xsl:if test="$showData = 'y'">

? ? ? ? ? ? ? ? ? ? ? ? ?? <td><xsl:value-of select="./binary" /></td>

? ? ? ? ? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ? ? ? ? ?? </tr>

? ? ? ? ? ? ?? </xsl:for-each>

? ? ? ? ? ? ?? </table>

? ? ? ? ?? </xsl:if>

? ? ?? </xsl:for-each>

?? </xsl:if>

</xsl:template>

<xsl:template name="min">

?? <xsl:param name="nodes" select="/.." />

?? <xsl:choose>

? ? ?? <xsl:when test="not($nodes)">NaN</xsl:when>

? ? ?? <xsl:otherwise>

? ? ? ? ?? <xsl:for-each select="$nodes">

? ? ? ? ? ? ?? <xsl:sort data-type="number" />

? ? ? ? ? ? ?? <xsl:if test="position() = 1">

? ? ? ? ? ? ? ? ?? <xsl:value-of select="number(.)" />

? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ?? </xsl:for-each>

? ? ?? </xsl:otherwise>

?? </xsl:choose>

</xsl:template>

<xsl:template name="max">

?? <xsl:param name="nodes" select="/.." />

?? <xsl:choose>

? ? ?? <xsl:when test="not($nodes)">NaN</xsl:when>

? ? ?? <xsl:otherwise>

? ? ? ? ?? <xsl:for-each select="$nodes">

? ? ? ? ? ? ?? <xsl:sort data-type="number" order="descending" />

? ? ? ? ? ? ?? <xsl:if test="position() = 1">

? ? ? ? ? ? ? ? ?? <xsl:value-of select="number(.)" />

? ? ? ? ? ? ?? </xsl:if>

? ? ? ? ?? </xsl:for-each>

? ? ?? </xsl:otherwise>

?? </xsl:choose>

</xsl:template>

<xsl:template name="display-percent">

?? <xsl:param name="value" />

?? <xsl:value-of select="format-number($value,'0.00%')" />

</xsl:template>

<xsl:template name="display-time">

?? <xsl:param name="value" />

?? <xsl:value-of select="format-number($value,'0 ms')" />

</xsl:template>

</xsl:stylesheet>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容