Converting objects to XML packets using the SimpleXMLEncoder class in Flex

In a previous example, “Converting XML to objects using the Flex SimpleXMLDecoder class”, we saw how to convert an XML instance into an Object instance using the SimpleXMLDecoder class and decodeXML() method.

The following example shows how you can convert an array of objects into an XML object using the SimpleXMLEncoder class and encodeValue() method in Flex.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/03/04/converting-objects-to-xml-packets-using-the-simplexmlencoder-class-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();">

    <mx:ArrayCollection id="arrColl">
        <mx:source>
            <mx:Array>
                <mx:Object c1="1.A" c2="1.B" />
                <mx:Object c1="2.A" c2="2.B" />
                <mx:Object c1="3.A" c2="3.B" />
                <mx:Object c1="4.A" c2="4.B" />
                <mx:Object c1="5.A" c2="5.B" />
                <mx:Object c1="6.A" c2="6.B" />
            </mx:Array>
        </mx:source>
    </mx:ArrayCollection>

    <mx:Script>
        <![CDATA[
            import mx.rpc.xml.SimpleXMLEncoder;
            import mx.utils.ObjectUtil;

            private function init():void {
                var xml:XML = objectToXML(arrColl.source);
                textArea1.text = ObjectUtil.toString(arrColl.source);
                textArea2.text = xml.toXMLString();
            }

            private function objectToXML(obj:Object):XML {
                var qName:QName = new QName("root");
                var xmlDocument:XMLDocument = new XMLDocument();
                var simpleXMLEncoder:SimpleXMLEncoder = new SimpleXMLEncoder(xmlDocument);
                var xmlNode:XMLNode = simpleXMLEncoder.encodeValue(obj, qName, xmlDocument);
                var xml:XML = new XML(xmlDocument.toString());
                // trace(xml.toXMLString());
                return xml;
            }
        ]]>
    </mx:Script>

    <mx:HDividedBox width="100%" height="100%">
        <mx:TextArea id="textArea1"
                editable="false"
                width="100%"
                height="100%" />
        <mx:TextArea id="textArea2"
                editable="false"
                width="100%"
                height="100%" />
    </mx:HDividedBox>

</mx:Application>

View source is enabled in the following example.

