XML--可扩展标记语言,我想看本文的你早已经将他用得滚瓜烂熟了。OK,下面就直奔主题,看看在ActionScript 3.0中是通过什么方式来处理XML数据。
在ActionScript 3.0中,用于处理XML数据的主要有两个类:XML和XMLList。前者表示单个XML元素,它可以是包含多个子元素的XML文档,也可以是文档中的单值元素。后者表示一组XML元素。
既然是XML,在ActionScript 3.0中同样有着和C#/Java一样的相关术语,如:文档、元素、节点以及属性等。本文将以XML文档的创建、添加数据、删除数据、查询数据以及加载外 部XML文件为中心,详细介绍在ActionScript 3.0中对XML的处理。
在此之前先来了解下E4X方法。什么是ECMAScript for XML (E4X)方法呢?它是ActionScript 3.0中所提供的一些运算符,用于访问和处理XML数据的特定功能。ActionScript 3.0 包含以下 E4X 类:XML、XMLList、QName 和 Namespace。它们位于flash.xml包下,目的就是为了达到更容易编写和理解用于处理XML数据的代码。
一、创建内部XML文档
在Flex下要创建一个XML文档是很简单的,可以使用XML对象直接创建,如下所示:
2 <Book id="1">
3 <Name>ActionScript入门到精通</Name>
4 <Author>张三</Author>
5 <Price>48.50</Price>
6 </Book>
7 <Book id="2">
8 <Name>ASP.NET高级编程</Name>
9 <Author>李四</Author>
10 <Price>86.70</Price>
11 </Book>
12 </Root>
二、加载外部XML文档
除了上面这种创建XML文档的方式外,我们同样可以使用一个外部已存在的xml文档(此xml文档可以是一个xml文件,也可以是一个函数的返回值等),要加载一个外部的xml文档在Flex下可以通过<mx:XML>标签来完成,如下所示:
2
3 </mx:XML>
通过上面这中方式载入的XML文档在界面设计的时候就可以直接通过book实例来绑定在界面元素上了。那么我们需要在编程中使用外部XML则需要 通过另外一种方式载入XML,既使用URLLoader.load()方法,且还需要设置dataFormat属性为DataFormat.TEXT读取 数据,通过complete事件处理函数来转换载入的数据为XML实例,如下代码块:
2 {
3 //创建URLLloader实例以简单文本形式读取数据
4 //设置数据装载格式为DataFormat.TEXT
5 //监听并添加complete事件处理函数
6 var loader:URLLoader = new URLLoader();
7 loader.dataFormat = DataFormat.TEXT;
8 loader.addEventListener(Event.COMPLETE,handlerComplete);
9 loader.load(new URLRequest("Data/Book.xml"));
10 }
11
12 private function handlerComplete(event:Event):void
13 {
14 var book:XML = new XML(event.target.data);
15 }
另外装载外部XML数据还有种情况就是RPC,某种情况下也叫XML-RPC,常见的开发模式通常为服务器端提供调用接口,接口可以为asp,jsp,php,aspx,webservice,wcf等提供的都可以,这里就不多说,详细在以后的文章里介绍。
三、XML的元素、节点与属性
在ActionScript 3.0中使用E4X语法创建子元素并添加到XML中,XML对象提供了两个非常使用的方法:insertChildBefort()方法和 insertChildAfter()方法,这两个方法都是以当前元素为基础来进行元素的添加。
要给XML文档节点里添加属性,需要使用“@”操作符。使用很简单,如下所示:
2 {
3 var book:XML = <book>
4 <item></item>
5 </book>;
6 book.item.@id=1;
7 book.item.@name="ActionScript 3.0";
8
9 Alert.show(book);
10 }
下面是添加属性后的xml对象数据:
四、使用XMLList读取XML数据
XML对象提供了一个返回XMLList类型的方法elements(),既返回所有XML对象的子元素节点,随后我们可以通过for each语句循环则可访问到整个XML数据内容。以上面创建内部XML文档的XML数据为例,详细见如下代码块:
2 for each(var element:XML in list)
3 {
4 //获取每一个节点的id
5 Alert.show(element.@id);
6 trace(element.@id);
7 }
这里需要注意一点就是elements()方法只会当前节点的下一级节点,如果XML层次结构比较多还需递归来处理。另外还可以使用“.”操作符来取数据,格式为:根节点.子节点.....元素名称;
详细大家可以查阅《ActionScript 3.0 Cookbook》这本翻译笔记,里面介绍得非常清楚。
以下是XMl的入门
XML运用
XML(eXtensible Markup Language可扩展置标语言),它是有别于HTML(Hyper Text Markup Language超文本置标语言)的一种数据表示规范。由于它极大的灵活性和方便性,在存储和表示数据方面占据了巨大的优势。
ActionScript中的XML对象为你提供了访问XML文档的途径,使用点语法和XML对象的属性可以方便地访问XML文档(既可以是存储XML数据的文本文档,也可以是XML格式的文档)中的具体数据,并可以在Flash中将外部XML文档中的数据显示出来。
16.1 XML基础
XML与HTML有相似之处,因为它们都使用标签(tag)。但是HTML中的标签都是HTML的语法所预定好的, 如<font></font>表示字体,<br>表示换行等;而XML中的标签则可以由用户根据需要、习惯和爱好自 由指定,如下所示是一个XML的例子:
<student>
<name>Thyme</name>
<age>18</age>
<score>
<English>94</English>
<Physics>86</Physics>
<Chemistry>99</Chemistry>
</score>
<grade>B</grade>
</student>
上例的XML文档定义了一个student对象,在student对象下面包含4组信息,分别是name、age、score和grade,在score 下面又分为English、Physics、Chemistry这3类,以上这些成对出现的标志即是XML的标签,标签又称为XML的元素 (element)或节点(node)。每对节点之间包含与该节点相对应的数据,这些数据又称为文本节点(text node)。该XML文档表示的数据结构如图16-1所示。
图16-1 XML文档的数据结构
使用XML表示的数据结构一目了然,这也是它之所以深受人们宠爱的原因之一。在Flash中使用XML对象可以方便地解析XML的数据结构,以访问需要的节点或数据。
XML的另一大优点就是可以使用简单的文本编辑器进行编辑,程序员可以很容易地编写出访问XML格式数据的程序。这也为使用Flash制作与服务器交互的影片提供了一条捷径。
16.2 XML对象
同ActionScript的其他对象一样,要使用XML对象,就得先创建XML对象的实例,其方法如下:
myXML = new XML();
XML对象提供了众多的属性、方法和事件,下面重点介绍常用的几种。
16.2.1 load方法
XML的load方法用于从指定的URL中加载XML文档,并使用下载的XML数据替换指定XML对象的内容。使用load方法加载的XML文档必须与Flash影片处于相同的文件夹中。如下所示的ActionScript创建并从外部文本文档中加载XML对象:
myXML = new XML();
myXML.load("XMLData.txt");
如下所示的ActionScript创建并从外部XML文档中加载XML对象:
myXML = new XML();
myXML.load("XMLData.xml");
和LoadVars.load方法类似,使用XML.load命令后并不能立即将外部文档中的数据加载到影片中,如果直接引用文档中的数据可能会得不到需要的结果。要判断XML文档是否已经加载到影片中,可以使用下面要介绍的onLoad事件。
16.2.2 onLoad事件
当从服务器上接收XML文档时,由Flash Player调用XML的onLoad事件。调用onLoad事件时自动返回一个参数success,如果成功地收到XML文档,则success参数为 true;如果未收到该文档,或从服务器上接收响应时出现错误,则success参数为false。
onLoad事件的使用方法如下所示:
myXML = new XML();
myXML.load("XMLData.txt");
myXML.onLoad = function() {
if (success == true) {
trace("XML is successfully loaded");
} else {
trace("Something is wrong with the XML document");
}
};
16.2.3 childNodes属性
XML的childNodes属性返回指定XML对象的子级的数组,数组中的每个元素都是对表示子节点的XML对象的引用,也就是说childNodes属性将XML对象当前级的子级节点作为一个数据返回。与数据一样,使用方括号可以访问数据的每一个元素。
例如外部文档中有图16-1所示结构图的XML对象,先将其加载到影片中的XML对象中:
myXML = new XML();
myXML.load("XMLData.xml");
myXML.onLoad = function(success) {
if (success == true) {
trace(myXML.childNodes[0]);
}
};
运行以上脚本,输出窗口中将显示整个XML对象,如图16-2所示。
图16-2 使用childNodes属性访问整个XML对象
将上面脚本中的trace语句换成如下所示:
trace(myXML.childNodes[0].childNodes[0]);
运用脚本,奇怪,输出窗口中没有显示。其实并不是没有显示,而是因为<student>后面有一个换行,Flash没能识别这个换行,而是将一个空行也作为XML对象的一个节点了。如果要验证,可以运行以下脚本:
trace(myXML.childNodes[0].childNodes[1]);
输出窗口中显示:
<name>Thyme</name>
如果Flash Player不能识别空格和空行,那么就不能把XML文档写成很有层次的格式,也就不方便我们阅读了。事实上,不用担心,下一个属性将帮助你解决这个问题。
16.2.4 ignoreWhite属性
ignoreWhite属性的默认设置为false,当设置为true时,在分析过程中将放弃仅包含空白的文本节点。要解决前面遇到的问题,只需要将XML对象的ignoreWhite属性设置为true即可。
在上例中使用如下所示的ActionScript将在输出窗口中返回<name>Thyme</name>:
myXML = new XML();
myXML.load("XMLData.xml");
myXML.ignoreWhite = true;
myXML.onLoad = function(success) {
if (success == true) {
trace(myXML.childNodes[0].childNodes[0]);
}
};
如果要返回<Physics>86</Physics>就需要如下的ActionScript:
trace(myXML.childNodes[0].childNodes[2].childNodes[1]);
如何才能返回Physics字段中的86呢?下面的ActionScript可以吗:
trace(myXML.childNodes[0].childNodes[2] .childNodes[1].childNodes[0]);
上面的脚本的确是返回了86,但事实上,它返回的是86这个节点,而不是这个节点中的文本。要得到文本节点中的文本字段,就需要使用nodeValue属性。
16.2.5 nodeValue属性
nodeValue属性返回XML对象的节点值。如果XML对象为文本节点,则nodeValue为该节点的文本;如果该XML对象是XML元素,则其nodeValue为null。
要得到上例中的文本86,可以使用如下所示的ActionScript:
trace(myXML.childNodes[0].childNodes[2].childNodes[1].childNodes[0].nodeValue);
既然XML元素和XML的文本节点是有区别的,就有必要将这两种类型的节点区别开来。
16.2.6 nodeType属性
nodeType是一个只读属性,值为1表示XML元素,为3表示文本节点。如上例中,使用以下脚本将分别返回1和3。
trace(myXML.childNodes[0].childNodes[2].childNodes[1].nodeType);
trace(myXML.childNodes[0].childNodes[2].childNodes[1].childNodes[0].nodeType);
16.2.7 nodeName属性
与节点密切相关的还有一个nodeName属性。nodeName属性返回XML对象的节点名称,如果该XML对象是一个XML元素 (nodeType==1),则nodeName是表示XML文件中节点的标签名称;如果该XML对象为文本节点(nodeType==3),则 nodeName为null。如上例中,使用以下脚本将分别返回Physics和null:
trace(myXML.childNodes[0].childNodes[2].childNodes[1].nodeName);
trace(myXML.childNodes[0].childNodes[2].childNodes[1].childNodes[0].nodeName);
16.2.8 status属性
如果从外部加载进来的XML文档有漏洞,在Flash影片中引用时肯定会出现问题。XML对象的status属性可以帮助检查XML对象是否完整和存在缺陷。调用status属性将返回一个数值,该数值的不同状态分别表示不同的含义,如下所示:
= 0 没有错误;成功地完成了分析。
= -2 一个CDATA部分没有正确结束。
= -3 XML声明没有正确结束。
= -4 DOCTYPE声明没有正确结束。
= -5 一个注释没有正确结束。
= -6 一个XML元素有格式错误。
= -7 内存不足。
= -8 一个属性值没有正确结束。
= -9 一个开始标记没有匹配的结束标记。
= -10 遇到一个没有匹配的开始标记的结束标记。
通过分析status属性的不同值,可以对相应的XML文档作有针对性的检查和修改,直到没有错误为止。
16.3 练习:用表单显示XML文档内容
本练习的目的是使用表单加载和显示XML文档的内容,以对XML对象的各种常用属性、方法和事件有进一步的了解。本练习的源文件为XML.fla。在同一文件夹中包含一个XML格式的文档,其中的内容如下所示:
<form>
<formname>Author's Information</formname>
<Name>
<firstname>Thyme</firstname>
<familyname>CD</familyname>
</Name>
<IDNo.>510228198111079090</IDNo.>
<Address>
<mailID>610031</mailID>
<Street>New 2 Fu Qing West Road</Street>
<City>Chengdu</City>
<Country>China</Country>
</Address>
<Tel>
<Home>028-87732901</Home>
<Move>028-81822013</Move>
</Tel>
<E-mail>chendong2000will@sina.com</E-mail>
</form>
在文件XML.fla的第一帧中添加了table0~table17共18个动态文本,在帧动作面板中添加了如下所示的ActionScript:
stop();
myXML = new XML();
myXML.ignoreWhite = true;
myXML.load("information.xml");
myXML.onLoad = function() {
if (myXML.status == 0) {
t0 = myXML.childNodes[0].childNodes[0].childNodes[0].nodeValue;
t1 = myXML.childNodes[0].childNodes[1].nodeName;
t2 = myXML.childNodes[0].childNodes[1].childNodes[0].childNodes[0].nodeValue;
t3 = myXML.childNodes[0].childNodes[1].childNodes[1].childNodes[0].nodeValue;
t4 = myXML.childNodes[0].childNodes[2].nodeName;
t5 = myXML.childNodes[0].childNodes[2].childNodes[0].nodeValue;
t6 = myXML.childNodes[0].childNodes[3].nodeName;
t7 = myXML.childNodes[0].childNodes[3].childNodes[3].childNodes[0].nodeValue;
t8 = myXML.childNodes[0].childNodes[3].childNodes[2].childNodes[0].nodeValue;
t9 = myXML.childNodes[0].childNodes[3].childNodes[1].childNodes[0].nodeValue;
t10 = myXML.childNodes[0].childNodes[3].childNodes[0].childNodes[0].nodeValue;
t11 = myXML.childNodes[0].childNodes[4].nodeName;
t12 = myXML.childNodes[0].childNodes[4].childNodes[0].nodeName;
t13 = myXML.childNodes[0].childNodes[4].childNodes[0].childNodes[0].nodeValue;
t14 = myXML.childNodes[0].childNodes[4].childNodes[1].nodeName;
t15 = myXML.childNodes[0].childNodes[4].childNodes[1].childNodes[0].nodeValue;
t16 = myXML.childNodes[0].childNodes[5].nodeName;
t17 = myXML.childNodes[0].childNodes[5].childNodes[0].nodeValue;
} else {
gotoAndStop("error");
}
};
第2帧用于显示XML文档加载出错的信息。将第2帧的帧标签设为error,在其中添加一个按钮“get more information”,在该按钮的动作面板中添加如下ActionScript:
on (release) {
gotoAndStop("errorinfor");
switch (myXML.status) {
case -2 :
errorinfor = "A CDATA has no correct ending";
break;
case -3 :
errorinfor = "XML declaration has no correct ending";
break;
case -4 :
errorinfor = "DOCTYPE declaration has no correct ending";
break;
case -5 :
errorinfor = "A comment has no correct ending";
break;
case -6 :
errorinfor = "An XML node has wrong format";
break;
case -7 :
errorinfor = "Memory of computer is not enough";
break;
case -8 :
errorinfor = "An attibute has no correct ending";
break;
case -9 :
errorinfor = "A beginning tag without an ending one";
break;
case -10 :
errorinfor = "An ending tag without a beginnig one";
break;
}
}
将第3帧的帧标签设为errorinfor,并在第3帧中添加一个名为errorinfor的动态文本。当单击“get more information”按钮时,将在第3帧中显示相关的出错信息。
XML文档无误时的Flash表单如图16-3所示。试着改一下XML文档的内容(以记事本方式打开information.xml进行修改),此时的Flash影片如图16-4所示。单击“get more information”,结果如图16-5和16-6所示。