您的位置:首页 > Web前端 > JavaScript

JavaScript解析XML实现多级级联下拉列表

2007-10-15 16:49 746 查看
1.创建XML文档:cascaded_select.xml


<?xml version="1.0" encoding="GBK"?>


<select>


<province key="sx" value="陕西">


<city key="xa" value="西安"/>


<city key="bj" value="宝鸡"/>


<city key="wn" value="渭南">


<xian key="fp" value="富平">


<zhen key="zq" value="张桥"/>


</xian>


</city>


<city key="ak" value="安康"/>


</province>


<province key="js" value="江苏">


<city key="nj" value="南京"/>


<city key="xz" value="徐州"/>


</province>


<province key="sh" value="上海"/>


</select>

2.创建BlueParseXML.js,用来加载解析XML文档




/**//**


* @description 解析并封装XML


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @modifDate 2007-10-15


* @version 1.0


*/


//解析XML文件对象构造器




function BlueParseXML()...{


}


BlueParseXML.prototype.xml;//定义对象属性xml


BlueParseXML.prototype.loadFinish;//加载完成函数


BlueParseXML.prototype.nodeProperties=new Array();//节点属性数组


BlueParseXML.prototype.key="key";


BlueParseXML.prototype.value="value";


BlueParseXML.prototype.nodeList;//节点集合


BlueParseXML.prototype.rootName;


BlueParseXML.XML_NULL=-1;//未加载xml,或加载失败




//加载xml文件




BlueParseXML.prototype.loadXML=function(url)...{


var newXML;


var obj=this;


//如果它受支持,采用标准的2级DOM技术




if(document.implementation && document.implementation.createDocument)...{


//创建新的Document对象


newXML=document.implementation.createDocument("","",null);


//设置装载完毕时触发事件




newXML.onload=function()...{




if(obj.loadFinish)...{


obj.loadFinish();


}


}


newXML.load(url);




}else...{//IE浏览器创建Document对象


newXML=new ActiveXObject("Microsoft.XMLDOM");


//设置onload




newXML.onreadystatechange=function()...{




if(newXML.readyState==4)...{




if(obj.loadFinish)...{


obj.loadFinish();


}


}


}


newXML.load(url);


}


this.xml=newXML;


}




//解析遍历xml




BlueParseXML.prototype.parseXML=function()...{




if(this.xml==null)...{


alert("XML未加载,请先加载XML文件!");


return parseXML.XML_NULL;


}


var rootNode=this.xml.documentElement;


this.rootName=rootNode.tagName;


this.nodeList=new ChildNodeList();


this.level=this.iteratorNode(this.nodeList,rootNode,1);


return this.level;


}


//遍历节点,将节点信息封装存入ChildNodeList中




BlueParseXML.prototype.iteratorNode=function(list,node,level)...{




if(!isNaN(level) && level>0)...{


list.nodeLevel=level;


}


var result=list.nodeLevel;//节点级别


var flag=true;//判断节点是否有子节点标记




for(var child=node.firstChild;child!=null;child=child.nextSibling)...{


flag=false;//有子节点




if(list.nodeName==null || list.nodeName=="")...{


list.nodeName=child.tagName;


}




if(list.nodeName==child.tagName)...{


var nodeInfo=new NodeInfo();


nodeInfo.nodeLevel=list.nodeLevel;//设置节点级别


nodeInfo.nodeName=list.nodeName;//设置节点名称


nodeInfo.key=child.getAttribute(this.key);//设置节点属性


nodeInfo.value=child.getAttribute(this.value);




for(var index=0;index<this.nodeProperties.length;index++)...{


nodeInfo[this.nodeProperties[index]]=child.getAttribute(this.nodeProperties[index]);


}


list.addElement(nodeInfo.key,nodeInfo);//把节点加入父节点的子节点集合


var n=this.iteratorNode(nodeInfo.childNodeList,child,list.nodeLevel+1);




if(n>result)...{//如果子节点返回的节点级别大于改节点级别,设置返回节点级别为最大级别


result=n;


}


}


}




if(flag)...{//当改节点没有子节点时返回的节点级别-1


result=result-1;


}


return result;


}


//扩展String对象,增加trim方法去掉字符串前后空格




String.prototype.trim=function()...{


return this.replace(/^s*/g,"").replace(/s*$/g,"");


}




/**//**


* @description 自定义集合对象(利用对象属性键值对,类似Hashtable使用)


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @modifDate 2007-10-15


* @version 1.0


*/


ChildNodeList.prototype.nodeLevel=1;


ChildNodeList.prototype.nodeName;


ChildNodeList.prototype.keyArray;


ChildNodeList.prototype.ELEMENT_NULL=-1;//元素为空


ChildNodeList.prototype.ELEMENT_EXIST=-2;//元素已经存在


ChildNodeList.prototype.ELEMENT_NOT_EXIST=-3;//元素不存在


ChildNodeList.prototype.INDEX_OUT=-4//数组下标越界


ChildNodeList.prototype.ERROR_DELETE=-5//删除元素出错




function ChildNodeList()...{


this.keyArray=new Array();


}


//添加集合元素




ChildNodeList.prototype.addElement=function(key,element)...{




if(key==null || element==null)...{


return ChildNodeList.ELEMENT_NULL;


}




if(this[key]!=null)...{


return ChildNodeList.ELEMENT_EXIST;


}


var index=this.keyArray.length;


this.keyArray[index]=key;


this[key]=element;


return index;


}


//根据下标删除集合元素




ChildNodeList.prototype.deleteElementByIndex=function(index)...{




if(index>=this.keyArray.length)...{


return ChildNodeList.INDEX_OUT;


}


var key=this.keyArray[index];




for(var i=index;i<this.keyArray.length;i++)...{


this.keyArray[i]=this.keyArray[i+1];


}


this.keyArray.length=this.keyArray.length-1;


delete this[key];


return index;


}


//根据key删除集合元素




ChildNodeList.prototype.deleteElementByKey=function(key)...{




if(this[key]==null)...{


return ChildNodeList.ELEMENT_NOT_EXIST;


}




for(var index=0;index<this.keyArray.length;index++)...{




if(this.keyArray[index]==key)...{


return this.deleteElementByIndex(index);


}


}


return ChildNodeList.ERROR_DELETE;


}


//根据key查找元素




ChildNodeList.prototype.getElementByKey=function(key)...{


return this[key];


}


//根据下标查找元素




ChildNodeList.prototype.getElementByIndex=function(index)...{


return this.getElementByKey(this.keyArray[index]);


}


//获取集合大小




ChildNodeList.prototype.size=function()...{


return this.keyArray.length;


}






/**//**


* @description 节点信息封装对象


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @modifDate 2007-10-15


* @version 1.0


*/


NodeInfo.prototype.nodeLevel;


NodeInfo.prototype.nodeName;//节点名称


NodeInfo.prototype.key;//节点名称,对应xml节点key属性


NodeInfo.prototype.value;//节点内容,对应xml节点value属性


NodeInfo.prototype.childNodeList;//子节点列表,用ChildNodeList对象封装


//构造器




function NodeInfo()...{


this.childNodeList=new ChildNodeList();


}

3.创建BlueCasadedSelect.js文件,用来生成级联下拉框




/**//**


* @description 级联下拉对象


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @modifDate 2007-10-15


* @version 1.0


*/


BlueCasadedSelect.prototype.selectList;


BlueCasadedSelect.prototype.defaultValue="-1";


BlueCasadedSelect.prototype.defaultText="请选择…";


BlueCasadedSelect.prototype.nodeList;//节点总集合


BlueCasadedSelect.prototype.isAddOnChangeEvent=false;


BlueCasadedSelect.prototype.SELECTLIST_NULL=-1;//下拉对象数组为空


BlueCasadedSelect.prototype.SELECTLIST_TYPE_NOT_ARRAY=-2;//下拉对象数组不是数组对象


BlueCasadedSelect.prototype.SELECTLIST_EMPTY=-3;//下拉对象数组为空数组


BlueCasadedSelect.prototype.SELECTLIST_LENGTH_OUT=-4;//下拉对象数组小于节点集合级别


BlueCasadedSelect.prototype.NODELIST_EMPTY=-5;//节点集合为空


BlueCasadedSelect.prototype.EVENT_NULL=-6;//事件源为空


//构造器




function BlueCasadedSelect(nodeList)...{




if(nodeList!=null)...{


this.nodeList=nodeList;




}else...{


this.nodeList=new ChildNodeList();


}


}




/**//**


* 创建下拉列表


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @lastModifDate 2007-10-13


* @param parentNode 下拉列表父节点对象


* @param nameList 下拉列表名字集合[可选参数]


* @version 1.0


*/




BlueCasadedSelect.prototype.createSelect=function(parentNode,nameList)...{




if(nameList==null)...{




if(this.nodeList.size()>0)...{


return this.createSelectDefault(parentNode,this.nodeList);


}


return this.NODELIST_EMPTY;


}




if(this.selectList==null)...{


this.selectList=new Array();


}


this.selectList.length=nameList.length;


var obj=this;




for(var i=0;i<nameList.length;i++)...{


var select=document.createElement("select");


select.setAttribute("name",nameList[i]);


select.setAttribute("id",nameList[i]);


select.options.length=1;


select.options[0].value=this.defaultValue;


select.options[0].text=this.defaultText;




if(i<nameList.length-1)...{




select.attachEvent("onchange",function()...{obj.changeSelect(select);});


this.isAddOnChangeEvent=true;


}


this.selectList[i]=select;


parentNode.appendChild(select);


}


return this.selectList.length;


}






/**//**


* 创建下拉列表(默认创建方法)


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @lastModifDate 2007-10-13


* @param parentNode 下拉列表父节点对象


* @param nodeList XML文档节点集合


* @version 1.0


*/




BlueCasadedSelect.prototype.createSelectDefault=function(parentNode,nodeList)...{




if(this.selectList==null)...{


this.selectList=new Array();


}


var obj=this;




if(nodeList!=null && nodeList.nodeName!=null)...{


this.selectList.length=this.selectList.length+1;


var select=document.createElement("select");


select.setAttribute("name",nodeList.nodeName);


select.setAttribute("id",nodeList.nodeName);


select.options.length=1;


select.options[0].value=this.defaultValue;


select.options[0].text=this.defaultText;


this.selectList[this.selectList.length-1]=select;


parentNode.appendChild(select);




for(var i=0;i<nodeList.size();i++)...{


var childNodeList=nodeList.getElementByIndex(i).childNodeList;




if(childNodeList.size()>0)...{




select.attachEvent("onchange",function()...{obj.changeSelect(select);});


this.isAddOnChangeEvent=true;


this.createSelectDefault(parentNode,childNodeList);


break;


}


}


}


return this.selectList.length;


}






/**//**


* 添加下拉列表onChange事件响应


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @lastModifDate 2007-10-13


* @version 1.0


*/




BlueCasadedSelect.prototype.addOnChangeEvent=function()...{




if(this.isAddOnChangeEvent)...{


return;


}




if(this.selectList==null)...{


return this.SELECTLIST_NULL;


}




if(this.selectList.constructor!=Array)...{


return this.SELECTLIST_TYPE_NOT_ARRAY;


}




if(this.selectList.length<=0)...{


return this.SELECTLIST_EMPTY;


}


var obj=this;




for(var i=0;i<this.selectList.length-1;i++)...{


var select=this.selectList[i];




select.attachEvent("onchange",function()...{obj.changeSelect(select);});


}


this.isAddOnChangeEvent=true;


}






/**//**


* 初始化下拉列表


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @lastModifDate 2007-10-13


* @param paramList 初始化每一级下拉默认选项参数列表


* @param nodeList XML文档节点集合[可选参数]


* @version 1.0


*/




BlueCasadedSelect.prototype.init=function(paramList,nodeList)...{


var currentList;




if(nodeList==null)...{


currentList=this.nodeList;




}else...{


currentList=nodeList;


}




if(this.selectList==null)...{


return this.SELECTLIST_NULL;


}




if(this.selectList.constructor!=Array)...{


return this.SELECTLIST_TYPE_NOT_ARRAY;


}




if(this.selectList.length<=0)...{


return this.SELECTLIST_EMPTY;


}




if(this.selectList.length<currentList.nodeLevel)...{


return this.SELECTLIST_LENGTH_OUT;


}




if(currentList.size()<=0)...{


return this.NODELIST_EMPTY;


}


var select=this.selectList[currentList.nodeLevel-1];


var defaultValue=paramList[currentList.nodeLevel-1];




for(var i=0;i<currentList.size();i++)...{


var nodeInfo=currentList.getElementByIndex(i);


var index=select.options.length;


select.options.length=index+1;


select.options[index].value=nodeInfo.key;


select.options[index].text=nodeInfo.value;




if(defaultValue!=null && defaultValue==nodeInfo.key)...{


select.options[index].selected=true;




if(nodeInfo.childNodeList.size()<=0)...{




for(var j=currentList.nodeLevel;j<this.selectList.length;j++)...{


var sel=this.selectList[j];


var n=sel.options.length;


sel.options.length=n+1;


sel.options
.value=nodeInfo.key;


sel.options
.text=nodeInfo.value;


sel.options
.selected=true;


}




}else...{


this.init(paramList,nodeInfo.childNodeList);


}


}


}


return select.options.length;


}






/**//**


* 下拉列表联动


* @author BluesLee


* @lastModif BluesLee


* @createDate 2007-10-13


* @lastModifDate 2007-10-13


* @param event 事件源下拉对象


* @version 1.0


*/




BlueCasadedSelect.prototype.changeSelect=function(event)...{




if(event==null)...{


return this.EVENT_NULL;


}




if(this.selectList==null)...{


return this.SELECTLIST_NULL;


}




if(this.selectList.constructor!=Array)...{


return this.SELECTLIST_TYPE_NOT_ARRAY;


}




if(this.selectList.length<=0)...{


return this.SELECTLIST_EMPTY;


}




if(this.nodeList.size()<=0)...{


return this.NODELIST_EMPTY;


}


var nextList=this.nodeList;


var nextSelect=event;


var flag=false;


var n=0;




for(var i=0;i<this.selectList.length;i++)...{


var select=this.selectList[i];




if(flag)...{


this.selectList[i].options.length=1;




}else...{




if(nextList.getElementByKey(select.value)!=null)...{


nextList=nextList.getElementByKey(select.value).childNodeList;




}else...{


nextList=new ChildNodeList();


}


}




if(select==event)...{


nextSelect=this.selectList[i+1];


flag=true;


n=i;


}


}




if(nextList.size()<=0 && event.value!=this.defaultValue)...{




for(var i=n+1;i<this.selectList.length;i++)...{


nextSelect=this.selectList[i];


var index=nextSelect.options.length;


nextSelect.options.length=index+1;


nextSelect.options[index].value=event.value;


nextSelect.options[index].text=event.options[event.selectedIndex].text;


nextSelect.options[index].selected=true;


}


return nextSelect.options.length;


}




for(var i=0;i<nextList.size();i++)...{


var nodeInfo=nextList.getElementByIndex(i);


var index=nextSelect.options.length;


nextSelect.options.length=index+1;


nextSelect.options[index].value=nodeInfo.key;


nextSelect.options[index].text=nodeInfo.value;


}


return nextSelect.options.length;


}

4.创建测试页面cascaded_select.html


<!--深蓝忧郁级联下拉框-->




<script src="BlueParseXML.js">...


//加载XML


</script>




<script src="BlueCasadedSelect.js">...


//生成级联下拉


</script>


<body>


</body>




<script>...




function finish()...{


alert("加载完成");


}


var myxml=new BlueParseXML();


//添加xml加载完成事件响应


myxml.loadFinish=finish;


myxml.loadXML("cascaded_select.xml");


var level=myxml.parseXML();




//多级级联下拉


var blueCasadedSelect=new BlueCasadedSelect(myxml.nodeList);


//生成下拉列表,下拉列表name属性为xml节点名


blueCasadedSelect.createSelect(document.body);


//如果下拉列表提前已有,则不需生成,需要设置下拉列表集合为已有下拉集合,并添加onchange事件响应内容


//blueCasadedSelect.selectList=sels;


//blueCasadedSelect.addOnChangeEvent();


blueCasadedSelect.init(new Array("sx","xa"));




//简单的树结构遍历测试


//====================================


document.write("<br>");




function iterator(list)...{




if(list.size()<=0)...{


return;


}




for(var i=0;i<list.size();i++)...{


var obj=list.getElementByIndex(i);




for(var j=1;j<list.nodeLevel;j++)...{


document.write("——");


}


document.write("<a href='"+obj.key+"'>"+obj.nodeLevel+obj.value+"</a><br>");


iterator(obj.childNodeList);


}


}


iterator(myxml.nodeList);


//====================================


</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: