JSON and Two Smoking Stacks March 11, 2011
JSON is something to me that is just simple to use in its native environment, that I would never consider writing a parser. I would just try to use it in its natural environment, if I ever have to use it. Well, I found a case where that is not the case!
In my dealings with geocoding locations for clients, I've come across many instances where a limit on the amount of geocoding calls was reached, and I would have to wait until the next day to geocode some more locations. I could write a geocoding mega-program that abstractly geocodes addresses with all of the free services available until it reaches a limit, then moves on to the next service! Fun stuff.
The problem is, with the other geocoders out there, they do not let you specify which format you would like the response to be in. XML is easy to do in C#, however I hadn't researched a JSON parser, so I had tasked myself with writing one from scratch with no previous parsing experience.
Although, it can only have a certain number of syntax elements. {}[],: as far as I know. Quotes ("") contain strings, curlies {} contain objects, squares [] contain arrays. Arrays can contain objects, objects can contain arrays. Objects have to be in field : value pairs. So here's the basic structure:
private Stack syntaxStack;
private Stack tokenStack;
StringBuilder sb = new StringBuilder(); // string builder for catching data
for (loop through json){
switch (char){
case '"':
we're either in a string or just out of a string (set a boolean so we can check in the other cases)
if it's a " preceded by a , add it to the string buffer
break;
case '[':
if we're not in a string
push a '[' onto the syntax stack
push an array token onto the token stack
break;
case '{':
if we're not in a string
push a '{' onto the syntax stack
push an object token onto the token stack
break;
case ']':
if we're not in a string
Get the last value in the array, if there is one
( it could have also been an array of arrays, and we're closing the outer array, so there won't be a value)
add to the children of the last token in the token stack
pop from each stack, we're out of the current array
break;
case '}':
if we're not in a string and we're in an object
get the last value in the object, if there is one
set the value in the last object
pop from each stack, we are out of that object
case ',':
if we're not in a string
if we're in an object, a value was just specified. if it's a string value, set the last field's value to the data in the string builder
clear the string buffer
break;
case ':':
if we're not in a string
we should be in an object, and the previous string was the field, so create a field token and add it to the current node
clear the string buffer
break;
default:
append the character to the data string buffer
}
}
bool InArray
= this.syntaxStack.Peek() == '['
bool InObject
= this.syntaxStack.Peek() == '{'
Here is the Visual Studio 2008 project with C# code for parsing your own JSON. I think mine looks decent compared to others out there