-- 作者:x5duan
-- 发布时间:7/18/2005 11:43:00 AM
-- 用xslt和javascript对xml数据进行添加、修改、删除操作,并将结果分页显示
前面学习XSLT时做的例子只有查询功能,随着学习的深入,还想再加入添加、修改、删除等基本的操作,正好我前一段时间的工作中刚好做过一个页面,里面也有添加、修改、删除等操作,只不过是B/S结构的,也没有用到XSLT,不过在这个基础上改改还是能省很多事的:) 本来是要做成一个页面的,但是例子中涉及到保存文件等操作,普通页面的权限是不够的,就想起了强大的HTA! XML数据文件的结构如下: <?xml version="1.0" encoding="GB2312"?> <rules> <rule> <event> <id>10001</id> <name>TFTP下载文件</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10002</id> <name>TFTP上传文件</name> </event> <enable>false</enable> </rule> . . . </rules> 我的目的就是要对XML数据进行选择搜索,并把结果分页显示出来,同时要能对数据集进行添加、修改、删除等操作。 而搜索功能前面已经做过了,只是又加了个分页显示功能,这个无非是又加了个交互变量,对显示结果集进行筛选,主要功能语句是XSL文件中的这一行: <xsl:if test="position() > $startno and position() <= $endno"/> 其中"startno"和"endno"是通过WEB交互传进XSL的变量,一个是显示结果集的开始序号,一个是结束序号,只有position()结果在"startno"和"endno"之间的才符合筛选条件,这样就实现了分页显示的效果。 下面主要介绍一下对XML数据的添加、修改、删除操作。 添加: function add_rule(){ // 创建节点"id" var id = xmlDoc.createElement("id"); // 给"id"节点加入"TEXT"子节点 id.appendChild(xmlDoc.createTextNode(add_id.value)); // 创建节点"name" var name = xmlDoc.createElement("name"); // 给"name"节点加入"TEXT"子节点 name.appendChild(xmlDoc.createTextNode(add_name.value)); // 创建节点"name",并将"id"和"name"当作子节点加入 var event = xmlDoc.createElement("event"); event.appendChild(id); event.appendChild(name); var enable = xmlDoc.createElement("enable"); if( add_state.checked ) { enable.appendChild(xmlDoc.createTextNode("true")); } else { enable.appendChild(xmlDoc.createTextNode("false")); } var rule = xmlDoc.createElement("rule"); rule.appendChild(event); rule.appendChild(enable); // 把当前创建的节点放在头部位置 var parent = xmlDoc.selectSingleNode("/rules"); if( parent.hasChildNodes() ) { parent.insertBefore(rule, parent.firstChild); } else { parent.appendChild(rule); } } 修改: 修改最简单,直接改相应节点的"text"值就可以了。 function modify_node(node){ node.selectSingleNode("event/id").text = modify_id.value; node.selectSingleNode("event/name").text = modify_name.value; if( modify_state.checked ) { node.selectSingleNode("enable").text = "true"; } else { node.selectSingleNode("enable").text = "false"; } } 删除: 删除节点时要注意先要将子节点删除干净了才能删除当前节点。 function delete_node(node){ if( node.hasChildNodes() ) { // 如有子节点,先将子节点删除干净 var kids = node.childNodes; for(var i=0;i<kids.length;i++) { delete_node(kids[i]); } } // 删除当前节点 node.parentNode.removeChild(node); } 还是直接下载源码后,运行起来看要直观得多。 XML数据修改后的结果是存在另一个文件里了“rule_tmp.xml”,免得一下子把数据删完了,下次没得可看了:) 下载不了,我就直接贴全了,就是长了点:) XML数据文件,rule.xml: <?xml version="1.0" encoding="GB2312"?> <rules> <rule> <event> <id>10001</id> <name>TFTP下载文件</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10002</id> <name>TFTP上传文件</name> </event> <enable>false</enable> </rule> <rule> <event> <id>10003</id> <name>telnet登录成功</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10004</id> <name>telnet登录失败</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10005</id> <name>ftp登录成功</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10006</id> <name>ftp登录失败</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10007</id> <name>Microsoft IIS超长畸形请求拒绝服务攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10008</id> <name>Microsoft IIS 4.0/5.0 CGI文件名错误解码攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10009</id> <name>HTTP服务暴力猜测口令攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10010</id> <name>通过Web服务执行tftp.exe程序</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10011</id> <name>Microsoft IIS 4.0 异常编码请求</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10012</id> <name>通过Web服务利用"../"串遍历目录攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10013</id> <name>HTTP服务基本登录认证</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10014</id> <name>Code Red网络蠕虫攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10015</id> <name>Code Red II网络蠕虫攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10016</id> <name>利用search.cgi脚本漏洞远程执行命令</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10017</id> <name>HIS Auktion脚本漏洞扫描利用</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10018</id> <name>count.cgi脚本漏洞扫描探测</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10019</id> <name>PHP Post文件上传缓冲区溢出攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10020</id> <name>PHPKIT CGI脚本SQL注入攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10021</id> <name>通过Web服务执行finger程序</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10022</id> <name>Sendmail WIZ命令远程执行命令攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10023</id> <name>SMTP服务带超长参数的EXPN命令溢出攻击</name> </event> <enable>true</enable> </rule> <rule> <event> <id>10024</id> <name>SMTP服务发送Plexus蠕虫病毒邮件</name> </event> <enable>true</enable> </rule> </rules> ------------------------------------------------------------------------------------------------------------- XSL文件,rule.xsl: <?xml version="1.0" encoding="GB2312"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output method= "html"/> <xsl:param name="ename">undefined</xsl:param> <xsl:param name="startno">undefined</xsl:param> <xsl:param name="endno">undefined</xsl:param> <xsl:template match="/"> <html> <body> <xsl:apply-templates select="rules"/> </body> </html> </xsl:template> <xsl:template match="rules"> <input type="hidden" name="total_item"> <xsl:attribute name="value"><xsl:value-of select="count(rule[contains(event/name, $ename)])"/></xsl:attribute> </input> <TABLE id="viewTable" name="viewTable" width="100%" border="1" bordercolor="#85979f" cellSpacing="0" cellPadding="0" style="border-collapse:collapse;"> <tr height="25"> <TD width="10%" align="center">选择</TD> <TD width="10%" align="center">状态</TD> <TD width="10%" align="center">事件号</TD> <TD width="*" align="center">事件名</TD> </tr> <xsl:for-each select='rule[contains(event/name, $ename)]'> <xsl:sort select="event/id"/> <xsl:if test="position() & gt; $startno and position() & lt;= $endno"> <tr> <td align="center"> <input type='checkbox'> <xsl:attribute name="name">viewchk_<xsl:value-of select="event/id"/></xsl:attribute> <xsl:attribute name="value"><xsl:value-of select="event/id"/></xsl:attribute> <xsl:attribute name="onClick">checkOVItem(<xsl:value-of select="event/id"/>)</xsl:attribute> </input> </td> <xsl:choose> <xsl:when test="enable[. = 'true']"> <td align="center">有效</td> </xsl:when> <xsl:otherwise> <td align="center">禁用</td> </xsl:otherwise> </xsl:choose> <td align="center"><xsl:value-of select="event/id"/></td> <td><xsl:value-of select="event/name"/></td> </tr> </xsl:if> </xsl:for-each> </TABLE> </xsl:template> </xsl:stylesheet> ------------------------------------------------------------------------------------------------------------- HTA文件,rule.hta: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <TITLE>Photos Player</TITLE> <HTA:APPLICATION ID="oHTA" APPLICATIONNAME="myApp" BORDER="thick" BORDERSTYLE="normal" CAPTION="yes" ContextMenu="yes" ICON="" MAXIMIZEBUTTON="yes" MINIMIZEBUTTON="yes" scroll="no" selection="no" SHOWINTASKBAR="yes" SINGLEINSTANCE="yes" SYSMENU="yes" VERSION="1.0" WINDOWSTATE="normal" > <style type="text/css"> </style> </HEAD> <script language="javascript"> // load the xml file var xmlDoc = new ActiveXObject("Msxml2.DOMDocument"); xmlDoc.async = false; xmlDoc.resolveExternals = false; xmlDoc.load("rule.xml"); // load the xsl file var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument"); xslDoc.async = false; xslDoc.resolveExternals = false; xslDoc.load("rule.xsl"); // create the xslt object var xslt = new ActiveXObject("Msxml2.XSLTemplate"); xslt.stylesheet = xslDoc; var xslProc = xslt.createProcessor(); xslProc.input = xmlDoc; var checked_count = 0; var cur_page = 1; var total_page = 1; function OutputDocument(number){ xslProc.addParameter("ename", number); xslProc.addParameter("startno", (cur_page - 1)*10); xslProc.addParameter("endno", cur_page*10); xslProc.transform(); return xslProc.output; } function delete_node(node){ if( node.hasChildNodes() ) { var kids = node.childNodes; for(var i=0;i<kids.length;i++) { delete_node(kids[i]); } } node.parentNode.removeChild(node); } function delete_rule(id){ var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]"); delete_node(node); } function modify_node(node){ node.selectSingleNode("event/id").text = modify_id.value; node.selectSingleNode("event/name").text = modify_name.value; if( modify_state.checked ) { node.selectSingleNode("enable").text = "true"; } else { node.selectSingleNode("enable").text = "false"; } } function modify_rule(id){ var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]"); modify_node(node); } function add_rule(){ var id = xmlDoc.createElement("id"); id.appendChild(xmlDoc.createTextNode(add_id.value)); var name = xmlDoc.createElement("name"); name.appendChild(xmlDoc.createTextNode(add_name.value)); var event = xmlDoc.createElement("event"); event.appendChild(id); event.appendChild(name); var enable = xmlDoc.createElement("enable"); if( add_state.checked ) { enable.appendChild(xmlDoc.createTextNode("true")); } else { enable.appendChild(xmlDoc.createTextNode("false")); } var rule = xmlDoc.createElement("rule"); rule.appendChild(event); rule.appendChild(enable); var parent = xmlDoc.selectSingleNode("/rules"); if( parent.hasChildNodes() ) { parent.insertBefore(rule, parent.firstChild); } else { parent.appendChild(rule); } } function gotoPage(pageno){ if( pageno < 1 ) { cur_page = 1; } else if( pageno >= total_page ) { cur_page = total_page; } else { cur_page = pageno; } Transform(); } function saveXML(){ xmlDoc.save("rule_tmp.xml"); } function protectsubmit(val){ if( val == 1 ) { //add if( add_id.value < 10000 || add_name.value == "" ) { window.alert("事件号必须是5位整数且事件名不能为空"); } else if( xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + add_id.value + "]") ) { window.alert("事件号" + add_id.value + "已经存在"); } else { add_rule(); saveXML(); Transform(); } } else if( val == 2 ) { //modify var id = viewTable.rows[getFirstCheckedLine()].cells[2].innerText; if( modify_id.value < 10000 || modify_name.value == "" ) { window.alert("事件号必须是5位整数且事件名不能为空"); } else if( id != modify_id.value && xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + modify_id.value + "]") ) { window.alert("事件号" + modify_id.value + "已经存在"); } else { if( confirm("确认修改?") ) { modify_rule(id); saveXML(); Transform(); } } } else if( val == 3 ) { //delete if( !confirm("确认删除?") ) { return; } for( var i = 1; i < viewTable.rows.length; i++ ) { var id = viewTable.rows[i].cells[2].innerText; if( eval("viewchk_" + id + ".checked") == true ) { delete_rule(id) } } saveXML(); Transform(); } else if( val == 4 ) { //select all checked_count = viewTable.rows.length - 1; for( var i = 1; i < viewTable.rows.length; i++ ) { var id = viewTable.rows[i].cells[2].innerText; eval("viewchk_" + id + ".checked = true"); } changeState(); } else if( val == 5 ) { //cancel all checked_count = 0; for( var i = 1; i < viewTable.rows.length; i++ ) { var id = viewTable.rows[i].cells[2].innerText; eval("viewchk_" + id + ".checked = false"); } changeState(); } } function getFirstCheckedLine(){ for( var i = 1; i < viewTable.rows.length; i++ ) { var id = viewTable.rows[i].cells[2].innerText; if( eval("viewchk_" + id + ".checked") == true ) { return i; } } return 0; } function checkOVItem(val){ if( eval("viewchk_" + val+".checked") == true ) { checked_count++; } else { checked_count--; } changeState(); } function changeState(){ if( checked_count ) { delete_btn.disabled = false; cancel_all_btn.disabled = false; } else { delete_btn.disabled = true; cancel_all_btn.disabled = true; } if( (checked_count + 1) == viewTable.rows.length ) { select_all_btn.disabled = true; } else { select_all_btn.disabled = false; } if( checked_count == 1 ) { modify_btn.disabled = false; modify_id.disabled = false; modify_name.disabled = false; modify_state.disabled = false; var id = getFirstCheckedLine(); modify_id.value = viewTable.rows(id).cells(2).innerText; modify_name.value = viewTable.rows(id).cells(3).innerText; if( viewTable.rows(id).cells(1).innerText == "有效" ) { modify_state.checked = true; } else { modify_state.checked = false; } } else { modify_btn.disabled = true; modify_id.disabled = true; modify_name.disabled = true; modify_state.disabled = true; modify_id.value="请选择一条规则"; modify_name.value="请选择一条规则"; } } function showPageInfo(){ if( total_item.value == 0 ) { total_page = 1; } else { total_page = Math.floor((9 + parseInt(total_item.value)) / 10); } var txt = " 共"+total_item.value+"条记录"; var prev_page = cur_page - 1; var next_page = parseInt(cur_page) + 1; if( cur_page > 1 ) { txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")'/>" } else { txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")' disabled/>" } if( cur_page < total_page ) { txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")'/>" } else { txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")' disabled/>" } txt += " 第<input type='text' id='page_number' size='4' maxlength='4' value='" + cur_page + "' onBlur='gotoPage(this.value)'/>页 共" + total_page + "页"; page_info.innerHTML = txt; // window.alert(txt); } function Transform(){ var txt = document.getElementById("ename").value; var str = OutputDocument(txt); rule_list.innerHTML = str; checked_count = 0; showPageInfo(); changeState(); // window.alert(str); } </script> <BODY onLoad="Transform()"> <table width="550" border="1" cellpadding="0" cellspacing="0" style="border-collapse:collapse;"> <tr> <td> <table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;"> <TR height=5><td colspan=10 style="font-size:0px;"></td></TR> <TR height=25> <td colspan=3 align=center>事件名包含:</td> <td colspan=3 align=center><input type="text" value="" id="ename" size="35" maxlength="16"/></td> <td colspan=4><input type="button" value="搜索" onClick="Transform()"/></td> </TR> <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR> <TR height=30> <td width=45 align=center><b>添加</b></td> <td width=5 align=center><font color=gray>|</font></td> <td width=50 align=center>事件号</td> <td width=55 align=center><input type="text" name="add_id" value="" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"></td> <td width=55 align=center>事件名</td> <td width=* align=center><input type="text" name="add_name" maxlength="48" value=""></td> <td width=70 align=center>是否使用</td> <td width=30 align=center> <input type='checkbox' name='add_state' checked> </td> <td width=5 align=center><font color=gray>|</font></td> <td width=70 align=center><input type="button" name="add_btn" value="确定" onClick="protectsubmit(1)"></td> </TR> <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR> <TR height=30> <td width=45 align=center><b>修改</b></td> <td width=5 align=center><font color=gray>|</font></td> <td width=50 align=center>事件号</td> <td width=55 align=center> <input type="text" name="modify_id" value="<请选择一条规则>" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" disabled></td> <td width=55 align=center>事件名</td> <td width=* align=center> <input type="text" name="modify_name" maxlength="48" value="<请选择一条规则>" disabled></td> <td width=70 align=center>是否使用</td> <td width=30 align=center> <input type='checkbox' name='modify_state' disabled> </td> <td width=5 align=center><font color=gray>|</font></td> <td width=70 align=center><input type="button" name="modify_btn" value="确定" onClick="protectsubmit(2)"></td> </TR> <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR> <TR height=30> <td colspan=5 align=left class=tablefont></td> <td align=right><input type="button" name="select_all_btn" value="全部选择" onClick="protectsubmit(4)"></td> <td colspan=2 align=right><input type="button" name="cancel_all_btn" value="全部不选" onClick="protectsubmit(5)" disabled></td> <td align=center></td> <td align=center><input type="button" name="delete_btn" value="删除" onClick="protectsubmit(3)" disabled></td> </TR> <TR height=30><td colspan=4>规则列表</td><TD colspan=6 align=right><div id="page_info" name="page_info"/></TR> <TR> <TD colspan=10><div id="rule_list" name="rule_list"/></TD> </TR> <TR height=5><td colspan=10></td></TR> </table> </td> </tr> <tr> </tr> </table> </BODY> </HTML> [此贴子已经被作者于2005-7-23 9:12:04编辑过]
|