新人补钙系列教程之:XML处理方法
初始化XML对象
XML对象可以代表一个XML元素、属性、注释、处理指令或文本元素。在ActionScript 3.0中我们可以直接将XML数据赋值给变量:
- var myXML:XML =
- <order>
- <item id=’1’>
- <menuName>burger</menuName>
- <price>3.95</price>
- </item>
- <item id=’2’>
- <menuName>fries</menuName>
- <price>1.45</price>
- </item>
- </order>
复制代码
你也可以使用new 构造器来从XML数据文本创建一个XML对象实例:
- var myXML:XML = new XML("<order><item id=’1’><menuName>burger</menuName><price>3.95</price></item></order>")
复制代码
如果XML数据不是格式完好的(如少了结束标签),那么将会出现运行时错误。
注意,你也可以将变量实例传入XML数据中:
- var tagname:String = "item";
- var attributename:String = "id";
- var attributevalue:String = 5;
- var content:String = "Chicken";
- var x:XML = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
- trace (x.toXMLString())
- // Output: <item id="5">Chicken</item>
复制代码
通常,我们的应用是从外部源导入XML数据,如web service或RSS feed,以下是一个从远程URL导入XML数据的例子:
- var myXML:XML = new XML();
- var XML_URL:String = "http://www.example.com/Sample3.xml";
- //创建URLRequest。
- var myXMLURL:URLRequest = new URLRequest(XML_URL);
- //使用URLLoader导入数据。
- var myLoader:URLLoader = new URLLoader(myXMLURL);
- //添加事件监听器,以在XML数据导入完成后处理XML数据。
- myLoader.addEventListener("complete", xmlLoaded);
- //导入完成后,创建使用导入的数据创建XML对象
- function xmlLoaded(evtObj:Event) {
- var myXML:XML = XML(myLoader.data);
- trace("Data loaded.");
- }
复制代码
为了演示代码的清晰性,本文中的大部份示例都第1种直接使用文本的方法创建XML对象。
E4X包含一些直观的方法XML数据的操作符(如.和@:用于访问属性):
- //获取第1个item的menuName值
- trace(myXML.item[0].menuName); // Output: burger
- [b]//获取第1个item的id属性值 [/b]
- trace(myXML.item[0].@id);//Output:1
- [b]//获取id属性为2的item的menuName值 [/b]
- trace(myXML.item.(@id==2).menuName); // Output: fries
- [b]//获取menuName为burger的item的price值 [/b]
- trace(myXML.item.(menuName=="burger").price); // Output: 3.95
复制代码
( 增 )你也可以使用appendChild()方法给XML添加新的子节点:
- var newItem:XML =
- <item id="3">
- <menuName>medium cola</menuName>
- <price>1.25</price>
- </item>
- myXML.appendChild(newItem);
- [b]( 改 )[/b]当然你也可以使用@和.操作符来更新数据:
- myXML.item[0].menuName="regular burger";
- myXML.item[1].menuName="small fries";
- myXML.item[2].menuName="medium cola";
- myXML.item.(menuName=="regular burger").@quantity = "2";
- myXML.item.(menuName=="small fries").@quantity = "2";
- myXML.item.(menuName=="medium cola").@quantity = "2";
复制代码
(查)访问XML数据
你可以使用.(点号)和..操作符访问XML对象的子节点,使用@操作符访问某一节点的属性。考虑以下XML对象:
- var x:XML =
- <book ISBN="0942407296">
- <title>Baking Extravagant Pastries with Kumquats</title>
- <author>
- <lastName>Contino</lastName>
- <firstName>Chuck</firstName>
- </author>
- <pageCount>238</pageCount>
- </book>
- <book ISBN="0865436401">
- <title>Emu Care and Breeding</title>
- <editor>
- <lastName>Case</lastName>
- <firstName>Justin</firstName>
- </editor>
- <pageCount>115</pageCount>
- </book>
- </order>
复制代码
对象x.book表示一个包含所有名称为book的子节点的XMLList对象,该XMLList包含两个XML对象(两个book节点)。
对象x..lastName表示一个包含XML树结构下部所有的lastName属性的XMLList对象,该XMList包含两个XML对象(两个LastName属性)。
对象x.book.editor.lastName表示一个包含所有x对象的所有名称为book的子节点的所有名称为editor的子节点的所有lastName节点的XMLList对象,该XMLList只包含一个XML对象(值为"Case"的lastName属性)。
(查)访问父节点和子节点
parent()方法返回XML对象的父节点。
你可以使用子节点列表的顺序索引值来访问特定的子节点,例如,假定某一XML对象x有两个名称为book的子节点,你可以如下访问它们:
//第1个book节点
x.book[0]
//第2个book节点
x.book[1]
要访问孙子节点,我们可以如下直接使用儿子和孙子节点的索引值来访问:
x.book[0].title[0]
不过如果x.book[0]只有一个名称为title的子节点的话,那么可以省略索引:
x.book[0].title
类似的,如果x对象只有一个book子节点,并且该book节点的子节点对象只有一个title对象,那么两个索引值都可以省略:
x.book.title
注意,你也可以使用child()方法,直接使用名称访问特定的子节点:
- var x.XML =
- <order>
- <book>
- <title>Dictionary</title>
- </book>
- </order>
- var childName:String = "book";
- trace (x.child(childName).title) // Output: Dictionary
复制代码
(查)访问属性
我们使用使用@操作符访问XMLNode属性:
- var myXML:XML =
- <order>
- <item id=’1’>
- <menuName>burger</menuName>
- <price>3.95</price>
- </item>
- <item id=’2’>
- <menuName>fries</menuName>
- <price>1.45</price>
- </item>
- </order>
复制代码
//获取第1个item的id属性值
trace(myXML.item[0].@id);//Output:1
使用属性或元素值过滤XML数据
我们可以使用特定的元素名称和属性值来定位到特定的元素考虑以下XML对象:
- var x:XML =
- <employeeList>
- <employee id="347">
- <lastName>Zmed</lastName>
- <firstName>Sue</firstName>
- <position>Data analyst</position>
- </employee>
- <employee id="348">
- <lastName>McGee</lastName>
- <firstName>Chuck</firstName>
- <position>Jr. data analyst</position>
- </employee>
- </employeeList>
复制代码
以下是正确的访问方法:
- //lastName为“McGee”的employee对象,第1个employee节点
- x.employee.(lastName == "McGee") // The first employee node
- //lastName为“McGee”的employee对象的firstName节点,第1个employee节点的节点
- x.employee.(lastName == "McGee").firstName // The firstName property of that node
- //lastName为“McGee”的id属性
- x.employee.(lastName == "McGee").@id // The value of the id attribute
- //所有id属性值为347的employee对象列表
- x.employee.(@id == 347)
- //id属性值为347的employee对象的lastName子节点
- x.employee.(@id == 347).lastName
- //所有id属性值大于347的employee对象列表
- x.employee.(@id > 300) // An XML list with both employee properties
- //所有position子节点值包含“analyst”的employee对象列表
- x.employee.(position.toString().search("analyst") > -1)
复制代码
(查)使用for ... in和for each ... in 语句
ActionScript 3.0 包括了一个新用来遍历XMLList对象的的for ... in语句和for each ... in语句。例如,考虑以下XML对象,myXML和myXML..item XMLList对象(包含两个item XML对象节点的XML列表):
- var myXML:XML =
- <order>
- <item id=’1’ quantity=’2’>
- <menuName>burger</menuName>
- <price>3.95</price>
- </item>
- <item id=’2’ quantity=’2’>
- <menuName>fries</menuName>
- <price>1.45</price>
- </item>
- </order>
复制代码
for ... in语句可以让我们遍历XMLList的所有属性名称,实际上就是个节点的索引值:
- var total:Number = 0;
- for (var pname:String in myXML..item)
- {
- total += Number(myXML.item.@quantity[pname]) * Number(myXML.item.price[pname]);
- }
复制代码
for each ... in语句遍历XMLList的所有节点:
- var total2:Number = 0;
- for each (var item:XML in myXML..item)
- {
- total2 += Number(item@quantity) * Number(item.price);
- }
复制代码
使用with语句
我们可以使用with语句,来指明后续的属性和节点值都是基于某一XML对象,前面的for each ... in示例代码,使用with语句的代码如下:
- var total:Number = 0;
- for each (var item in myXML..item)
- {
- with (item)
- {
- //{内的属性和节点对象都是基于item XML对象的,所有不需要使用item.来访问。
- total += Number(@quantity) * Number(price);
- }
- }
- trace(total);
复制代码
[b](改)修改XML对象
我们可以使用prependChild()方法或者appendChild()方法在XML对象的子节点列表的前面或者最后面添加节点:
- var x1:XML = <p>Paragraph 1</p>
- var x2:XML = <p>Paragraph 2</p>
- var x:XML = <body></body>
- x = x.appendChild(x1);
- x = x.appendChild(x2);
- x = x.prependChild(<p>Paragraph 0</p>);
- // x == <body><p>Paragraph 0</p><p>Paragraph 1</p><p>Paragraph 2</p></body>
复制代码
使用insertChildBefore()方法或者insertChildAfter()方法在特定的节点前面活着回后面添加节点:
- var x:XML =
- <body>
- <p>Paragraph 1</p>
- <p>Paragraph 2</p>
- </body>
- var newNode:XML = <p>Paragraph 1.5</p>
- x = x.insertChildAfter(x.p[0], newNode)
- x = x.insertChildBefore(x.p[2], <p>Paragraph 1.75</p>)
- 注意,我们也可以在构造XML对象的时候使用大括号({和})来引用变量:
- var ids:Array = [121, 122, 123];
- var names:Array = [["Murphy","Pat"],["Thibaut","Jean"], ["Smith","Vijay"]]
- var x:XML = new XML("<employeeList></employeeList>");
- for (var i:int = 0; i < 3; i++) {
- var newnode:XML = new XML();
- newnode =
- <employee id={ids[i]}>
- <last>{names[i][0]}</last>
- <first>{names[i][1]}</first>
- </employee>
- x = x.appendChild(newnode)
- }
复制代码
我们也可以使用=操作符来给XML对象节点赋值:
- var x:XML =
- <employee>
- <lastname>Smith</lastname>
- </employee>
- x.firstname = "Jean";
- x.@id = "239";
复制代码
以上代码将把XML对象X设置成如下:
- <employee id="239">
- <lastname>Smith</lastname>
- <firstname>Jean</firstname>
- </employee>
复制代码
我们也可以使用+和+=操作符来连结XMLList:
- var x1:XML = <a>test1</a>
- var x2:XML = <b>test2</b>
- var xList:XMLList = x1 + x2;
- xList += <c>test3</c>
复制代码
(删)删除XML对象
E4X规范中定义有delete和deleteByIndex方法用来删除特定的XML节点,但是在当前版本的ActionScript 3.0实现中,并没有实现这两个方法,所有我们不能直接使用这两个方法,不过我们可以使用遍历XML树,剔除特定的节点,重新构造新的XML对象的方法来删除某一特定节点,以下我们将删除employee的lastname子节点:
- private function deleteByIndex(xmlNode:XML,index:Number):XML{
- var newStr:String=’’;
- newStr+=’<’+xmlNode.localName();
- for each (var att:XML in xmlNode.attributes()){
- newStr+=’ ’+att.localName()+’="’+att.toString()+’"’;
- }
- newStr+=’>’;
- var i:Number=0;
- for each(var node:XML in xmlNode.children()){
- if(i!=index)
- newStr+=node.toXMLString();
- i++;
- }
- newStr+=’</’+xmlNode.localName()+’/>’;
- return new XML(newStr);
- }
- var myXML:XML=
- <employee id="239">
- <lastname>Smith</lastname>
- <firstname>Jean</firstname>
- <address>
- <city>shangrao</city>
- <load>daihu</load>
- <no>5</no>
- </address>
- </employee>
- myXML=deleteByIndex(myXML,0);
复制代码
以上的deleteByIndex函数有两个参数,第1的参数是被删除节点的父节点,第2的参数是被删除节点的在父节点的子节点列表中索引值。先遍历父节点的索引属性,然后遍历其所有的子节点,跳过我们要删除的节点,然后将它们组合成新的XML对象返回。
如果XML对象非常复杂,数据量必较大的话,以上删除节点的实现方法效率是非常好低,所有正确的选择还是使用E4X定义的删除方法,不过这个功能要等到ActionScript 3.0的下一个测试版本才能够实现。
XML类型转换
我们可以将XML对象和XMLList对象转换为字符串,同样的,我们也可以将字符串转换为XML对象和XMLList对象。顺便,请记住所有的XML属性值、名称和文本值都是字符串。
转换XML和XMLList对象为字符串
XML对象和XMLList对象都有有两个成员方法:toString()和toXMLString()方法。toXMLString()方法返回包含所有标签、属性、命名空间声明和XML对象内容的字符串,对与复杂的XML对象(包含有子元素),toString()方法的效果和toXMLString()方法的效果一样,但是对与简单的XML对象(只包含一个文本元素),toString()方法只返回元素的文本内容:
- var myXML:XML =
- <order>
- <item id=’1’ quantity=’2’>
- <menuName>burger</menuName>
- <price>3.95</price>
- </item>
- <order>
- trace(myXML.item0.menuName.toXMLString())
- // Output: <menuName>burger</menuName>
- trace(myXML.item0.menuName.toString())
- // Output: burger
复制代码
将文本字符串转换为XML对象
我们可以使用new构造方法从字符串创建一个XML对象
var x:XML = new XML(’<a>test<b>’);
但是如果我们试图将一个非XML或者结构不完整的字符串转换为XML对象,那么将会报运行时错误:
var x:XML = new XML(’<a>test’); // Throws an error
从Internet读取Rss Fead数据
以下代码将读取本站的rss fead数据:
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.macromedia.com/2005/mxml" xmlns="*" creationComplete="doInit()">
- <mx:Script>
- <![CDATA[
- private function doInit():Void{
- getRssData("http://blog.eshangrao.com/rss.php",ta_view);
- }
- public function getRssData(url:String, outTxt:TextArea):Void
- {
- private var myXMLURL:URLRequest = new URLRequest(url);
- private var myLoader:URLLoader = new URLLoader(myXMLURL);
- myLoader.addEventListener("complete", xmlLoaded);
- }
- private function xmlLoaded(event:Event):Void{
- ta_view.text=’load ok’;
- var myLoader:URLLoader = URLLoader(event.target);
- XML.ignoreProcessingInstructions=false;
- var myXML:XML =new XML(myLoader.data);
- private var outStr:String = "";
- for each (var item:XML in myXML.children()) {
- if(item.localName()==’item’){
- outStr += "<p><b>" + item.children()0.toString() + ":</b></p><p>";
- outStr += item.children()6.toString() ;
- outStr += " <br/><a href=’" + item.children()1.toString();
- outStr += "’><font color=’#008000’>More...</font></a></p>";
- }
- }
- //ta_view.text=myXML.toString();
- ta_view.htmlText = outStr;
- }
- ]]>
- </mx:Script>
- <mx:Canvas width="100%" height="100%">
- <mx:TextArea id="ta_view">
- <mx:layoutConstraints>
- <mx:EdgeAnchor bottom="10" top="10" left="10" right="10"/>
- </mx:layoutConstraints>
- </mx:TextArea>
- </mx:Canvas>
- </mx:Application>
复制代码
运行示例(FlashPlayer8.5 required)
注意,我们没有直接使用节点名称访问节点(不知道为什么,如果使用item.title访问title节点的话,返回是空的,可能跟我的RSS XML的中rdf指令有关,如果有朋友知道解决的办法,请告诉我),而是使用了children()方法,该方法返回某一XML对象的所有子节点对像.
新人补钙系列教程之:XML处理方法的更多相关文章
- 新人补钙系列教程之:拒绝CPU高占用
1.关于MovieClip和Sprite的鼠标事件,当不需要鼠标事件的时候将mouseEnabled和mouseChildren设为false. 不断的检测鼠标交互事件会消耗CPU,尤其是大量交互对象 ...
- 新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树
1. 什么是BSP树 BSP算法的初始数据是一个多边形集,BSP在预处理的时候先在多边形集中选取一个多边形作为支持平面,然后根据这个平面将集合划分成两个部分,每个部分是一个新的子节点,递归进行该过程, ...
- 新人补钙系列教程之:体验ApplicationDomain 应用程序域
要说应用程序域,就不得不说安全沙箱 安全沙箱在帮助文档的解释是: 客户端计算机可以从很多来源(如外部 Web 站点或本地文件系统)中获取单个 SWF 文件.当 SWF 文件及其它资源(例如共享对象.位 ...
- 新人补钙系列教程之:AS3 与 PHP 简单通信基础
package { import flash.display.Loader; import flash.events.Event; import flash.net.URLLoader; import ...
- 新人补钙系列教程之:AS 与 JS 相互通信
比较常用的,AS 调用 JS private function callJS():void{ ExternalInterface.addCallback("callbackQQPay&quo ...
- 新人补钙系列教程之:Molehill底层API中最重要的Context3D
Context3D,是一个三维空间的处理环境,负责创建并处理三维对象的各个要素如顶点.片段.透视等等,并将处理的结果使用AGAL(Adobe图形汇编语言)上传给显卡进行运算,运算结果最终被回传给CPU ...
- 新人补钙系列教程之:AS3 位运算符
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...
- 新人补钙系列教程之:AS3事件处理--事件流
一个flash应用程序可能会非常复杂,比如,有很多可视实例嵌套在一起,这样的话会形成一个树形结构,这个结构的根是stage,然后一级级到不同的实例,一般来说,要把这个树形结构倒过来看,即stage在顶 ...
- Spring 系列教程之 bean 的加载
Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...
随机推荐
- zoj 1508 Intervals (差分约束)
Intervals Time Limit: 10 Seconds Memory Limit: 32768 KB You are given n closed, integer interva ...
- 转:Android ListView 异步加载图片
http://www.iteye.com/topic/1118828 http://www.iteye.com/topic/1127914 这样做无疑是非常可取的方法,但是加载图片时仍然会感觉到轻微的 ...
- 转 android Listview,gridview局部刷新,部分刷新 (仿QQ动态评论局部刷新)
转自:http://blog.csdn.net/jdsjlzx/article/details/45582719 众所周知Listview和Gridview的刷新界面的方式是调用adapter.not ...
- Java设计模式_创建型模式_单例模式
单例模式的实现: 定义一个类,在类中定义该类的静态变量,再定一个一个获取该类的静态变量的方法. UML图:
- C++11 lambda表达式(19篇C++11文章)
C++11引入了lambda表达式,使得程序员可以定义匿名函数,该函数是一次性执行的,既方便了编程,又能防止别人的访问. Lambda表达式的语法通过下图来介绍: 这里假设我们定义了一个如上图的lam ...
- Express定制参数解析错误响应值
Nodejs的Express框架本身所提供的东西并没有其它框架那么多.其中的一个问题就是对于请求数据的解析. express中的请求对象并没有未经过解析的请求体,几乎所有的请求体都要经过类似于body ...
- Fiddler抓包2-只抓APP的请求【转载】
本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/p/6582437.html 前言 fiddler抓手机app的请求,估计大部分都会,但是如何只 ...
- Delphi中获取文件大小
大概有这些方法可以获得文件大小FileSizeByName(需要引用IdGlobal单元)GetFileSizeFileSize(不能获得正在使用的文件大小)FileSeekTFileStream.S ...
- Ext中点击某个东西弹出框展示
renderer:function(v){ return '<a href="123" data-qtitle="OK Button" data-qwid ...
- (29)C#多线程
使用线程的原因 1.不希望用户界面停止响应. 2.所有需要等待的操作,如文件.数据库或网络访问需要一定的时间. 一个进程的多个线程可以同时运行不同cpu或多核cpu的不同内核上 注意多线程访问相同的数 ...