ActionScript 3 (AS3) JSON encoder with “pretty” output by adding linefeeds and spaces


I’m sure many ActionScript 3 or Flex developers have used the as3corelib for one reason or another. It’s a wonderful little library with lots of useful functionality. I’ve frequently used its JSONĀ  encoding and decoding functionality. It works great, however, it doesn’t add spaces or linefeeds to make the resulting JSON string more readable. That’s fine if you are just serializing something to send over the wire but not if you want it to render something that is easily read by a human. In my case, I want a user to actually be able to edit the resulting JSON. To make this workable, I needed a JSON encoder that would add appropriate linefeeds and spaces. Rather than write my own, I simply adapted the one in as3corelib.

One side benefit of having done this is that you can now get JSON serialization without getting the entire as3corelib library.

The default interface is identical to the one in as3corelib. If you just call JSON.encode(my_object), it will behave almost exactly like the one in as3corelib. I say “almost” because my version add a space after each “:” and “,” even in default mode. Update: I’ve changed it so it behaves exactly like the serializer in as3corelib so no extra spaces are added unless you use the optional parameters described below.

If you want linefeeds and truly “pretty” output, you can add an optional second parameter, like so JSON.encode(my_object, true). This will cause any array [ ] or object { } that would be longer than 60 characters to wrap to newlines, which works out about right for my purposes.

You can also adjust the maximum line length with an optional third parameter, like this JSON.encode(my_object, true, 10). This will cause any line above 10 to wrap. If you want every array [ ] and object { } to wrap, just use any number 2 or lower in this third parameter. If you want it to wrap everything but empty objects or arrays, use 3 for this parameter.

Let’s see it in action.

package
{
    import com.maccherone.json.JSON;
    import flash.display.Sprite;    
 
    public class Tester extends Sprite
    {
 
        public function Tester()
        {
            var obj1:Object = {
                commit: {file: "commit.xml"},
                commit_detail: {file: "commit_detail.xml"},
                file: {file: "file.xml"},
                person: {file: "person.xml"},
                count: [1, 2, 3]
            }
            trace("Just like as3corelib (no line feeds or spaces):\n" + JSON.encode(obj1) + "\n");
            trace('"Smart" linefeeds:\n' + JSON.encode(obj1, true) + "\n");
            trace("Only allow short lines:\n" + JSON.encode(obj1, true, 10) + "\n");
 
            var obj2:Object = {
                "glossary": {
                    "title": "example glossary",
                    "GlossDiv": {
                        "title": "S",
                        "GlossList": {
                            "GlossEntry": {
                                "ID": "SGML",
                                "SortAs": "SGML",
                                "GlossTerm": "Standard Generalized Markup Language",
                                "Acronym": "SGML",
                                "Abbrev": "ISO 8879:1986",
                                "GlossDef": {
                                    "para": "A meta-markup language, used to create markup languages such as DocBook.",
                                    "GlossSeeAlso": ["GML", "XML"]
                                },
                                "GlossSee": "markup"
                            }
                        }
                    }
                }
            }
            trace("A bigger example from JSON.org:\n" + JSON.encode(obj2, true));
        }
    }
}

The above code would result in the following output:

Just like as3corelib (no line feeds or spaces):
{"file":{"file":"file.xml"},"commit":{"file":"commit.xml"},"commit_detail":{"file":"commit_detail.xml"},"person":{"file":"person.xml"},"count":[1,2,3]}
 
"Smart" linefeeds:
{
    "file": {"file": "file.xml"},
    "commit": {"file": "commit.xml"},
    "commit_detail": {"file": "commit_detail.xml"},
    "person": {"file": "person.xml"},
    "count": [1, 2, 3]
}
 
Only allow short lines:
{
    "file": {
        "file": "file.xml"
    },
    "commit": {
        "file": "commit.xml"
    },
    "commit_detail": {
        "file": "commit_detail.xml"
    },
    "person": {
        "file": "person.xml"
    },
    "count": [1, 2, 3]
}
 
A bigger example from JSON.org:
{
    "glossary": {
        "GlossDiv": {
            "GlossList": {
                "GlossEntry": {
                    "GlossSee": "markup",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "ID": "SGML",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "Abbrev": "ISO 8879:1986",
                    "Acronym": "SGML",
                    "SortAs": "SGML"
                }
            },
            "title": "S"
        },
        "title": "example glossary"
    }
}

Note that (unlike XML) the order of the elements in a JSON object { } is indeterminant. Of course the order of an array [ ] is preserved.

You can download it from here.

 

This entry was posted in Code, Flex/Flash/ActionScript and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Spam Protection by WP-SpamFree