第8章 XML文档数据分页浏览设计

8.1 设计需求

给定如下XML文档:
<?xml version="1.0" encoding="utf-8"?> <table border="1" id="books"> <tr style="background-color:greenyellow"> <th id="ISBN">书号</th> <th id="title">书名</th> <th id="price">价格</th> </tr> <tr> <td>5744885</td> <td>Java programming</td> <td>80</td> </tr> <tr> <td>2323885</td> <td>C# programming</td> <td>87</td> </tr> <tr> <td>8888</td> <td>Python programming</td> <td>68</td> </tr> <tr> <td>8767885</td> <td>NodeJS</td> <td>90</td> </tr> <tr> <td>r64547565647689</td> <td>C++ programming</td> <td>68</td> </tr> <tr> <td>45634748758478</td> <td>MongoDB</td> <td>90</td> </tr> <tr> <td>675665647689</td> <td>operation system</td> <td>68</td> </tr> <tr> <td>2342353758478</td> <td>XML技术</td> <td>90</td> </tr> </table>
现提出如下设计需求:
  1. 设计合适的用户接口,可自定义浏览页面大小(即可自定义每页可展示图书条目的数量)。
  2. 基于选定的页面大小,用户可选择性地浏览"最前页"、"最后页"、"前一页"、"后一页"。

8.2 设计分析

8.2.1 功能分析

测试用户期望功能如下:

  1. 定义页面大小(单页浏览条目数)。
  2. 浏览最前一页。
  3. 浏览最后一页。
  4. 浏览当前页前一页
  5. 浏览当前页后一页
用户测试功能用例建模
图8.1 用户测试功能用例建模

8.2.2 核心业务数据流分析

XML文档分页浏览的核心业务描述如下:

  1. 页面加载时,读取XML文档并XML对象形式返回到前端;
  2. XML对象保存为全局变量。
  3. 用户选择浏览页面大小(单页信息条目数)。
  4. XML对象、页面大小、页面总数、当前页面号、数据输出容器div作为参数,经分页处理程序处理后生成可视分页结果。
核心业务数据流
图8.2 核心业务数据流

8.2.3 文件包及文件设计分析

基于分层架构视角的文件包及文件设计如表8.1所述。

序号 包设计 文件设计
1 设计表示层包(包名:UI),抽象表示层文件容器。
  1. 设计界面主页文件main.js。
  2. 设计自定义XML_page.js(主页引入,用于分页浏览处理)。
  3. 主页引入jquery框架(jquery.js),辅助表示层处理。
2 设计数据层包(包名:data),抽象数据层文件容器。
  1. 设计XML数据存储文件books.xml。
文件包设计及文件关系
图8.3 文件包设计及文件关系

8.3 文件架构

文件架构
图8.4 文件架构
序号 文件(夹)名 作用
1 books.xml 创新格式XML文档
2 XML_page.js XML文档数据分成浏览自定义函数
3 jquery.js 加载JQuery函数库
4 main.html 用户界面主页
5 UI 存放表示层文件的文件夹
6 data 存放XML数据文件
7 _doc 其他文档

8.4 代码实现

8.4.1 主页实现代码

对应文件:main.html

<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> </head> <body> <h3>XML数据浏览测试</h3> <hr /> 【<span style="background-color:black;color:white">页面大小(每页显示记录</span> <select id="p_size" disabled="disabled" onchange='pagesize_change(xmldom, "p_size", "p_count","p_current", "result" )'> <option>3</option> <option>6</option> <option>9</option> </select><span style="background-color:black;color:white">条);</span> 共<input readonly="readonly" id="p_count" type="text" style="width:60px" />页; 当前是第<input readonly="readonly" id="p_current" type="text" value="1" style="width:60px"/>页】 <hr /> <input class="op_but" disabled="disabled" type="button" value="最前页" onclick='first_page(xmldom, "p_size", "p_count","p_current", "result" )' /> <input class="op_but" disabled="disabled" type="button" value="上一页" onclick='prior_page(xmldom, "p_size", "p_count","p_current", "result" )' /> <input class="op_but" disabled="disabled" type="button" value="下一页" onclick='next_page(xmldom, "p_size", "p_count","p_current", "result" )' /> <input class="op_but" disabled="disabled" type="button" value="最后页" onclick='last_page(xmldom, "p_size", "p_count","p_current", "result" )' /> <hr /> <div id="result"> </div> </body> </html> <script type="text/javascript" src="./UI/jquery.js"></script> <script type="text/javascript" src="./UI/XML_page.js"></script> <script type="text/javascript" > //初始化,按默认参数显示图书信息 var xmldom; $(document).ready(function () { $.get("./data/books.xml", function (data) { xmldom = data; var book_count = xmldom.getElementsByTagName("tr").length - 1; var page_size = parseInt($("#p_size option:selected").text()); var page_count = Math.ceil(book_count / page_size); $("#p_count").val(page_count); $("#p_size").attr("disabled", false); $(".op_but").attr("disabled", false); display_cur_page(xmldom, "p_size", "p_count", "p_current", "result"); }, "xml"); }); </script>