16 thoughts on “Converting objects to XML packets using the SimpleXMLEncoder class in Flex

  1. for a project i wrote this.

    this retrieve a description of a single object and after i call it in recursive way.

    /**
     *
     * describe an object in xml way
     * */
    private function objectToXML( sourceObj:Object):XML {
    
        if(!sourceObj) return null
    
        //-- get class info
        var calssInfo :Object =  ObjectUtil.getClassInfo( sourceObj );
        var xml : XML =
    
        //-- for each property
        for each (var propQName : QName in calssInfo.properties){
            var propValue : Object = sourceObj[ propQName.localName ];
    
            var node :XML =
            node.@name = propQName.localName;
            node.@type = flash.utils.getQualifiedClassName( propValue ) ;
    
            //-- append
            xml.appendChild( node ) ;
    
        }
    
        return xml;
    }
    

    the result is like

    hope helpful

  2. I keep seeing occurrences of the tag “true” which breaks the XML parser and generates an error. Guess I can just strip it out of the XMLDocument before converting XML.

  3. What about if we have a multidimensional array created from Actionscript?

    How would we provide titles inside the Array (similar to your mx:object c=”?”) so it doesn’t simple output “item” for each XML tag.

    Thanks again for the great example.

  4. one small question:

    The above example that I gave will output

    1.A
    1.B

    What’s up with the double item? How can this be removed?

    Andrew.

  5. First off your blog rocks and it is the Flex bible as far as I am concerned.

    I am using the SimpleXMLEncoder class to covert objects to XML. All is well except when dealing with types Array Collections.

    If I have an array of objects who themselves have their own types, the XML that the encoder generates refers to them as items, not the type of the object within the array. Here is an example.
    Here is what I want….

    <campuses>
    <campuse_choice>
         properties here......
    </campuse_choice>
    </campuses>
    

    What i get is…..

    <campuses>
         <list>
           <source>
               <item>
               </item>
           </source>
         </list>
    </campuses>
    

    I looked in the SimpleXMLEncoder class and I see the line (152) that converts them to items. any way to have it pick up the object types within the ArrayCollection?

  6. I came up with a nasty workaround here….but it works.
    I created a non-framework copy of the SimpleXMLEncoder, renamed it and changed all the internal references. I change the conditional on or around line 151 to the following….

    I am thinking this is a bug and I will attempt to submit to Adobe.

        else if (typeType == CustomXMLEncoder.ARRAY_TYPE) {
            var numMembers:uint = obj.length;
            // var itemQName:QName = new QName("", "item");
    
            for (var i:uint = 0; i  0) {
                var className:String = classNameArray[classNameArray.length -1];
                itemQName = new QName("", className.toLowerCase());
            }
            else itemQName = new QName("", "item");
    
            encodeValue(obj[i], itemQName, myElement);
        }
    }
    
    1. Keith H
      Peter D,

      This is a great fix. And yes a very annoying “Bug” in Adobes Sources.
      I was wondering did anyone mention this to the Adobe Team (Tracker)

      Was this fixed, yet?

      Regards

  7. Great blog, and the code above works great as is, but
    I’m clearly missing something here:

    var xmlDocument:XMLDocument = new XMLDocument();
    var simpleXMLEncoder:SimpleXMLEncoder = new SimpleXMLEncoder(xmlDocument);
    var xmlNode:XMLNode = simpleXMLEncoder.encodeValue(obj, qName, xmlDocument);
    var xml:XML = new XML(xmlDocument.toString());
    

    xmlDocument is in the first line, and gets referred to in the last line, but the objects simpleXMLEncoder and xmlNode do not get used. Why not simply use the first line and the last line? What additional work is happening in the middle two lines?

  8. Paul B. Hartzog,

    Correct, it doesn’t look like I use the XMLNode reference returned by the simpleXMLEncoder.encodeValue() method.
    I haven’t looked at this code in a long time, but here’s what I think is happening:
    1) The first line creates a new XMLDocument object.
    2) The second line creates a new SimpleXMLEncoder object and passes the XMLDocument object created in on the first line. I believe the SimpleXMLEncoder constructor sets the empty XMLDocument object as the root XML node.
    3) The third line calls calls the encodeValue() method on the SimpleXMLEncoder object which “encodes an ActionScript object to XML using default serialization”. According to the comments in the source code, the first parameter (obj) is “the ActionScript object to encode”, the second parameter (qName) is “the qualified name of the child node”, and the third parameter (xmlDocument) is “an XMLNode under which to put the encoded value”.
    4) The fourth line converts the XMLDocument object to an XML object.

    So, if you only used the first and last line, you’d always have an empty XML object. The second line creates a SimpleXMLEncoder instance which gets used in the third line to covert the specified Object and insert it into the xmlDocument instance. I’m guessing the magic that is happening is that the SimpleXMLEncoder is directly modifying the XMLDocument object, which is why I didn’t need to use the returned XMLNode object from line 3.

    If you want to see exactly what happens in the SimpleXMLEncoder class, you can check out the source code in the installed SDKs /frameworks/projects/rpc/src/mx/rpc/xml/SimpleXMLEncoder.as file.

    Peter

  9. I have a custom object and I want only some of its properties to be encoded to xml. Is there a way I can tell the encoder which properties to encode and which ones to ignore?

  10. Hi!
    Great job!
    But… Does it works also for private attributes?
    ‘Cause I’m trying to encode some classes in XML and if they have private attributes and references to other classes it doesn’t work… How could I fix this problem?
    Any ideas?
    Thanks so much in advance.

Comments are closed.