This is an old post that I’d like to comment on.
The following compound command transforms a JSON string into an equivalent Applescript value by taking advantage of the remarkable similarity of the Applescript and JSON value specifications. The primary differences between the two seem to be JSON’s use of double-quoted text strings for record labels (called object keys in JSON) and JSON’s allowance of a single value to span multiple lines. JSON’s use of square brackets to enclose lists (called arrays in JSON) does not require transformation, since square brackets are an acceptable alternative to curly braces for enclosing Applescript lists. The sed command converts double-quoted object keys to piped record labels (which “automatically” become unpiped if not needed), and the tr command strips any linefeed or carriage return characters:
set applescriptValue to run script (do shell script ("echo " & jsonString's quoted form & " | sed -E 's/\"([^\"]+)\"[[:space:]]*:[[:space:]]*/|\\1|:/g' | tr -d '\\n\\r'"))
Using an example taken from the web:
set jsonString to "{
\"MenuID\":5,
\"MenuVersion\":1,
\"MenuName\":\"Lunch Menu\",
\"MenuItems\":[
{
\"Name\":\"TUSCANI MEDITERRANEAN CON POLLO\",
\"Description\":\"Pasta\",
\"PKID\":2,
\"ParentID\":1,
\"Ingredients\":[
{
\"PKID\":123,
\"IngName\":\"Cheese\",
\"Included\":true,
\"ExtraPrice\":0
},
{
\"PKID\":124,
\"IngName\":\"Sausage\",
\"Included\":false,
\"ExtraPrice\":0.99
}
],
\"ItemPricing\":[
{
\"PKID\":456,
\"SizeName\":\"Large\",
\"SizePrice\":12.99
},
{
\"PKID\":678,
\"SizeName\":\"Small\",
\"SizePrice\":14.99
}
]
}
]
}"
set applescriptValue to run script (do shell script ("echo " & jsonString's quoted form & " | sed -E 's/\"([^\"]+)\"[[:space:]]*:[[:space:]]*/|\\1|:/g' | tr -d '\\n\\r'"))
-->
{MenuID:5, MenuVersion:1, MenuName:"Lunch Menu", MenuItems:{{|name|:"TUSCANI MEDITERRANEAN CON POLLO", |description|:"Pasta", PKID:2, ParentID:1, Ingredients:{{PKID:123, IngName:"Cheese", Included:true, ExtraPrice:0}, {PKID:124, IngName:"Sausage", Included:false, ExtraPrice:0.99}}, ItemPricing:{{PKID:456, SizeName:"Large", SizePrice:12.99}, {PKID:678, SizeName:"Small", SizePrice:14.99}}}}}
It has successfully decoded a number of JSON strings in my testing thus far. Are there any flaws with this straightforward decoding technique? (Two that come to mind are: (1) if a JSON text string value contains a pattern mimicking an object key, i.e., a double-quoted string following by a colon character, presumably a fairly rare occurrence in real-life usage; and (2) if a JSON text string value contains a linefeed or carriage return character. If one knew that neither of those patterns would be encountered, then I believe the above command would work well. Alternatively, both of those problems could be resolved by tokenizing text string values before running the above command, then detokenizing the result.)