站内搜索: 请输入搜索关键词

当前页面: 开发资料首页JSP 专题树型目录的XML实现(二)jsp+XML+js,跟CSDN的论坛列表相同?

树型目录的XML实现(二)jsp+XML+js,跟CSDN的论坛列表相同?

摘要: javabean jsp XML js xmlhttp 树型

本功能实现有些复杂,涉及的知识点:
*java的XML遍历——SAX实现
*java的XML更新——DOM实现
*HTML页面js的无刷新提交数据——XMLHTTP实现,需要MSXML2支持
*js的XML遍历——XMLDOM实现,需要Microsoft插件支持
*HTML及JSP页面让cache立即过期的代码实现
第三和第四点也是实现无刷新聊天室的核心技术!!!
总共包括四个文件:
tree2.htm——树型结构的客户端显示,用户的所有操作(打开、增加和删除节点)都从这个页面提交
tree2.xml——树型的数据和结构
tree2.jsp——XML树型结构的遍历
do_tree2.jsp——树型节点的增加与删除操作(测试用,如果只是显示树型,可以不要)
几点说明:
1、这个功能实现脱离了数据库DB,其数据来源是XML文件,tree2.xml文件的基本结构如下:
<?xml version="1.0" encoding="GB2312"?>

table
{
font-family:宋体;
cursor:default;
font-size:9pt;
}

.container {
position:relative;
top:4px;
padding:1px;
padding-top:5px;
width:13px;
height:13px;
border:solid 1px black;
background-color:#ffffff;
}

SPAN.clsCollapse
{
top:3px;
padding-left:1px;
padding-top:26px;
overflow:hidden;
line-height:3px;
font-size:13px;
}

SPAN.clsExpand
{
padding-left:1px;
overflow:hidden;
line-height:3px;
font-size:13px;
padding-top:3px;
}

SPAN.clsLeaf
{
top:0px;
padding-left:3px;
overflow:hidden;
line-height:0px;
font-size:11px;
cursor:normal;
}

SPAN.clsLabel
{

height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
border:1px solid #FFFFFF
}

SPAN.clsMouseOver
{
position:relative;
height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
background-color:#CCCCCC;
border:1px solid #999999;
cursor:hand;
}

SPAN.clsMouseOut
{
position:relative;
height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
background-color:#CCCCCC;
border:1px solid #FFFFFF;
}

SPAN.clsMouseDown
{
position:relative;
height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
background-color:#999999;
border:1px solid #999999;
}
SPAN.clsCurrentHasFocus
{
position:relative;
height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
background-color:#FFFFFF;
border:1px solid #999999;
cursor:hand;
}

SPAN.clsNotReady
{
position:relative;
height:17px;
overflow:hidden;
padding-left:3px;
padding-top:2px;
background-color:#CCCCCC;
border:1px solid #FFFFFF;
}
DIV.focusColor {backgroud-color:red}
DIV.normalColor {backgroud-color:green}

<script language="JavaScript">

function onMouseOver()
{
if(window.event.srcElement.tagName=="SPAN" && window.event.srcElement.className=="clsLabel")
{
window.event.srcElement.className="clsMouseOver"
window.event.srcElement.title=window.event.srcElement.innerText
}
}
function onMouseOut()
{

if(window.event.srcElement.tagName=="SPAN" && window.event.srcElement.className=="clsMouseDown")
{
window.event.srcElement.className="clsCurrentHasFocus"
return
}

if(window.event.srcElement.tagName=="SPAN" && window.event.srcElement.className=="clsMouseOver")
window.event.srcElement.className="clsLabel"
}

