13.8 过滤和排序一个XMLListCollection集合
需要对一个XMLListCollection过滤和排序
13.8.2解决
使用ListViewCollection类的filterFunction和sortFunction属性(XMLListCollection类扩展自该类)或者仅仅传递一个类型Sort的对象给XMLListCollections的sort属性。
13.8.3讨论
XMLListCollections描述XML数据,在根部含有多个节点。例如,包含在nutriton节点里的food项目集将被解释成XMLListCollection,使得这些food节点被看作一个集合。
<
nutrition
>
< food >
< name >Avocado Dip </ name >
< calories >110 </ calories >
< total-fat >11 </ total-fat >
< saturated-fat >3 </ saturated-fat >
< cholesterol >5 </ cholesterol >
< sodium >210 </ sodium >
< carb >2 </ carb >
< fiber >0 </ fiber >
< protein >1 </ protein >
</ food >
...
</ nutrition >
< food >
< name >Avocado Dip </ name >
< calories >110 </ calories >
< total-fat >11 </ total-fat >
< saturated-fat >3 </ saturated-fat >
< cholesterol >5 </ cholesterol >
< sodium >210 </ sodium >
< carb >2 </ carb >
< fiber >0 </ fiber >
< protein >1 </ protein >
</ food >
...
</ nutrition >
过滤XMLListCollection的方式和ArrayCollection相同:也是通过传递一个函数的引用,该函数接收一个Object作为参数,返回布尔值,用来决定是否该对象应该留在过滤后的视图中。例如:
coll.filterFunction = lowCalFilter;
private function lowCalFilter(value:Object):Boolean {
if(Number(value.calories) < 200) {
return true;
}
return false;
}
private function lowCalFilter(value:Object):Boolean {
if(Number(value.calories) < 200) {
return true;
}
return false;
}
过滤XMLListCollection需要一个Sort对象,这个对象的fields数组属性需要设置为一些SortField对象。
var sort:Sort = new Sort();
sort.fields = [new SortField("calories", false, false, true)];
coll.sort = sort;
coll.refresh();
sort.fields = [new SortField("calories", false, false, true)];
coll.sort = sort;
coll.refresh();
这里列出了演示XMLListCollection的完整的代码,代码包含HTTPService的调用,排序及过滤,如下:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300"
creationComplete="xmlService.send()">
<mx:HTTPService url="assets/data.xml" resultFormat="xml" id="xmlService" result=
"createXMLCollection(event)"/>
<mx:Script>
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.rpc.events.ResultEvent;
import mx.collections.XMLListCollection;
[Bindable]
private var coll:XMLListCollection;
private function createXMLCollection(event:ResultEvent):void {
var list:XMLList = new XMLList(event.result);
coll = new XMLListCollection(list.food);
var sort:Sort = new Sort();
sort.fields = [new SortField("calories", false, false, true)];
coll.sort = sort;
coll.refresh();
}
private function applyFilter():void {
coll.filterFunction = lowCalFilter;
coll.refresh();
}
private function lowCalFilter(value:Object):Boolean {
if(Number(value.calories) < 200) {
return true;
}
return false;
}
]]>
</mx:Script>
<mx:DataGrid dataProvider="{coll}">
<mx:columns>
<mx:DataGridColumn dataField="calories"/>
<mx:DataGridColumn dataField="name"/>
</mx:columns>
</mx:DataGrid>
<mx:Button click="applyFilter()" label="filter"/>
</mx:VBox>
creationComplete="xmlService.send()">
<mx:HTTPService url="assets/data.xml" resultFormat="xml" id="xmlService" result=
"createXMLCollection(event)"/>
<mx:Script>
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.rpc.events.ResultEvent;
import mx.collections.XMLListCollection;
[Bindable]
private var coll:XMLListCollection;
private function createXMLCollection(event:ResultEvent):void {
var list:XMLList = new XMLList(event.result);
coll = new XMLListCollection(list.food);
var sort:Sort = new Sort();
sort.fields = [new SortField("calories", false, false, true)];
coll.sort = sort;
coll.refresh();
}
private function applyFilter():void {
coll.filterFunction = lowCalFilter;
coll.refresh();
}
private function lowCalFilter(value:Object):Boolean {
if(Number(value.calories) < 200) {
return true;
}
return false;
}
]]>
</mx:Script>
<mx:DataGrid dataProvider="{coll}">
<mx:columns>
<mx:DataGridColumn dataField="calories"/>
<mx:DataGridColumn dataField="name"/>
</mx:columns>
</mx:DataGrid>
<mx:Button click="applyFilter()" label="filter"/>
</mx:VBox>
通过对XML集合中的不同节点使用E4X语句可以实现复杂的过滤;例如,通过如下所示的@语法访问属性:
private function lowFatFilter(value:Object):Boolean {
if(value.calories(@fat) < Number(value.calories)/5) {
return true;
}
return false;
}
if(value.calories(@fat) < Number(value.calories)/5) {
return true;
}
return false;
}
译者注:如果觉得老外的例子不是很好,改了改:
程序代码:
<?
xml
version
="1.0"
encoding
="utf-8"
?>
< mx:Application xmlns:mx ="http://www.adobe.com/2006/mxml" creationComplete ="xmlService.send()" >
< mx:Style >
Application{font-size:12px;}
</ mx:Style >
< mx:HTTPService url ="data.xml" resultFormat ="xml" id ="xmlService" result ="createXMLCollection(event)" />
< mx:Script >
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.rpc.events.ResultEvent;
import mx.collections.XMLListCollection;
[Bindable]
private var coll:XMLListCollection;
private function createXMLCollection(event:ResultEvent):void {
var list:XML = new XML(event.result);
coll = new XMLListCollection(list.student);
var sort:Sort = new Sort();
//SortField(字段名=null,大小写不敏感?=false,降序?=false,Object是否按编号?=null)
sort.fields = [new SortField("total", false, true, true)];//降序
coll.sort = sort;
coll.refresh();//因为绑定,coll的变化引起DataGrid的刷新
}
private function applyFilter():void {
coll.filterFunction = myFilter;
coll.refresh();
}
private function myFilter(value:Object):Boolean {
if(Number(value.total) < 380) {
return true;//保留总分<380,看看<380的都有哪些人
}
return false;
}
]] >
</ mx:Script >
< mx:DataGrid dataProvider ="{coll}" >
< mx:columns >
< mx:DataGridColumn headerText ="姓名" dataField ="name" />
< mx:DataGridColumn headerText ="语文" dataField ="chinese" />
< mx:DataGridColumn headerText ="数学" dataField ="math" />
< mx:DataGridColumn headerText ="英语" dataField ="english" />
< mx:DataGridColumn headerText ="总分" dataField ="total" />
</ mx:columns >
</ mx:DataGrid >
< mx:Button click ="applyFilter()" label ="过滤" />
</ mx:Application >
< mx:Application xmlns:mx ="http://www.adobe.com/2006/mxml" creationComplete ="xmlService.send()" >
< mx:Style >
Application{font-size:12px;}
</ mx:Style >
< mx:HTTPService url ="data.xml" resultFormat ="xml" id ="xmlService" result ="createXMLCollection(event)" />
< mx:Script >
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.rpc.events.ResultEvent;
import mx.collections.XMLListCollection;
[Bindable]
private var coll:XMLListCollection;
private function createXMLCollection(event:ResultEvent):void {
var list:XML = new XML(event.result);
coll = new XMLListCollection(list.student);
var sort:Sort = new Sort();
//SortField(字段名=null,大小写不敏感?=false,降序?=false,Object是否按编号?=null)
sort.fields = [new SortField("total", false, true, true)];//降序
coll.sort = sort;
coll.refresh();//因为绑定,coll的变化引起DataGrid的刷新
}
private function applyFilter():void {
coll.filterFunction = myFilter;
coll.refresh();
}
private function myFilter(value:Object):Boolean {
if(Number(value.total) < 380) {
return true;//保留总分<380,看看<380的都有哪些人
}
return false;
}
]] >
</ mx:Script >
< mx:DataGrid dataProvider ="{coll}" >
< mx:columns >
< mx:DataGridColumn headerText ="姓名" dataField ="name" />
< mx:DataGridColumn headerText ="语文" dataField ="chinese" />
< mx:DataGridColumn headerText ="数学" dataField ="math" />
< mx:DataGridColumn headerText ="英语" dataField ="english" />
< mx:DataGridColumn headerText ="总分" dataField ="total" />
</ mx:columns >
</ mx:DataGrid >
< mx:Button click ="applyFilter()" label ="过滤" />
</ mx:Application >
data.xml:
<?
xml
version
="1.0"
encoding
="utf-8"
?>
< students >
< student >
< name >张三 </ name >
< chinese >130 </ chinese >
< math >140 </ math >
< english >125 </ english >
< total >395 </ total >
</ student >
< student >
< name >李四 </ name >
< chinese >110 </ chinese >
< math >138 </ math >
< english >126 </ english >
< total >374 </ total >
</ student >
< student >
< name >王五 </ name >
< chinese >120 </ chinese >
< math >125 </ math >
< english >135 </ english >
< total >380 </ total >
</ student >
</ students >
< students >
< student >
< name >张三 </ name >
< chinese >130 </ chinese >
< math >140 </ math >
< english >125 </ english >
< total >395 </ total >
</ student >
< student >
< name >李四 </ name >
< chinese >110 </ chinese >
< math >138 </ math >
< english >126 </ english >
< total >374 </ total >
</ student >
< student >
< name >王五 </ name >
< chinese >120 </ chinese >
< math >125 </ math >
< english >135 </ english >
< total >380 </ total >
</ student >
</ students >
这里的total字段的值是钉死的,实际中可能会根据其他字段计算求和的。
本文转自 xcf007 51CTO博客,原文链接:http://blog.51cto.com/xcf007/101638,如需转载请自行联系原作者