squix78 / json-streaming-parser

Arduino library for parsing potentially huge json streams on devices with scarce memory
MIT License
205 stars 88 forks source link

how access grandparent (got currentParent and currentKey, but need currentGrandparent) #20

Closed aliceand closed 6 years ago

aliceand commented 6 years ago

I'm having trouble when a value I'm looking for is 3 levels deep: Using this json as an example: { "past": {"data":[{"id":11,"qty":22}]}, "present": {"data":[{"id":33,"qty":44}]}, "future": {"data":[{"id":55,"qty":66}]} } My goal is to pick up data items in "future". But I only know how to specific two levels such as this: if (currentParent == "data" && currentKey == "id") ....

Is it possible with this streamer? Is the answer obvious? I would love to be embarrassed by a simple answer. I thought about setting a global variable when I hit future and data, but that seemed like a kludge -- maybe it's the only way?

aliceand commented 6 years ago

I broke down and used a global var to help identify the time to grab data and things seem to be progressing well. I'll close this issue, but will check back if you have the obvious answer that will make me smh. Thank you!

squix78 commented 6 years ago

I recently implemented a bread crumb for our upcoming spotify client. This lets you get all the ancestors. You can then check for keys like "item.album.images.url" which is quite convenient. Here are the important methods. Don't forget to add these two private members: String rootPath[10]; uint8_t level = 0;

void SpotifyClient::startDocument() { Serial.println("start document"); level = 0; }

void SpotifyClient::key(String key) { currentKey = String(key); rootPath[level] = key; }

String SpotifyClient::getRootPath() { String path = ""; for (uint8_t i = 1; i <= level; i++) { String currentLevel = rootPath[i]; if (currentLevel == "") { break; } if (i > 1) { path += "."; } path += currentLevel; } return path; }

void SpotifyClient::startObject() { currentParent = currentKey; level++; }

void SpotifyClient::endObject() { level--; currentParent = ""; }

aliceand commented 6 years ago

I've been trying to get my head around the details of the streaming parser by breaking down the code I found in the weather station, but I just wasn't getting it. I think my problem has been that there is so much in that codebase that I couldn't get a sense of the forest -- all I could see were the trees. From the parser description on your blog, the code above, and the parser example code I'm about 75% comfortable with my understanding of the overall flow and control, and my implementation is making progress.

Thank you for taking the time to post the code above. It has been very helpful.