function onMouseDown()
{
for(i=0;i {
if(document.getElementsByTagName("SPAN")[i].className=="clsCurrentHasFocus") document.getElementsByTagName("SPAN")[i].className="clsLabel";
}

if(window.event.srcElement.tagName=="SPAN" && (window.event.srcElement.className=="clsMouseOver" || window.event.srcElement.className=="clsLabel"))
{
window.event.srcElement.className="clsMouseDown";
parentid.value=window.event.srcElement.id;
}
}

window.document.onmouseover = onMouseOver;
window.document.onmouseout = onMouseOut;
window.document.onmousedown = onMouseDown;

var oDiv;
var xmlhttp;
var np;
function window.onload() {
readXML(0);
}

function readXML(id) {
oDiv = document.createElement("DIV");
nP = parseInt(document.all["pid"+id].style.paddingLeft);
oDiv.innerHTML = "

. " + "正在装载栏目数据,请稍侯.......
"
oDiv.style.paddingLeft= nP + "px";
document.all["pid"+id].appendChild(oDiv);
var str="parentid="+id;
xmlhttp=new ActiveXObject("MSXML2.XMLHTTP");//提取树型结构数据的核心就在这里
xmlhttp.onreadystatechange=getReady;
xmlhttp.open("get","tree2.jsp?"+str,true);//提交数据到tree2.jsp
xmlhttp.send();
}

function getReady() {
if(xmlhttp.ReadyState==4) {
if(xmlhttp.status==200) {
var xmldom = new ActiveXObject("Microsoft.XMLDOM")
xmldom.loadXML(xmlhttp.responseText);//当tree2.jsp操作完成,用xmldom获取这些xml数据
if(xmldom==null||xmldom.documentElement==null) {
oDiv.innerHTML="

. " + "抱歉,装载数据失败。原因:返回的数据不是一个XML结构的文档。
";
return;
}


var nodes = xmldom.documentElement.selectNodes("/root/xiruo");
if(nodes == null ){
oDiv.innerHTML = "
. " + "抱歉,装载数据失败。原因:没有返回正确的XML结构格式。
";
return;
}


var str = "";
for(var i=0;i parentid.options.add(new Option(nodes[i].selectSingleNode("id").text,nodes[i].selectSingleNode("id").text));
if(nodes[i].selectSingleNode("childcount").text!='0') {
str += "
+ ";
str += ""+ nodes[i].selectSingleNode("message").text + " id="+nodes[i].selectSingleNode("id").text+"
";
} else {
str += "
. "
str += ""+ nodes[i].selectSingleNode("message").text + " id="+nodes[i].selectSingleNode("id").text+"
";
}
}
str+="";
oDiv.innerHTML = str;
} else {
oDiv.innerHTML = "
. " + "抱歉,装载数据失败。
";
}
}
}

function hideshow(o,oId)
{

var subjectid = oId.substr(3,oId.length)
if (o.status=="")
{
readXML(subjectid)
o.innerText="-";
o.status="old";
return;
}

var oChild = null
for(var i=0;i {
if(document.all[oId].childNodes(i).tagName=="DIV") oChild = document.all[oId].childNodes(i)
}
if(oChild==null) return

if(oChild.style.display=="")
{
o.innerText="+";
oChild.style.display="none";
}
else
{
o.innerText="-";
oChild.style.display="";
}
event.returnValue=false;
return false;
}

function addTreeNode() {//添加节点
var str="parentid="+parentid.value+"&message="+message.value+"&action=add";
pid0.innerText="";
parentid.innerText="";
var xmlhttp=new ActiveXObject("MSXML2.XMLHTTP");
xmlhttp.onreadystatechange=function addReady(){
if(xmlhttp.ReadyState==4&&xmlhttp.status==200) {
if(xmlhttp.responseText.indexOf("error")!=-1) {
var oDiv = document.createElement("DIV");
pid0.appendChild(oDiv);
oDiv.innerHTML="

. " + "抱歉,节点添加失败。
";
} else {
parentid.options.add(new Option("0","0"));
readXML(0);
}
}
};
xmlhttp.open("get","do_tree2.jsp?"+str,true);
xmlhttp.send();
}

function deleteTreeNode() {//删除节点
if(parentid.value=="0") {
alert("不存在ID为0的节点!");
return;
}
var str="parentid="+parentid.value+"&action=delete";
pid0.innerText="";
parentid.innerText="";
var xmlhttp=new ActiveXObject("MSXML2.XMLHTTP");
xmlhttp.onreadystatechange=function addReady(){
if(xmlhttp.ReadyState==4&&xmlhttp.status==200) {
if(xmlhttp.responseText.indexOf("error")!=-1) {
var oDiv = document.createElement("DIV");
pid0.appendChild(oDiv);
oDiv.innerHTML="

. " + "抱歉,节点删除失败。
";
} else {
parentid.options.add(new Option("0","0"));
readXML(0);
}
}
};
xmlhttp.open("get","do_tree2.jsp?"+str,true);
xmlhttp.send();
}
//
</script>
<table>
<tr><td height="300" valign="top">

</td></tr>
<tr><td valign="top">
parentid:
<select name="parentid" id="parentid">
<option value="0">0</option>
</select>
0-表示根节点,
message:<input type="text" name="message">
<input type="button" value="add" onClick="addTreeNode();">&nbsp;<input type="button" value="delete" onClick="deleteTreeNode();">
</td></tr></table>
********************
* tree2.jsp *//这个是遍历并返回xml数据的文件
********************
<%@ page contentType="text/xml; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>

<%!//方便起见就不写成javabean了
class myHandler extends org.xml.sax.helpers.DefaultHandler {//继承org.xml.sax.helpers.DefaultHandler,然后通过SAX遍历XML
String s="",parentid="",tarValue="";
boolean isxiruo=false;
public myHandler(String parentid) {
this.parentid=parentid;
}

public void startDocument() {
s+="<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n\r\n\r\n";
}

public void startElement(String namespaceURI,String localName,String qName,org.xml.sax.Attributes attr) {
if(qName.equals("xiruo")) {
if(attr.getValue("parentid").equals(parentid)) {
isxiruo=true;
s+="\t\r\n";
} else
isxiruo=false;
}
}

public void endElement(String namespaceURI,String localName,String qName) {
if(isxiruo) {
if(qName.equals("xiruo"))
s+="\t\r\n";
else
s+="\t\t<"+qName+">"+tarValue+"\r\n";
}
}

public void endDocument() {
s+="";
}

public void characters(char[] ch,int start,int length) {
tarValue=new String(ch,start,length);
}

public String getXML() {
return this.s;
}
}

class buildXML {
public buildXML(javax.servlet.http.HttpServletRequest request,javax.servlet.jsp.JspWriter out) throws Exception {
if(request.getParameter("parentid")==null)return;
javax.xml.parsers.SAXParserFactory spf=javax.xml.parsers.SAXParserFactory.newInstance();
javax.xml.parsers.SAXParser sp=spf.newSAXParser();
org.xml.sax.XMLReader xmlreader=sp.getXMLReader();
myHandler h=new myHandler(request.getParameter("parentid"));//通过构造器输入过滤条件,实现SAX的的XML遍历
xmlreader.setContentHandler(h);
xmlreader.parse(request.getRealPath("tree\\tree2.xml"));//我的tree2.xml文件放在tree目录下,如果放在别的地方,需要改这个路径
out.println(h.getXML());//返回SAX遍历的结果,这里返回的是一个XML的数据结构
}
}
%>

void init(javax.servlet.http.HttpServletRequest request,javax.servlet.jsp.JspWriter out) throws Exception {
if(!getField(request)) {
out.println("error");
return;
}
if(action.equals("add"))addTreeNode(request);
else if(action.equals("delete"))deleteTreeNode(request);
}
//增加节点
private void addTreeNode(javax.servlet.http.HttpServletRequest request) throws Exception {
int maxid=0;
javax.xml.parsers.DocumentBuilderFactory dbf=javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder db=dbf.newDocumentBuilder();
org.w3c.dom.Document document=db.parse(request.getRealPath("tree\\tree2.xml"));
org.w3c.dom.Element element=document.getDocumentElement();
org.w3c.dom.NodeList nl=element.getElementsByTagName("xiruo");
for(int i=0;i int curid=0;
org.w3c.dom.Element ele = (org.w3c.dom.Element) nl.item(i);
org.w3c.dom.NodeList nl1=ele.getElementsByTagName("id");
if(nl1.getLength()==1) {
org.w3c.dom.Element e=(org.w3c.dom.Element)nl1.item(0);
org.w3c.dom.Text text=(org.w3c.dom.Text)e.getFirstChild();
curid=Integer.parseInt(text.getNodeValue());
maxid=maxid>curid?maxid:curid;
}
nl1=ele.getElementsByTagName("childcount");
if(nl1.getLength()==1&&curid==Integer.parseInt(parentid)) {//所要增加节点的根节点childcount加1
org.w3c.dom.Element e=(org.w3c.dom.Element)nl1.item(0);
org.w3c.dom.Text text=(org.w3c.dom.Text)e.getFirstChild();
text.setNodeValue(String.valueOf(Integer.parseInt(text.getNodeValue())+1));
}
}
org.w3c.dom.Element newElement=document.createElement("xiruo");
element.appendChild(newElement);
newElement.setAttribute("parentid",parentid);
org.w3c.dom.Element e=document.createElement("id");
e.appendChild(document.createTextNode(String.valueOf(maxid+1)));
newElement.appendChild(e);
e=document.createElement("message");
e.appendChild(document.createTextNode(message));
newElement.appendChild(e);
e=document.createElement("childcount");
e.appendChild(document.createTextNode("0"));
newElement.appendChild(e);
javax.xml.transform.dom.DOMSource domsource=new javax.xml.transform.dom.DOMSource(document);
javax.xml.transform.TransformerFactory tf=javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer t=tf.newTransformer();
javax.xml.transform.stream.StreamResult streamresult=new javax.xml.transform.stream.StreamResult(request.getRealPath("tree\\tree2.xml"));
Properties properties=t.getOutputProperties();
properties.setProperty(javax.xml.transform.OutputKeys.ENCODING,"gb2312");
properties.setProperty(javax.xml.transform.OutputKeys.METHOD,"xml");
properties.setProperty(javax.xml.transform.OutputKeys.VERSION,"1.0");
properties.setProperty(javax.xml.transform.OutputKeys.INDENT,"no");
t.setOutputProperties(properties);
t.transform(domsource,streamresult);
}
//删除节点用递归
private void deleteTreeNode(javax.servlet.http.HttpServletRequest request) throws Exception {
javax.xml.parsers.DocumentBuilderFactory dbf=javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder db=dbf.newDocumentBuilder();
org.w3c.dom.Document document=db.parse(request.getRealPath("tree\\tree2.xml"));
org.w3c.dom.Element element=document.getDocumentElement();
org.w3c.dom.NodeList nl=element.getElementsByTagName("xiruo");
java.util.ArrayList al=new java.util.ArrayList();
getDeleteTreeNodeI(parentid,al,nl);
java.util.Collections.sort(al);
java.util.Collections.reverse(al);
for(int i=0;i element.removeChild(nl.item(((Integer)al.get(i)).intValue()));
javax.xml.transform.dom.DOMSource domsource=new javax.xml.transform.dom.DOMSource(document);
javax.xml.transform.TransformerFactory tf=javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer t=tf.newTransformer();
javax.xml.transform.stream.StreamResult streamresult=new javax.xml.transform.stream.StreamResult(request.getRealPath("tree\\tree2.xml"));
Properties properties=t.getOutputProperties();
properties.setProperty(javax.xml.transform.OutputKeys.ENCODING,"gb2312");
properties.setProperty(javax.xml.transform.OutputKeys.METHOD,"xml");
properties.setProperty(javax.xml.transform.OutputKeys.VERSION,"1.0");
properties.setProperty(javax.xml.transform.OutputKeys.INDENT,"no");
t.setOutputProperties(properties);
t.transform(domsource,streamresult);
}

private void getDeleteTreeNodeI(String id,java.util.ArrayList al,org.w3c.dom.NodeList nl) throws Exception {
int removeid=0,minusid=0;
for(int i=0;i org.w3c.dom.Element ele = (org.w3c.dom.Element) nl.item(i);
org.w3c.dom.NodeList nl1=ele.getElementsByTagName("id");
if(nl1.getLength()==1) {
org.w3c.dom.Element e=(org.w3c.dom.Element)nl1.item(0);
org.w3c.dom.Text text=(org.w3c.dom.Text)e.getFirstChild();
if(text.getNodeValue().equals(id)){al.add(new Integer(i));removeid=Integer.parseInt(id);minusid=Integer.parseInt(((org.w3c.dom.Element)nl.item(i)).getAttribute("parentid"));}
}
}
for(int i=0;i int curid = 0;
org.w3c.dom.Element ele = (org.w3c.dom.Element) nl.item(i);
org.w3c.dom.NodeList nl1 = ele.getElementsByTagName("id");
if (nl1.getLength() == 1) {
org.w3c.dom.Element e = (org.w3c.dom.Element) nl1.item(0);
org.w3c.dom.Text text = (org.w3c.dom.Text) e.getFirstChild();
curid = Integer.parseInt(text.getNodeValue());
if((Integer.parseInt(((org.w3c.dom.Element)nl.item(i)).getAttribute("parentid"))==removeid))
getDeleteTreeNodeI(text.getNodeValue(),al,nl);
}
nl1 = ele.getElementsByTagName("childcount");
if (nl1.getLength() == 1 && minusid == curid) {
org.w3c.dom.Element e = (org.w3c.dom.Element) nl1.item(0);
org.w3c.dom.Text text = (org.w3c.dom.Text) e.getFirstChild();
text.setNodeValue(String.valueOf(Integer.parseInt(text.getNodeValue())-1));
}
}
}
}
%>
<%
response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
new buildXML().init(request,out);
%>
这个是我测试的图片:



↑返回目录
前一篇: 转载--jsp连接数据库大全
后一篇: JSP连接数据库大全