xml在j2EE中应用非常广泛,主要作为一些配置存在。在我们的项目中由于需要方便的对菜单进行管理,因此也将菜单定义成了xml。
然后使用ext去解析这个xml进行菜单展示。
菜单格式大致如下:
<?xml version="1.0" encoding="UTF-8"?>
<根节点 expanded="true">
<节点一 expanded="true" id="tree-test1">
<子节点一 href="page1.html" />
<子节点二 href="page2.html" />
<子节点三 href="page3.html" />
<子节点四 href="page5.html" />
<子节点五 href="page4.html" />
</节点一>
<节点二 expanded="true" id="tree-test1">
<子节点一 href="page1.html" />
<子节点二 href="page2.html" />
<子节点三 href="page3.html" />
<子节点四 href="page5.html" />
<子节点五 href="page4.html" />
</节点二>
</根节点>
基本是按照树形结构写的菜单,如果有多级菜单,则按照xml的嵌套规则进行嵌套即可。
1、必须有一个根节点
2、对某个节点的属性可以通过xml属性定义。如id="xx",href='xx'。
3、如果没有子节点,可以对单个标记写。如<节点 />
剩下的就是解析函数,这里参考ext官方论坛的一个帖子,偶自己改了一下以适应定义的xml:
//解析xml字符串
function loadXML(xmlStr){
if(!xmlStr)return null; //空串返回null
if (window.ActiveXObject){
var xmlDom=new ActiveXObject("Microsoft.XMLDOM");
}else{
if (document.implementation&&document.implementation.createDocument){var xmlDom=document.implementation.createDocument("","doc",null)}
}
xmlDom.async = false;
try{
xmlDom.loadXML(xmlStr);
}catch(e){ //非IE浏览器
var oParser=new DOMParser();
xmlDom=oParser.parseFromString(xmlStr,"text/xml");
}
return xmlDom;
}
//下面两个函数用于解析xml为树结构输出
function createXmlTree(el,xmlsrc,callback) {
var tree=new Ext.tree.TreePanel({el:el,animate:true,border:false,autoHeight:true});
var xmlDom=loadXML(xmlsrc);
try{ //作为xml串解析
tree.setRootNode(treeNodeFromXml(xmlDom.documentElement||xmlDom));
callback.call(tree);
}catch(e){ //作为url解析
var p = new Ext.data.HttpProxy({url:xmlsrc||"etc/menu.xml"}); //默认为etc/menu.xml
p.on("loadexception",function(o,response,e){tree.setRootNode(new Ext.tree.TreeNode("根节点"))});
p.load(null,{
read: function(response) {
var doc=response.responseXML;
tree.setRootNode(treeNodeFromXml(doc.documentElement||doc));
}
},callback,tree);
}
return tree;
}
function treeNodeFromXml(XmlEl) {
var t=((XmlEl.nodeType==3)?XmlEl.nodeValue:XmlEl.tagName);
if(t.replace(/\s/g,'').length==0){return null}
var result = {text : t};
if(XmlEl.nodeType==1){
Ext.each(XmlEl.attributes,function(a){
if(a.nodeName=="href"&&XmlEl.hasChildNodes()) return; //目录不添加链接属性
result[a.nodeName]=a.nodeValue;
});
result = new Ext.tree.TreeNode(result); //根据属性设置构建树
Ext.each(XmlEl.childNodes,function(el){
if((el.nodeType==1)||(el.nodeType ==3)){
var c=treeNodeFromXml(el);
if(c){result.appendChild(c);}
}
});
}
return result;
}
以上方法支持传入xml的url或直接传入xml串。
调用示例: //第一个参数:要显示树形菜单的容器id或dom对象,
//第二个参数:xml源:可以为url或xml字符串
//第三个参数:解析树成功后执行的回调函数
var menuTree = new createXmlTree('menuTree',"etc/menu.xml",function(){
this.render();
this.getRootNode().expand();
});