前序遍历,把XML解析成AS3对象

    AS3的原生XML工具还凑合,但是有时候需要把自己定义的XML数据解析成ActionScript3的Object。

    废话不说,代码:

package com.linkage.cmp.serialization.xml{
	/**
	 * 静态工具类,将xml对象或者字符串转换成AS3对象。
	 * 注意:参数必须是标准单根结构的XML对象或者字符串,如果传递的参数不是合法的XML格式,将会抛出解析异常。
	 * @author	章小飞 [email protected]
	 * @since  	2011-01-18
	 */ 
	public class XmlParser{
		/**
		 * 私有:解析过程中内部使用的堆栈
		 */ 
		private static var stack:Array=[];
		
		public function XmlParser(){
			throw new Error("不能实例化工具类XmlParser");
		}
		
		public static function parse(obj:*):*{
			var result:Object=null;
			try{
				if(!obj){
					return result;
				}
				if(!(obj is XML)){
					obj=new XML(obj.toString());
				}
				//清空堆栈
				stack=[];
				doParse(obj);
				result=stack[0];
			}catch(e:Error){
				throw new Error("Xml2Obj无法解析所提供的XML数据");
			}
			return result;
		}
		
		/**
		 * 递归解析,前序遍历
		 */ 
		private static function doParse(root:XML):void{
			var obj:Object={name:root.name().toString(),children:[]};
			stack.push(obj);
			
			//解析直接属性
			var attrLen:int=root.attributes().length();
			for(var j:int=0;j<attrLen;j++){
				var attr:XML=root.attributes()[j];
				obj[attr.name().toString()||"_temp"]=attr.toString();
			}
			
			//解析子标签
			var len:int=root.children().length();
			if(len){
				for(var i:int=0;i<len;i++){
					var sub:XML=root.children()[i];
					var subLen:int=sub.children().length();
					if(subLen){
						doParse(sub);
						var temp:Object=stack.pop();
						var temp2:Object=stack[stack.length-1];
						temp2.children.push(temp);
					}else{
						var top:Object=stack[stack.length-1];
						delete top.children;
//						top[top.name]=sub.toString();
//						delete top.name;
						top.value=sub.toString();
					}
				}
			}
		}
	}
}

 下面是测试用例:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import com.linkage.cmp.serialization.json.JSON;
			import com.linkage.cmp.serialization.xml.XmlParser;
			private function test():void{
				//第一种用法,直接解析XML对象,可以嵌套任意深度
				var xml:XML=<root>
								<name>大漠穷秋</name>
								<age>25</age>
								<skills>
									<skill>AS3</skill>
									<skill>C++</skill>
									<skill>Java</skill>
								</skills>
							</root>;
				var obj:Object=XmlParser.parse(xml);
				trace(JSON.encode(obj));
				
				//第二种用法:直接给一个XML字符串
				var str:String="<root type='001' attr2='002'><node>名称</node></root>";
				var obj2:Object=XmlParser.parse(str);
				trace(JSON.encode(obj2));
			}
		]]>
	</fx:Script>
	<s:Button click="test()" label="test">
		
	</s:Button>
</s:Application>

 说明:

    XmlParser的包声明你自己改吧,应该木有难度。

    这是FlashBuilder的工程,如果是Flex3,请自行更改测试代码里面的标签。

    示例出来的效果是这样的:

   

{"children":[{"name":"name","value":"大漠穷秋"},{"name":"age","value":"25"},{"children":[{"name":"skill","value":"AS3"},{"name":"skill","value":"C++"},{"name":"skill","value":"Java"}],"name":"skills"}],"name":"root"}
{"type":"001","children":[{"name":"node","value":"名称"}],"name":"root","attr2":"002"}

 

    子节点都放在children属性里面,最终形成”树“一样的数据结构。

你可能感兴趣的:(数据结构,xml,json,Flex,Adobe)