JSONMBS - unroll arrays?

I cant understand what Im doing wrong here. Theres clearly a ChildNode oject under the “layers” object in the debugger but it will not assign to “layernode”. I could swear this worked and then all of a sudden its not working. The deal is the json has some layers iM interested in and some not so I want to process through them and if the name is one I want, prefix the dict keyname since the entries are all the same. Anyone spot the problem?
Heres the code for a window opening event:

Var f As FolderItem
Var input As TextInputStream
var json as New JSONMBS

f = FolderItem.ShowOpenFileDialog("json")
// All the file types in this set
If f <> Nil Then
  input = TextInputStream.Open(f)
  input.Encoding = Encodings.UTF8
  json=new JSONMBS(input.ReadAll)
  input.Close
End If


var d as dictionary = new dictionary

d.value("project")=json.Child("project").ValueString
d.value("day")=json.Child("day").ValueDouble
d.value("designer")=json.Child("designer").ValueString
d.value("rate")=json.Child("rate").ValueDouble

// deal with array of layers
var layers As JSONMBS =json.Child("layers")
// the layer object
var layernode as JSONMBS = layers.ChildNode

while layers.LastChildNode<>nil
  // the first data object
  var datanode as JSONMBS = layernode.ChildNode
  select case datanode.ValueString
  case "Colors"
    datanode=datanode.NextNode
    d.value("Colors_shapes")=datanode.ValueInteger
    datanode=datanode.NextNode
    d.value("Colors_colors")=datanode.ValueDouble
    datanode=datanode.NextNode
    d.value("Colors_devs")=datanode.ValueDouble
  case "Artwork"
    datanode=datanode.NextNode
    d.value("Artwork_shapes")=datanode.ValueInteger
    datanode=datanode.NextNode
    d.value("Artwork_colors")=datanode.ValueDouble
    datanode=datanode.NextNode
    d.value("Artwork_devs")=datanode.ValueDouble
  case "Vectors"
    datanode=datanode.NextNode
    d.value("Vectors_shapes")=datanode.ValueInteger
    datanode=datanode.NextNode
    d.value("Vectors_colors")=datanode.ValueDouble
    datanode=datanode.NextNode
    d.value("Vectors_devs")=datanode.ValueDouble
  case else
  end select
  layernode = layernode.NextNode
wend

and heres the json for the file:

{
	"layers":	[
		{
			"name":	"Vats",
			"shapes":	10,
			"colors":	4,
			"devs":	-1
		},
		{

			"name":	"Artwork",
			"shapes":	10,
			"colors":	4,
			"devs":	-1
		}, 
		{
			"name":	"Vectors",
			"shapes":	10,
			"colors":	4,
			"devs":	-1
		},
		{
			"name":	"Colors",
			"shapes":	10,
			"colors":	4,
			"devs":	-1
		}
	],
	"project":	"Wintertime",
	"day":	6,
	"designer":	"Tjerd",
	"rate":	65.45,

}

I don’t know anything about JSONMBS so I’m afraid I can’t answer your question, but I am wondering why you didn’t just use ParseJSON instead of writing all the code that does what it could do for you natively in one line?

2 Likes

Well, your loop should look on the layernode and wait for it to be nil as you walk from node to node with NextNode.

Thats the line that gives the NOE - layers.ChildNode will not assign to layernode

Im not seeing how it would do it in one line? Then, I just have a dict of dicts to run through and have roughly the same amount of work to do. The goal is to flatten out the data to one dimension so I can easily squirt it into a db row. That is what I wound up doing though because I cant get past this assignment

so layers is nil?
Are you sure there is a layers entry in the JSON?

json.Child(“layers”) may look on the wrong json?

No, layers is valid and so is the ChildNode - this is the problem. If you drop the code into a window opening event and use the json you’ll see it

While I do not see why this would prevent the loop from running, I would say this is clearly a bug. Layers.LastNode will always be the same child of layers, so the loop should never end.
It should be
while layernode <> nil

I made that code change and ran it over your JSON string:

For me, layernode is nil. line 13 does not assign the child node. I don tknow how you get past that and I dont…and yes, I dont want/need the layer’s name in the results is why that is passed over.

So the only difference I see is that your string is derived from a file while I used it as a constant.
Did you inspect the contents of the read file? Or js.tostring to see if something went wrong?
If all seems ok: Is the code working with my changes? (Taking the string from a constant, and the changed while clause?
I am a bit sceptical about using nextnode without checking for nil, but you know the structure of your JSONs better. And it should not interfere with assigning layer node.

Maybe, but iterating through dictionary.keys avoids the While loop and dealing with nodes and children and you probably wouldn’t be running into any nil issues…

1 Like

Christian sort of solved this earlier too but it took me a bit to see it. Thank you all for chiming in. I assumed that the layer objects inside the layer array had to be stepped into each. So what was happeneing was that as the layernode.nextobject was advancing to the end and it eventually became Nil when the nodes ran out. I was not seeing that in the debugger since my actual data set is much larger but traversing this has been a learning experience for sure. :grinning: