flex xml操作

 
        今天我们来看看AS3中新的XML处理方法:E4X,直到现在,ECMA脚本语言规范(ECMA-262)--AscriptScript 3.0的核心基础,并没有提供任何的XML数据处理类或方法。AcriontScript之前的版本(从Flash 5中的ActionScript开始)有一些处理XML数据的类和方法,但是它们并不是基于ECMAScript标准的。         新的ECMA脚本语言规范第4版草稿中定义了一系列新的处理XML数据的类和方法。这些类和方法的集合并命名为E4X("ECMAScript for XML"),ActionScript 3.0包括如下新的E4X类: XML、XMLList、 QName和Namespace。 E4X类的方法属性和操作的开法基于以下的目标: 简单--E4X尽可能的使得处理XML数据的代码容易编写并且易于理解。 一致性--E4X的方法于Actionscript的其它部分协调一致。 友好--实用非常好理解的操作符处理XML数据,如点号(.)。 注意:为避免与E4X中的新的XML类冲突,原来ActionScript 2.0中的XML类在ActionScript 3.0被重命名为XMLDocument,为了向前兼容,在ActionScript 3.0中遗留下来的类--XML、XMLNode、XMLParser和XMLTag--被包含进了flash.xml包中。新的E4X类是核心类--使用它们不需要import任何包。 初始化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 //获取第1个item的id属性值 trace(myXML.item[0].@id);//Output:1 //获取id属性为2的item的menuName值 trace(myXML.item.(@id==2).menuName); // Output: fries //获取menuName为burger的item的price值 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); 当然你也可以使用@和.操作符来更新数据: 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); 修改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对象的所有子节点对象, 获取更多AS3中E4X类的使用信息,请查看Adobe在线文档,详细API参考:Adobe Flex 2 api文档 作者 feiy,星期三 4 一月 2006 à 16:46 ::程序人生::#164::RSS << 2006,旺年旺上加旺 | 开源软件新时代:55个经典开源Windows工具 >> Trackbacks 无trackback. trackbak地址 : http://www.eshangrao.com/tb.PHP?id=164 评论 1. 星期一 16 一月 2006 à 10:04,作者 king 你好,我想问一下,比方讲我现在有个XML文件,我用FLEX2.0生成的SWF,能不能直接修改,删除,新增这个XML文件的节点. 具体怎么操作? 2. 星期一 16 一月 2006 à 11:58,作者 feiy XML节点的修改不是问题,问题是如何保存这个修改的问题,目前的FLEX的XML处理,还不支持直接在FLEX中更新远程文件,需要后台支持,如coldfusion等。。。 不过对于如果是本地文件,可以使用Flex的LocalConnection,调用javaScript实现修改保存,javascript中可以调用一个签名java组件实现。 3. 星期二 17 一月 2006 à 14:09,作者 king 我就是只修改本地文件的. 我的意思就是生成一个swf 文件,以及一个xml 文件,放到购买的空间上去,然后就是用浏览器访问这个swf,去修改这个xml,这样子也算本地吗? 4. 星期二 17 一月 2006 à 17:20,作者 feiy 不算了,对于访问你的SWF的访客来说,本地是指该访客自己机子硬盘上的文件,而你的XML文件对他来说是远端的文件了,所有需要后台支持! 5. 星期四 2 十一月 2006 à 00:06,作者 frogcjn 认真阅读了您的教程,对于删除节点(child)的方法,我认为还可以有以下简洁方法: 就是使用delete运算符.以您所举的deleteByIndex函数作例: private function deleteByIndex(xmlNode:XML,index:Number):XML{ var newxmlNode = xmlNode.copy(); delete newxmlNode.children()[index]; return newxmlNode; } 这种使用delete方法删除节点(child)的方法,使用范围相当的广,也相当的简单,但是只能删除一个XML,而不能删除XMLList。当要删除XMLList内所有内容或符合条件的部分内容是,就使用for each遍历XMLList内的所有XML即可。 注意的是,delete会将指定的XML完全从内存中删除,所以要想在内存保留,那么就使用XML的copy函数即可,如上例deleteByIndex函数中一样

相关文章

一:display:flex布局display:flex是一种布局方式。它即可以...
1. flex设置元素垂直居中对齐在之前的一篇文章中记载过如何...
移动端开发知识点pc端软件和移动端apppc端软件是什么,有哪些...
最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周...
display:flex;把容器设置为弹性盒模型(设置为弹性盒模型之后...
我在网页上运行了一个Flex应用程序,我想使用Command←组合键...