Products
Technologies

Developer resources

Serializing object to XML

Avg. Rating 1.7

Problem

Need to convert ActionScript object to XML.

Solution

Serializing complex cross-referenced nested structures is not a trivial task, but writing serializer for converting simple objects is easy.

Detailed explanation

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.

 
Let's say we have objects:
 
package org.zgflex.dto
{
      public class Client
      {
            private var _age:int;
            private var _revenue:Number;
           
            public var id:Number;
            public var name:String;
            public var contacted:Boolean;
            public var mainProduct:Product;
           
            public function get age():int{
                  return _age;
            }           

            public function get revenue():Number{

                  return _revenue;
            }    

            public function set revenue(value:Number):void {

                  _revenue=value;
            }
      }
}
 
package org.zgflex.dto
{
      public class Product
      {
            public var id:Number;
            public var name:String;
      }
}
 

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 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;

                  qualifiedClassName=qualifiedClassName.replace("::",".");
                  writer.xml.setName(qualifiedClassName);                 

                  foreach(property in objDescriptor.elements("variable")){
                        propertyValue=source[property.@name];

                        if (propertyValue!=null){
                             if (ObjectUtil.isSimple(propertyValue)){
                                   writer.addProperty(property.@name, propertyValue.toString());
                             }
                             else {

                                   writer.addProperty(property.@name, (new ReflectionConverter).marshal(propertyValue).toXMLString());
                             }                                 
                        }                           
                  } 
                  return writer.xml;
            }
      }

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:

package org.zgflex.dto
{

 

public class XMLWriter
{
            public var xml:XML;
           
            public function XMLWriter()
            {
                  xml=<obj/>;
            }       

            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).



 

SimpleSerializer.zip
[Simple AS3-XML de/serializer]
Report abuse

Related recipes