flex和xml的结合非常精密,本身flex就有xml的对象,所以在开发xml也让人感觉非常方便。但是传统的xml对象的解析下,无法对xml执行sax的操作,要递归出一些具有相同属性的节点相对比较麻烦。传统flex的xml的修改也非常麻烦,比较容易出错。直接上代码吧:
package com.shine.framework.core.util
{
import mx.collections.ArrayCollection;
public class ArrayMap
{
private var entry:ArrayCollection=new ArrayCollection;
public function ArrayMap()
{
}
/**
* 比较是否存在相同的key
* @param key
* */
public function containsKey(key:Object):Boolean{
var length:int=entry.length;
var b:Boolean=false;
for(var i:int=0;i<length;i++){
var mapValue:MapValue=entry.getItemAt(i) as MapValue;
if(mapValue.key==key){
b=true;
break;
}
}
return b;
}
/**
* 比较是否存在相同的value
* @param value
* */
public function containsValue(value:Object):Boolean{
var length:int=entry.length;
var b:Boolean=false;
for(var i:int=0;i<length;i++){
var mapValue:MapValue=entry.getItemAt(i) as MapValue;
if(mapValue.value==value){
b=true;
break;
}
}
return b;
}
/**
* 存入数据
* @param key
* @param value
* */
public function put(key:Object,value:Object):void{
var mapValue:MapValue=null;
var length:int=entry.length;
var b:Boolean=true;
for(var i:int=0;i<length;i++){
mapValue=entry.getItemAt(i) as MapValue;
if(mapValue.key==key){
MapValue(entry.getItemAt(i)).value=value;
b=false;
break;
}
}
if(b){
mapValue=new MapValue;
mapValue.key=key;
mapValue.value=value;
entry.addItem(mapValue);
mapValue=null;
}
}
/**
* 根据key获取数据
* @param key
* */
public function get(key:Object):Object{
var length:int=entry.length;
for(var i:int=0;i<length;i++){
var mapValue:MapValue=entry.getItemAt(i) as MapValue;
if(mapValue.key==key){
return mapValue.value;
}
}
return null;
}
/**
* 获取长度
* */
public function getLength():int{
return entry.length;
}
/**
* 根据顺序获取key
* @param index
* */
public function getKeyByIndex(value:int):Object{
if(value<entry.length)
return (entry.getItemAt(value) as MapValue).key;
return null;
}
/**
* 根据顺序获取value
* @param index
* */
public function getValueByIndex(value:int):Object{
if(value<entry.length)
return (entry.getItemAt(value) as MapValue).value;
return null;
}
/**
*获取key的位置
*@param key
* */
public function getIndexByKey(key:Object):int{
if(this.containsKey(key)){
var length:int=entry.length;
for(var i:int=0;i<length;i++){
var mapValue:MapValue=entry.getItemAt(i) as MapValue;
if(mapValue.key==key){
return i;
}
}
}
return 0;
}
/**
*获取首个value的位置
*@param value
* */
public function getIndexByValue(value:Object):int{
if(this.containsValue(value)){
var length:int=entry.length;
for(var i:int=0;i<length;i++){
var mapValue:MapValue=entry.getItemAt(i) as MapValue;
if(mapValue.value==value){
return i;
}
}
}
return 0;
}
/**
*删除该key
*@param key
* */
public function removeMapValue(key:Object):void{
if(this.containsKey(key)){
entry.removeItemAt(this.getIndexByKey(key));
}
}
/**
*删除该value
*@param value
* */
public function removeMapByValue(value:Object):void{
if(this.containsValue(value)){
entry.removeItemAt(this.getIndexByValue(value));
}
}
/**
* 删除所有数据
* */
public function removeAll():void{
entry.removeAll();
}
/**
* 获取所有值的数组
* */
public function getValueArray():Array{
var valueArray:Array=new Array;
var num:int=this.getLength();
for(var i:int=0;i<num;i++){
valueArray.push(this.getValueByIndex(i));
}
return valueArray;
}
}
}
class MapValue{
public var key:Object;
public var value:Object;
}
package com.shine.framework.core.model
{
import com.shine.framework.core.util.ArrayMap;
import com.shine.framework.core.util.StringBuffer;
import flashx.textLayout.formats.Float;
import mx.controls.Alert;
/**
* Base xml model
*
* @author viruscodecn@gmail.com
* @project FlexFramework 2.0 2011-01-13
*/
public class BaseXmlModel extends ArrayMap
{
public var xml:String="";
public function BaseXmlModel(value:String=null)
{
super();
initXmlValue(value);
}
/**
* 初始xml model的值,把xml节点中所有属性和值存入model
*
* value=<node key1="value1" key2="value2" key3="value3" />
* */
public function initXmlValue(value:String):void{
xml=value;
this.removeAll();
var xmlData:XML=XML(value);
var length:int=xmlData.attributes().length();
for(var i:int=0;i<length;i++){
var xmlValue:XML=XML(xmlData.attributes()[i]);
this.put(xmlValue.name().toString(),xmlValue.toString());
}
}
//获取xml的数据结构 <node key1="value1" key2="value2" key3="value3" />
public function getXmlValue():String{
var xmlData:StringBuffer=new StringBuffer;
xmlData.append("<node ");
var length:int=this.getLength();
for(var i:int=0;i<length;i++){
xmlData.append(this.getKeyByIndex(i)+"='"+this.getValueByIndex(i)+"' ");
}
xmlData.append("/>");
return xmlData.toString();
}
//获取xml的数据结构 <name key1="value1" key2="value2" key3="value3" />
public function getOriginalXmlValue():String{
var xmlData:StringBuffer=new StringBuffer;
xmlData.append("<"+String(XML(this.xml).name())+" ");
var length:int=this.getLength();
for(var i:int=0;i<length;i++){
xmlData.append(this.getKeyByIndex(i)+"='"+this.getValueByIndex(i)+"' ");
}
xmlData.append("/>");
return xmlData.toString();
}
/**
* 初始xml model的值,把子节点中的名称做key,值做value
*
* value=<node><key1>value1</key1><key2>value2</key2><key3>value3</key3></node>
* */
public function initBaseXmlValue(value:String):void{
xml=value;
this.removeAll();
var xmlData:XML=XML(value);
for each(var nodeXml:XML in xmlData.children()){
this.put(nodeXml.name().toString(),nodeXml.toString());
}
}
//获取xml的数据结构 <node><key1>value1</key1><key2>value2</key2><key3>value3</key3></node>
public function getBaseXmlValue():String{
var xml:XML=XML("<node />");
var length:int=this.getLength();
for(var i:int=0;i<length;i++){
var keyXml:XML=XML("<"+this.getKeyByIndex(i)+">"+this.getValueByIndex(i)+"</"+this.getKeyByIndex(i)+">");
xml.appendChild(keyXml);
}
return xml.toXMLString();
}
//由key获取String value
public function getString(key:String):String{
if(this.get(key)==null)
return null;
return String(this.get(key));
}
//由key获取int value
public function getInt(key:String):int{
return int(this.get(key));
}
//由key获取num value
public function getNumber(key:String):int{
return Number(this.getString(key));
}
//获取xml的name
public function getName():String{
return String(XML(this.xml).name());
}
}
}
package com.shine.framework.core.util
{
import com.shine.framework.core.model.BaseXmlModel;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
public class XMLArrayCollection extends ArrayCollection
{
public function XMLArrayCollection()
{
}
/**
* 获取所有节点
* */
public function saxXmlNode(value:XML):void{
var baseXMLModel:BaseXmlModel=new BaseXmlModel;
baseXMLModel.initBaseXmlValue(value.toXMLString());
this.addItem(baseXMLModel);
baseXMLModel=null;
if(value.children().length()!=0){
for each(var xml:XML in value.children()){
saxXmlNode(xml);
}
}
}
/**
* 获取所有指定名称的节点
* */
public function saxXmlNodeByTag(value:XML,tag:Array):void{
if(tag.indexOf(value.name().toString())!=-1){
var baseXMLModel:BaseXmlModel=new BaseXmlModel;
baseXMLModel.initXmlValue(value.toXMLString());
this.addItem(baseXMLModel);
}
if(value.children().length()!=0){
for each(var xml:XML in value.children()){
saxXmlNodeByTag(xml,tag);
}
}
}
/**
* 获取指定的model
**/
public function getBaseXMLModel(value:int):BaseXmlModel{
return this.getItemAt(value) as BaseXmlModel;
}
}
}
在说例子前,我简单给大家解析一下使用逻辑。首先通过递归把xml解析到XMLArrayCollection里面,里面的对象主要是BaseXmlModel。我们简单给大家一个使用例子。
样本xml
<?xml version="1.0" encoding="UTF-8"?>
<BusinessView saveUrl="/GraphicalView.do?method=saveMap&mapId=2">
<Nodes>
<Node image="/images/fl/biz.gif" y="37" id="2" message="名称:MyBizView" type="BIZ" name="MyBizView" x="359" />
<Node image="/images/fl/url_1.gif" y="177" id="10000103" message="名称: www.abc.com<br>类型: Url监视器<br>可用性: 不可用<br>健康度: 告警<br>响应时间: 0ms<br>资源停止. 资源www.abc.com不可用。Host Unavailable:响应码 -200" type="UrlMonitor" name="http://www.abc.com" x="634" />
<Node image="/images/fl/sys_5.gif" y="248" id="10000038" message="名称: win2008<br>类型: Windows 2000<br>可用性: 可用<br>健康度: 正常<br>响应时间: 1ms" type="Windows 2000" name="afunms-win2008" x="474" />
<Node image="/images/fl/dbs_5.gif" y="172" id="10000039" message="名称: tbsm<br>类型: DB2-server<br>可用性: 可用<br>健康度: 正常<br>响应时间: 34ms" type="DB2-server" name="IF-afunms-win2008_DB2-server_50000" x="121" />
<Node image="/images/fl/ser_5.gif" y="262" id="10000100" message="名称: 80.13<br>类型: Ping Monitor<br>可用性: 可用<br>健康度: 正常<br>响应时间: 0ms" type="Ping Monitor" name="80.13" x="141" />
<Node image="/images/fl/ser_5.gif" y="300" id="10000098" message="名称: 80.130<br>类型: Ping Monitor<br>可用性: 可用<br>健康度: 正常<br>响应时间: 0ms" type="Ping Monitor" name="80.130" x="254" />
<Node image="/images/fl/url_1.gif" y="215" id="10000104" message="名称: dd<br>类型: Url监视器<br>可用性: 不可用<br>健康度: 告警<br>响应时间: 0ms<br>资源停止. 资源dd不可用。Host Unavailable:响应码 -200" type="UrlMonitor" name="http://www.dd.2" x="535" />
<Node image="/images/fl/url_1.gif" y="294" id="10000102" message="名称: 163.com<br>类型: Url监视器<br>可用性: 不可用<br>健康度: 告警<br>响应时间: 0ms<br>资源停止. 资源163.com不可用。Host Unavailable:响应码 -200" type="UrlMonitor" name="http://www.163.com" x="355" />
<Node image="/images/fl/hai_1.gif" y="107" id="10000105" message="名称: MyGroup<br>类型: 监视器组<br>可用性: 不可用<br>健康度: 告警<br>响应时间: -1ms<br>资源MyGroup为停止. 根本原因:资源停止. 资源www.abc.com不可用。Host Unavailable:响应码 -200资源停止. 资源dd不可用。Host Unavailable:响应码 -200资源停止. 资源163.com不可用。Host Unavailable:响应码 -200" type="HAI" name="MyGroup" x="362" />
</Nodes>
<Lines>
<Line end="10000105" color="0xd9D6C3" start="2" />
<Line end="10000103" color="0xFF0000" start="10000105" />
<Line end="10000038" color="0xd9D6C3" start="10000105" />
<Line end="10000039" color="0xd9D6C3" start="10000105" />
<Line end="10000100" color="0xd9D6C3" start="10000105" />
<Line end="10000098" color="0xd9D6C3" start="10000105" />
<Line end="10000104" color="0xFF0000" start="10000105" />
<Line end="10000102" color="0xFF0000" start="10000105" />
</Lines>
<Tree icon="/images/fl/root.gif" name="resourceTree" root="true">
<node icon="/images/fl/root.gif" name="MyBizView" root="true">
<node icon="/images/fl/root.gif" name="MyGroup" root="true">
<node icon="/images/fl/node.gif" name="afunms-win2008" id="10000038" />
<node icon="/images/fl/node.gif" name="IF-afunms-win2008_DB2-server_50000" id="10000039" />
<node icon="/images/fl/node.gif" name="80.130" id="10000098" />
<node icon="/images/fl/node.gif" name="80.13" id="10000100" />
<node icon="/images/fl/node.gif" name="http://www.163.com" id="10000102" />
<node icon="/images/fl/node.gif" name="http://www.abc.com" id="10000103" />
<node icon="/images/fl/node.gif" name="http://www.dd.2" id="10000104" />
</node>
</node>
</Tree>
<alarms>
<alarm logTime="2011-12-18 14:13:19" status="严重" alarmImage="/images/fl/status1.gif" group="监视器组" content="资源MyGroup为停止. 根本原因:资源停止. 资源www.abc.com不可用。Host Unavailable:响应码 -200资源停止. 资源dd不可用。Host Unavailable:响应码 -200资源停止. 资源163.com不可用。Host Unavailable:响应码 -200" alias="MyGroup" />
<alarm logTime="2011-12-18 13:55:44" status="严重" alarmImage="/images/fl/status1.gif" group="Url监视器" content="资源停止. 资源dd不可用。Host Unavailable:响应码 -200" alias="dd" />
<alarm logTime="2011-12-18 13:55:44" status="严重" alarmImage="/images/fl/status1.gif" group="Url监视器" content="资源停止. 资源www.abc.com不可用。Host Unavailable:响应码 -200" alias="www.abc.com" />
<alarm logTime="2011-12-18 08:20:25" status="严重" alarmImage="/images/fl/status1.gif" group="Url监视器" content="资源停止. 资源163.com不可用。Host Unavailable:响应码 -200" alias="163.com" />
</alarms>
</BusinessView>
解析例子
<?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" creationComplete="{complete()}">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.shine.framework.core.util.BaseHttpServiceUtil;
import com.shine.framework.core.util.XMLArrayCollection;
import com.shine.framework.core.util.XmlModelArrayCollection;
import mx.controls.Alert;
private var testXmlModelArrayCollertion:XMLArrayCollection=null;
private function complete():void{
//远程加载xml
var httpUtil:BaseHttpServiceUtil=new BaseHttpServiceUtil;
httpUtil.getResultXml("xml/1.xml",xmlResult);
}
private function xmlResult(xml:String):void{
//解析所有的Node节点
testXmlModelArrayCollertion=new XMLArrayCollection;
testXmlModelArrayCollertion.saxXmlNodeByTag(XML(xml),["Node"]);
Alert.show(testXmlModelArrayCollertion.getBaseXMLModel(0).getString("image"));
}
]]>
</fx:Script>
</s:Application>
如果希望了解更多相关内容,请查看svn代码
svn地址:http://code.google.com/p/ken-javaframeword/source/browse/#svn%2Ftrunk%2Fframework2.0