给定如下XML文档:
现提出如下设计需求:
测试用户期望功能如下:
用户测试功能用例建模如图11.1所示。
XML文档分页浏览的核心业务描述如下:
核心业务数据流如图11.2所示。
基于三层架构视角的文件包及文件设计如表11.1所述。
序号 | 包设计 | 文件设计 |
---|---|---|
1 | 设计表示层包(包名:UI),抽象表示层文件容器。 |
|
2 | 设计业务逻辑层包(包名:server),抽象业务层文件容器。 |
|
3 | 设计数据层包(包名:data),抽象数据层文件容器。 |
|
文件包设计及文件关系如图11.3所示。
文件架构如图11.4所示。
说明:为让通用逻辑服务除了本项目以外的项目,文件server.js位于所有文件夹外围。
文件功能说明见表11.2所述。
序号 | 文件(夹)名 | 作用 |
---|---|---|
1 | books.xml | 存放在后台用于测试的XML基础数据文件 |
2 | main.html | 实现人机交互的用户界面主页 |
3 | Server.js | NodeJS后台通用逻辑服务程序,动态引入Server_11.js模块。 |
4 | XML_page.js | 包含XML文档数据分页函数。 |
5 | jquery.js | 加载JQuery函数库,辅助表示层数据可视化。 |
6 | UI | 存放表示层文件的文件夹 |
7 | Server | 存放业务逻辑层文件的文件夹 |
8 | Data | 存放XML数据文件 |
9 | Server_11.js | 本案例后台服务专用逻辑 |
对应文件:main.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="/jquery.js"></script>
<script type="text/javascript" src="XML_page.js"></script>
<script type="text/javascript" >
//初始化,按默认参数显示图书信息
var xmldom;
$(document).ready(function () {
var xhr = new XMLHttpRequest();
xhr.open("post", "http://localhost:1017/viewAllbooks_11", true);
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
xmldom = $.parseXML(xhr.responseText);
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");
}
}
xhr.send();
});
</script>
文件XML_page.js实现代码:
// 重要说明
//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);
}
主服务server.js实现代码:
// JavaScript source code
//---------------请将这个文件保存为Unicode格式,否则麻烦大大的----------------
const http_obj = require("http");//用于产生服务对象
const fs_obj = require("fs");//读写后台文件
const url_tran_obj = require("url");//解释URL
const server = http_obj.createServer(function (request, response) {
//请求路径处理
var req_str = decodeURI(request.url);
var req_head;
var POS = req_str.indexOf("?");
if (POS == -1) { req_head = req_str; }
else { req_head = req_str.substring(0, POS); }
//设置查询对象
var url_obj = url_tran_obj.parse(req_str, true);
var Q_obj = url_obj.query;
//响应头设置
response.setHeader("Content-Type", "text/plain;charset=utf-8");
response.setHeader("Access-Control-Allow-Origin", "*");//实现跨域访问
response.writeHead(200);
//%%%%%%%%%%%%%----------------begin your code
require("./11/server/server_11.js")(request, response, req_head, Q_obj, fs_obj);
//%%%%%%%%%%%%%------------------end your code
});
server.listen(1007);
console.log("Server is running at port 1007...");
模块服务Server_11.js实现代码:
function server_11(request, response, req_head, Q_obj, fs_obj) {
if (req_head == "/viewAllbooks_11") {
//代码1
fs_obj.readFile("./11/data/books.xml", "utf-8", function (err, data) {
if (err) { response.end(err); }
else { response.end(data); }
});
}
}
module.exports = server_11
实现效果如图11.4所示。
给定如下XML文档:
现提出如下设计需求: