首先,我们来看一下这个xml文件是怎么一种格式(因为比较长,我只选择了其中几个比较有代表性的来说明)
后面的function就是返回读取回来的xml对象,然后我们就可以操作这个对象了,那么HTML我们可以这样写,三个select我们一开始都写出来,但是后面的city和status隐藏
其实原理很简单,一开始文件加载完毕,我们就读取xml把所有的country读取出来,然后遍历(each)一个一个以<option value="code">name</option>的形式append到$('#country')里面去,然后为country绑定一个change方法,这个方法会读取当前country值,然后使用这个值到xml里面找到这个节点,然后把这个节点的children里面的status找出来,然后这里要判读一次,因为有可能会出现这个status没有值,只是有city的情况,那么我们就需要,这种情况下,我们就要直接把这个节点的city拿出来然后添加到$('city')里面去,然后展示出来,如果存在status,我们把节点里面的所有status拿出来放到$('province')里面去(用each和上面一样),最后又是重复,选择了status以后,获取这个status在xml里面的节点,然后取出city展示出来这样。
<?xml version="1.0" encoding="utf-8"?>
<CountryRegion Name="澳大利亚" Code="AUS">
<State Name="北部地区" Code="NT">
<City Name="北帕默斯顿" Code="PAL"/>
<City Name="达尔文" Code="DRW"/>
</State>
<State Name="堪培拉" Code="ACT">
<City Name="堪培拉" Code="CBR"/>
</State>
<State Name="昆士兰" Code="QLD">
<City Name="布里斯班" Code="BNE"/>
<City Name="黄金海岸" Code="OOL"/>
<City Name="凯恩斯" Code="CNS"/>
<City Name="日光海岸" Code="CUD"/>
<City Name="汤斯维尔" Code="TSV"/>
<City Name="图文巴" Code="TWB"/>
</State>
<State Name="南澳大利亚" Code="SA">
<City Name="阿德莱德" Code="ADL"/>
<City Name="奥古斯塔港" Code="PUG"/>
<City Name="甘比亚山" Code="MGB"/>
<City Name="怀阿拉" Code="WAY"/>
<City Name="林肯港" Code="PLO"/>
<City Name="默里布里奇" Code="MYB"/>
<City Name="皮里港" Code="PPI"/>
<City Name="维克托港" Code="VHA"/>
</State>
<State Name="塔斯马尼亚" Code="TAS">
<City Name="伯尼港" Code="BWT"/>
<City Name="德文波特" Code="DPO"/>
<City Name="霍巴特" Code="HBA"/>
<City Name="朗塞斯顿" Code="LST"/>
</State>
<State Name="维多利亚" Code="VIC">
<City Name="吉朗" Code="GEX"/>
<City Name="墨尔本" Code="MEL"/>
</State>
<State Name="西澳大利亚" Code="WA">
<City Name="奥尔巴尼" Code="ALH"/>
<City Name="班伯里" Code="BUY"/>
<City Name="弗里曼特尔港" Code="FRE"/>
<City Name="杰拉尔顿" Code="GET"/>
<City Name="卡尔古利" Code="KGI"/>
<City Name="曼哲拉" Code="MDU"/>
<City Name="珀斯" Code="PER"/>
</State>
<State Name="新南威尔士" Code="NSW">
<City Name="纽卡斯尔" Code="NTL"/>
<City Name="伍伦贡" Code="WOL"/>
<City Name="悉尼" Code="HBS"/>
</State>
</CountryRegion>
<CountryRegion Name="阿尔巴尼亚" Code="ALB">
<State >
<City Name="爱尔巴桑" Code="EL"/>
<City Name="迪勃拉" Code="DI"/>
<City Name="地拉那" Code="TR"/>
<City Name="都拉斯" Code="DR"/>
<City Name="发罗拉" Code="VL"/>
<City Name="费里" Code="FR"/>
<City Name="吉诺卡斯特" Code="GJ"/>
<City Name="科尔察" Code="KO"/>
<City Name="库克斯" Code="KU"/>
<City Name="莱什" Code="LE"/>
<City Name="培拉特" Code="BR"/>
<City Name="斯库台" Code="SH"/>
</State>
</CountryRegion>
<CountryRegion Name="伊拉克" Code="IRQ" />
</Location>
第一种,以澳大利亚为例子,这种国家是比较完整的,有country->status->city.三种都有,
效果图:
第二种,以阿尔巴里亚为例子,这种只有country->city,只有国家和城市(只有第一级和第三级)
效果图
最后一种以伊拉克为例,只有country第一级
效果图
其实还存在一种,有country和status但是没有city的情况,这种情况比较少但是判断也很简单,后面会说到、
那么我们在各级select的时候就要有所判断了
那么jquery要怎么读取.xml文件呢,可以使用ajax方法,读取一个xml文件的ajax方法:
$.ajax({
url: 'xx.xml',
type: 'POST',
dataType: 'xml',
})
.done(function(xml) {});
后面的function就是返回读取回来的xml对象,然后我们就可以操作这个对象了,那么HTML我们可以这样写,三个select我们一开始都写出来,但是后面的city和status隐藏
<select name="country" id="country">
<option value="0">选择国家</option>
</select>
<select name="province" id="province" class="hide">//这里使用province来代替
<option value="0">选择省</option>
</select>
<select name="city" id="city" class="hide">
<option value="0">选择城市</option>
</select>
class="hide"就是隐藏,在css里面已经写好了,然后我们就可以写我们的jquery
<script type="text/javascript">
$(function(){
$.ajax({
url: '{$web_path}data/xml/country.xml',//这里是我的xml文件在项目中存放的位置
type: 'POST',
dataType: 'xml',
})
.done(function(xml) {
$(xml).find('CountryRegion').each(function(index) {
var name = ($(this).attr('Name'));
var code = ($(this).attr('Code'));
var newOption = "<option value=" + code + ">" + name + "</option>";
$('#country').append(newOption);;
});
//选择国家以后
$('#country').bind('change', function() {
//当前选中的国家的值
var contry = $('#country').val();
//根据值找出选中的节点
var contryObj = $(xml).find("[Code=" + contry + "]");
//判断是是否存在多个states
if (!contryObj.find('State').first().attr('Name')) {
//这里还存在一种只有国家连城市都没有的
if (!contryObj.find('City').first().attr('Name')) {
//后面的全部删除并且隐藏
$('#province').hide().children().not(':first').remove();
$('#city').hide().children().not(':first').remove();
return false;
};
//不存在直接处理城市整个省节点并且删除节点
$('#province').hide().children().not(':first').remove();
$('#city').show().children().not(':first').remove();
//直接根据国家遍历节点
contryObj.find('City').each(function() {
var name = ($(this).attr('Name'));
var code = ($(this).attr('Code'));
var newOption = "<option value=" + code + ">" + name + "</option>";
$('#city').append(newOption);
});
}else{
//存在显示也删除所有节点
$('#province').show().children().not(':first').remove();
$('#city').hide().children().not(':first').remove();
//然后添加省节点
contryObj.children('State').each(function() {
var name = ($(this).attr('Name'));
var code = ($(this).attr('Code'));
var newOption = "<option value=" + code + ">" + name + "</option>";
$('#province').append(newOption);
});
//省点击绑定city出现
$('#province').bind('change', function() {
//当前选中的省的值
var province = $('#province').val();
//根据值找出选中的节点
var provinceObj = contryObj.find("[Code=" + province + "]");
//判断是否存在城市
if (!provinceObj.find('City').first().attr('Name')) {
$('#city').hide().children().not(':first').remove();
return false;
};
//同样先删除节点
$('#city').show().children().not(':first').remove();
//然后添加城市节点
provinceObj.children('city').each(function() {
var name = ($(this).attr('Name'));
var code = ($(this).attr('Code'));
var newOption = "<option value=" + code + ">" + name + "</option>";
$('#city').append(newOption);
});
});
}
})
})
.fail(function() {
console.log("error");
});
})
</script>
其实原理很简单,一开始文件加载完毕,我们就读取xml把所有的country读取出来,然后遍历(each)一个一个以<option value="code">name</option>的形式append到$('#country')里面去,然后为country绑定一个change方法,这个方法会读取当前country值,然后使用这个值到xml里面找到这个节点,然后把这个节点的children里面的status找出来,然后这里要判读一次,因为有可能会出现这个status没有值,只是有city的情况,那么我们就需要,这种情况下,我们就要直接把这个节点的city拿出来然后添加到$('city')里面去,然后展示出来,如果存在status,我们把节点里面的所有status拿出来放到$('province')里面去(用each和上面一样),最后又是重复,选择了status以后,获取这个status在xml里面的节点,然后取出city展示出来这样。
这个算法不是很难,但是有些要注意的地方,我们每次在改变country和status以后,必须把后面的select重置一下,重置的方法看上面的代码,要是不重置,我们的下一级select就会一直添加option,后面就会出现各种错误了。