A JavaScript Fancier

伟大的javascript技术研究中...

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  304 随笔 :: 0 文章 :: 479 评论 :: 0 Trackbacks


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();
    });

posted on 2008-05-30 11:01 Yemoo'S JS Blog 阅读(4131) 评论(2)  编辑 收藏 引用 所属分类: Js框架组件

评论

# re: 解析Xml构建Ext树形菜单 2008-12-05 20:31 赵东旭
问一个简单的问题!!
如何打开href后面的连接的叶面!!  回复  更多评论
  

# re: 解析Xml构建Ext树形菜单 2009-10-05 00:07 ydd
Ext.onReady(function(){
function loadXML(xmlStr){

if(!xmlStr)return 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{
alert(xmlStr);
xmlDom.loadXML(xmlStr);
}catch(e){
var oParser=new DOMParser();
xmlDom=oParser.parseFromString(xmlStr,"text/xml");
}
alert(xmlDom);
return xmlDom;

}

function createXmlTree(el,xmlsrc,callback) {
var tree=new Ext.tree.TreePanel({el:el,animate:true,border:false,autoHeight:true});
var xmlDom=loadXML(xmlsrc);
try{
tree.setRootNode(treeNodeFromXml(xmlDom.documentElement||xmlDom));
callback.call(tree);
}catch(e){
var p = new Ext.data.HttpProxy({url:xmlsrc||"etc/menu.xml"});

p.on("loadexception",function(o,response,e){tree.setRootNode(new Ext.tree.TreeNode("¸ù½Úµã"))});
p.load(null,{
reader: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;
}
var menuTree = new createXmlTree('menuTree',"etc/menu.xml",function(){
this.render();
this.getRootNode().expand();
});
});


Line 38
char 7
code 0
error 缺少对象

帮忙解决。。。谢谢
reader:function(response)这里解析出错

  回复  更多评论
  

只有注册用户登录后才能发表评论。