﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-Eternity-文章分类-XML</title><link>http://www.cnitblog.com/Eternity/category/4695.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 03 Oct 2011 03:58:51 GMT</lastBuildDate><pubDate>Mon, 03 Oct 2011 03:58:51 GMT</pubDate><ttl>60</ttl><item><title>用XML创建可排序、分页的数据显示页面</title><link>http://www.cnitblog.com/Eternity/articles/22000.html</link><dc:creator>Eternity</dc:creator><author>Eternity</author><pubDate>Wed, 17 Jan 2007 18:58:00 GMT</pubDate><guid>http://www.cnitblog.com/Eternity/articles/22000.html</guid><wfw:comment>http://www.cnitblog.com/Eternity/comments/22000.html</wfw:comment><comments>http://www.cnitblog.com/Eternity/articles/22000.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Eternity/comments/commentRss/22000.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Eternity/services/trackbacks/22000.html</trackback:ping><description><![CDATA[在Web开发中，我们经常会遇到分页显示和排序数据记录集的情况，这在服务器端使用服务器端的代码和<a class="Channel_KeyLink" href="http://www.netbei.com/Article/db/Index.html"><font color="#f3f3f3">数据库</font></a>技术是件很轻松的事情，比如：ASP、PHP、JSP等。然而，如果要在客户端显示多条记录并且排序是一件很令人头疼的事情。下面，我们利用Extensible Markup Language（XML，可扩展标记语言）和Extensible Stylesheet Language Transformations（XSLT，可扩展样式单语言转换），并结合XML Path Language（XPath，XML路径语言），只需要编写简单的代码，就可轻松实现。这种方法避免了与服务器频繁打交道的过程，节省了数据显示的时间，浏览者无须等待就可以看到结果，也可以减少服务器的负担。另外。由于XML和XSLT技术，使数据存储和数据显示分离，还可以让我们的代码能够重复利用，大大减轻了程序员编写代码的负担。 <br />   下面，我们一步一步地来实现我们的功能。 <br />   <br />   首先：创建XSLT <br />   <br />   XSLT样式单的第一行标明该XML所遵照的XML规范版本，然后是标明该样式单使用的名称空间，这里，我们以XSL规范的正式版本来进行编写，而不采用XSL的草案的写法： <br />   &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"&gt; <br />   注意：两者在功能和写法上有很大的差异。 <br />   &lt;?xml version="1.0"?&gt; <br />   &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; <br />   接下来，我们定义XSLT里的模板标记： <br />   <br />   &lt;xsl:template match="/"&gt; <br />   &lt;xsl:apply-templates select="/客户关系表"/&gt; <br />   &lt;/xsl:template&gt; <br />   <br />   &lt;xsl:template match="/客户关系表"&gt;&lt;/xsl:template&gt; <br />   <br />   我们把要显示的样式写到模板里面。我们使用HTML的数据岛来存放我们的数据，这些数据可以利用SQL Server 2000的XML查询来得到，对于不支持XML的<a class="Channel_KeyLink" href="http://www.netbei.com/Article/db/Index.html"><font color="#f3f3f3">数据库</font></a>，我们可以自己编写组件把数据转换成XML格式，然后在放到数据岛里。在HTML里使用数据岛有两种方法： <br />   一是直接嵌入数据，如下所示： <br />   &lt;XML id='Data'&gt; <br />   &lt;客户关系表&gt; <br />   &lt;客户&gt;每条数据&lt;/客户&gt; <br />   &lt;/客户关系表&gt; <br />   &lt;/XML&gt; <br />   二是通过SRC属性引用外部文件，如下所示： <br />   &lt;XML id='Data' src='Data.xml'&gt;&lt;/XML&gt; <br />   要使用数据岛里的数据，必须通过id名来引用它，当然，由于XSLT文件也是XML格式文件的一种，也可以通过这种方法来实现： <br />   &lt;XML id='Style' src='Style.xsl'&gt;&lt;/XML&gt; <br />   我们在页面中加入标记DIV来显示我们的转换的结果： <br />   &lt;div id="DisplayArea"&gt;&lt;/div&gt; <br />   使用XSLT转换数据岛里的数据，采用DOMDocument的transNode()方法，并把结果通过DIV的innerHTML属性来展现出来： <br />   DisplayArea.innerHTML = Data.transformNode(Style.DocumentElement) <br />   <br />   第二步：实现客户端排序的功能 <br />   <br />   我们先设定一个默认的排序字段，这里选择“序号”作为默认的排序关键字，并且是按递增的顺序排列，在XSLT里加入sort标记： <br />   &lt;xsl:for-each select="客户"&gt; <br />   &lt;xsl:sort select="序号" order="descending" data-type="number"/&gt; <br />   &lt;/xsl:for-each&gt; <br />   接下来，我们为样式表增加排序的功能，以便可以响应用户的操作，我们在表头的每个列上添加onClick事件，该事件调用sort()函数，允许用户通过单击该表头来进行对该列的排序。 <br />   &lt;td onClick="sort('序号')"&gt;序号&lt;/td&gt; <br />   Sort()函数的语句如下所示： <br />   Function Sort(strField) <br />   <br />   Dim sortField <br />   Dim sortOrderAttribute <br />   <br />   '　得到原来排序字段的属性值 <br />   Set sortField = Style.XMLDocument.selectSingleNode("//xsl:sort/@select") <br />   <br />   '　得到原来排序的顺序属性值 <br />   Set sortOrderAttribute = Style.XMLDocument.selectSingleNode("//xsl:sort/@order") <br />   <br />   '　如果我们已经按所点击的列的字段排序，我们必须改变排序的顺序； <br />   '　否则，我们只需要按新所点击的列字段按默认的顺序进行排序 <br />   If sortField.Value = strField Or sortField.Value = "./*[0]" Then <br />   If sortOrderAttribute.Value = "descending" Then <br />   sortOrderAttribute.Value = "ascending" <br />   Else <br />   sortOrderAttribute.Value = "descending" <br />   End If <br />   Else <br />   sortField.Value = strField <br />   sortOrderAttribute.Value = "ascending" <br />   End If <br />   <br />   Set sortField = Nothing <br />   Set sortOrderAttribute = Nothing <br />   '　输出排序后的结果 <br />   DisplayArea.innerHTML = Data.transformNode(Style.DocumentElement) <br />   <br />   End Function <br />   下面，我们实现每页面显示的记录数和设定前页、后页的功能。使用span标记显示目前显示的是第几页、共多少页和记录的总数。我们默认每页显示6条记录，用变量intRecordsPerPage保存该值： <br />   &lt;table width="100%" border="0" style="font-size:9pt"&gt; <br />   &lt;tr&gt; <br />   &lt;td align="left"&gt;&lt;b&gt;第 &lt;span id="CurrentPage"&gt;&lt;/span&gt; 页 总 &lt;span id="PageCount"&gt;&lt;/span&gt; 页    共有 &lt;span id="RecordCount"&gt;&lt;/span&gt; 条记录&lt;/b&gt;&lt;/td&gt; <br />   &lt;td align="right"&gt;&lt;b&gt;每页记录数：&lt;input onblur="setRecordsPerPage()" id="RecordsPerPage" style="vertical-align:middle;height:15pt;width:30px"/&gt;&lt;/b&gt;&lt;/td&gt; <br />   &lt;td align="right"&gt; <br />   &lt;span id="Paging"&gt; <br />   &lt;input type="button" OnClick="FirstPage()" value="第一页"/&gt; <br />   &lt;input type="button" OnClick="previousPage(1)" value="上一页"/&gt; <br />   &lt;input type="button" OnClick="nextPage(1)" value="下一页"/&gt; <br />   &lt;input type="button" OnClick="LastPage()" value="最末页"/&gt; <br />   &lt;/span&gt; <br />   &lt;/td&gt; <br />   &lt;/tr&gt; <br />   &lt;/table&gt; <br />   下面以“下一页”按钮执行的操作为例子，说明转换不同页面的处理过程。该函数根据参数intPage来决定要显示的记录的条数和相应的页面，每个按钮Value值的变化是通过动态改变XSL DOM的内容来实现的： <br />   Function nextPage(intPage) <br />   <br />   Dim strDisplay <br />   Dim strDateRange <br />   <br />   If CInt(CStr(intPage) * intRecordsPerPage) &lt; _ <br />   Data.selectNodes("/客户关系表/客户").length Then <br />   intPage = CInt(intPage) + 1 <br />   <br />   Style.XMLDocument.selectNodes("//@OnClick") _ <br />   (1).Value = "previousPage(" &amp; intPage &amp; ")" <br />   <br />   Style.XMLDocument.selectNodes("//@OnClick") _ <br />   (2).Value = "nextPage(" &amp; intPage &amp; ")" <br />   <br />   Style.XMLDocument.selectNodes _ <br />   ("//xsl:for-each/@select")(1).Value = _ <br />   "./客户[position() &lt;= " &amp; (CStr(intPage) _ <br />   * intRecordsPerPage) &amp; " and position() &gt; " _ <br />   &amp; (CInt(intPage) - 1) * intRecordsPerPage &amp; _ <br />   "]" <br />   <br />   redisplay (intPage) <br />   <br />   End If <br />   <br />   End Function <br />   下面，我们来看看设置每个页面记录条数的函数setRecordsPerPage()，该函数通过动态修改xsl:for-each的select属性值来实现的，使用XPath来遍历那些符合节点位置大于0并且节点位置小于每页记录数加1的那些节点。其中主要的语句是下面的一行： <br />   Style.XMLDocument.selectNodes("//xsl:for-each/@select")(1). _ <br />   value = "./客户[position() &lt; " &amp; intRecordsPerPage + 1 &amp; " and "&amp; " position() &gt; 0]" <br />   到目前为止，我们的页面既可以实现排序，也实现动态改变每页显示记录条数的功能了，为了实现可重用的要求，我们还可以进行进一步的改进。XPath是进行XML/XSLT应用开发的一个强有力的工具，XPath中可以使用通配符，使XSLT样式单文件完全不依赖于你的数据节点名称。因此，我们在改变XML数据的时候，只要不改变节点的层次关系，可以不必改动XSLT就可以直接使用。比如：在本例中，你可以添加或者删除某些字段、或添加删除一些记录，直接使用本例中的XSLT，不但可以在表格里正常显示出数据，而且还能正常排序和分页。 <br />   下面我们就分析一下是如何实现的。比如下面的层次关系： <br />   &lt;客户关系表&gt; <br />   &lt;客户&gt; <br />   &lt;序号&gt;&lt;/序号&gt; <br />   &lt;姓名&gt;&lt;/姓名&gt; <br />   &lt;电子邮件&gt;&lt;/电子邮件&gt; <br />   &lt;/客户&gt; <br />   &lt;/客户关系表&gt; <br />   假如我们的XSLT中有这样一个选择模板的句子： <br />   &lt;xsl:apply-templates select="/客户关系表"/&gt; <br />   为了实现通用性的要求，我们可以使用通配符： <br />   &lt;xsl:apply-templates select="/*"/&gt; <br />   这里我们使用了子运算符"/"，它选择了根下的所有节点，两者的不同点在于："/客户关系表"选择的是根下的客户关系表子节点，而"/*"选择的是根下所有的直接子节点，在上面的XML数据格式中，二者是完全等价的。 <br />   对于下面的for-each循环来说： <br />   &lt;xsl:for-each select="客户"&gt; <br />   &lt;xsl:sort select="序号" order="ascending"/&gt; <br />   &lt;/xsl:for-each&gt; <br />   我们可以改变成这样的形式： <br />   &lt;xsl:for-each select="./*"&gt; <br />   &lt;xsl:sort select="./*[1]" order="ascending"/&gt; <br />   &lt;/xsl:for-each&gt; <br />   这里"./*"表示你应当包含进去当前节点下所有的一级子节点，语法"./*[1]"表示的是选择当前节点中的第一个子节点。 <br />   另外还有一个地方可以改进的是&lt;xsl:value-of select="序号"/&gt;，我们可以把它改成&lt;xsl:value-of select="."/&gt;，表示在每一次循环中选择当前节点。 <br />   在我们的函数中，还使用了一些硬代码，如果不做改动的话，我们的通用性还是实现不了，因此，我们下面就看看如何替换硬代码中的语句。 <br />   在创建表头的时候，我们使用了&lt;td onClick="sort('序号')"&gt; 序号&lt;/td&gt;的语句，如果XML数据里没有序号节点的话，这里显然会出现错误的，为了实现通用性，我们自定义了一个函数getName，来取得所要显示的节点的名称： <br />   &lt;td&gt; <br />   &lt;xsl:attribute name="onClick"&gt; <br />   Sort('&lt;xsl:value-of select="user:getName(.)"/&gt;') <br />   &lt;/xsl:attribute&gt; <br />   &lt;xsl:value-of select="user:getName(.)"/&gt; <br />   &lt;/td&gt; <br />   自定义函数是XSLT的一个突出的功能，要使用这个特性，我们得用msxml:script元素来定义，同时，必须在样式单定义的时候指定一个用户定义的名字空间。下面就是我们使用自定义函数的全部内容： <br />   &lt;xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform <br />   xmlns:msxsl="urn:schemas-microsoft-com:xslt" <br />   xmlns:user="http://lucky.myrice.com" <br />   version="1.0"&gt; <br />   &lt;msxsl:script language="VBScript" implements-prefix="user"&gt; <br />   &lt;![CDATA[ <br />   function getName(node) <br />   getName = node.item(0).nodeName <br />   end function <br />   ]]&gt; <br />   &lt;/msxsl:script&gt; <br />   在我们的XSLT文件中，使用了两个循环，我们分别进行相应的更改，第一处：显示表头的地方改为&lt;xsl:for-each select="./*[1]/*"&gt;，它等同于&lt;xsl:for-each select="客户关系表/客户[1]/*"&gt;；第二处循环是显示每行记录，改成&lt;xsl:for-each select="./*"&gt;。还有其他的地方需要更改的，请参见后面的完整源代码部分。这样我们就完成了通用的XSLT文件，不管你的XML数据有多少字段，也不管节点名称是什么，我们都无需更改XSLT文件，就可以实现我们的功能了。最终的浏览效果将会象下图所示： <br />  <img src="http://www.netbei.com/Article/UploadFiles/200409/20040904175204228.gif" /><br />   <br />   <br />   以下是完整的Style.xsl文件的内容： <br />   <br />   &lt;?xml version="1.0" encoding="gb2312"?&gt; <br />   &lt;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"&gt; <br />   &lt;msxsl:script language="VBScript" implements-prefix="user"&gt; <br />   &lt;![CDATA[ <br />   Function getName(node) <br />   getName = node.Item(0).nodeName <br />   End Function <br />   ]]&gt; <br />   &lt;/msxsl:script&gt; <br />   <br />   &lt;xsl:template match="/"&gt; <br />   &lt;xsl:apply-templates select="/*"/&gt; <br />   &lt;/xsl:template&gt; <br />   <br />   &lt;xsl:template match="/*"&gt; <br />   &lt;table width="100%" border="0" style="font-size:9pt"&gt; <br />   &lt;tr&gt; <br />   &lt;td align="left"&gt;&lt;b&gt;第 &lt;span id="CurrentPage"&gt;&lt;/span&gt; 页 总 &lt;span id="PageCount"&gt;&lt;/span&gt; 页    共有 &lt;span id="RecordCount"&gt;&lt;/span&gt; 条记录&lt;/b&gt;&lt;/td&gt; <br />   &lt;td align="right"&gt;&lt;b&gt;每页记录数：&lt;input onblur="setRecordsPerPage()" id="RecordsPerPage" style="vertical-align:middle;height:15pt;width:30px"/&gt;&lt;/b&gt;&lt;/td&gt; <br />   &lt;td align="right"&gt; <br />   &lt;span id="Paging"&gt; <br />   &lt;input type="button" OnClick="FirstPage()" value="第一页"/&gt; <br />   &lt;input type="button" OnClick="previousPage(1)" value="上一页"/&gt; <br />   &lt;input type="button" OnClick="nextPage(1)" value="下一页"/&gt; <br />   &lt;input type="button" OnClick="LastPage()" value="最末页"/&gt; <br />   &lt;/span&gt; <br />   &lt;/td&gt; <br />   &lt;/tr&gt; <br />   &lt;/table&gt; <br />   &lt;Table WIDTH="100%" BORDER="0" cellpadding="0" cellspacing="1" style="font-size:11pt" bgcolor="#0099ff"&gt; <br />   &lt;tr bgcolor="#FF6600" style="cursor: hand;padding:5px"&gt; <br />   &lt;xsl:for-each select="./*[1]/*"&gt; <br />   &lt;td align="center"&gt; <br />   &lt;xsl:attribute name="onclick"&gt; <br />   Sort('&lt;xsl:value-of select="user:getName(.)"/&gt;') <br />   &lt;/xsl:attribute&gt; <br />   &lt;font color="#EEEEEE"&gt;&lt;b&gt;&lt;u&gt;&lt;xsl:value-of select="user:getName(.)"/&gt;&lt;/u&gt;&lt;/b&gt;&lt;/font&gt; <br />   &lt;/td&gt; <br />   &lt;/xsl:for-each&gt; <br />   &lt;/tr&gt; <br />   &lt;xsl:for-each select="./*[position() &lt; 6 and position() &gt; 0]"&gt; <br />   &lt;xsl:sort select="./*[1]" order="ascending"/&gt; <br />   &lt;tr bgcolor="#FFCCFF"&gt; <br />   &lt;xsl:for-each select="./*"&gt; <br />   &lt;td&gt; &lt;xsl:value-of select="."/&gt;&lt;/td&gt; <br />   &lt;/xsl:for-each&gt; <br />   &lt;/tr&gt; <br />   &lt;/xsl:for-each&gt; <br />   &lt;/Table&gt; <br />   &lt;/xsl:template&gt; <br />   &lt;/xsl:stylesheet&gt; <br />   以下是进行输出的Exam.htm文件： <br />   &lt;HTML&gt; <br />   &lt;Head&gt; <br />   &lt;META http=equiv="Content-Type" Content="text/html;charset=gb2312"&gt; <br />   &lt;STYLE&gt; <br />   body { font-family:宋体; font-size:9pt;} <br />   th { font-family:宋体; font-size:11pt; font-weight:bold;} <br />   &lt;/STYLE&gt; <br />   &lt;Script language="vbscript"&gt; <br />   Option Explicit <br />   <br />   Dim intRecordsPerPage '每个页面显示的记录数 <br />   intRecordsPerPage = 6 '每个页面显示的记录数，默认设定为6 <br />   <br />   ' 更新显示页面的函数 <br />   Function window_onload() <br />   <br />   ' 显示设定的记录数 <br />   Style.XMLDocument.selectNodes("//xsl:for-each/@select")(1).Value = "./*[position() &lt; " &amp; intRecordsPerPage + 1 &amp; " and position() &gt; 0]" <br />   transform() <br />   setPageCount() <br />   <br />   End Function <br />   <br />   ' 进行XML-XSLT转换，并显示当前记录的一些信息 <br />   Function transform() <br />   <br />   DisplayArea.innerHTML = Data.transformNode(Style.DocumentElement) <br />   RecordsPerPage.Value = intRecordsPerPage <br />   <br />   End Function <br />   <br />   ' 重新转换XML，并显示一个状态信息 <br />   Function redisplay(intPage) <br />   <br />   Dim strDisplay <br />   Dim intPageCount <br />   Dim intRecordCount <br />   <br />   ' 保存状态信息 <br />   intPageCount = PageCount.innerHTML <br />   intRecordCount = RecordCount.innerHTML <br />   transform() <br />   ' 显示状态信息 <br />   PageCount.innerHTML = intPageCount <br />   RecordCount.innerHTML = intRecordCount <br />   CurrentPage.innerHTML = intPage <br />   <br />   End Function <br />   <br />   ' 重新排序和显示 <br />   Function Sort(strField) <br />   <br />   Dim sortField <br />   Dim sortOrderAttribute <br />   ' 得到排序属性值 <br />   Set sortField = Style.XMLDocument.selectSingleNode("//xsl:sort/@select") <br />   Set sortOrderAttribute = Style.XMLDocument.selectSingleNode("//xsl:sort/@order") <br />   <br />   ' 改变排序的方式 <br />   If sortField.Value = strField Or sortField.Value = "./*[0]" Then <br />   If sortOrderAttribute.Value = "descending" Then <br />   sortOrderAttribute.Value = "ascending" <br />   Else <br />   sortOrderAttribute.Value = "descending" <br />   End If <br />   Else <br />   sortField.Value = strField <br />   sortOrderAttribute.Value = "ascending" <br />   End If <br />   <br />   Set sortField = Nothing <br />   Set sortOrderAttribute = Nothing <br />   <br />   redisplay (CurrentPage.innerHTML) <br />   <br />   End Function <br />   <br />   ' 重新设置每页的记录数 <br />   Function setRecordsPerPage() <br />   <br />   If IsNumeric(RecordsPerPage.Value) Then <br />   intRecordsPerPage = CInt(RecordsPerPage.Value) <br />   window_onload <br />   End If <br />   <br />   End Function <br />   <br />   ' 显示页数信息 <br />   Function setPageCount() <br />   <br />   Dim intTotalRecords <br />   <br />   PageCount.innerHTML = getNumberOfPages(intTotalRecords) <br />   RecordCount.innerHTML = intTotalRecords <br />   CurrentPage.innerHTML = 1 <br />   <br />   End Function <br />   <br />   ' 计算总页数和总记录数 <br />   Function getNumberOfPages(intTotalRecords) <br />   <br />   Dim intPages <br />   <br />   intTotalRecords = Data.XMLDocument.selectNodes("/*/*").length <br />   intPages = intTotalRecords / intRecordsPerPage <br />   If InStr(intPages, ".") &gt; 0 Then <br />   intPages = CInt(Left(intPages, InStr(intPages, "."))) + 1 <br />   End If <br />   <br />   getNumberOfPages = intPages <br />   <br />   End Function <br />   <br />   ' “下一页”的处理 <br />   Function nextPage(intPage) <br />   <br />   Dim strDisplay <br />   Dim strDateRange <br />   <br />   If CInt(CStr(intPage) * intRecordsPerPage) &lt; Data.selectNodes("/*/*").length Then <br />   intPage = CInt(intPage) + 1 <br />   Style.XMLDocument.selectNodes("//@OnClick")(1).Value = "previousPage(" &amp; intPage &amp; ")" <br />   Style.XMLDocument.selectNodes("//@OnClick")(2).Value = "nextPage(" &amp; intPage &amp; ")" <br />   Style.XMLDocument.selectNodes("//xsl:for-each/@select")(1).Value = "./*[position() &lt;= " &amp; (CStr(intPage) * intRecordsPerPage) &amp; " and position() &gt; " &amp; (CInt(intPage) - 1) * intRecordsPerPage &amp; "]" <br />   redisplay (intPage) <br />   End If <br />   <br />   End Function <br />   <br />   ' 处理“上一页” <br />   Function previousPage(intPage) <br />   <br />   Dim strDisplay <br />   Dim strDateRange <br />   <br />   If intPage &gt; 1 Then <br />   intPage = CInt(intPage) - 1 <br />   Style.XMLDocument.selectNodes("//@OnClick")(1).Value = "previousPage(" &amp; intPage &amp; ")" <br />   Style.XMLDocument.selectNodes("//@OnClick")(2).Value = "nextPage(" &amp; intPage &amp; ")" <br />   Style.XMLDocument.selectNodes("//xsl:for-each/@select")(1).Value = "./*[position() &lt;= " &amp; (CStr(intPage) * intRecordsPerPage) &amp; " and position() &gt; " &amp; (CInt(intPage) - 1) * intRecordsPerPage &amp; "]" <br />   redisplay (intPage) <br />   End If <br />   <br />   End Function <br />   <br />   ' “第一页”的处理 <br />   Function FirstPage() <br />   <br />   Style.XMLDocument.selectNodes("//@OnClick")(1).Value = "previousPage(1)" <br />   Style.XMLDocument.selectNodes("//@OnClick")(2).Value = "nextPage(1)" <br />   Style.XMLDocument.selectNodes("//xsl:for-each/@select")(1).Value = "./*[position() &lt; " &amp; intRecordsPerPage + 1 &amp; " and position() &gt; 0]" <br />   transform() <br />   setPageCount() <br />   <br />   End Function <br />   <br />   ' “最末页”的处理 <br />   Function LastPage() <br />   <br />   Dim intTotalPages <br />   Dim intTotalRecords <br />   <br />   intTotalPages = getNumberOfPages(intTotalRecords) <br />   nextPage (intTotalPages - 1) <br />   <br />   End Function <br />   &lt;/Script&gt; <br />   &lt;/Head&gt; <br />   &lt;body&gt; <br />   &lt;p align="center" style="font-weight:bold;font-size:12pt;color:#0000FF;border-bottom:3px double red;padding-bottom:5px"&gt;客户关系表&lt;/p&gt; <br />   &lt;XML id='Data'&gt; <br />   &lt;客户关系表 xmlns:dt="urn:schemas-microsoft-com:datatypes"&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;01&lt;/序号&gt;&lt;姓名&gt;Mi&lt;/姓名&gt;&lt;电子邮件&gt;water@21cn.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;02&lt;/序号&gt;&lt;姓名&gt;uyi&lt;/姓名&gt;&lt;电子邮件&gt;Lily@sina.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;03&lt;/序号&gt;&lt;姓名&gt;uiyu&lt;/姓名&gt;&lt;电子邮件&gt;John@21cn.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;04&lt;/序号&gt;&lt;姓名&gt;Doug&lt;/姓名&gt;&lt;电子邮件&gt;Karry@163.net&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;05&lt;/序号&gt;&lt;姓名&gt;Ellen&lt;/姓名&gt;&lt;电子邮件&gt;vivki@sina.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;06&lt;/序号&gt;&lt;姓名&gt;Frank&lt;/姓名&gt;&lt;电子邮件&gt;net_lover@mengxianhui.com.cn&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;07&lt;/序号&gt;&lt;姓名&gt;Greg&lt;/姓名&gt;&lt;电子邮件&gt;meng@mengxianhui.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;08&lt;/序号&gt;&lt;姓名&gt;Harry&lt;/姓名&gt;&lt;电子邮件&gt;sunny@xianhui.net&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;09&lt;/序号&gt;&lt;姓名&gt;Ingrid&lt;/姓名&gt;&lt;电子邮件&gt;cathy@hotmail.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;10&lt;/序号&gt;&lt;姓名&gt;Jeff&lt;/姓名&gt;&lt;电子邮件&gt;your@mxh.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;11&lt;/序号&gt;&lt;姓名&gt;Kelly&lt;/姓名&gt;&lt;电子邮件&gt;Iloveyou@mengxianhui.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;12&lt;/序号&gt;&lt;姓名&gt;Larry&lt;/姓名&gt;&lt;电子邮件&gt;smilling@mengxianhui.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;13&lt;/序号&gt;&lt;姓名&gt;Mark&lt;/姓名&gt;&lt;电子邮件&gt;money@21cn.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;14&lt;/序号&gt;&lt;姓名&gt;Nancy&lt;/姓名&gt;&lt;电子邮件&gt;www@yahoo.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;15&lt;/序号&gt;&lt;姓名&gt;Peter&lt;/姓名&gt;&lt;电子邮件&gt;dotnet@aol.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;16&lt;/序号&gt;&lt;姓名&gt;Rachel&lt;/姓名&gt;&lt;电子邮件&gt;billgates@microsoft.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;17&lt;/序号&gt;&lt;姓名&gt;Seth&lt;/姓名&gt;&lt;电子邮件&gt;flying@yous.net&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;客户&gt;&lt;序号 dt:dt="int"&gt;18&lt;/序号&gt;&lt;姓名&gt;Tim&lt;/姓名&gt;&lt;电子邮件&gt;agooyboy@lovegirl.com&lt;/电子邮件&gt;&lt;/客户&gt; <br />   &lt;/客户关系表&gt; <br />   &lt;/XML&gt; <br />   &lt;XML id='Style' src='Style.xsl'&gt;&lt;/XML&gt; <br />   &lt;div id="DisplayArea"&gt;&lt;/div&gt; <br />   &lt;table border="0" width="100%" style="font-size:11pt;"&gt; <br />   &lt;tr&gt; <br />   &lt;td align="right"&gt;资料来源：【&lt;a href="http://lucky.myrice.com"&gt;孟宪会之精彩世界&lt;/a&gt;】&lt;/td&gt; <br />   &lt;/tr&gt; <br />   &lt;/table&gt; <br />   &lt;/body&gt; <br />   &lt;/HTML&gt; <br /><img src ="http://www.cnitblog.com/Eternity/aggbug/22000.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Eternity/" target="_blank">Eternity</a> 2007-01-18 02:58 <a href="http://www.cnitblog.com/Eternity/articles/22000.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 之DOM对象的属性及方法</title><link>http://www.cnitblog.com/Eternity/articles/21999.html</link><dc:creator>Eternity</dc:creator><author>Eternity</author><pubDate>Wed, 17 Jan 2007 18:57:00 GMT</pubDate><guid>http://www.cnitblog.com/Eternity/articles/21999.html</guid><wfw:comment>http://www.cnitblog.com/Eternity/comments/21999.html</wfw:comment><comments>http://www.cnitblog.com/Eternity/articles/21999.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Eternity/comments/commentRss/21999.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Eternity/services/trackbacks/21999.html</trackback:ping><description><![CDATA[XML 之DOM对象的属性及方法<br />1、 访问DOM中的节点<br />（1）、遍历树<br />● parentNode( ).这个方法可以访问父节点。<br />● firstChild( ).这个方法可以访问该节点的第一个子节点，不存在就返回空。<br />● nextSibling( ). 这个方法可以访问下一个兄弟节点，不存在就返回空。<br />● previousSibling( ). 这个方法可以访问上一个兄弟节点，不存在就返回空。<br />(2)、使用名字来访问节点<br />● getElementsByTagName(elementname):取得一个在文件或是某一部分文件中具有这<br />个名字的所有元素的列表；创建了这样的NodeList,就可以通过索引来访问这些命<br />名了的节点了。<br />2、 DOM方法返回的数据类型<br />数据类型 使用这种数据类型的节点描述<br />Unsigned short 所有的节点类型是无符号短整数<br />Unsigned long NodeList或NameNodeMap的长度是无符号的长整数<br />Node 包含所有节点细节的对象，（类型、名称、值、父节点、子节点…）<br />NodeList 节点对象索引列表的对象<br />NameNodeMap 节点对象非索引列表的对象（实用中有Attr、实体或符号节点）<br />DOMString 由统一字符编码标准字符组成的字符串<br />Boolean 真或假<br />Void 一些不返回值的方法<br />3、 Document接口的属性和方法<br />（1）、属性（只读）<br />★ doctype属性：返回文件首部的”&lt;!DOCTYPE”信息。<br />★ Implementation属性：这个属性返回implementation节点。它有一个hasFeatures()<br />的布尔方法，有两个参数：文件类型（合法值是HTML或XML）和版本号。<br />★ DocumentElement属性：返回文件的根元素对象。<br />(2)、方法<br />★ createElement( )方法：将新元素的标记名做为参数，所创建的元素对象可以接<br />受属性及取值。<br />★ createDocumentFragment( )方法：创建一个documentFragment节点。<br />★ createTextNode( )、createComment( )和createCDATASection( )方法：创建如它们<br />名字所示的节点，它们的参数将成为节点内容的字符串。<br />★ createProcessingInstruction( )方法：有两个参数：<br />◆ PI对象作为第一个字符串<br />◆ PI数据作为第二个节点<br />★ CreateAttribute( )方法：创建具有给定名字的Attr节点；一旦创建了属性，就必<br />须用element接口的setAttribute( )方法赋给一个元素。<br />★ CreateEntityReference( )方法：参数是实体引用的名字。<br />★ GetElementsByTagName( )方法：取得所有具有所传参数指定的名字的后续元素<br />的列表，返回一个NodeList对象。用于XML文件的检索过程中。<br /><br /><br />4、 DocumentFragment接口<br />它可以在文件的一小部分上工作。<br />5、 Node接口<br />(1)、Node接口的属性<br />☆ nodeType属性：W3C DOM中描述了12种节点类型。<br />节点类型 整数 定义的常量值<br />Element 1 ELEMENT_NODE<br />Attr 2 ATTRIBUTE_NODE<br />Text 3 TEXT_NODE<br />CDATA Section 4 CDATA_SECTION_NODE<br />Entity Reference 5 ENTITY_REFERENCE_NODE<br />Entity node 6 ENTITY_NODE<br />Processing INSTRUCTION 7 PROCESSING_INSTRUCTION_NODE<br />Comment 8 COMMENT_NODE<br />Document 9 DOCUMENT_NODE<br />Document type 10 DOCUMENT_TYPE_NODE <br />Document fragment 11 DOCUMENT_FRAGMENT_NODE<br />Notation 12 NOTATION_NODE<br />☆ nodeName和nodeValue属性<br />节点类型 节点名 节点值<br />Element 标记名 NULL<br />Attr 属性名 属性的值<br />Text #text Text节点内容<br />CDATA Section #cdata-section CDATA段内容<br />Entity Reference 实体名引用 空。实体引用的替换值作为这个节点的第一节点。<br />Entity 实体名 实体的替换值作为这个节点的第一节点。<br />Processing instruction PI的目标 除目标之外的整个内容<br />Comment #comment 注释的内容<br />Document #document 符号的替换值作为这个节点的第一节点<br />Document Type 文件类型名 NULL<br />Document Fragment #document Fragment NULL<br />Notation 符号名 NULL<br />☆ parentNode属性：除了Document，documentFragment，entity，notation和Attr之外<br />的所有节点都有父节点。<br />☆ ChildNodes属性：返回这个节点的所有子节点的NodeList。用hasChildNodes( )方<br />法来检查子节点是否真的存在。<br />☆ FirstChild，lastChild，previousSibling和nextSibling属性：这些属性具有相应位置<br />关系的节点对象，不存在就返回空。<br />☆ Attributes属性：这个（IDL）属性只对元素类型的节点有效，其他节点都返回空<br />返回包含所有属性的一个NamedNodeMap.<br />☆ OwnerDocument属性：这个属性将文件对象作为一个节点返回。<br /><br />(2)、node接口的方法<br />★ insertBefore( )方法：将新的子节点插入到引用子节点并返回new_node:<br />dummy = node_object.insertBefore(new_node,reference_node)<br />这时dummy包含被插入的节点的一个副本。<br />★ replaceChild( )方法：替换子节点并返回被替换的节点<br />dummy = node_object.replaceChild(new_node,reference_node)<br />这时dummy包含被插入的节点的一个副本。<br />★ removeChild( )方法：删除被引用的子节点并返回被删除的节点<br />dummy = node_object.removeChild(reference_node)<br />这时dummy包含被删除的节点的部分。 <br />★ appendChild( )方法：将新节点加入到其他子节点的后面并返回新节点<br />dummy = node_object.appendChild(new_node)<br />这时dummy包含新节点的一个副本。<br />★ hasChildNodes( )方法：返回一个布尔值，它是给定节点是否有子节点的测试结果。<br />★ cloneNode( )方法：建立被Clone节点的一个副本，用true和false做为参数<br />◇ True：除Clone元素本身外，还Clone它的所有内容<br />◇ False：仅Clone元素本身。<br />Clone的节点是一个孤儿。<br />★getChildNodes( )方法：返回被引用的文档的所有孩子节点<br />6、 NodeList接口<br />◇ item( )方法：将一个索引作为参数并返回这个索引位置上的节点，如果索引超出范围，则返回空。<br />◇ length属性：返回一个无符号的长整数，并指出NodeList种节点的个数。<br />7、 NamedNodeMap接口<br />● getNamedItem( ),setNamedItem( )和removeNamedItem( )方法：这些方法获取、增加和删除给定名字的节点。<br />● length属性：返回NamedNodeMap的长度。<br />8、 CharacterData接口<br />(1) 属性<br />◎ data属性：以Unicode串返回这个节点的所有内容。<br />◎ length属性：返回这个字符串的字符个数。<br />(2) 方法<br />◎ subStringData方法：返回字符串的一个子串。<br />◎ appendData( )方法：参数是一个 字符串，被追加到这个节点的后面。<br />◎ insertData( )方法：有两个参数，偏移量指出插入数据的位置；字符串是<br />被插入的字符串。<br />◎ deleteData( )方法：两个整数做参数:偏移量和计数参数。<br />◎ replaceData( )方法：有三个参数，偏移量、指出替换多少字符的计数器<br />以及替换字符串。<br />9、 Attr接口<br />◆ name属性：返回属性名称。<br />◆ value属性：返回属性值。<br />◆ specified属性：这是一个布尔属性；无论是原文件还是代码，如果这个属性<br />被赋了值，specified属性就返回true<br />10、 Element接口<br />★ getAttribute( )方法：通过名字来取得属性的值。<br />★ setAttribute( )方法：实际被用来创建属性并设置属性值。<br />★ removeAttribute( )方法：将具有给定名字的属性删除。<br />★ getAttributeNode ( )方法：如果传给它一个名字，就返回一个Attr节点。<br />★ setAttributeNode( )方法：如果传给它一个Attr节点，它就设置一个属性。<br />★ removeAttributeNode( )方法：如果传给它节点的名字，实际的Attr节点对象<br />就被删除。<br />★ getElementsByTagName( )方法：这个方法用在document接口和用在<br />DocumentFragment接口上具有相同的语法。在element接口中，它仅仅返回<br />一个元素节点中具有这个名字的后续节点的NodeList，而不是整个文件。<br />★ normalize( )方法：如果factory方法创建一个或多个相邻的文本子节点而不影响<br />元素的建立，那么尽管它们相邻睥，但仍然作为独立的节点存在。Normailze()<br />方法可以将它们结合成为一个节点。<br />◆tagname属性：这个属性Copy了node接口中nodeName属性的功能。<img src ="http://www.cnitblog.com/Eternity/aggbug/21999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Eternity/" target="_blank">Eternity</a> 2007-01-18 02:57 <a href="http://www.cnitblog.com/Eternity/articles/21999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>