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;
  }
  
 }
}

 

posted @ 2010-07-15 15:27  CoderWayne  阅读(1154)  评论(0编辑  收藏  举报