以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XSL/XSLT/XSL-FO/CSS 』  (http://bbs.xml.org.cn/list.asp?boardid=8)
----  用xslt和javascript对xml数据进行添加、修改、删除操作,并将结果分页显示  (http://bbs.xml.org.cn/dispbbs.asp?boardid=8&rootid=&id=20471)


--  作者: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() &gt; $startno and position() &lt;= $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='&lt;' onClick='gotoPage(" + prev_page + ")'/>"
 } else {
  txt += "   <input type='button' value='&lt;' onClick='gotoPage(" + prev_page + ")' disabled/>"
 }
 if( cur_page < total_page ) {
  txt += "   <input type='button' value='&gt;' onClick='gotoPage(" + next_page + ")'/>"
 } else {
  txt += "   <input type='button' value='&gt;' 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编辑过]

--  作者:x5duan
--  发布时间:7/18/2005 12:02:00 PM

--  
版主看看,怎么我贴上来的附件下不了?害我还重复贴了一次附件-_-!



[此贴子已经被作者于2005-7-19 9:29:49编辑过]

--  作者:孤独
--  发布时间:7/18/2005 2:52:00 PM

--  
转向其他页面了/?
--  作者:tloner
--  发布时间:11/22/2005 4:30:00 PM

--  
有意思,好好研究
--  作者:tloner
--  发布时间:11/22/2005 10:10:00 PM

--  
研究了一下,受益菲浅啊,多谢LZ
--  作者:5sghl
--  发布时间:11/29/2005 9:23:00 AM

--  
太高深了,我看不懂,
--  作者:guan1200
--  发布时间:12/1/2005 9:14:00 PM

--  
太麻烦了
能将rule.hta类容写到xml文件中吗?主要问题是在xslt中如何取的是用他的xml文件??
--  作者:supersiben
--  发布时间:7/17/2006 4:41:00 PM

--  
为什么运行后总显示 "样式表没有包含文档元素" 错误啊?
--  作者:lhsunrice
--  发布时间:4/28/2007 9:39:00 AM

--  
帖子内容还没有看,不过先顶一个
--  作者:龙藤
--  发布时间:6/27/2007 4:08:00 PM

--  
谢谢!
--  作者:grainrain_sy
--  发布时间:6/30/2008 4:26:00 PM

--  
感谢!!!!
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
156.250ms