xml| | page | sort | data | show | page
In web development, we often encounter paging display and sorting data recordset, which use server-side code and database technology is a very easy thing, such as: ASP, PHP, JSP and so on. However, if you want to display more than one record on the client side, sorting is a very frustrating thing. We take advantage of the Extensible Markup Language (XML, Extensible Markup Language) and Extensible Stylesheet Language Transformations (XSLT, extensible Style Single Language conversion), Combined with XML Path Language (xpath,xml path language), it is easy to write simple code. This method avoids the process of dealing with the server frequently, saves the time that the data displays, the viewer can see the result without waiting, also can reduce the burden of the server. Other than that. The separation of data storage and data display by XML and XSLT technology can also allow our code to be reused, greatly reducing the burden on programmers to write code.
Below, we implement our functions step-by-step.
First: Create an XSLT
The first line of the XSLT style sheet identifies the XML specification version that the XML complies with, and then the namespace used to indicate the style sheet, where we write in the official version of the XSL specification, rather than using the XSL draft:
<xsl:stylesheet xmlns:xsl= "http://www.w3.org/TR/WD-xsl" >
Note: There is a big difference between the two in the function and the wording.
<?xml version= "1.0"?>
<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" >
Next, we define the template tags in the XSLT:
<xsl:template match= "/" >
<xsl:apply-templates select= "/customer Relationship table"/>
</xsl:template>
<xsl:template match= "/Customer Relationship Table" ></xsl:template>
We write the style to be displayed in the template. We use HTML data islands to store our data, which can take advantage of SQL Server 2000 XML queries, and for databases that do not support XML, we can write our own components to convert the data into XML format, and then put it in the data island. There are two ways to use a data island in HTML:
The first is to embed the data directly, as follows:
<xml id= ' data ' >
< customer Relationship Table >
< customer > per data </customer >
</Customer Relationship Table >
</xml>
The second is to refer to the external file through the SRC attribute, as follows:
<xml id= ' data ' src= ' Data.xml ' ></xml>
To use the data in the data island, you must refer to it by ID name, of course, because the XSLT file is also one of the XML format files, which can be implemented by this method:
<xml id= ' style ' src= ' style.xsl ' ></xml>
We add a tag div to the page to show the result of our transformation:
<div id= "Displayarea" ></div>
Using XSLT to transform data in the data island, use the DOMDocument Transnode () method and display the results through the innerHTML attribute of the DIV:
displayarea.innerhtml = Data.transformnode (style.documentelement)
Step two: Enable the client to sort the function
We first set a default sort field, where we select "ordinal" as the default sort key, and in ascending order, add the sort tag in the XSLT:
<xsl:for-each select= "Customer" >
<xsl:sort select= "ordinal" order= "descending" data-type= "number"/>
</xsl:for-each>
Next, we add the sort function to the stylesheet so that we can respond to the user's actions, we added the onclick event on each column of the header, which calls the sort () function, which allows the user to sort the column by clicking the header.
<TD > Serial number </td>
The statement for the sort () function looks like this:
function sort (Strfield)
Dim SortField
Dim Sortorderattribute
' Get the property value of the original sort field
Set SortField = Style.xmldocument.selectsinglenode ("//xsl:sort/@select")
' Gets the order attribute value of the original sort
Set sortorderattribute = Style.xmldocument.selectsinglenode ("//xsl:sort/@order")
' If we have sorted by the fields of the columns we clicked, we have to change the order of the sort;
' Otherwise, we just need to sort by the default order of the newly clicked column fields.
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
' Output sorted after the result
displayarea.innerhtml = Data.transformnode (style.documentelement)
End Function
Below, we implement the number of records displayed per page and set the function of the front page and the back page. Use the span tag to display the total number of pages, total pages, and records currently displayed. We default to display 6 records per page, save the value with variable intrecordsperpage:
<table width= "100%" border= "0" style= "font-size:9pt" >
<tr>
<TD align= "left" ><b> <span id= "currentpage" ></span> page total <span id= "PageCount" ></span > Page Total <span id= "RecordCount" ></span> Records </b></td>
<TD align= "Right" ><b> records per page: <input onblur= "Setrecordsperpage ()" id= "Recordsperpage" style= " vertical-align:middle;height:15pt;width:30px "/></b></td>
<TD align= "Right" >
<span id= "Paging" >
<input type= "button" value= "first page"/>
<input type= "button" value= "previous page"/>
<input type= "button" value= "next page"/>
<input type= "button" value= "last Page"/>
</span>
</td>
</tr>
</table>
The following is an example of how the process of converting different pages is done using the "next" button. Depending on the parameter intpage, the function determines the number of records to display and the corresponding page, and the change in the value of each button is achieved by dynamically changing the contents of the XSL DOM:
function NextPage (intpage)
Dim strdisplay
Dim Strdaterange
If CInt (CStr (intpage) * Intrecordsperpage) < _
Data.selectnodes ("/Customer relationship Sheet/customer"). 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 = _
"./customer [position () <=" & (CStr (Intpage) _
* intrecordsperpage) & "and position () >" _
& (CInt (intpage)-1) * Intrecordsperpage & _
"]"
Redisplay (intpage)
End If
End Function
Let's take a look at the function setrecordsperpage () that sets the number of record bars per page, which is implemented by dynamically modifying the value of the Select property of the Xsl:for-each. Use XPath to traverse those nodes that meet the node position greater than 0 and the node position is less than the number of records plus 1 per page. The main statement is the following line:
Style.xmldocument.selectnodes ("//xsl:for-each/@select") (1). _
Value = "./customer [Position () < & Intrecordsperpage + 1 &" and "&" position () > 0] "
So far, our page can not only achieve sorting, but also to achieve dynamic changes in the display of the number of records per page function, in order to achieve the requirements of reuse, we can also make further improvements. XPath is a powerful tool for XML/XSLT application development, and you can use wildcards in XPath to make XSLT style sheet files completely independent of your data node name. Therefore, when we change the XML data, as long as we do not change the hierarchical relationship of the nodes, you can use it without changing the XSLT. For example, in this example, you can add or remove certain fields, or add and delete some records, directly using the XSLT in this example, not only can display the data normally in the table, but also the normal sorting and paging.
Here we will analyze how it is achieved. For example, the following hierarchical relationships:
< customer Relationship Table >
< Customer >
< serial number ></>
< name ></name >
< e-mail ></email >
</Customer >
</Customer Relationship Table >
If there is a sentence in our XSLT that chooses the template:
<xsl:apply-templates select= "/customer Relationship table"/>
To achieve versatility, we can use wildcard characters:
<xsl:apply-templates select= "/*"/>
Here we use the sub operator "/", which selects all nodes under the root, the difference between the two is that the "/Customer Relationship table" selects the Customer relationship table child nodes under the root, and "/*" selects all the direct child nodes under the root, which are completely equivalent in the XML data format above.
For the following For-each loops:
<xsl:for-each select= "Customer" >
<xsl:sort select= "serial number" order= "Ascending"/>
</xsl:for-each>
We can change into this form:
<xsl:for-each select= "./*" >
<xsl:sort select= "./*[1]" order= "Ascending"/>
</xsl:for-each>
Here, "./*" means you should include all the first-level subnodes under the current node, and the syntax "./*[1]" represents the selection of the child node in the current node.
Another place to improve is the <xsl:value-of select= "serial number"/>, we can change it to <xsl:value-of select= "." />, which indicates that the current node is selected in each loop.
In our function, we also use some hard code, if we do not make changes, our versatility will not be achieved, so we'll look at how to replace the hard code in the statement.
When we create the header, we use the <TD > ordinal </td> statement, if there is no ordinal node in the XML data, there is obviously an error, in order to achieve versatility, we have customized a function getname to get the name of the node to display:
<td>
<xsl:attribute name= "onclick" >
Sort (' <xsl:value-of select= "user:getname (.)" /> ')
</xsl:attribute>
<xsl:value-of select= "User:getname (.)" />
</td>
Custom functions are a prominent feature of XSLT, and to use this feature, we have to define them with the msxml:script element, and we must specify a user-defined namespace when the style sheet is defined. Here's what we do with the custom function:
<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>
In our XSLT file, we used two loops, and we made the corresponding changes, first: the place where the header was displayed was changed to <xsl:for-each select= "./*[1]/*", which is equivalent to <xsl:for-each select= "Customer relationship Table/customer [1]/*" >; the second loop is to display each row of records, change to <xsl:for-each select= "./*" >. There are other places that need to be changed, see the Complete source code section later. So we're done with the generic XSLT file, and no matter how many fields your XML data has or what the node name is, we can implement our functionality without having to change the XSLT file. The final browsing effect will be as shown in the following illustration:
The following are the contents of the complete style.xsl file:
<?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> page total <span id= "PageCount" ></span > Page Total <span id= "RecordCount" ></span> Records </b></td>
<TD align= "Right" ><b> records per page: <input onblur= "Setrecordsperpage ()" id= "Recordsperpage" style= " vertical-align:middle;height:15pt;width:30px "/></b></td>
<TD align= "Right" >
<span id= "Paging" >
<input type= "button" value= "first page"/>
<input type= "button" value= "previous page"/>
<input type= "button" value= "next page"/>
<input type= "button" value= "last Page"/>
</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>
The following is the exam.htm file for the output:
<meta http=equiv= "Content-type" content= "text/html;charset=gb2312" >
<style>
Body {font-family: XXFarEastFont-font-size:9pt;}
th {font-family: song body; font-size:11pt; font-weight:bold;}
</style>
<script language= "VBScript" >
Option Explicit
Dim intrecordsperpage ' number of records displayed per page
Intrecordsperpage = 6 ' number of records displayed per page, default set to 6
' Update function to display page
function Window_onload ()
' Show the set number of records
Style.xmldocument.selectnodes ("//xsl:for-each/@select") (1). Value = "./*[position () <" & Intrecordsperpage + 1 & Amp "and position () > 0]"
Transform ()
Setpagecount ()
End Function
' Make a xml-xslt conversion and display some information about the current record
Function transform ()
displayarea.innerhtml = Data.transformnode (style.documentelement)
Recordsperpage.value = Intrecordsperpage
End Function
' re-convert XML and display a status message
Function Redisplay (intpage)
Dim strdisplay
Dim Intpagecount
Dim Intrecordcount
' Save state information
Intpagecount = pagecount.innerhtml
Intrecordcount = recordcount.innerhtml
Transform ()
' Show status information
pagecount.innerhtml = Intpagecount
recordcount.innerhtml = Intrecordcount
currentpage.innerhtml = Intpage
End Function
' Reorder and display
function sort (Strfield)
Dim SortField
Dim Sortorderattribute
' Get the Sort attribute value
Set SortField = Style.xmldocument.selectsinglenode ("//xsl:sort/@select")
Set sortorderattribute = Style.xmldocument.selectsinglenode ("//xsl:sort/@order")
' Change the sort of way
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
' re-set the number of records per page
function Setrecordsperpage ()
If IsNumeric (Recordsperpage.value) Then
Intrecordsperpage = CInt (recordsperpage.value)
Window_onload
End If
End Function
' Show page information
function Setpagecount ()
Dim inttotalrecords
pagecount.innerhtml = Getnumberofpages (inttotalrecords)
recordcount.innerhtml = Inttotalrecords
currentpage.innerhtml = 1
End Function
' Count total pages and total records
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
' Next page ' processing
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
' Process the previous page '
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
' first page ' processing
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 & Amp "and position () > 0]"
Transform ()
Setpagecount ()
End Function
' last page ' processing
function LastPage ()
Dim inttotalpages
Dim inttotalrecords
intTotalPages = Getnumberofpages (inttotalrecords)
NextPage (inttotalpages-1)
End Function
</script>
<body>
<p align= "center" style= "Font-weight:bold;font-size:12pt;color: #0000ff; border-bottom:3px double red; padding-bottom:5px "> Customer Relationship Table </p>
<xml id= ' data ' >
< Customer relationship table xmlns:dt= "Urn:schemas-microsoft-com:datatypes" >
< customer >< serial number dt:dt= "int" >01</serial number >< name >mi</name >< email >water@21cn.com</e-mail >< /Customer >
< customer >< serial number dt:dt= "int" >02</serial number >< name >uyi</name >< email >lily@sina.com</e-mail >< /Customer >
< customer >< serial number dt:dt= "int" >03</serial number >< name >uiyu</name >< email >john@21cn.com</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >04</serial number >< name >doug</name >< email >karry@163.net</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >05</serial number >< name >ellen</name >< email >vivki@sina.com</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >06</serial number >< name >frank</name >< Email >net_lover@mengxianhui.com.cn </Email ></Customer >
< customer >< serial number dt:dt= "int" >07</serial number >< name >greg</name >< email >meng@mengxianhui.com</e-mail ></Customer >
< customer >< serial number dt:dt= "int" >08</serial number >< name >harry</name >< email >sunny@xianhui.net</e-mail ></Customer >
< customer >< serial number dt:dt= "int" >09</serial number >< name >ingrid</name >< email >cathy@hotmail.com</e-mail ></Customer >
< customer >< serial number dt:dt= "int" >10</serial number >< name >jeff</name >< email >your@mxh.com</e-mail >< /Customer >
< customer >< serial number dt:dt= "int" >11</serial number >< name >kelly</name >< Email >iloveyou@mengxianhui.com< /email ></Customer >
< customer >< serial number dt:dt= "int" >12</serial number >< name >larry</name >< Email >smilling@mengxianhui.com< /email ></Customer >
< customer >< serial number dt:dt= "int" >13</serial number >< name >mark</name >< email >money@21cn.com</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >14</serial number >< name >nancy</name >< email >www@yahoo.com</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >15</serial number >< name >peter</name >< email >dotnet@aol.com</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >16</serial number >< name >rachel</name >< Email >billgates@microsoft.com< /email ></Customer >
< customer >< serial number dt:dt= "int" >17</serial number >< name >seth</name >< email >flying@yous.net</e-mail > </Customer >
< customer >< serial number dt:dt= "int" >18</serial number >< name >tim</name >< email >agooyboy@lovegirl.com</e-mail ></Customer >
</Customer Relationship Table >
</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" > Source: "<a href=" http://www.xrss.cn "> Network base Camp </a>" </td>
</tr>
</table>
</body>
Copy the contents of the above to the local computer, save the corresponding file separately, in the ie5+ and xml3.0+ environment can see the effect!