XML数据直接转换成as3类
平时做游戏开发的时候,很大程度上都会采用xml来做配置文件。有时候需要写很多,然后又需要依次去解析。如果有一个工具来自动解析每一个xml,并且提取出自己需要的数据,多好呀。所以偷了个懒,写了一个解析一定格式的xml和解析类,把这个格式丢给策划自己去调整数据啦。同时自己这边只需要接受现成的类
注意,这里的指的类,一般是自定义的数据结构(类似javaBean,使用的都是属性值)。这样通过访问有数据类型定义的类,比直接访问xml的属性来得方便多了,而且也省了数据类型的转换的麻烦
(当然,这里只是开了个头,需要做好的地方还有很多,也包括其他的文件,例如csv等)
先看一下程序:
package{import flash.display.Sprite;import flash.system.ApplicationDomain;import org.sujun.utils.XMLUtils;import test.TestBean;import test.TwoBean;public class TestXML extends Sprite{//反射需要用到,所以必须先声明private var testBean:TestBean;private var twoBean:TwoBean;//xml文件。这里为了方便,直接写在代码里,实际可以从外部加载private var xml:XML = <testBean type="class" path="test.TestBean"><!-- 注意,字符串,数值类型是可以不设置type的 --><attribute name="name" value="sodaChen" /><attribute name="age" value="18" /><attribute name="flag" type="Boolean" value="true" /><!-- 数组内容描述 --><attribute name="urls" type="array" ><attribute type="int" value="18" /><attribute type="string" value="soda" /><!-- 数组里包含一个对象 --><attribute type="class" value="test.TwoBean" ><attribute name="name" value="www.sujun.org" /><attribute name="has" value="true" /></attribute></attribute><attribute name="twoBean" type="class" value="test.TwoBean" ><attribute name="name" type="string" value="http://blog.csdn.net/sujun10" /><attribute name="has" type="Boolean" value="true" /></attribute></testBean>public function TestXML(){//调用XMLUtils类来解析,直接把XML格式数据转换成自己的类,然后输出数据检验结果var myBean:TestBean = XMLUtils.xmlToObject(xml,ApplicationDomain.currentDomain);trace("myBean.name:" + myBean.name);trace("myBean.flag:" + myBean.flag);trace("myBean.urls:" + myBean.urls);trace("myBean.urls[2].name:" + myBean.urls[2].name);trace("myBean.twoBean.name:" + myBean.twoBean.name);}}}?输出结果是:myBean.name:sodaChen
myBean.flag:true
myBean.urls:18,soda,[object TwoBean]
myBean.urls[2].name:www.sujun.org
myBean.twoBean.name:http://blog.csdn.net/sujun10
?
看到结果之后,XMLUtils这个类做的事也很简单,就是一步一步分析xml,然后根据类型进行数据格式的转换,特别处理数组和自定义对象。
当然,其实这里可以完善的地方还是非常多。例如可以使用简单的xml属性,更好排列格式等
再简单地看看解析xml的类吧
package org.sujun.utils{import flash.system.ApplicationDomain;/** * XML的相关工具 * @author SodaChen * */public class XMLUtils{public function XMLUtils(){}/** * 根据XML转换成对象,并填充对应的值 * @param xml:描述对应数值的XML对象 * @return 返回成功填充数据的对象 * */public static function xmlToObject(xml:XML,domain:ApplicationDomain):*{//生成实例,根据类路径反射出类var obj:* = referenceObject(xml.@path,null,domain);//填充属性fillAttribute(obj,xml.attribute,domain);return obj;}/** * 根据XMLList的内容填充具体的数据 * @param obj: * @param propertys: * */public static function fillAttribute(obj:*,attributes:XMLList,domain:ApplicationDomain):void{for each(var xml:XML in attributes){if(xml.@type.toString() == ""){//没有填写tpye属性的有限处理,必须是基本数据obj[xml.@name.toString()] = xml.@value;}else if(xml.@type.toString() == "array"){obj[xml.@name.toString()] = fillArrayValue(xml,domain);}else if(xml.@type.toString() == "class"){var tempObj:* = referenceObject(xml.@value,null,domain);obj[xml.@name.toString()] = tempObj;//递归fillAttribute(tempObj,xml.attribute,domain);}else if(xml.@type.toString() == "boolean"){if(xml.@value.toString() == "true"){obj[xml.@name.toString()] = true;}else{obj[xml.@name.toString()] = false;}}else{obj[xml.@name.toString()] = xml.@value;}}}/** * 填充数组的xml数据 * @param arrayXML:描述数组数据结构的xml对象 * */public static function fillArrayValue(arrayXML:XML,domain:ApplicationDomain):Array{var tempAry:Array = new Array();for each(var ary:XML in arrayXML.attribute){if(ary.@type.toString() == "class"){var arrayObj:* = referenceObject(ary.@value,null,domain);tempAry.push(arrayObj);//递归fillAttribute(arrayObj,ary.attribute,domain);}else if(ary.@type.toString() == "array"){tempAry.push(fillArrayValue(ary,domain));}else if(ary.@type.toString() == "boolean"){tempAry.push(Boolean(ary.@value));}else if(ary.@type.toString() == "int"){tempAry.push(int(ary.@value));}else if(ary.@type.toString() == "number"){tempAry.push(Number(ary.@value));}else if(ary.@type.toString() == "unit"){tempAry.push(uint(ary.@value));}else{tempAry.push(String(ary.@value));}}return tempAry;}/** * 根据名称创建一个实例,允许传递参数 * @param name:类全路径 * @param args:参数,只一个参数 * @param domain:所在的域 * @return *:返回实例 * 该方法可能会抛出ReferenceError异常,但不需要显式捕捉 */public static function referenceObject(name:String,args:Object = null,domain:ApplicationDomain = null):*{var cl:Class = null;//判断域是否为空 if(domain != null){cl = domain.getDefinition(name) as Class;}else{cl = ApplicationDomain.currentDomain.getDefinition(name) as Class;}if(args != null){return new cl(args);}return new cl();}}}?