时间: 2021-07-31 作者:daque
在web开拓中,咱们常常会遇到分页表露和排底数据记载集的情景,这在效劳器端运用效劳器端的代码和数据库本领是件很轻快的工作,比方:asp、php、jsp等。但是,即使要在存户端表露多条记载而且排序是一件很令人头疼的工作。底下,咱们运用extensible markup language(xml,可扩充标志谈话)和extensible stylesheet language transformations(xslt,可扩充款式单谈话变换),并贯串xml path language(xpath,xml路途谈话),只须要编写大略的代码,就可轻快实行。这种本领制止了与效劳器一再打交道的进程,俭朴了数据表露的功夫,欣赏者不必等候就不妨看到截止,也不妨缩小效劳器的承担。其余。因为xml和xslt本领,使数据保存和数据表露辨别,还不妨让咱们的代码不妨反复运用,大大减少了步调员编写代码的承担。 底下,咱们一步一步地来实行咱们的功效。 开始:创造xslt xslt款式单的第一条龙表明该xml所按照的xml典型本子,而后是表明该款式单运用的称呼空间,这边,咱们以xsl典型的正式版从来举行编写,而不沿用xsl的草案的写法: <xsl:stylesheet xmlns:xsl="http://www.w3.org/tr/wd-xsl"> 提防:两者在功效和写法上有很大的分别。 <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"> 接下来,咱们设置xslt里的沙盘标志: <xsl:template match="/"> <xsl:apply-templates select="/存户联系表"/> </xsl:template> <xsl:template match="/存户联系表"></xsl:template> 咱们把要表露的款式写到沙盘内里。咱们运用html的数据岛来寄存咱们的数据,那些数据不妨运用sql server 2000的xml查问来获得,对于不扶助xml的数据库,咱们不妨本人编写组件把数据变换成xml方法,而后在放到数据岛里。在html里运用数据岛有两种本领: 一是径直嵌入数据,如次所示: <xml id=''data''> <存户联系表> <存户>每条数据</存户> </存户联系表> </xml> 二是经过src属性援用外部文献,如次所示: <xml id=''data'' src=''data.xml''></xml> 要运用数据岛里的数据,必需经过id名来援用它,固然,因为xslt文献也是xml方法文献的一种,也不妨经过这种本领来实行: <xml id=''style'' src=''style.xsl''></xml> 咱们在页面中介入标志div来表露咱们的变换的截止: <div id="displayarea"></div> 运用xslt变换数据岛里的数据,沿用domdocument的transnode()本领,并把截止经过div的innerhtml属性来展示出来: displayarea.innerhtml = data.transformnode(style.documentelement) 第二步:实行存户端排序的功效 咱们先设定一个默许的排序字段,这边采用“序号”动作默许的排序要害字,而且是按递加的程序陈设,在xslt里介入sort标志: <xsl:for-each select="存户"> <xsl:sort select="序号" order="descending" data-type="number"/> </xsl:for-each> 接下来,咱们为款式表减少排序的功效,再不不妨相应用户的操纵,咱们在表头的每个列上增添onclick事变,该事变挪用sort()因变量,承诺用户经过单击该表头来举行对该列的排序。 <td onclick="sort(''序号'')">序号</td> sort()因变量的语句如次所示: function sort(strfield) dim sortfield dim sortorderattribute '' 获得从来排序字段的属性值 set sortfield = style.xmldocument.selectsinglenode("//xsl:sort/@select") '' 获得从来排序的程序属性值 set sortorderattribute = style.xmldocument.selectsinglenode("//xsl:sort/@order") '' 即使咱们仍旧按所点击的列的字段排序,咱们必需变换排序的程序; '' 要不,咱们只须要按新所点击的列字段按默许的程序举行排序 if sortfield.value = strfield or sortfield.value = "./*[0]" then if sortorderattribute.value = "descending" then sortorderattribute.value = "ascending" else sortorderattribute.value = "descending" end if else sortfield.value = strfield sortorderattribute.value = "ascending" end if set sortfield = nothing set sortorderattribute = nothing '' 输入排序后的截止 displayarea.innerhtml = data.transformnode(style.documentelement) end function 底下,咱们实行每页面表露的记载数和设定前页、后页的功效。运用span标志表露暂时表露的是第几页、共几何页和记载的总额。咱们默许每页表露6条记载,用变量intrecordsperpage生存该值: <table width="100%" border="0" style="font-size:9pt"> <tr> <td align="left"><b>第 <span id="currentpage"></span> 页 总 <span id="pagecount"></span> 页 公有 <span id="recordcount"></span> 条记载</b></td> <td align="right"><b>每页记载数:<input onblur="setrecordsperpage()" id="recordsperpage" style="vertical-align:middle;height:15pt;width:30px"/></b></td> <td align="right"> <span id="paging"> <input type="button" onclick="firstpage()" value="第一页"/> <input type="button" onclick="previouspage(1)" value="上一页"/> <input type="button" onclick="nextpage(1)" value="下一页"/> <input type="button" onclick="lastpage()" value="最末页"/> </span> </td> </tr> </table> 底下以“下一页”按钮实行的操动作例子,证明变换各别页面包车型的士处置进程。该因变量按照参数intpage来确定要表露的记载的条数和相映的页面,每个按钮value值的变革是经过动静变换xsl dom的实质来实行的: function nextpage(intpage) dim strdisplay dim strdaterange if cint(cstr(intpage) * intrecordsperpage) < _ data.selectnodes("/存户联系表/存户").length then intpage = cint(intpage) + 1 style.xmldocument.selectnodes("//@onclick") _ (1).value = "previouspage(" & intpage & ")" style.xmldocument.selectnodes("//@onclick") _ (2).value = "nextpage(" & intpage & ")" style.xmldocument.selectnodes _ ("//xsl:for-each/@select")(1).value = _ "./存户[position() <= " & (cstr(intpage) _ * intrecordsperpage) & " and position() > " _ & (cint(intpage) - 1) * intrecordsperpage & _ "]" redisplay (intpage) end if end function 底下,咱们来看看树立每个页面记载条数的因变量setrecordsperpage(),该因变量经过动静窜改xsl:for-each的select属性值来实行的,运用xpath来遍历那些适合节点场所大于0而且节点场所小于每页记载数加1的那些节点。个中重要的语句是底下的一条龙: style.xmldocument.selectnodes("//xsl:for-each/@select")(1). _ value = "./存户[position() < " & intrecordsperpage + 1 & " and "& " position() > 0]" 到暂时为止,咱们的页面既不妨实行排序,也实行动静变换每页表露记载条数的功效了,为了实行可重用的诉求,咱们还不妨进前进一步的矫正。xpath是举行xml/xslt运用开拓的一个强有力的东西,xpath中不妨运用通配符,使xslt款式单文献实足不依附于你的数据节点称呼。所以,咱们在变换xml数据的功夫,只有不改背叛点的档次联系,不妨不用变换xslt就不妨径直运用。比方:在本例中,你不妨增添大概简略某些字段、或增添简略少许记载,径直运用本例中的xslt,不只不妨在表格里平常表露出数据,并且还能平常排序和分页。 底下咱们就领会一下是怎样实行的。比方底下的档次联系: <存户联系表> <存户> <序号></序号> <全名></全名> <电子邮件></电子邮件> </存户> </存户联系表> 假设咱们的xslt中有如许一个采用沙盘的句子: <xsl:apply-templates select="/存户联系表"/> 为了实行通用性的诉求,咱们不妨运用通配符: <xsl:apply-templates select="/*"/> 这边咱们运用了子演算符"/",它采用了根下的一切节点,两者的各别点在乎:"/存户联系表"采用的是根下的存户联系表子节点,而"/*"采用的是根下一切的径直子节点,在上头的xml数据方法中,二者是实足等价的。 对于底下的for-each轮回来说: <xsl:for-each select="存户"> <xsl:sort select="序号" order="ascending"/> </xsl:for-each> 咱们不妨改形成如许的情势: <xsl:for-each select="./*"> <xsl:sort select="./*[1]" order="ascending"/> </xsl:for-each> 这边"./*"表白你该当包括进去暂时节点下一切的头等子节点,语法"./*[1]"表白的是采用暂时节点中的第一个子节点。 其余再有一个场合不妨矫正的是<xsl:value-of select="序号"/>,咱们不妨把它改成<xsl:value-of select="."/>,表白在每一次轮回中采用暂时节点。 在咱们的因变量中,还运用了少许硬代码,即使不做变换的话,咱们的通用性仍旧实行不了,所以,咱们底下就看看怎样替代硬代码中的语句。 在创造表头的功夫,咱们运用了<td onclick="sort(''序号'')"> 序号</td>的语句,即使xml数据里没无序号节点的话,这边明显会展示缺点的,为了实行通用性,咱们自设置了一个因变量getname,来博得所要表露的节点的称呼: <td> <xsl:attribute name="onclick"> sort(''<xsl:value-of select="user:getname(.)"/>'') </xsl:attribute> <xsl:value-of select="user:getname(.)"/> </td> 自设置因变量是xslt的一个超过的功效,要运用这个个性,咱们得用msxml:script元从来设置,同声,必需在款式单设置的功夫指定一个用户设置的名字空间。底下即是咱们运用自设置因变量的十足实质: <xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/xsl/transform xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://lucky.myrice.com" version="1.0"> <msxsl:script language="vbscript" implements-prefix="user"> <![cdata[ function getname(node) getname = node.item(0).nodename end function }> </msxsl:script>
在咱们的xslt文献中,运用了两个轮回,咱们辨别举行相映的变动,第一处:表露表头的场合改为<xsl:for-each select="./*[1]/*">,它同等于<xsl:for-each select="存户联系表/存户[1]/*">;第二处轮回是表露每行记载,改成<xsl:for-each select="./*">。再有其余的场合须要变动的,请拜见反面的完备源代码局部。如许咱们就实行了通用的xslt文献,尽管你的xml数占有几何字段,也尽管节点称呼是什么,咱们都无需变动xslt文献,就不妨实行咱们的功效了。最后的欣赏功效将会象下图所示:
以次是完备的style.xsl文献的实质: <?xml version="1.0" encoding="gb2312"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://lucky.myrice.com" version="1.0"> <msxsl:script language="vbscript" implements-prefix="user"> <![cdata[ function getname(node) getname = node.item(0).nodename end function }> </msxsl:script> <xsl:template match="/"> <xsl:apply-templates select="/*"/> </xsl:template> <xsl:template match="/*"> <table width="100%" border="0" style="font-size:9pt"> <tr> <td align="left"><b>第 <span id="currentpage"></span> 页 总 <span id="pagecount"></span> 页 公有 <span id="recordcount"></span> 条记载</b></td> <td align="right"><b>每页记载数:<input onblur="setrecordsperpage()" id="recordsperpage" style="vertical-align:middle;height:15pt;width:30px"/></b></td> <td align="right"> <span id="paging"> <input type="button" onclick="firstpage()" value="第一页"/> <input type="button" onclick="previouspage(1)" value="上一页"/> <input type="button" onclick="nextpage(1)" value="下一页"/> <input type="button" onclick="lastpage()" value="最末页"/> </span> </td> </tr> </table> <table width="100%" border="0" cellpadding="0" cellspacing="1" style="font-size:11pt" bgcolor="#0099ff"> <tr bgcolor="#ff6600" style="cursor: hand;padding:5px"> <xsl:for-each select="./*[1]/*"> <td align="center"> <xsl:attribute name="onclick"> sort(''<xsl:value-of select="user:getname(.)"/>'') </xsl:attribute> <font color="#eeeeee"><b><u><xsl:value-of select="user:getname(.)"/></u></b></font> </td> </xsl:for-each> </tr> <xsl:for-each select="./*[position() < 6 and position() > 0]"> <xsl:sort select="./*[1]" order="ascending"/> <tr bgcolor="#ffccff"> <xsl:for-each select="./*"> <td> <xsl:value-of select="."/></td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet> 以次是举行输入的exam.htm文献: <html> <head> <meta http=equiv="content-type" content="text/html;charset=utf8"> <style> body { font-family:宋体; font-size:9pt;} th { font-family:宋体; font-size:11pt; font-weight:bold;} </style> <script language="vbscript"> option explicit dim intrecordsperpage ''每个页面表露的记载数 intrecordsperpage = 6 ''每个页面表露的记载数,默许设定于6 '' 革新表露页面包车型的士因变量 function window_onload() '' 表露设定的记载数 style.xmldocument.selectnodes("//xsl:for-each/@select")(1).value = "./*[position() < " & intrecordsperpage + 1 & " and position() > 0]" transform() setpagecount() end function '' 举行xml-xslt变换,并表露暂时记载的少许消息 function transform() displayarea.innerhtml = data.transformnode(style.documentelement) recordsperpage.value = intrecordsperpage end function '' 从新变换xml,并表露一个状况消息 function redisplay(intpage) dim strdisplay dim intpagecount dim intrecordcount '' 生存状况消息 intpagecount = pagecount.innerhtml intrecordcount = recordcount.innerhtml transform() '' 表露状况消息 pagecount.innerhtml = intpagecount recordcount.innerhtml = intrecordcount currentpage.innerhtml = intpage end function '' 从新排序和表露 function sort(strfield) dim sortfield dim sortorderattribute '' 获得排序属性值 set sortfield = style.xmldocument.selectsinglenode("//xsl:sort/@select") set sortorderattribute = style.xmldocument.selectsinglenode("//xsl:sort/@order") '' 变换排序的办法 if sortfield.value = strfield or sortfield.value = "./*[0]" then if sortorderattribute.value = "descending" then sortorderattribute.value = "ascending" else sortorderattribute.value = "descending" end if else sortfield.value = strfield sortorderattribute.value = "ascending" end if set sortfield = nothing set sortorderattribute = nothing redisplay (currentpage.innerhtml) end function '' 从新树立每页的记载数 function setrecordsperpage() if isnumeric(recordsperpage.value) then intrecordsperpage = cint(recordsperpage.value) window_onload end if end function '' 表露页数消息 function setpagecount() dim inttotalrecords pagecount.innerhtml = getnumberofpages(inttotalrecords) recordcount.innerhtml = inttotalrecords currentpage.innerhtml = 1 end function '' 计划总页数和总记载数 function getnumberofpages(inttotalrecords) dim intpages inttotalrecords = data.xmldocument.selectnodes("/*/*").length intpages = inttotalrecords / intrecordsperpage if instr(intpages, ".") > 0 then intpages = cint(left(intpages, instr(intpages, "."))) + 1 end if getnumberofpages = intpages end function '' “下一页”的处置 function nextpage(intpage) dim strdisplay dim strdaterange if cint(cstr(intpage) * intrecordsperpage) < data.selectnodes("/*/*").length then intpage = cint(intpage) + 1 style.xmldocument.selectnodes("//@onclick")(1).value = "previouspage(" & intpage & ")" style.xmldocument.selectnodes("//@onclick")(2).value = "nextpage(" & intpage & ")" style.xmldocument.selectnodes("//xsl:for-each/@select")(1).value = "./*[position() <= " & (cstr(intpage) * intrecordsperpage) & " and position() > " & (cint(intpage) - 1) * intrecordsperpage & "]" redisplay (intpage) end if end function '' 处置“上一页” function previouspage(intpage) dim strdisplay dim strdaterange if intpage > 1 then intpage = cint(intpage) - 1 style.xmldocument.selectnodes("//@onclick")(1).value = "previouspage(" & intpage & ")" style.xmldocument.selectnodes("//@onclick")(2).value = "nextpage(" & intpage & ")" style.xmldocument.selectnodes("//xsl:for-each/@select")(1).value = "./*[position() <= " & (cstr(intpage) * intrecordsperpage) & " and position() > " & (cint(intpage) - 1) * intrecordsperpage & "]" redisplay (intpage) end if end function '' “第一页”的处置 function firstpage() style.xmldocument.selectnodes("//@onclick")(1).value = "previouspage(1)" style.xmldocument.selectnodes("//@onclick")(2).value = "nextpage(1)" style.xmldocument.selectnodes("//xsl:for-each/@select")(1).value = "./*[position() < " & intrecordsperpage + 1 & " and position() > 0]" transform() setpagecount() end function '' “最末页”的处置 function lastpage() dim inttotalpages dim inttotalrecords inttotalpages = getnumberofpages(inttotalrecords) nextpage (inttotalpages - 1) end function </script> </head> <body> <p align="center" style="font-weight:bold;font-size:12pt;color:#0000ff;border-bottom:3px double red;padding-bottom:5px">存户联系表</p> <xml id=''data''> <存户联系表 xmlns:dt="urn:schemas-microsoft-com:datatypes"> <存户><序号 dt:dt="int">01</序号><全名>mi</全名><电子邮件>water@21cn.com</电子邮件></存户> <存户><序号 dt:dt="int">02</序号><全名>uyi</全名><电子邮件>lily@sina.com</电子邮件></存户> <存户><序号 dt:dt="int">03</序号><全名>uiyu</全名><电子邮件>john@21cn.com</电子邮件></存户> <存户><序号 dt:dt="int">04</序号><全名>doug</全名><电子邮件>karry@163.net</电子邮件></存户> <存户><序号 dt:dt="int">05</序号><全名>ellen</全名><电子邮件>vivki@sina.com</电子邮件></存户> <存户><序号 dt:dt="int">06</序号><全名>frank</全名><电子邮件>net_lover@mengxianhui.com.cn</电子邮件></存户> <存户><序号 dt:dt="int">07</序号><全名>greg</全名><电子邮件>meng@mengxianhui.com</电子邮件></存户> <存户><序号 dt:dt="int">08</序号><全名>harry</全名><电子邮件>sunny@xianhui.net</电子邮件></存户> <存户><序号 dt:dt="int">09</序号><全名>ingrid</全名><电子邮件>cathy@hotmail.com</电子邮件></存户> <存户><序号 dt:dt="int">10</序号><全名>jeff</全名><电子邮件>your@mxh.com</电子邮件></存户> <存户><序号 dt:dt="int">11</序号><全名>kelly</全名><电子邮件>iloveyou@mengxianhui.com</电子邮件></存户> <存户><序号 dt:dt="int">12</序号><全名>larry</全名><电子邮件>smilling@mengxianhui.com</电子邮件></存户> <存户><序号 dt:dt="int">13</序号><全名>mark</全名><电子邮件>money@21cn.com</电子邮件></存户> <存户><序号 dt:dt="int">14</序号><全名>nancy</全名><电子邮件>www@yahoo.com</电子邮件></存户> <存户><序号 dt:dt="int">15</序号><全名>peter</全名><电子邮件>dotnet@aol.com</电子邮件></存户> <存户><序号 dt:dt="int">16</序号><全名>rachel</全名><电子邮件>billgates@microsoft.com</电子邮件></存户> <存户><序号 dt:dt="int">17</序号><全名>seth</全名><电子邮件>flying@yous.net</电子邮件></存户> <存户><序号 dt:dt="int">18</序号><全名>tim</全名><电子邮件>agooyboy@lovegirl.com</电子邮件></存户> </存户联系表> </xml> <xml id=''style'' src=''style.xsl''></xml> <div id="displayarea"></div> <table border="0" width="100%" style="font-size:11pt;"> <tr> <td align="right">材料根源:【<a href="http://lucky.myrice.com">孟宪会之精粹寰球</a>】</td> </tr> </table> </body> </html> 把上头的实质正片到当地计划机上,辨别生存为相映的文献,在ie5+和xml3.0+的情况下即可看到功效!