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



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
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.
Guido Sarduchi,
Can you please log a bug with a simple, reproducible test case at http://bugs.adobe.com/flex/.
Also, if you post the bug number here, I can vote on the issue and subscribe.
Thanks,
Peter
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.
Well, I found my solution.
…this worked for me:
arrColl[i]=[
{
c1: “1.A”,
c2: “1.B”
}
];
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.
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?
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); } }Keith H,
Thanks. You can file Flex bugs/enhancement requests at: http://bugs.adobe.com/flex/
If you post the bug number here, perhaps a few of us can subscribe and/or vote on the issue.
Peter
Thanks Peter. Will do…
Once again, great blog and your snippets have saves me more than once.
Great blog, and the code above works great as is, but
I’m clearly missing something here:
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?
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
xmlDocumentinstance. 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