您的位置:首页 > 其它

flex中处理xml数据那些事

2011-12-27 14:24 381 查看
使用<mx:Modelid="example"/>

可在Model里放置数据的结构:

<mx:Modelid="userData">

<user>

<email></email>

<phone></phone>

<address>

<city></city>

<state></state>

</address>

</user>

</mx:Model>

或者直接放置数据:

<mx:Modelid="userData">

<user>

<email>example@example.com</email>

<phone>123555-1212</phone>

<address>

<city>Exampleville</city>

<state>CA</state>

</address>

</user>

</mx:Model>

但一般把较多的数据这在一个文件中:

<mx:Modelid="statesModel"source="states.xml"/>

这个文件的数据是在编译时被载入,而不是运行时。它与在<Model>标签里直接嵌入数据是一样的,只不过这样更简洁。一旦编译成.swf文件之后,你就不用带上这个文件,因为数据已被编译进.swf文件。
<mx:Model>并不是有名叫Model一个ActionScript类与它对应,实际上它是创建了一个ObjectProxy类的实例,ObjectProxy对象是一个Object实例的封装,完全可以象Object实例一样去对待它,使用ObjectProxy主要的目的是可以数据绑定。

因为相当于在ActionScript中创建了一个对象,当然可以使用点语法来直接访问它的子节点对象。对象本身的ID与它的根节点是同义的。即访问其子节点对象时不用再加根对象的名字了。

当一个datamodel结构是由两个或更多的同名兄弟节点组成是,它们将被转换成一个数组。如statesModel.state将是一个数组,存储了statesModel对象的所有名为state的子对象。
一般<mx:Model>用于传统数据,如对象,字符串和数组。而想用XML格式数据时,使用<mx:XML>标签。

<mx:XML>有一个xmlns属性来指定这个XML的命名空间。

一个<mx:XML>标签,在ActionScript中默认是创建一个XML对象,此时它的format属性为缺省的e4x,如果设置为xml,将会创建一个flash.xml.XMLNode对象。

使用ActionScript类

虽然使用<mx:Model><mx:XML>简单省力,但在很多情况下并不是理想的方案。它们适用于简单,静态的数据。但对于复杂的,动态的,或者带有规则的数据,使用定制的ActionScript类是更好的方法。因为:

1)使用<mx:Model>和<mx:XML>你不能强制数据的类型,但AS能。

2)不能进行数据的测试/一致性检查等,但AS类的setter方法可以测试有效的值,对无效的值可以忽略,转换或是出错。

3)不能带上商务逻辑

4)不能使用优雅的设计模式。AS类可让整个应用都可存取的实例???
写一个AS类作数据模型是简单的,只需定义一个类,为所有的属性定义公共的存取方法。所有setter和getter方法都是强类型的,有些Setter方法进行数据测试检查。

在包中定义类之后:

packagecom.oreilly.programmingflex.data{

publicclassUser{

}

}

就可以在MXML中创建它的实例了,但得首先将包声明为命名空间:
<?xmlversion="1.0"encoding="utf-8"?>

<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"xmlns:data="com.oreilly.programmingflex.data.*"layout="absolute">
<data:Userid="user"email="example@example.com"lastLogin="{newDate()}"

nameFirst="Abigail"nameLast="Smith"userType="1"/>
</mx:Application>

若在AS中使用,你需要导入这个类,然后使用它:

importcom.oreilly.programmingflex.data.User;

privatevaruser:User;

privatefunctioninitializeHandler(event:Event):void{

user=newUser();

user.email="example@example.com";

//etc.

}

====================================================================================

flex加载xml的几种方式做一个简单的介绍:
1.<mx:XMLsource="abc.xml"id="a">

</mx:XML>

<mx:XMLListCollectionsource="a.b">

</mx:XMLListCollection>

其中xml文件为

<per>

<b><code>sss</code><name>fdfd</name></b>

<b><code>sss</code><name>fdfd</name></b>

</per>

这样载入的xml是被编译进swf里的,也就是说编译以后,xml文件就没用了。

2.通过webservices

A、

privatefunctioninit():void{

varservice:HTTPService=newHTTPService();

service.url="static.xml";

service.useProxy=false;

service.resultFormat="e4x";

service.addEventListener(ResultEvent.RESULT,onResultHandler);

service.send();

}

privatefunctiononResultHandler(evt:ResultEvent):void

{

statics=XML(evt.result).children();

}

B、

主程序:

<?xmlversion="1.0"?>

<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"initialize="catalogService.send()">

<mx:HTTPServiceid="catalogService"url="catalog.xml"resultFormat="e4x"/>

<mx:XMLListCollectionid="myXC"source="{catalogService.lastResult.product}"/>

<mx:Repeaterid="r"dataProvider="{myXC}"startingIndex="1">

<mx:RadioButtonid="Radio"label="{r.currentItem.name}"/>

</mx:Repeater>

</mx:Application>

xml文件:

<?xmlversion="1.0"?>

<products>

<product>

<name>Name</name>

<price>Price</price>

<freeship>FreeShipping?</freeship>

</product>

<product>

<name>Whirlygig</name>

<price>5</price>

<freeship>false</freeship>

</product>

<product>

<name>TiltyThingy</name>

<price>15</price>

<freeship>true</freeship>

</product>

<product>

<name>ReallyBigBlocks</name>

<price>25</price>

<freeship>true</freeship>

</product>

</products>

3.通过URLLoader

privatefunctioninit2():void{

loader.addEventListener(Event.COMPLETE,setResult);

varreq:URLRequest=newURLRequest();

req.url="locations.xml";

loader.load(req);

}

privatefunctionsetResult(event:Event):void{

vardata:XML=XML(loader.data);

}

===============================================================================

在FlexBuilder中,如果要加载一个外部的XML是比较简单的,将绝对路径或则是相对路径写入就可以了。但是如果是一个web的工程,这个问题就显得比较复杂了,因为这个时候,你得不到文件的绝对和相对路径,在Flex3中,解决这个问题,有如下两个方法。

【一】mx:Model的方式

程序主文件:

1<?xmlversion="1.0"?>

2<!--SimpleexampletodemonstratetheLinkBarcontrol.-->

3<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml">

4<mx:Script>

5<![CDATA[

6]]>

7</mx:Script>

8<mx:Modelid="catalogService"source="news.xml"/>

9<mx:ArrayCollectionid="myXC"source="{catalogService.news}"/>

10<mx:Paneltitle="TestLinkBarForXML"

11height="323"width="466"horizontalAlign="center"

12paddingTop="10"paddingBottom="10"paddingLeft="10"paddingRight="10">

13

14<mx:Textwidth="100%"

15text="一个LinkBar的测试"/>

16

17<mx:LinkBarcolor="#0000FF"fontWeight="bold"dataProvider="{myViewStack}"/>

18

19<!--DefinetheViewStackandthethreechildcontainers.-->

20<mx:ViewStackid="myViewStack"borderStyle="solid"width="100%"height="80%">

21

22<mx:Canvasid="show1"backgroundColor="#FFFFCC"label="显示一"width="100%"height="100%">

23

24</mx:Canvas>

25

26<mx:Canvasid="show2"backgroundColor="#CCFFFF"label="显示二"width="100%"height="100%">

27<mx:DataGriddataProvider="{myXC}"/>

28</mx:Canvas>

29

30<mx:Canvasid="show3"backgroundColor="#FFCCFF"label="显示三"width="100%"height="100%">

31</mx:Canvas>

32</mx:ViewStack>

33

34</mx:Panel>

35<mx:XMLid="myXML"source="news.xml"/>

36

37<mx:Textid="myText"width="292"/>

38</mx:Application>

39

40

news.xml文件

1<?xmlversion="1.0"encoding="utf-8"?>

2<main>

3<news>

4<newsTitle>1-1</newsTitle>

5<newsItem>1-2</newsItem>

6</news>

7<news>

8<newsTitle>2-1</newsTitle>

9<newsItem>2-2</newsItem>

10</news>

11</main>

运行后画面:无

【二】mx:HTTPService的方式

主程序:

1<?xmlversion="1.0"?>

2<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"initialize="catalogService.send()">

3<mx:HTTPServiceid="catalogService"url="catalog.xml"resultFormat="e4x"/>

4<mx:XMLListCollectionid="myXC"source="{catalogService.lastResult.product}"/>

5<mx:Repeaterid="r"dataProvider="{myXC}"startingIndex="1">

6<mx:RadioButtonid="Radio"label="{r.currentItem.name}"/>

