1

ActionScript-3

I have an XML string that represents an object of any type (matrix of strings and primitives). I need to get the object / matrix out of the string.

// I have:
var xml: String = "<?xml version="1.0" encoding="utf-16"?><ArrayOfArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <ArrayOfAnyType>    <anyType xsi:type="xsd:string">TEXT</anyType> ....... </anyType></ArrayOfAnyType></ArrayOfArrayOfAnyType>"

// I need:
var obj: Object = ???;
// or in the end:
var array: Array = ???;
  • How do I deserialize a string to object ?
  • How do I serialize any object to string ?


Update:

  • I took a look at the children() list of new XML(str); object and I could trace() the values. So I could go by hand and iterate the lists to get my matrix but can't flash do that by itself ?

Update 2:

  • I'm not using Flex
  • my matrix also contains DateTime values, so type attribute must be used as accurate as possible.
  • In order to deserialize the strings that I get I did what I wrote in the 1st update.
    • Because of namespaces I couldn't get hold of the type attribute that is very important for me.
    • So I killed all namespace garbage to get something like this:
    • <anyType type="string">blah blah</anyType>
      • I manipulated attribute-strings to kill the "xsi:" and "xsd:" garbage
    • then I just iterated and build up the matrix I wanted.
  • the question in not resolved though, I wished there would be a better way of doing this.
4
  • Seems like you need to write your specific parser/translator Commented Nov 5, 2013 at 16:41
  • @Cherniv Really ? C# serialized a matrix to this string and it can easily deserialize it. Why would Flash not be able to do it ? Commented Nov 5, 2013 at 16:48
  • Are you looking for another answer, or has the issue been resolved? Commented Nov 7, 2013 at 14:32
  • @Atriace Sorry, no it's not resolved (at least not here). Maybe it's the a strange xml format ? But C# serialized my matrix the common way actually. For deserializing I used neither of your suggestions, see my update 2. Commented Nov 7, 2013 at 14:59

1 Answer 1

1

If you're using Flex, you can tap into SimpleXMLDecoder

function toObj(data:XML):Object {
    var xmlDoc:XMLDocument = new XMLDocument(data);
    var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
    return decoder.decodeXML(xmlDoc);
}

function toXML(obj:Object):XML {
    var qName:QName = new QName("root");
    var xmlDoc:XMLDocument = new XMLDocument();
    var simpleXMLEncoder:SimpleXMLEncoder = new SimpleXMLEncoder(xmlDoc);
    var xmlNode:XMLNode = simpleXMLEncoder.encodeValue(obj, qName, xmlDoc);

    return new XML(xmlDoc.toString());
}

If, like me, you aren't using Flex and its API, here's a pure AS3 method for converting to Object which I wrote. This only covers going to an Object; I've never needed to serialize to a string.

function translateXML(xml:XML):* {
    /*  Created by Atriace: Converts XML into an Object, with nested arrays, and relevant object types.
        Useful if you find AS3's XML methods an asinine waste of time. */
    var data:XMLList = xml.children();
    var store:Object = mineAttributes(xml.attributes()), item, key:String;

    if (hasTwo(data)) { // should this be an object or array?
        for each (item in data) {  // we store arrays by the name of the array
            key = item.name();
            if (store[key] == null) {
                store[key] = new Array(); // and then the contents inside that array
            } else if (getType(store[key]) != "Array") {
                trace("store[" + key + "] = " + store[key] + ":" + getType(store[key]));
            }
            store[key].push(translateXML(item));
        }
    } else { // Assuming there were no repeating elements at the beginning, we create unique objects
        for each (item in data){ 
            key = item.name();
            if (key == null) {  // Assuming we have an encapsulated string, we add a tag called "content" with its value.
                store["content"] = item.toString();
            } else {
                store[key] = translateXML(item);  // Otherwise, we recursively loop into the nested objects.
            }
        }
    }
    return store;
}

function hasTwo(data):Boolean {
    /* Determines whether there are two of the same object name at the beginning of a list. */
    var answer:Boolean = false;
    var original;
    var i:int = 1;
    for each (var k in data) {
        if (i == 2) {
            if (original == k.name()) {
                answer = true;
            }
            break;
        } else {
            original = k.name();
        }
        i++
    }
    return answer;
}

function mineAttributes(data:XMLList):* {
    /* Returns all the attibutes of an XML node */
    var d:Object = {}, key:String, val:String;
    for each (var item in data){
        key = item.name();
        val = item;
        d[key] = val;
    }
    return d;
}

function getType(value:*):String {
    // Returns the type of object passed to it.
    var msg:String = flash.utils.getQualifiedClassName(value);
    if (msg.lastIndexOf("::") != -1) {msg = msg.split("::")[1];}
    return msg;
}
Sign up to request clarification or add additional context in comments.

1 Comment

This class is not defined by AIR but by Flex 3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.