Help parsing JSON file

I have a file - gardenPlanner.json which contains the following:

[ { "WindowTitle":"Garden Layout" }, { "iconName":"beetroot24", "caption":"Beetroot", "top":71, "left":492 }, { "iconName":"broadbean24", "caption":"Broad Beans", "top":66, "left":544 }, { "iconName":"cabbage24", "caption":"Cabbage", "top":106, "left":599 } ]

That is a snippet from it.

I just cannot figure out how to create a Xojo Array or Dictionary from it. Any help would be appreciated. I have downloaded and am using Kem’s JSONItem_MTB class. This is a Desktop project, not Web.

I know that the first item in the file is “WindowTitle”:“Garden Layout” I am thinking I should remove that and save it in another file.

I haven’t worked with Kem’s class yet, but I understand it is a drop-in replacement so the following code should be of some help?

Sub ParseData(jsonStr As String)
  Dim root As new JSONItem(jsonStr)
  Dim i As Integer
  
  i = 0
  while i < root.Count
    if root.Child(i).Lookup("WindowTitle", "") <> "" then

      // do something with title
      MsgBox "WindowTitle: " + root.Child(i).Lookup("WindowTitle", "")
      
    else
      
      // add vegetable to array
      MsgBox "Vegetable: " + root.Child(i).Lookup("iconName", "")
      
    end if
    i = i + 1
  wend
End Sub

Hi Alwyn,

Thanks for that. I will certainly make a note of that method for future use, but I have decided to use a database instead. The reason being is that I have to also store all the pictures involved, and I couldn’t figure out how to do that using JSON. The pictures are only small 24x24 icons, so are only 3KB each. I am going to store them in a BLOB field of an SQLIte database.

Your time in replying with the above code snippet will not be lost. I have spent a fair bit of time looking at the JSON methods, and it will come in handy for other Preference uses in the future.

You could attach pics with EncodeBase64 in JSON. I haven’t done this before but it might work without problems as the icons are small in size.

Cool. For the right scenarios JSON can sometimes be a very convenient format to use.

JSON is very simple to read, once you know what to look for. It always starts with “[” or “{”, and those indicate the type of structure. “{}” is used to enclose an “object”, which is equivalent to a case-sensitive Dictionary in Xojo. “[]” is used for an array, which is an array of Variant. The type of values accepted are string, double. integer, and boolean (true or false).

Because there are only two types of structures, every populated JSONItem is either as an array or an object, and you’d use them that way.

In your case, the main structure is an array, and each element happens to be an object (Dictionary), so some code like this will work for you:

dim j as new JSONItem_MTC( jsonString )

dim ub as integer = j.Count - 1
for i as integer = 0 to ub
  dim child as JSONItem_MTC = j( i )
  if child.HasName( "WindowTitle" ) then
    // do something with WindowTitle

  elseif child.HasName( "iconName" ) then
    // do something with that child

  end if
next

(I haven’t tested this.)

Clarification: A “value” can also be another JSON object or array. In your case, that JSON describes an array of objects.

The problem I am finding in all of this (whether I use JSON or even a database, I think) is that I have imported the 16x16 and 24x24 pngs into my Project (just like the sample project from Paul). Now when I save the iconName to either JSON or a database, it is a string. When I try to recreate the canvas object and use that string to create the actual icon, I get an error: Parameters are not compatible with this function". Now, I totally understand why I get that error, because I am supplying a string to a method that is expecting a Picture. But I don’t know how to supply a picture.

To get the error I am supplying this to the Method:

DrawingCanvas.RestoreObjects(699, 470, "garlic24", "Garlic")

It works OK if I supply this:

DrawingCanvas.RestoreObjects(699, 470, garlic24, "Garlic")

So I have to somehow store the “icon” as a Picture, or somehow Cast the String to a Picture.

This is the most complicated thing I have tried to do with Xojo, and I am afraid I am well past the extent of my knowledge.

I am thinking of the following:

I would still pass to the Method the picture as a string. In the Method I am going to try the following:

Select Case icon
Case "garlic24"
  mIcon = garlic24
Case "cabbage24"
mIcon = cabbage24
....
End Select

Anyway, I will give it a try later (have to go out and vote in our General Election right now. If that doesn’t work, then I am not sure what will, but I am sure there must be a way to store to file an image that can then be recreated next time the app starts up.

Thanks for all the help - I am learning heaps.

Look at the LR under Picture.FromData.

I think the problem is not that he has the picture data but that he has the name of the picture and needs a reference to the item in the project

Were the data for the image in the json then that’d be the right thing to do to restore it

Arrrgh, that’s getting so far from what I understand. In the LR, the example is an image contained in an ImageWell and then it is copied into a Memory Block (that sounds scary enough!).

So, I guess it is possible to get a Picture.FromData from a Canvas, and then store that in a JSONItem? Then, if I can figure that out how do I get the data from the JSONItem back into the Canvas when the app is launched? Is there a tutorial or LR reference about all these extra steps?

I really am sorry if I am coming across as being a bit dense, but when we start talking of Memory Blocks, etc, then I am getting lost. (Perhaps I am biting off more than I can chew with this program?) Also, I guess, if I get the Picture Data into the JSON object, it will be a long list of (I suppose Binary) characters which are meaningless to mere humans. The Icons I want to save are only 3KB in size, so I suppose that’s not too much, but there could be up to 80-100 canvases to be stored in the JSON array. Is that feasible?

[quote=130567:@Cliff Strange]Arrrgh, that’s getting so far from what I understand. In the LR, the example is an image contained in an ImageWell and then it is copied into a Memory Block (that sounds scary enough!).

So, I guess it is possible to get a Picture.FromData from a Canvas, and then store that in a JSONItem? Then, if I can figure that out how do I get the data from the JSONItem back into the Canvas when the app is launched? Is there a tutorial or LR reference about all these extra steps?
[/quote]
Right

Think of it as “saving the text” but this time its the data that makes up the image
You have to get that data from the image and put it into the JSON file in a way that is legal JSON
To get the picture back you have to read the data back from the json item, and turn it into a picture that you can put in the image well

And yes 3K of data would likely be HEX encoded and that could turn into 9K of HEX
But thats not really that much - even if you have hundreds

9K * 100 images is only 900K

Thanks Norman

I am going to try and get this app running correctly. But in the meantime I want to get it running anyway, so I have found that my idea from above actually works. This I guess is because when the Canvas Object is first created, a Pushbutton needs clicking, which in turn calls a Method to create the Canvas and display it. So in the Open event of the canvas, I am just directly calling that Method to really do the same thing. Cheating I know, but it works, and I can study all these other methods at my leisure.

Select Case icon
Case "garlic24"
  m.Icon = garlic24
Case "cabbage24"
mIcon = cabbage24
....
End Select
  m.Left = left
  m.Top = top
  m.Caption = caption
  
  mCanvasObjects.Append(m)
 

Thanks everyone for their help. Once I get a moment to study the suggestions made to me (and that will take a lot of reading the LR) I may be back with some more questions, in another post.

I meant to add (can’t edit my previous post) - Like they say in the Perl community “There’s more than one way to do it.” :slight_smile:

Not really cheating
For instance in the IDE when we write out a “Window” we write out all the relevant data - height width etc.
But when we read it in we have to create something in the IDE to hold that data
And there is something analogous to what you’re doing - it looks at the string it read & has a big switch statement that determines “AHA you want a window! Let me create the thing that holds Window data”
Once its created we have a place to put all that data

And in your case you have an image IN your app and you just want to know which one to use - so you have the name and need a reference to the object that has that name.

But, suppose you let people enter data & they could put their own images in
Then it would not be one of the ones in your app - and you really don’t want to have to recompile your program every time you add one image.
In that case you can save the raw data that makes up the image, put that in the JSON file and eventually read it back and get an image back.
Its more work BUT it’s also more flexible.

And you could intermix the two
If its one of your standard ones you could save it with the name & one json tag
And for others that are raw data you could save that as a different json tag so you can tell the difference

[quote=130579:@Norman Palardy]But, suppose you let people enter data & they could put their own images in
Then it would not be one of the ones in your app - and you really don’t want to have to recompile your program every time you add one image.
In that case you can save the raw data that makes up the image, put that in the JSON file and eventually read it back and get an image back.
Its more work BUT it’s also more flexible.[/quote]

Thanks for that thought. I will certainly be happy with doing that when I learn how to handle the JSON side of things. Of course, that leads to another thought - I wonder how I would allow users to add their own images? Oh my, just another thing to learn. Not that I am complaining - that’s one of the things I like about Xojo - it is great for learning, and this Forum is fantastic for its help, probably the best one I have ever been on.

Drag & drop springs to mind :stuck_out_tongue:

Dave S posted some simple methods which I use for some small graphics in a couple of databases.

See Thread

Thanks and noted.

For what its worth, here is a screenshot of my apps main window. All of the “vegetables” are recreated thanks to JSON.

Screenshot