7</mx:Repeater>

8</mx:Application>

9

xml文件:

1<?xmlversion="1.0"?>

2<products>

3<product>

4<name>Name</name>

5<price>Price</price>

6<freeship>FreeShipping?</freeship>

7</product>

8<product>

9<name>Whirlygig</name>

10<price>5</price>

11<freeship>false</freeship>

12</product>

13<product>

14<name>TiltyThingy</name>

15<price>15</price>

16<freeship>true</freeship>

17</product>

18<product>

19<name>ReallyBigBlocks</name>

20<price>25</price>

21<freeship>true</freeship>

22</product>

23</products>

==============================================================================================================

在flex中对XML文件的使用大体有两种,其一是在Model中使用,另外就是在HttpService中使用。我们在assets文件夹下创建data.xml文件,内容如下:

<data>

<resultmonth="Jan-04">

<apple>81768</apple>

<orange>60310</orange>

<banana>43357</banana>

</result>

<resultmonth="Feb-04">

<apple>81156</apple>

<orange>58883</orange>

<banana>49280</banana>

</result>

</data>

先看代码

在Model中对其调用:

<?xmlversion="1.0"?>

<!--charts/XMLFileDataProvider.mxml-->

<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Modelid="results"source="assets/data.xml"/>

<mx:Paneltitle="LineChart">

<mx:LineChartid="chart"dataProvider="{results.result}">

<mx:horizontalAxis>

<mx:CategoryAxiscategoryField="month"/>

</mx:horizontalAxis>

<mx:series>

<mx:LineSeriesyField="banana"displayName="Banana"/>

<mx:LineSeriesyField="apple"displayName="Apple"/>

<mx:LineSeriesyField="orange"displayName="Orange"/>

</mx:series>

</mx:LineChart>

</mx:Panel>

</mx:Application>

使用HttpService调用:

<?xmlversion="1.0"?>

<!--charts/HTTPServiceDataProvider.mxml-->

<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"

width="100%"height="100%"creationComplete="srv.send()">

<mx:HTTPServiceid="srv"url="../assets/data.xml"/>

<mx:Paneltitle="LineChart">

<mx:LineChartid="chart"

dataProvider="{srv.lastResult.data.result}"

>

<mx:horizontalAxis>

<mx:CategoryAxiscategoryField="month"/>

</mx:horizontalAxis>

<mx:series>

<mx:LineSeriesyField="apple"name="Apple"/>

<mx:LineSeriesyField="orange"name="Orange"/>

<mx:LineSeriesyField="banana"name="Banana"/>

</mx:series>

</mx:LineChart>

</mx:Panel>

</mx:Application>

比较两者,mx:Model作为一个模型标签,将source路径下的内容直接加载到XMLFileDataProvider.mxml中。经过编译器编译后,存储在生成的swf文件中。就是说数据是存储在客户端的。mx:HTTPService则不同,文件存储在服务器端,在服务器端提供这样一个service接口,creationComplete="srv.send()"的意思就是在初始化完毕会调用这个service,从服务器端去获取这个文件,传到客户端,通过srv.lastResult.data.result来获取。如果不调用这个send方法,客户端的srv.lastResult.data.result就是空的。

还有一点不同的是,调用Model中的result数据是用results.result,而在调用HTTPService中的result时,使用的是srv.lastResult.data.result;区别就在于前者没有父级标签data.后者有。如果在data标签之外再加一层父标签呢?是不是说Model可以直接指定到子标签,而HTTPService必须制定路径才能定义到子标签呢?如下:

<father>

<data>

<resultmonth="Jan-04">

<apple>81768</apple>

<orange>60310</orange>

<banana>43357</banana>

</result>

<resultmonth="Feb-04">

<apple>81156</apple>

<orange>58883</orange>

<banana>49280</banana>

</result>

</data>

</father>

如果我想的没错的话,那么XMLFileProvider是可以正确运行显示数据的,而HTTPServiceProvider中显示的图表中使没有数据的。测试一下看看。。。。

结果。。。两个都没有数据,呃。。。

再将XMLFileProvider中的<mx:LineChartid="chart"dataProvider="{results.result}">改成<mx:LineChartid="chart"dataProvider="{results.data.result}">试试看呢?果然,行了。再试试,改成<mx:LineChartid="chart"dataProvider="{results.father.data.result}">,结果没有数据。

