Skip to content

Instantly share code, notes, and snippets.

@salex
Created June 5, 2011 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salex/1009100 to your computer and use it in GitHub Desktop.
Save salex/1009100 to your computer and use it in GitHub Desktop.
jsonParseSimple for 4D v11
<%
method "jsonParseSimple"($json)
// First convert any dates in IETF format to 4d date
$re1 := "~\"?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)( \d\d*, \d{4})\"~"
$rp1 := "form.newDate(\"\1\2\")"
regex replace($re1; $json; $rp1; $json)
$json := trim($json)
if ($json[[1]] = "[") // if json is just an array, wrap in in an object
$json := '{"array":$json}'
end if
// replace any herdoc delimiters with %hex for double quote
$json := replace string($json;'"""';"%22")
//Next, hide commas, colons, apostrophe between quotes
$inQuote := false
// replacing characters with [[]] is shaky in v11, just write $json1
$json1 := ""
for ($index;1;length($json))
$char := $json[[$index]]
case of
:($char = '"')
$inQuote := not($inQuote)
$o := $char
:(($char = ",") & $inQuote)
$o := "%2c"
:(($char = ":") & $inQuote)
$o := "%3a"
:(($char = "'") & $inQuote)
$o := "%27"
:(($char = "\n") & not($inQuote))
$o := " "
:(($char = "\r") & not($inQuote))
$o := " "
:(($char = "\n") & ($inQuote))
$o := "%0a"
:(($char = "\r") & ($inQuote))
$o := "%0a"
:(($char = "{") & ($inQuote))
$o := "%7b"
:(($char = "}") & ($inQuote))
$o := "%7d"
:(($char = "[") & ($inQuote))
$o := "%5b"
:(($char = "}") & ($inQuote))
$o := "%5d"
else
$o := $char
end case
$json1 += $o
end for
//Now convert objects
array text($pattern;0) // regex pattern array
array text($replace;0) // reqex replace array
// set the reqex array - first the patterns to match
$pattern{} := "/\\:\s*\\{/" // object => convert :{ to ;new collection(
$pattern{} := "/\\[\\]/" // replace empty array with empty text array -> a call to emptyArray
$pattern{} := "/\\:\s*\\[/" // text, real, or longint array -> a call to newArray(''' JSON ARRAY ''')
$pattern{} := "/\\]/" // end array => convert ] to )
$pattern{} := "/\\}/" // end object => convert } to )
$pattern{} := "/[\\:,]/" // replace comma and colon with semi-colon
$pattern{} := "/\\{/" // replace begining object with new collection()
$pattern{} := "/new collection\\(\\)/" // replace empty collection convert new collection() with new collection
//set the replacement array
$replace{} := ";new collection(" // ojects that have a key
$replace{} := "emptyArray" // []
$replace{} := ";newArray( %22 " // [..,..,..]
$replace{} := " %22)"
$replace{} := ")"
$replace{} := ";"
$replace{} := "new collection(" // collections without a key (an array of collections)
$replace{} := "new collection"
regex replace($pattern; $json1; $replace; $results) // do the replacements
//put commas, colon, apos back and other json special characters back
$results := replace string($results;"%2c";",")
$results := replace string($results;"%3a";":")
$results := replace string($results;"%27";"'")
$results := replace string($results;"%0a";"\\n")
$results := replace string($results;"%7b";"{")
$results := replace string($results;"%7d";"}")
$results := replace string($results;"%5b";"[")
$results := replace string($results;"%5d";"]")
$results := replace string($results;"%22";'"""')
// create the collection from the parsed $results - make Active4D work
$collection := execute("return ("+ $results+ ")")
//writebr('<textarea>$results</textarea>')
//$collection := new collection
return($collection)
end method
/**********************************************************************************
emptyArray
The response to finding and empty array [] in a JSON object is to
return an empty text array
**********************************************************************************/
method "emptyArray"
array text($result;0)
return($result)
end method
/**********************************************************************************
newArray
$inList -> Text The JSON array os enclosed in a ''' ''' herdoc string.
JSON comma delimiters for the array had been changed to semi-colons at this point.
Return either a text array, a longint array, an array of collections, or a real array based in contents.
A parenthesis will assume a text array
A decimal (.) will assume a real array
An array of new collection(...) will create an array of collections (longint) after creating the collections
If none of the above, it assumes an array of longint.
**********************************************************************************/
method "newArray"($inList)
$inList := trim($inList)
$isNC := $inList = "new collection@"
// Handle an array of collections separately - just deal with top level if nested collection
if ($isNC)
$level := 0
for ($index;1;length($inList))
$char := $inlist[[$index]]
case of
:($char = "(")
$level++
:(($char = ")") )
$level--
:(($char = ";") & ($level = 0))
$inList[[$index]] := "|"
end case
end for
$cnt := split string($inList;"|";$chunks)
array longint($result;size of array($chunks))
for each ($chunks; $value; $index)
$ncoll := trim($value)
$result{$index} := execute("return ("+ $ncoll+ ")") // execute the new collection text
end for each
return($result)
end if
$isReal := "." ~ $inList
$isText := '"' ~ $inList
$isReal := $isReal & not($isText)
$count := split string($inList;";";$chunks)
case of
:($isText)
array text($result;$count)
for each ($chunks; $value; $index)
$result{$index} := trim(replace string($value;'"';''))
end for each
:($isReal)
array real($result;$count)
for each ($chunks; $value; $index)
$result{$index} := num($value)
end for each
else
array longint($result;$count)
for each ($chunks; $value; $index)
$result{$index} := num($value)
end for each
end case
return($result)
end method
/**********************************************************************************
null
The response to finding and Null word in a JSON object is to
return a nil pointer ( or could return char(0))
**********************************************************************************/
method "null"
return(nil pointer)
end method
/**********************************************************************************
newDate
The response to finding and date in a JSON object that is a string formatted
in the "Jan 2, 2011" format is to replace it with a 4D date
**********************************************************************************/
method "newDate"($date)
// replace date in Jan 2, 2011 with 4D date
array string(3; $months; *; "Jan"; "Feb"; "Mar"; "Apr"; "May"; "Jun"; "Jul"; "Aug"; "Sep"; "Oct"; "Nov"; "Dec")
$date := replace string($date;",";"")
$cnt := split string($date;" ";$chunks)
$tmp := string(find in array($months;$chunks{1}))+'/$chunks{2}/$chunks{3}'
return(date($tmp))
end method
$json := """
{
"test-null":null,
"test-empty-array" : [] ,
"test-empty-collection": {},
"test_true":true,
"test_false" : false,
"test_date":"Jan 2, 2011" ,
"test_reala":[3.34,43.5,445.2232],
"test_integera":[3,5,66,77,88],
"test_texta":["3uj","wd:hs","wm","ib77","iu88"],
"jobstageid":1852,
"selected":
[
{
"citizen":
{
"citizen.phone1":"5552149891",
"citizen.phone2":"5554799657",
"citizen.Address":"51 Lefevere",
"citizen.City":"Somewhere",
"citizen.state":"AL",
"citizen.zip":"01010",
"citizen.firstName":"Aladrienne",
"citizen.lastName":"Odom",
"citizen.mi":"C",
"citizen.emailAddress":"someone@yahoo.com",
"citizen.birthMMDD":"1209",
"action":"update",
"id":153517
},
"cs_ad":
{
"citizen_stage.jobstageid":1852,
"citizen_stage.score":"90.7761037140855",
"application_data.answers":"g0102g0202g0302g0401g0501g0601g0701g0801g0901g1001g1101g1201g1301e0105e0110",
"applicant_id":279
}
},
{
"citizen":
{
"citizen.phone1":"5552357646",
"citizen.phone2":"5552850789",
"citizen.Address":"4612 Meridian Street",
"citizen.City":"Somewhere",
"citizen.state":"MS",
"citizen.zip":"01010",
"citizen.firstName":"Farrah",
"citizen.lastName":"Warren",
"citizen.mi":"D",
"citizen.emailAddress":"someone@yahoo.com",
"citizen.birthMMDD":"0828",
"action":"update",
"id":153843
},
"cs_ad":
{
"citizen_stage.jobstageid":1852,
"citizen_stage.score":"90.78486334968466",
"application_data.answers":"g0102g0202g0301g0401g0501g0601g0701g0801g0901g1001g1101g1201g1301e0105",
"applicant_id":417
}
},
{
"citizen":
{
"citizen.phone1":"5552325995",
"citizen.phone2":"5554318634",
"citizen.Address":"6527 Old Shell Rd. #64",
"citizen.City":"Somewhere",
"citizen.state":"AL",
"citizen.zip":"01010",
"citizen.firstName":"Ballery",
"citizen.lastName":"Johnson",
"citizen.mi":"",
"citizen.emailAddress":"someone@mobilechamber.com",
"citizen.birthMMDD":"1220",
"action":"update",
"id":154260
},
"cs_ad":
{
"citizen_stage.jobstageid":1852,
"citizen_stage.score":"90.7761037140855",
"application_data.answers":"g0102g0202g0301g0402g0501g0601g0701g0801g0901g1001g1101g1201g1301e0105e0111",
"applicant_id":562
}
}
]
} """
$c := global.jsonParseSimple($json)
a4d.debug.dump collection($c; "test";true)
// an array of collections will not dump, but they are collections.
for each ($c{"selected"}; $citizen; $index)
a4d.debug.dump collection($citizen)
end for each
writebr($c{"test_date"})
$json := """
{
"privileges" : {
"read" : ["show","view","index","list"],
"manage" : ["create","read","update","delete"],
"create" : ["new"],
"update" : ["edit"],
"delete" : ["destroy"],
"me" : ["read","update","register"],
"manage_project" : ["create","read","update"]
},
"roles" : {
"guest" : {
"users" : ["create","update"],
"citizens" : ["register"],
"employees" : ["register"]
},
"citizen" : {
"citizens" : ["update=(kCurrentUserID = num($attributes{'id'}))"]
},
"employee" : {
"all" : ["read=($controller !~ kExcludeEmployee )"],
"employees" : ["read", "me=(kCurrentUserID = num($attributes{'id'}))"]
}
}
}
"""
$c := global.jsonParseSimple($json)
a4d.debug.dump collection($c)
%>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment