JSON manipulation pack

herby

  • Posts: 124
Published as "JSON" at the Forge.

Allows to read and modify JSON strings.

It is mainly useful to parse JSON responses from web services using the do http request and then do ... block, but you can as well use it to store ad-hoc structures in a single attribute instead of using lots of them, and for communicating such structured data between blocks.

I wanted to make it a simple behaviour, but I had to implement it as a resource pack by embedding JSON package classes' source codes into code behaviour and making the use of it public through custom blocks in the design behaviour. I was counselled as to make it this way, since, presently, Stencyl cannot make custom blocks directly in code behaviour.

This pack is mainly aimed at read/write of the first two levels of the JSON structure easily (that is, directly). This should be enough for majority of simple structures. You could, however, read the sub-structure from one or two levels deep and work subsequently on it alone, so you eventually can reach / modify deeper levels, too; but here, "make simple things simple, make hard things hard" was emphasized so no direct access to arbitrary level is present (yet).

niccosw

  • Posts: 91
Yikes! This is quite complex stuff. I'll try to play with it over the next week and give you some feedback. Thanks for making it!

BTW: You already taught me something about coding for Stencyl. I had no idea you could put multiple classes in code mode. I thought you needed to create multiple behaviors (which is probably confusing for users). Thanks for the tip!

herby

  • Posts: 124
I just googled it over somewhere... it was my first AS3 code (I heartfully hate static typing, so I hope I need as little actual AS3 coding as possible); the rule is, only one public class inside package, and then you can put more classes out of package, nonpublic, but they will only be file-visible.

cman

  • Posts: 14
Why is this useful??

Joe

  • *
  • Posts: 2478
Why is this useful??

As he says, it's mainly useful for talking to web servers that use JSON. Here's an example.

DoctorMikeReddy

  • *
  • Posts: 180
Could you give me an example of how to extract items from the JSON file after getting a response from a web site, such as the one given above.

Joe

  • *
  • Posts: 2478
Could you give me an example of how to extract items from the JSON file after getting a response from a web site, such as the one given above.

The example above returns a string that looks like this:

Code: [Select]
{"ip":"xxx.xxx.xxx.xxx"}
If you wanted to extract and print the IP address to the console, you would do something like this:


DoctorMikeReddy

  • *
  • Posts: 180
That is very helpful. Thanks. So JSON <data> AT <tag> gives the property (in this case the IP address) tagged by "ip"

<data> being {"ip":"xxx.xxx.xxx.xxx"}

I must admit to being perplexed by most of the other custom json functions. I guess I'll get there eventually, but this is a start.

DoctorMikeReddy

  • *
  • Posts: 180
for example, how would I parse:


{
   "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"
                }
            }
        }
    }
}

DoctorMikeReddy

  • *
  • Posts: 180
Here is my first attempt at trying to unravel the above json data file. There must be a way to deal with these in a for loop with a conditional to tell if a data item is data or an embedded json structure, surely? I'm guessing it's the custom objects related to lists that are currently taunting me.

Joe

  • *
  • Posts: 2478
The pack doesn't appear to have a block to easily do that, but it would be a nice suggestion. Presumably you have to know the full format of the JSON when you pull it down. You can, however, tell if the item is a list or not by using that custom "as list" block. It will return null if the text can't be interpreted as a list.

If you want to pull out a bunch of (top-level) properties, one more efficient way would be to do something like in the attached screenshot. You could do similar loops for sub-properties.

Also, as a note, the JSON blocks are global custom blocks, which means they are accessible in any Behavior; you don't have to put them in the same Behavior as the block definitions.

« Last Edit: September 03, 2011, 12:06:44 pm by Joe »

DoctorMikeReddy

  • *
  • Posts: 180
OK, I will play with that. Thanks. You are right about needing the structure in advance, but would it be possible to extract the first item (the index) from the list using string operators, then recursively peeling down the list each time: if a simple atom, store it, if a list then process in a nested fashion?

DoctorMikeReddy

  • *
  • Posts: 180
I'm really annoyed with myself now. I found a post earlier today where they extracted data using string manipulation and used the jsonip.com data as an example. Can I find it now? No.
Argh!

Joe

  • *
  • Posts: 2478
I think I posted that. :P That was a trivial case, though, because the IP address always starts at the same position in the string.

You could parse through the JSON yourself using string manipulation, but then you're basically reimplementing herby's script, which appears to have a tokenizer and parser embedded inside it. You may want to try getting in touch with him to see if he wants to extend the functionality -- basically you want a way to make the property list iterable, so you can pump it through a "for each item" block.

Out of curiosity, what's the use case for needing to parse the whole tree?

DoctorMikeReddy

  • *
  • Posts: 180
The case? If you imagine parsing a sentence that has been encoded using standard language notation such as:

   IP
  /  \
NP    VP
|     | \
N     V  \
|     |   PP
She   is /  \
        /    \
        P     NP
        |    /  \
        on  Det  N
            |    |
            the  computer

It is likely that strong rules can be encoded, but the end structure being quite different each time. This is also useful for generating text.

I'd be really interested in Stencyl code block examples for parsing the following:

{
   "staff":
   [
      {
         "firstName":"John",
         "lastName":"Parker",
         "age":"32",
         "country":"Canada",
         "job":"Programmer"
       },

       {
         "firstName":"Peter",
         "lastName":"Anderson",
         "age":"30",
         "country":"USA",
         "job":"System administrator"
       },

       {
         "firstName":"Bob",
         "lastName":"Johnson",
         "age":"35",
         "country":"Canada",
         "job":"Coder"
       }
   ]
}

It might also be possible for JSON data to use the same identifier multiple times, and I'm not sure what the Stencyl code would do with { "ip":"1.1.1.2", "ip":"1.1.1.3"} when looking for "ip"