多级树的传统作法是数据保存到数据库中,这样做的优点是可以保存的数据量大,可以用标准的sql对数据执行操作;但是这样做的缺点也是很明显的,那就是层次结构不能得到很好的体现,很不直观,维护起来比较困难;在数据量不是很大的情况下(如管理后台左边的导航栏数据),我比较喜欢把数据保存在 xml文件中,节点间的层次结构得到很好的体现,同时在增加一个节点的时候不再要求一定要同时该节点的父亲节点的信息;系统的结构为Ext2.0+struts1.3.8+spring2.0;有兴趣的朋友在下载后,将项目发布到Tomcat,在浏览器中输入http://localhost:8080/xmlTree/Province_City_County/provinceCityCounty_xml.html即可看到效果。以下为主要代码(红色部分为核心代码 )
实体类
package entity;
import java.util.List;
public class XmlTreeNode {
public String treeId; /*树节点id*/
public String text; /*树节点文本值*/
public List children; /*树节点对应孩子节点*/
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public String getTreeId() {
return treeId;
}
public void setTreeId(String treeId) {
this.treeId = treeId;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
action对应代码
package action;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import service.XmlTreeService;
import util.Factory;
import util.Print;
public class PCC_Xml_DataAction extends Action {
private XmlTreeService xmlTreeService;
private PrintWriter out ;
public ActionForward execute(ActionMapping mapping,ActionForm form ,HttpServletRequest request,HttpServletResponse response)throws Exception{
response.setContentType("text/x-json;charset=UTF-8");
xmlTreeService=(XmlTreeService) Factory.getBean("xmlTreeService");
String json=xmlTreeService.getResponseJson();
out=response.getWriter();
out.println(json);
out.flush();
out.close();
return null;
}
}
业务层实现类
package service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import entity.XmlTreeNode;
import util.Factory;
import util.Print;
import util.Tools;
import util.XmlTreeTool;
public class XmlTreeServiceImpl implements XmlTreeService {
/**获得一个Element获得一个集合,该集合的元素为该元素的子Elemtn转化而成的对象*/
public List getChildrens(Element element) {
List resultList=new ArrayList();
NodeList childrenNodes=element.getChildNodes();
for(int i=0;i<childrenNodes.getLength();i++){
if(childrenNodes.item(i).getNodeType()==1){
Element tempChildren=(Element) childrenNodes.item(i);
XmlTreeNode tempNode=elementToNode(tempChildren);
List tempList=getChildrens(tempChildren);
if(tempList.size()!=0){
tempNode.setChildren(tempList);
}
resultList.add(tempNode);
}
}
return resultList;
}
/**获得根元素的子元素转化而成的对象列表*/
public List getRootEleChild(){
DocumentBuilder documentBuilder=Factory.getDocumentBuilder();
Element rootElement=null;
try {
Document doc=documentBuilder.parse(XmlTreeServiceImpl.class.getClassLoader().getResourceAsStream("province.xml"));
rootElement=doc.getDocumentElement();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return getChildrens(rootElement);
}
/** 实现从Element到XmlTreeNode的转化*/
public XmlTreeNode elementToNode(Element element){
XmlTreeNode result=new XmlTreeNode();
boolean textIsNull=false;
String treeId=element.getAttribute("id");
String treeName1=element.getAttribute("text");
if(!Tools.isNull(treeId)){
result.setTreeId(treeId);
}
if(!Tools.isNull(treeName1)){
result.setText(treeName1);
return result;
}
String treeName2=element.getFirstChild().getNodeValue();
if(!Tools.isNull(treeName2)){
result.setText(treeName2);
}
return result;
}
public String getResponseJson(){
String json=Tools.listToJson(getRootEleChild())+"";
return transferJson(json);
}
/**把输入的数据转化成最终形式(client端想要的Json格式)*/
public String transferJson(String input){
String result=input.replaceAll("\"children\":\\[\\],","leaf:true,");
return result;
}
}
前台页面代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>provinceCityCounty.html</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../scripts/ext/resources/css/ext-all.css"/>
<script type="text/javascript" src="../scripts/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../scripts/ext/ext-all.js"></script>
<script type="text/javascript">
Ext.onReady(function(){
var tree=new Ext.tree.TreePanel({
renderTo:'pcc_xml',
width:1000,
rootVisible:false,
loader:new Ext.tree.TreeLoader({
dataUrl:'../pCC_Xml_Data.do'
}),
root:new Ext.tree.AsyncTreeNode({
text:'树的根'
})
});
tree.render();
});
</script>
</head>
<body>
<div id="pcc_xml"></div>
</body>
</html>