8.4.2 自定义JS文件实现代码

对应文件:XML_page.js

// 以下实现XML数据在Table中分页 // 重要说明 //xmldom:XML文档对象 // page_size_id:调整页面大小的下拉列表 //page_count_id:显示页面总数 //page_current_id:当前正在浏览的页面号 // result_div_id:输出结果的div //显示当前页数据 function display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { var page_size = parseInt($("#" + page_size_id).val()); var cur_page = parseInt($("#" + page_current_id).val()); var begin_pos = (cur_page - 1) * page_size + 1; var end_pos = cur_page * page_size; var max_page = parseInt($("#" + page_count_id).val()); var trs = xmldom.getElementsByTagName("tr"); if (cur_page == max_page) { end_pos = trs.length - 1; } var table_str = "<table border='1'>"; table_str += trs[0].outerHTML; for (var k = begin_pos; k <= end_pos; k++) { table_str += trs[k].outerHTML; } table_str += "</table>"; $("#" + result_div_id).html(table_str); } //页面大小变化时 function pagesize_change(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { var book_count = xmldom.getElementsByTagName("tr").length - 1; var page_size = parseInt($("#" + page_size_id + " option:selected").text()); var page_count = Math.ceil(book_count / page_size); $("#" + page_count_id).val(page_count); $("#" + page_current_id).val("1"); display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id); } //下一页 function next_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { var page_count = parseInt($("#" + page_count_id).val()); var cu_page = parseInt($("#" + page_current_id).val()); cu_page++; if (cu_page > page_count) { alert("已到最后一页"); return; } else { $("#" + page_current_id).val(cu_page); display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id); } } //上一页 function prior_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { var cu_page = parseInt($("#" + page_current_id).val()); cu_page--; if (cu_page == 0) { alert("已到最前一页"); return; } else { $("#" + page_current_id).val(cu_page); display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id); } } //最前一页 function first_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { $("#" + page_current_id).val("1"); display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id); } //最后一页 function last_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id) { var page_count = parseInt($("#" + page_count_id).val()); $("#" + page_current_id).val(page_count); display_cur_page(xmldom, page_size_id, page_count_id, page_current_id, result_div_id); }

8.4.3 实现效果

当自定义页面大小为3时,浏览最前一页如图8.5所示,浏览最后一页如图8.6所示。

浏览最前一页
图8.5 浏览最前一页
浏览最后一页
图8.6 浏览最后一页

8.5 问题思考

问题提出:对创新型XML文档数据进行分布浏览设计,其技术要点有哪些?

问题思考:

  1. 网页加载时,应读取XML文档并以dom对象返回,对象存储在全局变量中。
  2. 设计下拉列表,以便选择定义页面大小。
  3. 当页面大小发生变化时,就触发事件,该事件的主要处理代码应是:重新计算页面数量并刷新网页页面。
  4. 全局保存当前页面号(应为全局变量),作为"浏览上一页"、"浏览下一页"的依据。

8.6 仿真实训

给定如下XML文档:
<?xml version="1.0" encoding="utf-8"?> <table border="1" id="students"> <tr style="background-color:greenyellow"> <th id="s_id">学号</th> <th id="name">姓名</th> <th id="age">年龄</th> </tr> <tr> <td>5744885</td> <td>Max</td> <td>18</td> </tr> <tr> <td>2323885</td> <td>Jack</td> <td>17</td> </tr> <tr> <td>8888</td> <td>Roseg</td> <td>18</td> </tr> <tr> <td>8767885</td> <td>Json</td> <td>19</td> </tr> <tr> <td>64547565647689</td> <td>张三</td> <td>16</td> </tr> <tr> <td>45634748758478</td> <td>李四</td> <td>19</td> </tr> <tr> <td>675665647689</td> <td>王五</td> <td>18</td> </tr> <tr> <td>2342353758478</td> <td>刘六</td> <td>20</td> </tr> </table>
现提出如下设计需求:
  1. 设计合适的用户接口,可自定义浏览页面大小(即可自定义每页可展示学生条目的数量)。
  2. 基于选定的页面大小,用户可选择性地浏览"最前页"、"最后页"、"前一页"、"后一页"。

仿真本章案例功能完成以上设计。