AS3 CookBook学习整理(十六)
1. 读取XML元素的属性
假设有下面的xml:
var xml:XML = <menu> <item title="蜀绣" author="李宇春">栏目A</item> <item title="青花瓷" author="周杰伦">栏目B</item> <distinctItem><subItem>特别栏目</subItem></distinctItem> <item title="蓝莲花" author="许巍">栏目C</item> </menu>;
得到某个节点的某个属性
xml.item[1].@author
得到某个节点的所有属性,调用name( ) 方法可显示出属性名
var attrList:XMLList = xml.item[1].attributes(); for each(var node:XML in attrList) { trace(node.name() + ":" + node); }
调用attribute("attrName")来得到所有名称为"attrName"的属性
var attrList:XMLList = xml.item.attribute("title"); for each(var node:XML in attrList) { trace(node); }
可以使用操作符 * 和 @ 来得到所有属性
var list:XMLList = xml..@*; //如果有特殊字符,需要这样访问:xml..@["music-title"] for each(var attr:XML in list) { trace(attr.name() + ":" + attr); }
2. 删除XML元素,文本节点和属性
使用delete关键字
package { import flash.display.Sprite; public class Sample0709 extends Sprite { public function Sample0709() { var xml:XML = <menu> <item title="蜀绣" author="李宇春">栏目A</item> <item title="青花瓷" author="周杰伦">栏目B</item> <distinctItem><subItem>特别栏目</subItem></distinctItem> <item title="蓝莲花" author="许巍">栏目C</item> </menu>; //删除文本节点 delete xml.item[1].text()[0]; //删除指定节点 delete xml.item[0];
//删除子节点
delete xml.distinctItem.subItem;
//删除所有属性 delete xml.item.@*; trace(xml); } } }
3. 载入XML
使用URLLoader.load()方法并且设置dataFormat属性为DataFormat.TEXT读取数据,通过complete事件转换载入的数据为XML实例
PS:为避免非XML正常格式带来的转换错误,应该加入异常处理(捕获TypeError)
package { import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.system.System; public class Sample0710 extends Sprite { public function Sample0710() { flash.system.System.useCodePage = true; var loader:URLLoader = new URLLoader(new URLRequest("http://www.xxx.com/test.xml")); loader.dataFormat = URLLoaderDataFormat.TEXT; loader.addEventListener(Event.COMPLETE,onComplete); } private function onComplete(event:Event):void { try { var xml:XML = new XML(event.target.data); delete xml..channel[0]; trace(xml); } catch(e:TypeError) { trace("不是有效的XML格式文档,转换错误"); trace(e.message); } } } }
4. 发送XML数据给服务端脚本
调用sendToURL()和navigateToURL()发送数据,注意设置URLRequest的如下属性:
request.data = xml; //一个xml对象
request.contentType = "text/xml";
request.method = URLRequestMethod.POST;
服务器端代码(.net)
protected void Page_Load(object sender, EventArgs e) { XmlDocument xml = new XmlDocument(); xml.Load(Request.InputStream); //XmlNode node = xml.DocumentElement; //获取root XmlNodeList nodeList = xml.SelectSingleNode("musicBox").ChildNodes; for (int i = 0; i < nodeList.Count; i++) { Response.Write(nodeList.Item(i).Attributes[0].Value + "--" + nodeList.Item(i).InnerXml + "<br />"); } }
flex代码:
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.navigateToURL public class Sample0710 extends Sprite { private var request:URLRequest; public function Sample0710() { var xml:XML = <musicBox> <song author="游鸿明">花沙</song> <song author="陈奕迅">于心有愧</song> <song author="许哲佩">日光恋人</song> </musicBox>; request = new URLRequest("http://localhost:5611/Default.aspx"); request.data = xml; request.contentType = "text/xml"; request.method = URLRequestMethod.POST; stage.addEventListener(MouseEvent.CLICK,onClick); } private function onClick(event:MouseEvent):void { navigateToURL(request); } } }
5. 搜索XML
假如有如下的XML:
var xml:XML = <foodGroup> <fruits> <fruit color="red">苹果</fruit> <fruit color="yellow">香蕉</fruit> <fruit color="green">西瓜</fruit> <fruit color="yellow">鸭梨99</fruit> </fruits> <vegetables> <vegetable color="red">西红柿</vegetable> <vegetable color="brown">土豆</vegetable> <vegetable color="purple">茄子</vegetable> </vegetables> </foodGroup>;
直接通过点操作符定位
var singleNode:XML = xml.fruits.fruit[0]; //单个节点 var nodeList:XMLList = xml.fruits.fruit;//节点集合 for each(var node:XML in nodeList) { trace(node); }
通过双点操作符得到未知路径下的节点
var nodeList:XMLList = xml..vegetable; for each(var node:XML in nodeList) { trace(node); }
通过 * 操作符得到任意节点
var nodeList:XMLList = xml.*.fruit; for each(var node:XML in nodeList) { trace(node); }
@ 符号用来访问属性
var nodeList:XMLList = xml.fruits.fruit.@color; for each(var node:XML in nodeList) { trace(node); }
调用hasOwnProperty("attributeName")检查是否有某属性
var nodeList:XMLList = xml..fruit.(!hasOwnProperty("@color")); for each(var node:XML in nodeList) { trace(node); }
检查节点的属性值
var nodeList:XMLList = xml..fruit.(@color=="yellow"); for each(var node:XML in nodeList) { trace(node); }
检查节点值,并应用正则表达式
var nodeList:XMLList = xml.fruits.fruit; for each(var node:XML in nodeList) { if(node=="西瓜") { trace(node.@color); } if(/\d/.test(node)) { trace(node); } }
6. 在XML中使用HTML和特殊字符
使用CDATA标签,以 <![CDATA[ 开始,以 ]]> 结束
package { import flash.display.Sprite; import flash.net.URLRequest; public class Sample0710 extends Sprite { private var request:URLRequest; public function Sample0710() { var xml:XML = <menu> <item><![CDATA[a>b]]></item> <item><![CDATA[<a href="#">链接</a>]]></item> </menu>; for each(var node:XML in xml.elements()) { trace(node); } } } }
7. 在Flex里调用WebServices
Flash播放器没有内建web services支持,也不理解SOAP;不过Flash播放器能在HTTP上通讯,能解析XML数据,实际上SOAP web services也是在HTTP上通讯且SOAP协议也是以XML为基础的协议,因此用ActionScript完全可以调用web services方法,Flex framework 提供了解决方案
WebServices代码:(.net)
[WebMethod] public string HelloWorld() { return "Hello World"; } [WebMethod] public string GetUser(string name, int age) { return name + " is " + age + " years old"; }
Flex代码:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:WebService id="ws1" wsdl="http://localhost:4223/WebService1.asmx?WSDL"> <mx:operation name="HelloWorld" result="onResult(event);" fault="onFault(event);"> </mx:operation> <mx:operation name="GetUser" result="onResult(event);" fault="onFault(event);"> <mx:request> <name>臣本布衣</name> <age>26</age> </mx:request> </mx:operation> </mx:WebService> <mx:Text id="txtValue" x="300" y="50"></mx:Text> <mx:Button label="调用HelloWorld" click="ws1.HelloWorld.send();" x="300" y="100"></mx:Button> <mx:Button label="调用GetUser" click="ws1.GetUser.send();" x="300" y="200"></mx:Button> <mx:Script> <![CDATA[ import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private function onResult(event:ResultEvent):void { this.txtValue.text = event.result.toString(); } private function onFault(event:FaultEvent):void { this.txtValue.text = event.fault.toString(); } ]]> </mx:Script> </mx:Application>
8. AS调用Javascript函数
如果是比较简单的调用(例如alert('abc');),可以直接利用navigateToURL,这也是兼容所有浏览器的做法:
navigateToURL(new URLRequest("javascript:alert('老胡');"), "_self");
navigateToURL(new URLRequest("javascript:myFunc('老胡',27);"), "_self");
一般情况下应该使用ExternalInterface.call(funcName, parameters);
Javascript代码:
<script type="text/javascript"> function saySomething(name, age) { alert(name + " is " + age + " years old"); } function getSomething() { return "贾君鹏你妈妈喊你回家吃饭"; } </script>
AS3代码:
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.external.ExternalInterface; import flash.net.URLRequest; import flash.net.navigateToURL; import flash.text.TextField; public class Sample0721 extends Sprite { private var textBox:TextField; public function Sample0721() { var button:Sprite = new Sprite(); button.graphics.beginFill(0xFF0000); button.graphics.drawRect(100,100,100,50); button.graphics.endFill(); button.addEventListener(MouseEvent.CLICK,button_Click) this.addChild(button); textBox = new TextField(); textBox.text = "点击获取返回值"; textBox.x = textBox.y = 200; textBox.addEventListener(MouseEvent.CLICK,textBox_Click); this.addChild(textBox); } private function button_Click(event:MouseEvent):void { ExternalInterface.call("saySomething","胡晓伟",26); } private function textBox_Click(event:MouseEvent):void { textBox.text = ExternalInterface.call("getSomething"); } } }
PS:要注意在HTML代码里嵌入swf文件的方式,之前仅仅用了Embed嵌入,导致了IE无法获得Javascript函数的返回值
9. Javascript调用AS函数
使用ExternalInterface.addCallback(jsFuncName, asFuncName)
在客户端需要得到Flash播放器的对象引用,浏览器中的Flash播放器有两种类型:ActiveX和plug-in版本,ActiveX版本运行在Internet Explorer上,而plug-in版本运行在其它浏览器上
ActiveX版本播放器由HTML页中的
一般情况下,我们并不知道用户使用什么版本的Flash播放器,有个方法是通过JavaScript的navigator.appName来检测用户浏览器的类型:
如果navigator.appName 包含Microsoft关键字,那么用户使用的就是Internet Explorer,也就是ActiveX 播放器
如果navigator.appName 不包含Microsoft关键字,也就意味着是plug-in 版本播放器
AS代码:
package { import flash.display.Sprite; import flash.external.ExternalInterface; public class Sample0721 extends Sprite { public function Sample0721() { ExternalInterface.addCallback("drawCircle",addRectToStage); } private function addRectToStage():String { var circle:Sprite = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(Math.random()*300,Math.random()*300,20); circle.graphics.endFill(); this.addChild(circle); return "战斗大师的勇气"; } } }
Javascript代码:
<script type="text/javascript"> function callAS() { var flashPlayer; if (navigator.appName.indexOf("Microsoft") != -1) { flashPlayer = document.getElementById("hxwSwf"); } else { flashPlayer = document["hxwSwf"]; } alert(flashPlayer.drawCircle()); } </script>
10. 从HTML传递参数给Flash
使用FlashVars以"key1=value1&key2=value2"的形式传递参数(如果有特殊符号,例如&,需要用URL编码为%26),Flash端通过root.loaderInfo.parameters得到该FlashVars数组的引用
HTML代码:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="FlashVars" value="userName=关云%26长&group=蜀国"> <embed type="application/x-shockwave-flash" FlashVars="userName=张文远&group=魏国"> </object>
AS3代码:
package { import flash.display.Sprite; import flash.text.TextField; public class Sample0721 extends Sprite { public function Sample0721() { var label:TextField = new TextField(); this.addChild(label); var obj:Object = root.loaderInfo.parameters; label.text = obj.userName; } } }