Ant命令详解
Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能。
在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作。
一.安装与配置下载地址:/,在本文中下载的是 1.7.0版本。
解压到某个目录(例如E:"apache-ant-1.7.0),即可使用。
添加系统环境变量:ANT_HOME,该变量指向Ant解压后的根目录,在此为E:"apache-ant-1.7.0。
安装与配置完毕后,读者可以测试一下Ant是否可用,首先进入Ant的bin目录,运行命令ant –version,若安装和配置成功,则会显示Ant版本信息,如下图所示:由上可以看出,读者运行Ant的命令时,需要进入到Ant的bin目录,如何才能让系统自动找到Ant呢?这时需要读者在系统环境变量path中添加Ant的bin目录。
设置完成后,我们就可以在任何目录(例如C:"Documents and Settings"AmigoXie目录)输入Ant的命令,来获得命令的运行结果。
二.Ant的关键元素Ant的构件文件是基于XML编写的,默认名称为build.xml。
为了更清楚的了解Ant,在这里编写一个简单的Ant程序,用来展现Ant的功能,让读者对Ant有一个初步的了解。
首先在E盘下建立一个build.xml文件,内容如下:<?xml version="1.0"?><project name="helloWorld"><target name="sayHelloWorld"><echo message="Hello,Amigo"/></target></project>读者可以进入E盘,然后运行ant sayHelloWorld,可以看到如下的运行结果:其中sayHelloWorld为需要执行的任务的名称。
如果文件名不为build.xml,而为hello.xml时,读者运行同样的命令时,命令窗口会出现如下错误:Buildfile: build.xml does not exist!Build failed由上面的命令的错误提示可以看出,ant命令默认寻找build.xml文件。
若文件名为hello.xml时,读者还需要对命令做少许改变,改为:ant –f hello.xml sayHelloWorld、ant –buildfile hello.xml sayHelloWorld或ant –file hello.xml sayHelloWorld。
接下来开始向读者讲解本节的重点:Ant的关键元素project、target、property和task。
1.project元素project元素是Ant构件文件的根元素,Ant构件文件至少应该包含一个project元素,否则会发生错误。
在每个project元素下,可包含多个target元素。
接下来向读者展示一下project元素的各属性。
1)name属性用于指定project元素的名称。
2)default属性用于指定project默认执行时所执行的target的名称。
3)basedir属性用于指定基路径的位置。
该属性没有指定时,使用Ant的构件文件的附目录作为基准目录。
下面给读者一个简单的例子来展示project的各元素的使用。
修改E:"build.xml文件,修改后的内容如下:<?xml version="1.0"?><project name="projectStudy" default="sayBaseDir" basedir="E:"apache-ant-1.7.0"><target name="sayBaseDir"><echo message="The base dir is: ${basedir}"/></target></project>从上面的内容我们可以看出,在这里定义了default属性的值为sayBaseDir,即当运行ant命令时,若未指明执行的target时,默认执行的target的sayBaseDir,同时还定义了basedir属性的值为E:"apache-ant-1.7.0,进入E盘后运行ant命令,可看到运行的结果,如下图所示:因为设定了basedir的值,所以basedir属性的值变成了读者设置的值。
读者可以自行将project元素的basedir属性去掉后运行ant看看运行结果,此时basedir的值变成了E:",即为Ant构件文件的父目录。
有的时候,读者可能有这种需求,即想得到某个project下所有的target的名称,读者可以通过在ant命令里加上-proecthelp来达到该目的。
例如针对上述的例子我们运行ant –projecthelp,输出结果如下:Buildfile: build.xmlMain targets:Other targets:sayBaseDirDefault target: sayBaseDir2.target元素它为Ant的基本执行单元,它可以包含一个或多个具体的任务。
多个target可以存在相互依赖关系。
它有如下属性:1)name属性指定target元素的名称,这个属性在一个project元素中是唯一的。
我们可以通过指定target元素的名称来指定某个target。
2)depends属性用于描述target之间的依赖关系,若与多个target存在依赖关系时,需要以“,”间隔。
Ant会依照depends属性中target出现的顺序依次执行每个target。
被依赖的target会先执行。
3)if属性用于验证指定的属性是否存在,若不存在,所在target将不会被执行。
4)unless属性该属性的功能与if属性的功能正好相反,它也用于验证指定的属性是否存在,若不存在,所在target将会被执行。
5)description属性该属性是关于target功能的简短描述和说明。
下面带领读者来看一个各属性综合使用的例子。
修改E:"build.xml文件,修改后的内容如下:<?xml version="1.0"?><project name="targetStudy"><target name="targetA" if="ant.java.version"><echo message="Java Version: ${ant.java.version}"/></target><target name="targetB" depends="targetA" unless="amigo"><description>a depend example!</description><echo message="The base dir is: ${basedir}"/></target></project>进入E盘后运行ant targetB,可看到如下图所示的运行结果:读者分析结果后可以看到,我们运行的是名为targetB的target,因该target依赖于targetA,所以targetA将首先被执行,同时因为系统安装了java环境,所以ant.java.version属性存在,执行了targetA这个target,输出信息:[echo] Java Version: 1.5,targetA执行完毕后,接着执行targetB,因为amigo不存在,而unless属性是在不存在时进入所在的target的,由此可知targetB得以执行,输出信息:The base dir is: E:"。
3.property元素该元素可看作参量或者参数的定义,project的属性可以通过property元素来设定,也可在Ant之外设定。
若要在外部引入某文件,例如build.properties文件,可以通过如下内容将其引入:<property file=” build.properties”/>property元素可用作task的属性值。
在task中是通过将属性名放在“${”和“}”之间,并放在task属性值的位置来实现的。
Ant提供了一些内置的属性,它能得到的系统属性的列表与Java文档中System.getPropertis()方法得到的属性一致,这些系统属性可参考sun网站的说明。
同时,Ant还提供了一些它自己的内置属性,如下:basedir:project基目录的绝对路径,该属性在讲解project元素时有详细说明,不再赘述;ant.file:buildfile的绝对路径,如上面的各例子中,ant.file的值为E:"build.xml;ant.version:Ant的版本,在本文中,值为1.7.0;:当前指定的project的名字,即前文说到的project的name属性的值;ant.java.version:Ant检测到的JDK的版本,在上例运行结果中可看到为1.5。
下面让读者来看一个property元素使用的简单例子。
修改E:"build.xml文件,内容如下:<?xml version="1.0"?><project name="propertyStudy" default="example"><property name="name" value="amigo"/><property name="age" value="25"/><target name="example"><echo message="name: ${name}, age: ${age}"/></target></project>该例的运行结果如下图所示:由此读者可以看出,通过如下两个语句:<property name="name" value="amigo"/><property name="age" value="25"/>我们设置了名为name和age的两个属性,这两个属性设置后,读者在下文中可以通过${name}和${age}分别取得这两个属性的值。
react-ant-design 的tabs组件使用方法
react-ant-design 的tabs组件使用方法React-ant-design的Tabs组件是一个常用的用于显示多个内容区域的导航组件。
它可以方便地实现切换不同内容的功能,并提供了丰富的配置选项供开发者自定义样式和行为。
首先,我们需要安装react-ant-design库。
可以使用npm或者yarn进行安装,具体命令如下:```npm install antd// 或者yarn add antd```安装完成后,我们需要在项目中引入Tabs组件:```jsximport { Tabs } from 'antd';const { TabPane } = Tabs;```接下来,我们可以在组件中使用Tabs组件,并为其配置不同的TabPane。
```jsx<Tabs defaultActiveKey="1" onChange={callback}><TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane><TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane><TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane></Tabs>```在上面的代码中,我们使用了Tabs组件并设置了默认激活的TabPane为第一个。
通过设置onChange属性,我们可以监听Tab切换事件,以便进行一些额外的逻辑处理。
Tabs组件还提供了许多其他的配置选项。
下面是一些常用的属性:- activeKey:用于指定当前激活的TabPane,可以通过设置该属性来实现初始时激活指定的TabPane。
NTX300使用手册
NTX300使用手册Ver. 1.2.6 D r af tP/N: N TX300-M anual-1.2.62014/1/6注意:Ysync, Inc.深圳市南山区沙河西路3009号新能源产业园2A版权所有版权© 2009, Ysync, Inc。
保留所有权利。
本文档使用所有产品名称,服务标签,商标及注册商标均归其所有者拥有。
目录1、NTX300概述 (4)2、安装配置 (5)2.1. 选择合适的位置安装GPS天线 (5)3、使用操作 (6)3.1.安装 (6)3.2.NTX300连接 (6)3.3.管理通讯连接 (7)4、串口通讯监管 (7)4.1.VER命令 (7)4.2.HELP命令 (8)4.3. SA命令 (8)4.4. TZ命令 (9)4.5. UD命令 (9)4.6. ANT命令 (10)4.7. GPS命令 (10)4.8. STA命令 (11)4.8.1 . GPS版本(选配) (11)4.8.2. 1PPS版本(选配) (12)4.8.3. IRIGB版本(选配) (13)5、附录 (14)5.1. NTX300引脚定义 (14)5.2. 产品规格 (14)5.3. 结构说明 (16)5.4. NTX300测试评估板介绍 (17)5.4.1. NTX300测试评估板连接 (17)5.4.2. NTX300测试评估板配置 (18)1、NTX300概述NTX300代表着下一代的高精度GNSS时钟板的新概念,模块采用50x50mm的尺寸与高稳恒温晶振的尺寸相当,采用引脚设计,方便用户将模块安装在自己的电路板上与使用恒温晶振一样使用时钟板。
额外的输入输出连接器安置在模块的正面方便用户连接并扩展用户的实际需求。
使用NTX300与使用恒温晶振或铷原子钟一样简单方便,但NTX300具有比铷钟或恒温晶振更好的长期稳定性,板载的北斗B1,GPS L1波段接收机不仅有效提升了恒温晶振的温度特性并对老化进行了补偿同时双接收引擎保障用户的同步可靠性。
react-ant-design 的tabs组件使用方法
react-ant-design 的tabs组件使用方法React Ant Design Tabs 组件是一种用于在页面中展示多个选项卡的UI 组件,它可以让用户轻松地在不同选项卡之间切换。
以下是将react-ant-design 的Tabs 组件应用于实际项目的详细步骤。
1.首先,确保已安装了Ant Design 库。
如果尚未安装,可以使用以下命令进行安装:```pm install antd```2.在项目中引入Tabs 组件所需的样式和组件:```javascriptimport React from "react";import { Tabs } from "antd";import "antd/dist/antd.css";```3.创建一个Tabs 组件的基本实例:```javascriptconst TabPane = Tabs.TabPane;const App = () => {return (<div className="tabs-container"><Tabsnavigation={[{title: "Tab 1",key: "tab1",},{title: "Tab 2",key: "tab2",},{title: "Tab 3",key: "tab3",},]}>{({ tabs }) => (<>{tabs.map((tab, index) => (<TabPanekey={tab.key}tab={<span>{tab.title}</span>}>{index === 0 ? "Tab 1 content" : "Tab 2 content"}</TabPane>))}</>)}</Tabs></div>);};export default App;```4.配置Tabs 组件的属性:- `navigation`:定义Tab 标签的数组,包含每个Tab 的标题和唯一键。
(总结完整版) Ant 从SVNCVS下载 编译打包部署到本地远程服务器 (FTP上传)
通过一番琢磨,参考网上些许资料以及Ant文档,将Ant在J2EE构建中常用的脚本整合了起来,实现了Ant从版本控制器(SVN/CVS /VSS)checkout项目源码,编译编译打包,部署软件包到远程/本地服务器的整合,从此任何复杂的J2EE构建变得方便优雅...现记录大致笔记如下:分为两部分:1.我的环境2.文字大致叙述整合流程以及注意事项3.贴脚本实例一. 我的环境JDK1.7/TOMCAT6.0/ANT1.8.2/SVN/CVS/SERVER-U二:整合流程1.下载并安装Ant,配置ANT_HOME,PATH;在命令行执行ANT -VERSION,查看版本号检查是否安装配置成功2. 将ant从SVN checkout,上传FTP,启动Tomcat的依赖Jar分别加入进ant目录下地lib目录,具体为A.SVN依赖jar: svnant.jar/svnClientAdapter.jar/svnjavahl.jar;可从这里下载(/source/3544090)B.FTP依赖Jar: commons-net-1.4.1.jar;可从这里下载()C.Tomcat 依赖Jar:将Tomcat目录中lib目录下地catalina-ant.jar 拷贝之ant目录下地lib目录3.编写脚本(分段编写,并一一测试)A.从SVN/CVS checkout项目B.打包编译C.部署软件包到远程服务器(1)通过FTP上传到远程服务器webapps目录:注意事项:本人在远程服务器架设的ftp服务器是Server-U,设置Server-U账户权限时注意赋予账户写文件的权限以及访问需要的路径(可以为任意路径)(2) FTP上传完毕后,启动Web application:注意设置添加账户 <user username="admin"password="admin" roles="admin,manager"/>三:脚本实例<!-- svn下载,编译,打包,上传到ftp服务器,启动Web程序-->1.Tomcat/svn/ftp等配置属性文件 ant.properties=antDemocatalina.home=D:\Tomcat6.1catalina.apps=D:\Tomcat6.1\webapps#svn properties#svn.url=svn://192.168.1.202/antDemoername=*****svn.password=*****#cvs properties##cvs.root=:pserver:***@192.168.8.27:2401/home/Functions#cvs.password=*****#cvs.checkout.dir=.#tomcat properties#tomcat.manager.url=http://localhost:9080/managerername=*****tomcat.manager.password=*****#ftp properties#ftp.server=192.168.1.202ftp.password=*****erid=*****2.build.xml<?xml version="1.0" encoding="UTF-8"?><project name="${}" default="start" basedir="."><!-- svn下载,编译,打包,上传到ftp服务器,启动Web程序--><property file="ant.properties" /> <!-- 引入Tomcat/svn/ftp等配置属性文件--><property name="complile.dir" location="${basedir}/bin/classes"/> <property name="src.dir" value="${basedir}/src"/><property name="lib.dir" value="${basedir}/WebRoot/WEB-INF/lib"/><!-- =================================clean files================================= --><target name="cleanAll"><delete dir="${basedir}" /></target><!-- Ant svn Task Definition --><taskdef name="svn"classname="org.tigris.subversion.svnant.SvnTask" /><!-- =================================SVN Checkout================================= --><target name="svn.checkout" depends="cleanAll"><mkdir dir="${basedir}/SVN"/><svn javahl="true" username="${ername}"password="${svn.password}"><checkout url="${svn.url}"destPath="${basedir}/SVN"></checkout></svn></target><!-- =================================CVS Checkout================================= --><!--<target name="initpass" depends="cleanAll"><cvspass cvsroot="${cvs.root}" password="${cvs.password}" /> </target><target name="checkout" depends="initpass"><cvs cvsroot="${cvs.root}" command="checkout" quiet="true" cvsrsh="ssh" package="${}" dest="${cvs.checkout.dir}" /> <cvs cvsroot="${cvs.root}" command="checkout" quiet="true" cvsrsh="ssh" package="${}" dest="${cvs.checkout.dir}" /> </target>--><!-- =================================target: compile the src================================= --><target name="init"><delete dir="${complile.dir}"/><mkdir dir="${complile.dir}"/></target><path id="complile.classpath"><fileset dir="${catalina.home}/lib"><include name="catalina*.jar"/></fileset><fileset dir="${lib.dir}"><include name="**/*.jar"/></fileset></path><target name="complile" depends="init"><javac srcdir="${src.dir}" destdir="${complile.dir}"> <classpath path="${complile.dir}" /><classpath refid="complile.classpath"/></javac></target><!-- =================================target: deploy war================================= --><target name="war" depends="complile"><delete><fileset dir="." includes="**/*.war" /></delete><war destfile="${}.war"webxml="WebRoot/WEB-INF/web.xml"><classes dir="${complile.dir}"/><fileset dir="WebRoot" id="dir"><include name="**/*.*"/><exclude name="WEB-INF"/></fileset></war></target><!-- =================================target: upload with ftp================================= --><target name="upload" depends="war"><ftp password="${ftp.password}"server="${ftp.server}"userid="${erid}"remotedir="${catalina.apps}"binary="true"><fileset file="${basedir}/${}.war"/></ftp></target><!-- Ant Tomcat Task Definition --><taskdef name="deploy"classname="org.apache.catalina.ant.DeployTask" /><taskdef name="undeploy"classname="org.apache.catalina.ant.UndeployTask" /><taskdef name="remove"classname="org.apache.catalina.ant.RemoveTask" /><taskdef name="reload"classname="org.apache.catalina.ant.ReloadTask" /><taskdef name="start"classname="org.apache.catalina.ant.StartTask" /><taskdef name="stop" classname="org.apache.catalina.ant.StopTask" /><taskdef name="list" classname="org.apache.catalina.ant.ListTask" /><!-- =================================target: deploy_to_tomcat================================= --><target name="deploy" depends="war"><deploy url="${tomcat.manager.url}"password="${tomcat.manager.password}"path="/${}"war="file:${basedir}/${}.war" /> </target><target name="undeploy"><undeploy url="${tomcat.manager.url}"username="${ername}"password="${tomcat.manager.password}"path="/${}"/></target><target name="remove"><remove url="${tomcat.manager.url}"username="${ername}"password="${tomcat.manager.password}"path="/${}"/></target><target name="reload"><reload url="${tomcat.manager.url}"username="${ername}"password="${tomcat.manager.password}"path="/${}"/></target><target name="start" depends="upload"><start url="${tomcat.manager.url}"username="${ername}"password="${tomcat.manager.password}"path="/${}"/></target><target name="stop"><stop url="${tomcat.manager.url}"username="${ername}"password="${tomcat.manager.password}"path="/${}"/></target><target name="list"><list url="${tomcat.manager.url}"password="${tomcat.manager.password}"/></target><!-- =================================target: tomcat shell================================= --><target name="tomcat.start"><java jar="${catalina.home}/bin/bootstrap.jar" fork="true"> <jvmarg value="-Dcatalina.home=${catalina.home}"/></java></target><target name="tomcat.stop"><java jar="${catalina.home}/bin/bootstrap.jar"fork="true"><jvmarg value="-Dcatalina.home=${catalina.home}"/> <arg line="stop"/></java></target><target name="tomcat.debug"><java jar="${catalina.home}/bin/bootstrap.jar"fork="true"><jvmarg value="-Dcatalina.home=${catalina.home}"/> <jvmarg value="-Xdebug"/><jvmargvalue="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n" /></java></target></project>。
ant-design-charts react 使用
ant-design-charts react 使用Ant Design Charts 是一个基于Ant Design 的React 数据可视化库,用于创建各种类型的图表。
要使用Ant Design Charts 在React 项目中,可以按照以下步骤进行操作:1.安装Ant Design Charts:使用npm 或yarn 将Ant Design Charts 添加到你的React 项目中。
运行以下命令之一:bashnpm install @ant-design/charts --save或者bashyarn add @ant-design/charts2.引入图表组件:在你的React 组件中,通过import 语句引入所需的图表组件。
例如,要引入折线图组件,可以使用以下代码:jsximport { Line } from'@ant-design/charts';3.创建图表容器:在你的React 组件中,创建一个用于渲染图表的容器。
可以使用Ant Design 的布局组件或自定义容器。
例如,可以使用以下代码创建一个简单的容器:jsxconst ChartContainer = () => {return<div style={{ height: 400 }} />;};4.渲染图表组件:在图表容器中,使用React 的JSX 语法渲染相应的图表组件。
例如,要渲染一个折线图,可以使用以下代码:jsxconst data = [ /* 数据 */ ];const config = { /* 配置项 */ };return (<ChartContainer><Line data={data} config={config} /></ChartContainer>);根据你的需求,可以调整数据和配置项。
有关配置项的详细信息,请参阅Ant Design Charts 的文档。
支持ANT+设备配置文件实现不同厂家产品之间互通 完全
5
3.05 3.27
~9.3
~70
~22
~0.5
5.25 V
3.5
V
mA
mA
mA
mA
4.模块顶视图及主机接口 5. 典型应用
技
科
通
迅
一个典型的 2.4GHz 运动/医学无线应用网络:
1. AP3000 通过无线采集各应用节点(AP1000/AP2000)数据
: 广泛适用运动、健康、家庭健康监控、家庭/工业自动化、环境传感器网络、有源RFID、物流/货物 http 追踪、观众反馈系统等无线应用,低功耗应用及物联网的理想选择
技 科 通 迅
COPYRIGHT ©2010 ALL RIGHTS RESERVED 迅通科技 TEL: +86 10 64602884 +86 755 26675941 E-mail: nrf@
m ♦ 内建设备搜索及配对功能,内建时间及电源管理 o ♦ 内建抗干扰处理,可配置通道周期 5.2 ms - 2 s c ♦ 广播, 应答,及突发工作模式,突发速率可达 20 kbps . ♦ 适用于简单及复杂的网络拓扑结构: 点对点, 星形, 树形及其他实际网络结构 a ♦ 支持公共、私有及受管理网络 n ♦ 支持 ANT+设备配置文件实现不同厂家产品之间互通 i ♦ 完全兼容 nRF24AP1 和基于 Dynastream 公司 ANT 芯片/模组产品以及 nRF24AP2 系列 h ♦ 尺寸约为 42x15x2.8 mm(不含 USB 连接器), 或 57x15x5 mm(包括 USB 连接器) c ♦ 射频输出功率约+20dBm q ♦ 集射频和嵌入式设计之专业经验,具备优异的无线网络通信性能,超低功耗和强抗干扰性 e ♦ 提供 Windows/MAC 驱动,方便各种平台下的灵活应用 r 注:相关产品 f z AP1000 单通道无线模块,内置 PCB 天线;AP1000+为外置天线模块;AP1000PA 为增强功率模块 . z AP2000 八通道无线模块,内置 PCB 天线;AP2000+为外置天线模块;AP2000PA 为增强功率模块 w z AP3000 USB 接口无线模块,内置 PCB 天线;AP3000+为外置天线模块;AP3000PA 为增强功率模块 //ww 2. 适合各种无线网络拓扑结构应用
ant design vue tabs基本用法
ant design vue tabs基本用法Ant Design Vue Tabs是一个基于Vue.js的标签页组件,它可以帮助我们轻松地创建多个标签页,并在其中切换。
在本文中,我们将介绍Ant Design Vue Tabs的基本用法,以帮助您快速上手。
1. 安装Ant Design Vue在使用Ant Design Vue Tabs之前,我们需要先安装Ant Design Vue。
您可以通过以下命令来安装:```npm install ant-design-vue --save```2. 引入Ant Design Vue Tabs在安装完成后,我们需要在Vue项目中引入Ant Design Vue Tabs。
您可以在Vue组件中使用以下代码来引入:```import { Tabs } from 'ant-design-vue';```3. 使用Ant Design Vue Tabs在引入Ant Design Vue Tabs后,我们可以在Vue组件中使用它。
您可以使用以下代码来创建一个基本的标签页:```<template><div><a-tabs><a-tab-pane key="1" tab="Tab 1">Content of Tab Pane1</a-tab-pane><a-tab-pane key="2" tab="Tab 2">Content of Tab Pane2</a-tab-pane><a-tab-pane key="3" tab="Tab 3">Content of Tab Pane3</a-tab-pane></a-tabs></div></template>```在上面的代码中,我们创建了一个包含三个标签页的标签页组件。
Jmeter+selenium+ant接口自动化并生成报告
Jmeter+selenium+ant接⼝⾃动化并⽣成报告⼀、数据准备这⾥不详细介绍Jmeter的使⽤⽅法,重点介绍jmeter与ant的整合1、添加测试计划-->执⾏测试⽤例-->成功后⽂件另存为.jmx⽂件2、在jmeter的⽬录下新建TestCase⽂件夹3、将该.jmx⽂件存放⾄该⽂件夹下⼆、⼯具准备2、添加环境变量:新建系统变量ANT_HOME在path环境变量中加⼊%ANT_HOME%\bin(注意前⾯分号)3、确认ant环境配置,打开cmd命令提⽰符,输⼊ant -v,出现如下图说明环境配置OK三、整合1、把Jmeter根⽬录\extras下的ant-jmeter-xxx.jar拷贝到ant的根⽬录\lib下To2、将jmeter的根⽬录\extras下的build.xml⽂件复制⼀份到新建的⽂件TestCase⾥去四、修改配置1、修改build.xml⽂件如下2、修改jmeter.properties配置⽂件jmeter.save.saveservice.output_format=csv改为jmeter.save.saveservice.output_format=xml五、⽣成报告1、⽅法⼀:打开cmd命令提⽰符,进⼊build.xml所在⽬录的根⽬录,执⾏ant命令,⼀份简单的报告就这样⽣成了。
2、⽅法⼆:在build.xml同级⽬录创建⼀个build.bat⽂件,⽂件内容为ant,然后双击build.bat,jmeter脚本即可⾃动运⾏并在指定位置⽣成对应的测试报告六、优化报告上述⽣成的报告看起来成功,但如出错很难从报告上定位问题,并定位问题在哪⾥优化过程:1、jmeter默认的报告展⽰信息⽐较少,其实是由.jtl格式转化为.html格式的报告过程中style⽂件起了很关键的作⽤。
这⾥介绍另⼀种style⽂件的使⽤⽅法:A) 下载style⽂件:jmeter.results.shanhe.me.xsl ,该⽂件可⾃⾏⽹上搜索;作者使⽤的是 hph_report.xsl,将上述 build.xml 中 report sytle 值修改为此⽂件名B) 把下载的⽂件放到jmeter的extras⽬录下;2、修改JMeter.properties⽂件如下部分,我这⾥都修改成true,这样执⾏完脚本后就会保存这些结果到.jtl⽂件1 jmeter.save.saveservice.response_code=true2 # response_data is not currently supported for CSV output3 jmeter.save.saveservice.response_data=true4 # Save ResponseData for failed samples5 jmeter.save.saveservice.response_data.on_error=false6 jmeter.save.saveservice.response_message=true7 jmeter.save.saveservice.successful=true8 jmeter.save.saveservice.thread_name=true9 jmeter.save.saveservice.time=true10 jmeter.save.saveservice.subresults=true11 jmeter.save.saveservice.assertions=true12 #tency=true13 # Only available with HttpClient414 jmeter.save.saveservice.connect_time=true15 jmeter.save.saveservice.samplerData=true16 jmeter.save.saveservice.responseHeaders=true17 jmeter.save.saveservice.requestHeaders=true18 jmeter.save.saveservice.encoding=true19 #jmeter.save.saveservice.bytes=true20 # Only available with HttpClient421 jmeter.save.saveservice.sent_bytes=true22 jmeter.save.saveservice.url=true23 jmeter.save.saveservice.filename=true24 jmeter.save.saveservice.hostname=true25 jmeter.save.saveservice.thread_counts=true26 jmeter.save.saveservice.sample_count=true27 jmeter.save.saveservice.idle_time=truejmeter.property3、修改build.xml⽂件,附上⾃⼰的原⽂件,修改⼀下⾃⼰的 jmeter 环境变量地址<?xml version="1.0" encoding="UTF-8"?><!--Licensed to the Apache Software Foundation (ASF) under one or morecontributor license agreements. See the NOTICE file distributed withthis 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 withthe License. You may obtain a copy of the License at/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed 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 andlimitations under the License.--><project name="ant-jmeter" default="all" basedir="."><tstamp><format property="time" pattern="yyyy/MM/dd HH:mm"/><format property="timelog" pattern="yyyyMMddHHmm"/><format property="timeyj" pattern="MMddyyyHHmm"/></tstamp><description>Sample build file for use with ant-jmeter.jarSee /pages/projects/jmeter-ant-task.phpTo run a test and create the output report:ant -Dtest=scriptTo run a test only:ant -Dtest=script runTo run report on existing test outputant -Dtest=script reportThe "script" parameter is the name of the script without the .jmx suffix.Additional options:-Dshow-data=y - include response data in Failure Details-Dtestpath=xyz - path to test file(s) (default user.dir).N.B. Ant interprets relative paths against the build file-Djmeter.home=.. - path to JMeter home directory (defaults to parent of this build file)-Dreport.title="My Report" - title for html report (default is 'Load Test Results')</description><property name="jmeter.home" value="这⾥为 jmeter环境变量⽬录"/><property name="testpath" value="${jmeter.home}/TestCase"/><property name="jmeter.result.jtl.dir" value="${jmeter.home}/TestCase/report/jtl"/><property name="jmeter.result.html.dir" value="${jmeter.home}/TestCase/report/html"/><property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${timelog}.jtl"/><property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${timelog}.html"/> <property name="jmeter.result.htmlNameyj" value="${jmeter.result.html.dir}/${ReportName}${timeyj}.html"/> <property name="lib.dir" value="${jmeter.home}/lib"/><property name="ReportName" value="TestReport"/><!-- Name of test (without .jmx) --><property name="test" value="这⾥填写 jmeter 脚本名称,注意不含.jmx"/><!-- Should report include response data for failures? --><property name="show-data" value="n"/><property name="format" value="2.1"/><condition property="style_version" value="_21"><equals arg1="${format}" arg2="2.1"/></condition><condition property="funcMode"><equals arg1="${show-data}" arg2="y"/></condition><condition property="funcMode" value="false"><not><equals arg1="${show-data}" arg2="y"/></not></condition><!-- Allow jar to be picked up locally (jmeter 相对应 ant-jmeter-1.1.1.jar 包存放地址及包名设置)--><path id="jmeter.classpath"><fileset dir="${jmeter.home}/extras"><include name="ant-jmeter*.jar"/></fileset></path><taskdefname="jmeter"classpathref="jmeter.classpath"classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/><!--运⾏的顺序,先 run test 后 report --><target name="all" depends="run,report"/><target name="run"><echo>funcMode = ${funcMode}</echo><delete file="${jmeter.result.html.dir}/${test}.html"/><jmeterjmeterhome="${jmeter.home}"testplan ="${testpath}/${test}.jmx"resultlog="${jmeter.result.jtl.dir}/${test}.jtl"><!--<jvmarg value="-Xincgc"/><jvmarg value="-Xmx128m"/><jvmarg value="-Dproperty=value"/><jmeterarg value="-qextra.properties"/>--><!-- Force suitable defaults jmeter相对应配置要改为 true--><property name="jmeter.save.saveservice.response_data" value="true"/><property name="jmeter.save.saveservice.samplerData" value="true"/><property name="jmeter.save.saveservice.responseHeaders" value="true"/><property name="jmeter.save.saveservice.requestHeaders" value="true"/><property name="jmeter.save.saveservice.encoding" value="true"/><property name="jmeter.save.saveservice.url" value="true"/><property name="jmeter.save.saveservice.filename" value="true"/><property name="jmeter.save.saveservice.hostname" value="true"/><property name="jmeter.save.saveservice.thread_counts" value="true"/><property name="jmeter.save.saveservice.sample_count" value="true"/><property name="jmeter.save.saveservice.idle_time" value="true"/><property name="jmeter.save.saveservice.output_format" value="xml"/><property name="jmeter.save.saveservice.assertion_results" value="all"/><property name="jmeter.save.saveservice.bytes" value="true"/><property name="file_format.testlog" value="${format}"/><property name="jmeter.save.saveservice.response_data.on_error" value="${funcMode}"/></jmeter></target><property name="lib.dir" value="${jmeter.home}/lib"/><!-- Use xalan copy from JMeter lib directory to ensure consistent processing with Java 1.4+ --><path id="xslt.classpath"><fileset dir="${lib.dir}" includes="xalan*.jar"/><fileset dir="${lib.dir}" includes="serializer*.jar"/></path><target name="report" depends="xslt-report,copy-images"><echo>Report generated at ${report.datestamp}</echo></target><!-- 报告样式设置 --><target name="xslt-report" depends="_message_xalan"><tstamp><format property="report.datestamp" pattern="yyyy/MM/dd HH:mm"/></tstamp><xsltclasspathref="xslt.classpath"force="true"in="${jmeter.result.jtl.dir}/${test}.jtl"out="${jmeter.result.html.dir}/${test}.html"style="${jmeter.home}/extras/jmeter-results-hph_report.xsl"><param name="showData" expression="${show-data}"/><param name="titleReport" expression="${report.title}"/><param name="dateReport" expression="${report.datestamp}"/></xslt></target><!-- Copy report images if needed --><target name="copy-images" depends="verify-images" unless="samepath"><copy file="${basedir}/expand.png" tofile="${testpath}/expand.png"/><copy file="${basedir}/collapse.png" tofile="${testpath}/collapse.png"/></target><target name="verify-images"><condition property="samepath"><equals arg1="${testpath}" arg2="${basedir}"/></condition></target><!-- Check that the xalan libraries are present --><condition property="xalan.present"><and><!-- No need to check all jars; just check a few --><available classpathref="xslt.classpath" classname="org.apache.xalan.processor.TransformerFactoryImpl"/><available classpathref="xslt.classpath" classname="org.apache.xml.serializer.ExtendedContentHandler"/></and></condition><target name="_message_xalan" unless="xalan.present"><echo>Cannot find all xalan and/or serialiser jars</echo><echo>The XSLT formatting may not work correctly.</echo><echo>Check you have xalan and serializer jars in ${lib.dir}</echo></target></project>build.xml将此⽂件覆盖原jmeter-result-report.xsl1<?xml version="1.0" encoding="UTF-8"?>2<xsl:stylesheet xmlns:xsl="/1999/XSL/Transform" version="1.0">3<xsl:output method="html" indent="no" encoding="UTF-8" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system="/TR/html4/loose.dtd"/>4<xsl:strip-space elements="*"/>5<xsl:template match="/testResults">6<html lang="en">7<head>8<meta name="Author" content="shanhe.me"/>9<title>JMeter Test Results</title>10<style type="text/css"><![CDATA[1112 * { margin: 0; padding: 0 }13 html, body { width: 100%; height: 100%; background: #b4b4b4; font-size: 12px }14 table { border: none; border-collapse: collapse; table-layout: fixed }15 td { vertical-align: baseline; font-size: 12px }16 #left-panel { position: absolute; left: 0; top: 0; bottom: 0; width: 300px; overflow: auto; background: #dee4ea }17 #left-panel li.navigation { font-weight: bold; cursor: default; color: #9da8b2; line-height: 18px; background-position: 12px 5px; background-repeat: no-repeat; padding: 0 0 0 25px; background-image: url(data:image/png;base64,iVBOR18 #left-panel li.success { color: #565b60 }19 #left-panel li.failure { color: red }20 #left-panel li { list-style: none; color: black; cursor: pointer }21 #left-panel li.selected { background-repeat: repeat-x; color: white; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAA22 #left-panel div { line-height: 25px; background-position: 25px 3px; background-repeat: no-repeat; padding: 0 0 0 45px }23 #left-panel div.success { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcG24 #left-panel div.failure { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGA25 #left-panel div.detail { display: none }26 #right-panel { position: absolute; right: 0; top: 0; bottom: 0; left: 301px; overflow: auto; background: white }27 #right-panel .group { font-size: 12px; font-weight: bold; line-height: 20px; padding: 0 0 2px 18px; counter-reset: assertion; background-repeat: repeat-x; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA28 #right-panel .zebra { background-repeat: repeat; padding: 0 0 20px 18px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAmCAYAAAAFvPEHAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A29 #right-panel .data { line-height: 24px; white-space: nowrap}30 #right-panel pre.data { white-space: pre-line}31 #right-panel tbody.failure { color: red }32 #right-panel td.key { min-width: 108px }33 #right-panel td.delimiter { min-width: 18px }34 #right-panel td.assertion:before { counter-increment: assertion; content: counter(assertion) ". " }35 #right-panel td.assertion { color: black }36 #right-panel .trail { border-top: 1px solid #b4b4b4 }3738]]></style>39<script type="text/javascript"><![CDATA[4041 var onclick_li = (function() {42 var last_selected = null;43 return function(li) {44 if( last_selected == li )45 return;46 if( last_selected )47 last_selected.className = "";48 last_selected = li;49 last_selected.className = "selected";50 var detail = li.querySelector('div.detail');51 // deleted52 //document.getElementById("right-panel").innerHTML = last_selected.firstChild.nextSibling.innerHTML;53 // add54 document.getElementById("right-panel").innerHTML = detail.innerHTML;55 return false;56 };57 })();5859 var patch_timestamp = function() {60 var spans = document.getElementsByTagName("span");61 var len = spans.length;62 for( var i = 0; i < len; ++i ) {63 var span = spans[i];64 if( "patch_timestamp" == span.className )65 span.innerHTML = new Date( parseInt( span.innerHTML ) );66 }67 };6869 var patch_navigation_class = (function() {7071 var set_class = function(el, flag) {72 if(el) {73 el.className += flag ? " success" : " failure";74 }75 };7677 var traverse = function(el, group_el, flag) {78 while(1) {79 if(el) {80 if(el.className == 'navigation') {81 set_class(group_el, flag);82 group_el = el;83 flag = true;84 } else {85 var o = el.firstChild;86 o = o ? o.className : null;87 flag = flag ? (o == 'success') : false;88 }89 el = el.nextSibling;90 } else {91 set_class(group_el, flag);92 break;93 }94 }95 };9697 return function() {98 var o = document.getElementById("result-list");99 o = o ? o.firstChild : null;100 if(o)101 traverse(o, null, true);102 };103 })();104105 window.onload = function() {106 patch_timestamp();107 patch_navigation_class();108 // deleted109 //var o = document.getElementById("result-list");110 //o = o ? o.firstChild : null;111 //o = o ? o.nextSibling : null;112 // add113 var o = document.querySelector('li[onclick]');114 if(o)115 onclick_li(o);116 };117118]]></script>119</head>120<body>121<div id="left-panel">122<ol id="result-list">123<li onclick="return onclick_li(this);">124<div>测试结果概况</div>125<div class="detail">126<div class="zebra">127<xsl:call-template name="summary"/>128</div>129<div class="zebra">130<xsl:call-template name="pagelist"/>131</div>132</div>133</li>134<xsl:for-each select="*">135<!-- group with the previous sibling -->136<!--137 <xsl:if test="position() = 1 or @tn != preceding-sibling::*[1]/@tn">138 <li class="navigation">Thread: <xsl:value-of select="@tn"/></li>139 </xsl:if>140-->141<li onclick="return onclick_li(this);">142<div>143<xsl:attribute name="class">144<xsl:choose>145<xsl:when test="@s = 'true'">success</xsl:when>146<xsl:otherwise>failure</xsl:otherwise>147</xsl:choose>148</xsl:attribute>149<xsl:value-of select="@lb"/>150</div><div class="detail">151<div class="group">Sampler</div>152<div class="zebra">153<table>154<tr><td class="data key">Thread Name</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@tn"/></td></tr>155<tr><td class="data key">Timestamp</td><td class="data delimiter">:</td><td class="data"><span class="patch_timestamp"><xsl:value-of select="@ts"/></span></td></tr>156<tr><td class="data key">Time</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@t"/> ms</td></tr>157<tr><td class="data key">Latency</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@lt"/> ms</td></tr>158<tr><td class="data key">Bytes</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@by"/></td></tr>159<tr><td class="data key">Sample Count</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@sc"/></td></tr>160<tr><td class="data key">Error Count</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@ec"/></td></tr>161<tr><td class="data key">Response Code</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@rc"/></td></tr>162<tr><td class="data key">Response Message</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="@rm"/></td></tr>163</table>164</div>165<div class="trail"></div>166<xsl:if test="count(assertionResult) > 0">167<div class="group">Assertion</div>168<div class="zebra">169<table>170<xsl:for-each select="assertionResult">171<tbody>172<xsl:attribute name="class">173<xsl:choose>174<xsl:when test="failure = 'true'">failure</xsl:when>175<xsl:when test="error = 'true'">failure</xsl:when>176</xsl:choose>177</xsl:attribute>178<tr><td class="data assertion" colspan="3"><xsl:value-of select="name"/></td></tr>179<tr><td class="data key">Failure</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="failure"/></td></tr>180<tr><td class="data key">Error</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="error"/></td></tr>181<tr><td class="data key">Failure Message</td><td class="data delimiter">:</td><td class="data"><xsl:value-of select="failureMessage"/></td></tr>182</tbody>183</xsl:for-each>184</table>185</div>186<div class="trail"></div>187</xsl:if>188<div class="group">Request</div>189<div class="zebra">190<table>191<tr><td class="data key">Method/Url</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="method"/><xsl:text></xsl:text><xsl:value-of select=".URL" 192<tr><td class="data key">Query String</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="queryString"/></pre></td></tr>193<tr><td class="data key">Cookies</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="cookies"/></pre></td></tr>194<tr><td class="data key">Request Headers</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="requestHeader"/></pre></td></tr>195</table>196</div>197<div class="trail"></div>198<div class="group">Response</div>199<div class="zebra">200<table>201<tr><td class="data key">Response Headers</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="responseHeader"/></pre></td></tr>202<tr><td class="data key">Response Data</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="responseData"/></pre></td></tr>203<tr><td class="data key">Response File</td><td class="data delimiter">:</td><td class="data"><pre class="data"><xsl:value-of select="responseFile"/></pre></td></tr>204</table>205</div>206<div class="trail"></div>207</div>208</li>209</xsl:for-each>210</ol>211</div>212<div id="right-panel"></div>213<script>214 Spliter = function (objLeft, objRight) {215 this.flag = false;216 var ele = document.createElement('div');217 document.body.append(ele);218 ele.style.height = "100%";219 ele.style.position = "absolute";220 ele.style.width = "5px";221 ele.style.left = objLeft.offsetWidth - 2 + "px";222 ele.style.backgroundColor = "gray";223 ele.style.opacity = 0;224225 this.ele = ele226 this.objLeft = objLeft;227 this.objRight = objRight;228 this.ele.style.cursor = "w-resize"; //设置⿏标样式229 this.up = function (event) {230 if (this.flag) {231 if (this.ele.releaseCapture) {232 this.ele.releaseCapture();233 }234 else {235 document.removeEventListener('mouseup', this.up.bind(this), true);236 document.removeEventListener('mousemove', this.move.bind(this), true);237 event.preventDefault();238 }239240 this.ele.style.opacity = 0;241 this.flag = false;242 }243 };244 this.down = function (event) {245 if (!this.flag) {246 if (this.ele.setCapture)247 this.ele.setCapture();248 else {249 document.addEventListener('mouseup', this.up.bind(this), true);250 document.addEventListener('mousemove', this.move.bind(this), true);251 event.preventDefault();252 }253254 this.ele.style.opacity = 0.5;255 this.flag = true;256 }257 };258 this.move = function (event) {259260 if (this.flag) {261 var minWidth = 10;262 var left = Math.max(minWidth, event.clientX);263 this.objLeft.style.width = left + "px";264 this.objRight.style.left = left + "px";265 this.ele.style.left = left - 2 + "px";266 if (!this.ele.releaseCapture) {267 event.preventDefault();268 }269 }270 }271 var t = this;272 this.ele.onmousedown = function () {273 t.down(event);274 }275276 this.ele.onmouseup = function () {277 t.up(event);278 }279280 this.ele.onmousemove = function () {281 t.move(event);282 }283 return this;284 }285286 new Spliter(document.getElementById("left-panel"), document.getElementById("right-panel"));287</script>288</body>289290</html>291</xsl:template>292<xsl:template name="summary">293<div class="group">Summary</div>294<table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">295<tr valign="top">296<th>请求总数</th>297<th>异常数</th>298<th>成功率</th>299<th>平均消耗时间</th>300<th>最⼩消耗时间</th>301<th>最⼤消耗时间</th>302</tr>303<tr valign="top">304<xsl:variable name="allCount" select="count(/testResults/*)"/>305<xsl:variable name="allFailureCount" select="count(/testResults/*[attribute::s='false'])"/>306<xsl:variable name="allSuccessCount" select="count(/testResults/*[attribute::s='true'])"/>307<xsl:variable name="allSuccessPercent" select="$allSuccessCount div $allCount"/>308<xsl:variable name="allTotalTime" select="sum(/testResults/*/@t)"/>309<xsl:variable name="allAverageTime" select="$allTotalTime div $allCount"/>310<xsl:variable name="allMinTime">311<xsl:call-template name="min">312<xsl:with-param name="nodes" select="/testResults/*/@t"/>313</xsl:call-template>314</xsl:variable>315<xsl:variable name="allMaxTime">316<xsl:call-template name="max">317<xsl:with-param name="nodes" select="/testResults/*/@t"/>318</xsl:call-template>319</xsl:variable>320<xsl:attribute name="class">321<xsl:choose>322<xsl:when test="$allFailureCount > 0">Failure</xsl:when>323</xsl:choose>324</xsl:attribute>325<td align="center">326<xsl:value-of select="$allCount"/>327</td>328<xsl:if test="$allFailureCount > 0">329<td align="center" style="color:red">330<xsl:value-of select="$allFailureCount"/>331</td>332</xsl:if>333<xsl:if test="0 >= $allFailureCount">334<td align="center">335<xsl:value-of select="$allFailureCount"/>336</td>337</xsl:if>338<td align="center">339<xsl:call-template name="display-percent">340<xsl:with-param name="value" select="$allSuccessPercent"/>341</xsl:call-template>342</td>343<td align="center">344<xsl:call-template name="display-time">345<xsl:with-param name="value" select="$allAverageTime"/>346</xsl:call-template>347</td>348<td align="center">349<xsl:call-template name="display-time">350<xsl:with-param name="value" select="$allMinTime"/>351</xsl:call-template>352</td>353<td align="center">354<xsl:call-template name="display-time">355<xsl:with-param name="value" select="$allMaxTime"/>356</xsl:call-template>357</td>358</tr>359</table>360</xsl:template>361362<xsl:template name="pagelist">363<div class="group">Pages</div>364<table align="center" class="details" border="0" cellpadding="5" cellspacing="2" width="95%">365<tr valign="top">366<th width="50%">请求内容</th>367<th>请求数</th>368<th>异常数</th>369<th>成功率</th>370<th>平均消耗时间</th>371<th>最⼩消耗时间</th>372<th>最⼤消耗时间</th>373</tr>374<xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">375<xsl:variable name="label" select="@lb"/>376<xsl:variable name="count" select="count(../*[@lb = current()/@lb])"/>377<xsl:variable name="failureCount" select="count(../*[@lb = current()/@lb][attribute::s='false'])"/> 378<xsl:variable name="successCount" select="count(../*[@lb = current()/@lb][attribute::s='true'])"/> 379<xsl:variable name="successPercent" select="$successCount div $count"/>380<xsl:variable name="totalTime" select="sum(../*[@lb = current()/@lb]/@t)"/>381<xsl:variable name="averageTime" select="$totalTime div $count"/>382<xsl:variable name="minTime">383<xsl:call-template name="min">384<xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t"/>385</xsl:call-template>386</xsl:variable>387<xsl:variable name="maxTime">388<xsl:call-template name="max">389<xsl:with-param name="nodes" select="../*[@lb = current()/@lb]/@t"/>390</xsl:call-template>391</xsl:variable>392<tr valign="top">393<xsl:attribute name="class">。
antd steps用法
antd steps用法## antd steps用法### 概述`antd steps` 是 Ant Design 为了实现步骤条功能而提供的组件。
步骤条通常用于指示当前操作进度,并提供导航功能。
本文将介绍 `antd steps` 的基本用法。
### 使用步骤下面是 `antd steps` 的基本使用步骤:1. 首先,安装 Ant Design 的依赖包。
可以通过在终端中运行以下命令来安装:```npm install antd```2. 在需要使用步骤条的文件中,引入所需的模块:```javascriptimport { Steps } from 'antd';import 'antd/dist/antd.css';```3. 使用 `Steps` 组件,通过传递一个数组来定义步骤条的内容:```javascriptconst steps = [{title: '第一步',content: '这里是第一步的内容'},{title: '第二步',content: '这里是第二步的内容'},{title: '第三步',content: '这里是第三步的内容'}];const App = () => {return (<div><Steps current={0}>{steps.map(step => (<Steps.Step title={step.title} key={step.title} /> ))}</Steps><div>{steps[0].content}</div></div>);}```4. 最后,在需要显示步骤内容的地方,可以根据当前步骤的索引显示相应的内容:```javascript<div>{steps[当前步骤索引].content}</div>```请将 "当前步骤索引" 替换为你需要的值。
ant-design中的createstyles -回复
ant-design中的createstyles -回复Ant Design 是一个面向企业级设计的UI 框架,它由阿里巴巴前端团队开发并开源。
在Ant Design 中,createStyle 是一种创建样式的方法,它可以帮助开发者更加高效地进行样式定制和管理。
本文将从什么是createStyle 开始,逐步深入探讨其用法和作用,帮助读者更好地理解和应用这个功能。
首先,我们来了解一下createStyle 的基本概念。
CreateStyle 是Ant Design 提供的一个全局函数,它可以用于创建组织和管理样式的工具函数。
使用createStyle 可以将样式与组件解耦,提供了更好的可维护性和复用性。
接下来,让我们一步一步详细介绍createStyle 的使用方法。
第一步,安装Ant Design。
在使用createStyle 之前,我们需要先安装Ant Design 框架。
可以通过npm 或yarn 包管理工具进行安装。
打开终端,输入以下命令完成安装:npm install antd或者yarn add antd安装完成后,我们就可以在项目中引入Ant Design 的组件和样式,为后续使用createStyle 做准备。
第二步,引入createStyle。
在项目中的需要使用createStyle 的文件中,我们需要先引入createStyle。
代码如下:import { createStyle } from 'antd';这样,我们就可以在文件中使用createStyle 函数了。
第三步,使用createStyle。
在本步骤中,我们将通过一个简单的示例来演示如何使用createStyle。
假设我们需要创建一个自定义的按钮样式。
首先,我们可以使用createStyle 创建一个样式类。
代码如下:const ButtonStyle = createStyle(() => ({button: {backgroundColor: 'blue',color: 'white',padding: '8px 16px',borderRadius: '4px',cursor: 'pointer',},}));在上述代码中,我们通过createStyle 定义了一个名为ButtonStyle 的样式类。
