Quantcast
Channel: Limbo-Nova
Viewing all articles
Browse latest Browse all 10

XML数据源的级联ComboBox

$
0
0

Background

要做一个表单,其中自然少不了ComboBox,数据源不是从后台动态获取的,竟然是一个Excel表格文件!这个数据量很大,而且还有可能会修改,所以只能采用外部加载的方式。写一个解析Excel数据的库自然是不现实的,所以决定把Excel转换成XML格式,然后再加载。

Excel转换成XML

一般直接将Excel是不能导出成XML的,因为“不包含任何XML映射”,所以首先需要建立一个XML映射,其实就是设计一个XML结构,然后将Excel数据映射到对应的节点上。这一步其实很简单,但是颇具技巧性。

“开发工具”选项卡

导出XML需要“开发工具”功能,一般Excel不会显示这个选项卡,需要打开“文件”-“选项”-“自定义功能区”对话框,勾选“开发工具”。

excel_01

设计XML结构

XML结构根据自己要求设计,多个相同子节点表示可以重复。比如这个:

<?xml version="1.0" encoding="UTF-8"?>
<root>
	<province name="">
	 	<city name="">
	 		<dealer name="" address=""/>
	 	</city>
	</province>
	<province name="">
	 	<city name="">
	 		<dealer name="" address=""/>
	 	</city>
	</province>
</root>

导入XML文件

回到Excel里,新建一个空白Excel文档,点击“开发工具”里的“源”按钮,在右侧弹出的面板里点击“XML映射”,然后添加之前的XML文件。如果成功右侧面板里会显示XML的树形结构。

excel_02

映射数据

这步更简单,把那个树状结构根节点拖到工作表上,工作表上会显示行以XML节点属性为名称的表头。把数据对应地粘贴到这个表里。

excel_03

导出文件

点击“源”按钮右边的“导出”,就可以导出XML了。导出后检查下数据映射对不对,如果没问题就算完成了。

加载XML数据

加载直接用URLLoader就可以。

var url:String = xmlUrl;
var vars:URLVariables = new URLVariables();
var request:URLRequest = new URLRequest(url);

var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, dealerInfoLoadHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, loadErrorHandler);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadErrorHandler);

loader.load(request);

级联ComboBox

由于ActionScript E4X 的处理能力很强,所以利用XML作为数据源是完全可行的。经过几个简单的处理步骤就可以作为数据源提供给ComboBox。代码如下:

/**
 *  加载XML数据 
 * @param event
 * 
 */    
public function dealerInfoLoadHandler(event:Event):void {
  var loader:URLLoader = event.target as URLLoader;
  var xml:XML = new XML(loader.data);
  if(xml) 
  {
    dealerXML = xml; 
    var arrProv:Array = [];
    var seen:Object={};
    var prov:XMLList = xml.province.@name.(!seen[valueOf()]&amp;&amp;(seen[valueOf()]=true));
    prov.  (
      arrProv.push(toString())
    ); 

    this.provinces = arrProv;
  }
  cbxProv.dataProvider = new DataProvider(this.provinces);
}

/**
 *  省份ComboBox变化处理函数 
 * @param event
 * 
 */    
private function cbxProvChangeHandler(event:Event):void {
  cbxCity.dataProvider.removeAll();          //清空City DP
  var seen:Object={};    
  var provStr:String = cbxProv.selectedItem.data;  
  var prov:XMLList = this.dealerXML.province.(@name==provStr);  //根据省份名称从XML检索所有符合条件的城市子节点
  var city:XMLList = prov.city.@name.(!seen[valueOf()]&amp;&amp;(seen[valueOf()]=true));  //过滤重复的城市节点
  var arrCity:Array = [];
  city. (
    arrCity.push(toString())  //把City数据灌到Array里
  ); 

  cbxCity.dataProvider = new DataProvider(arrCity);
  cbxCity.selectedIndex = 0;

  this.cbxCityChangeHandler(event);  //联动一次cbxCity
}

/**
 *  城市ComboBox变化处理函数 
 * @param event
 * 
 */    
private function cbxCityChangeHandler(event:Event):void {
  cbxDealer.dataProvider.removeAll();
  var cityStr:String = cbxCity.selectedItem.data;
  var city:XMLList = this.dealerXML..city.(@name==cityStr);
  var dealer:XMLList = city.dealer.@name; //末节点经销商数据不会重复,不需要过滤重复的
  var arrDealer:Array = [];
  dealer. (
    arrDealer.push(toString())
  ); 
  cbxDealer.dataProvider = new DataProvider(arrDealer);
  cbxDealer.selectedIndex = 0;
}

示例

demo如下:

总结

单纯验证了XML作为级联ComboBox数据源的可行性。如果考虑重用性和稳定性,还有一些工作要做的。不过作为临时想出来的解决方案,也完全满足要求了,还挺有趣味性的。 😉

参考资料

  1. 从EXCEL导出数据到XML

Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles



Latest Images