Friday, February 13th, 2009

ActionScript XML Binding

By Andy Lewisohn

Marshaling and Unmarshaling, Serializing and Deserializing, Encoding and Decoding, whatever you prefer to call it, converting XML to an ActionScript object and back again can be a real chore. It’s a process that typically involves a lot of code to manage the points of connection between the AS object and the underlying XML representation. I’ve utilized various solutions to this problem in different projects: manipulating XML as the object changes via getters/setters, updating the XML in a bulk process with a toXML() function, or sometimes a combination of both. None of these solutions ever felt quite right. But short of convincing every backend developer that I work with to implement an AMF API, I couldn’t come up with a viable solution. I was stuck writing code to perform tasks that I didn’t think should be a part of my application’s core functionality.

Being a developer, and therefore lazy, I didn’t want to write my own library to perform marshaling/unmarshaling if someone else had already done so. I started searching on Google Code and Source Forge, and I found a couple of projects that did kind of what I wanted, but not exactly. FlexXB and FlexB were close, but I decided to write my own implementation.

So that brings us to ActionScript XML Binding (ASXB), which, while not a pure ActionScript implementation, could become one quite easily. Only a few classes from the Flex framework are utilized and are mostly logging classes. The other important Flex framework class is the mx.rpc.http.HTTPService, which I’ve extended as both a class to be instantiated in ActionScript (org.orpheus.xml.bind.XMLService) and an MXML extension (org.orpheus.xml.bind.mxml.XMLService). The XMLService class provides automatic handling of XML/ActionScript encoding and decoding.

This is the 0.1 release of ASXB, give it a try, and let me know what you think.

5 Responses

  1. William Lepinski said:

    How about nested objects classes?
    package
    {
    [XmlRootElement(name="book")]
    public class Book
    {
    [XmlElement]
    public var author:Author;
    [XmlAttribute(name="dateOfPublication")]
    public var dateOfPublication:Date;
    [XmlAttribute(name="pageCount")]
    public var pages:int;
    [XmlElement]
    public var title:String;
    }
    }
    I’m getting the following faultEvent:
    [FaultEvent fault=[RPC Fault faultString="Error #1023: Stack overflow occurred." faultCode="Client.CouldNotMarshal" faultDetail="null"] messageId=null type=”fault” bubbles=false cancelable=true eventPhase=2]

  2. Christopher Stokes said:

    Thanks for the code & the generous licensing.
    I am trying to convert this code to something fit for our project. It will basically be XML Schema -> AS3 class objects that are annotated along the same lines as this code.
    Will keep you posted if it goes anywhere…
    Is there a way to contribute back to this project? I did not see a SCM link anywhere.
    Thanks!
    Chris

  3. jonathan said:

    What were the problems with FlexXB that prompted you to write this?
    I’m just wondering as i’m in the process of choosing an xml mapping library.
    The only thing i see is the service layer, but that’s pretty easy to implement on my own.
    Does this do something xml-wise that flexXB doesn’t?

  4. Udy said:

    I find this tool useful; pretty simple when compared to as3httpclient in terms of sending XML packets. Having the binding annotated helps the coding process.
    I find that the POST request works with ASXB, but the GET, PUT, DELETE don’t even reach the RESTlet.
    Any ideas, will help? As well, what do you think is the roadmap of this library? Do you think you’ll expose the code for contribution? Let me know.
    Sample code:
    private function runRESTful(cmd:String):void{
    var xs:XMLService = new XMLService();
    xs.url = “http://localhost:8080/rest/demo/” + cmd.toLowerCase();
    xs.method = cmd.toUpperCase();
    xs.resultFormat = HTTPService.RESULT_FORMAT_E4X;
    xs.addEventListener(FaultEvent.FAULT, faultHandler);
    xs.addEventListener(ResultEvent.RESULT, resultHandler);
    }
    private function demoRESTful(){
    runRESTful(“get”);
    runRESTful(“post”);
    runRESTful(“delete”);
    runRESTful(“put”);
    }

  5. Jimmy Royer said:

    Does your framework also supports the various techniques that JAXB has for handling cyclic references? More specifically, I’m interested into the after unmashalling callback that is provided by JAXB via the afterUnmarshal method:

    https://jaxb.dev.java.net/guide/Mapping_cyclic_references_to_XML.html

    Thanks,
    Jimmy

Leave a Comment