经实践,证明:使用Model时,是不需要调根标签的。

那么就有一个新问题,我的xml文件里如果只有一个根标签,如下:

<data>12345</data>

我想通过Model在一个text中将数据显示出来怎么办呢?

先写一个XMLFlieRootTest.mxml

<?xmlversion="1.0"encoding="utf-8"?>

<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute">

<mx:Modelid="results"source="assets/data.xml"/>

<mx:HBox>

<mx:Labeltext="datavalue="/>

<mx:Texttext="{results.data}"/>

</mx:HBox>

</mx:Application>

运行一下,是没有数据的。暂时只能在外面再加一层父标签,才能够调到data的值。而且在这个xml文件中有且只有一个根标签,只做框架使用,不存数据。

使用Model的时候可以先将数据存储到ArrayCollection中

如下:

<?xmlversion="1.0"?>

<!--charts/XMLFileToArrayCollectionDataProvider.mxml
-->

<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"width="100%"height="100%">

<mx:Script>importmx.utils.ArrayUtil;</mx:Script>

<mx:Modelid="results"source="../assets/data.xml"/>

<mx:ArrayCollectionid="myAC"source="{ArrayUtil.toArray(results.result)}"/>

<mx:Paneltitle="LineChart"><mx:LineChartid="chart"dataProvider="{myAC}">

<mx:horizontalAxis><mx:CategoryAxiscategoryField="month"/></mx:horizontalAxis>

<mx:series><mx:LineSeriesyField="banana"displayName="Banana"/>

<mx:LineSeriesyField="apple"displayName="Apple"/>

<mx:LineSeriesyField="orange"displayName="Orange"/>

</mx:series>

</mx:LineChart>

</mx:Panel></mx:Application>


这样做的好处是一次存储,多次调用。不用每次都到model里面去取。

同样,HTTPService也可以使用ArrayCollection

<?xmlversion="1.0"?>

<!--charts/HTTPServiceToArrayCollectionDataProvider.mxml-->
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"creationComplete="srv.send()">

<mx:Script>
<![CDATA[importmx.collections.ArrayCollection;

[Bindable]
publicvarmyData:ArrayCollection;

]]>
</mx:Script>
<mx:HTTPServiceid="srv"url="../assets/data.xml"useProxy="false"result="myData=ArrayCollection(srv.lastResult.data.result)"
/>
<mx:Paneltitle="LineChart">

<mx:LineChartid="chart"dataProvider="{myData}">

<mx:horizontalAxis>
<mx:CategoryAxiscategoryField="month"/>

</mx:horizontalAxis>
<mx:series><mx:LineSeriesyField="apple"name="Apple"/>

<mx:LineSeriesyField="orange"name="Orange"/>

<mx:LineSeriesyField="banana"name="Banana"/>

</mx:series>
</mx:LineChart>
</mx:Panel>
</mx:Application>


HTTPService还可以使用XMLListCollection来存储。将服务器端传过来的数据首先设置成E4X就可以了,如下:

<?xmlversion="1.0"?>

<!--charts/HTTPServiceToXMLListCollection.mxml
-->
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"creationComplete="srv.send()">

<mx:Script><![CDATA[importmx.utils.ArrayUtil;]]>
</mx:Script>
<mx:HTTPServiceid="srv"url="../assets/data.xml"resultFormat="e4x"/>

<mx:XMLListCollectionid="myAC"source="{srv.lastResult.result}"/>

<mx:Paneltitle="LineChart"><mx:LineChartid="chart"dataProvider="{myAC}">
<mx:horizontalAxis>
<mx:CategoryAxiscategoryField="month"/>

</mx:horizontalAxis>
<mx:series>
<mx:LineSeriesyField="apple"name="Apple"/>

<mx:LineSeriesyField="orange"name="Orange"/>

<mx:LineSeriesyField="banana"name="Banana"/>

</mx:series>
</mx:LineChart>
</mx:Panel>
</mx:Application>


值得一提的是在flexbuilder2中对内存的管理不完善,创建的ArrayCollection,XMLListCollection
每次编译都会贮存在内存里,没有及时回收就会造成内存泄漏。善用。

不信你就在flexbuilder2里面建这样几个文件,然后多改几次,它在自动编译的模式下,就会出现outofmemory
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: