Need to convert ActionScript object to XML.
Serializing complex cross-referenced nested structures is not a trivial task, but writing serializer for converting simple objects is easy.
Our core tool will be Flash utility function flash.utlis.describeType()
describeType() takes any kind of data type as argument and returns its description in XML format.
public function get revenue():Number{
public function set revenue(value:Number):void {
Notice that some properties are accessed directly and others are defined over getter/setter functions.
Call to describeType(new Client()) would return us this:
<type name="org.zgflex.dto::Client" base="Object" isDynamic="false" isFinal="false" isStatic="false">
<extendsClass type="Object"/>
<variable name="name" type="String"/>
<variable name="contacted" type="Boolean"/>
<accessor name="revenue" access="readwrite" type="Number" declaredBy="org.zgflex.dto::Client"/>
<accessor name="age" access="readonly" type="int" declaredBy="org.zgflex.dto::Client"/>
<variable name="id" type="Number"/>
<variable name="mainProduct" type="org.zgflex.dto::Product"/>
</type>
This output gives us a detailed description of Client class: qualified class name, what class it extends, list of variables and their types and so on.
It's important to notice that directly accessed variables have description inside <variable/> tags, and those accessed over getter/setter functions are described inside <accessor/> tags.
Now, all we have to do is iterate through these XML nodes to get variable names, read their values from object and write them down into XML.
Here's a simple example that illustrates solution. It supports serialization of nested objects and simple types, but in order to keep example simple, it doesn't support arrays and collections.
package org.zgflex.dto
import flash.utils.describeType;
import mx.utils.ObjectUtil;
public class ReflectionConverter
public function marshal(source:Object):XML
var writer:XMLWriter=new XMLWriter();
var objDescriptor:XML=describeType(source);
var property:XML;
var propertyType:String;
var propertyValue:Object;
var qualifiedClassName:String=objDescriptor.@name;
foreach(property in objDescriptor.elements("variable")){
propertyValue=source[property.@name];
if (propertyValue!=null){
if (ObjectUtil.isSimple(propertyValue)){
writer.addProperty(property.@name, propertyValue.toString());
}
else {
And that's it. This code will serialize any custom class and return XML representation of it. As a bonus, it goes recursive for any custom object found inside.
This code works only for directly accessed properties. See attached sources to see how it extends for getters/setters.
This is an output sample:
<org.zgflex.dto.Client>
<name>John</name>
<contacted>true</contacted>
<id>57</id>
<mainProduct>
<org.zgflex.dto.ServiceProduct>
<departmentID>1</departmentID>
<name>Cleaning</name>
<id>2</id>
</org.zgflex.dto.ServiceProduct>
</mainProduct>
<revenue>NaN</revenue>
</org.zgflex.dto.Client>
And here's a simple util class for writing XML:
public function addProperty(propertyName:String, propertyValue:String):XML {
var xmlProperty:XML=<new/>
xmlProperty.setName(propertyName);
xmlProperty.appendChild(propertyValue);
xml.appendChild(xmlProperty);
return xmlProperty;
}
}
}
Sources attached to this cookbook entry contain working demo.
If you have higher demands than this simple example can cover, there are several open source ActionScript XML serializers you can check out.
One of them is asx3m (http://code.google.com/p/asx3m).