Permalink
Browse files

json->parse_json, add query_json

  • Loading branch information...
1 parent d6cb8b8 commit 72b1557bf0677024dbe6b1244cae77b0ea231963 @dubiousjim committed May 6, 2012
Showing with 102 additions and 2 deletions.
  1. +38 −1 README.lib
  2. +64 −1 library.awk
View
39 README.lib
@@ -285,7 +285,7 @@ delete_quoted(str, [repl=""])
Optionally permits substituting a different replacement string (rather than "").
-json(str, T, V, [slack=""])
+parse_json(str, T, V, [slack=""])
Parses JSON str. A successful parse will fill the T and V arrays like this:
parse of: {"one": 10, "two": [20,30,[40,[50,60]]], "three": {}}
@@ -317,6 +317,43 @@ a return value < 1.
they conform to JavaScript identifier syntax.
+query_json(str, A, [root, [slack]])
+ Parses JSON str with supplied slack, if any. Unpacks the returned object or
+array into A. Optionally permits specifying a different root to unpack.
+Example:
+
+ query of: {"one": 1, "two": {"alpha":0, "beta": {"uno": { "id":1, "child": {
+"legal": true, "id": 11 }}, "dos": {"id": 2, "child": {"legal": true,
+"id": 21 }}}}}
+ with root="two.beta"
+
+ A["uno","id"] = 1
+ A["uno","child", "legal"] = 1
+ A["uno","child", "id"] = 11
+ A["dos","id"] = 2
+ A["dos","child", "legal"] = 1
+ A["dos","child", "id"] = 21
+
+Arrays are handled like this:
+
+ query of: {"one": 1, "two": {"alpha":0, "beta": {"uno": { "id":[1,101,1001], "child": {
+"legal": true, "id": [11,-11] }}, "dos": {"id": 2, "child": {"legal": true,
+"id": 21 }}}}}
+ with root="two.beta"
+
+ A["uno","id", 0] = 3
+ A["uno","id", 1] = 1
+ A["uno","id", 2] = 101
+ A["uno","id", 3] = 1001
+ A["uno","child", "legal"] = 1
+ A["uno","child", "id", 0] = 2
+ A["uno","child", "id", 1] = 11
+ A["uno","child", "id", 2] = -11
+ A["dos","id"] = 2
+ A["dos","child", "legal"] = 1
+ A["dos","child", "id"] = 21
+
+
rep(str, n, [sep=""])
Returns the concatenation of n copies of str, optionally joined by sep.
View
65 library.awk
@@ -579,7 +579,7 @@ function delete_quoted(str, repl) {
}
-function json(str, T, V, slack, c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) {
+function parse_json(str, T, V, slack, c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) {
# use strings, numbers, booleans as separators
# c = "[^\"\\\\[:cntrl:]]|\\\\[\"\\\\/bfnrt]|\\u[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]"
c = "[^\"\\\\\001-\037]|\\\\[\"\\\\/bfnrt]|\\\\u[[:xdigit:]A-F][[:xdigit:]A-F][[:xdigit:]A-F][[:xdigit:]A-F]"
@@ -699,6 +699,69 @@ function json(str, T, V, slack, c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) {
}
+function query_json(str, X, root, slack, T, V, A, B, C, i, j, k) {
+ k = parse_json(str, T, V, slack)
+ if (k < 1) return k
+ split(root, C, ".")
+ j = 1
+ while (j in C) {
+ if (T[k] == "array")
+ split(V[k], A, ",")
+ else {
+ split("", A)
+ asplit(V[k], B, ":", ",")
+ for (i in B)
+ A[V[i]] = B[i]
+ }
+ if (C[j] in A) {
+ k = A[C[j]]
+ j++
+ } else return -11 # can't find requested root
+ }
+ # split("", B)
+ # split("", C)
+ B[k] = ""
+ C[k] = 0
+ C[0] = k
+ do {
+ C[0] = C[k]
+ delete C[k]
+ j = T[k]
+ if (j == "array") {
+ j = split(V[k], A, ",")
+ k = B[k] ? B[k] SUBSEP : ""
+ X[k 0] = j
+ for (i=1; i<=j; i++) {
+ # push A[i] to C, (B[k],i) to B
+ C[A[i]] = C[0]
+ B[A[i]] = k i
+ C[0] = A[i]
+ }
+ } else if (j == "object") {
+ asplit(V[k], A, ":", ",")
+ k = B[k] ? B[k] SUBSEP : ""
+ for (i in A) {
+ # push A[i] to C, (B[k],V[i]) to B
+ C[A[i]] = C[0]
+ B[A[i]] = k V[i]
+ C[0] = A[i]
+ }
+ } else if (j == "number") {
+ X[B[k]] = V[k]
+ } else if (j == "true") {
+ X[B[k]] = 1
+ } else if (j == "false") {
+ X[B[k]] = 0
+ } else {
+ # null will satisfy ismissing()
+ X[B[k]]
+ }
+ k = C[0]
+ } while (k)
+ return 0
+}
+
+
# repeat str n times, from http://awk.freeshell.org/RepeatAString
function rep(str, n, sep, remain, result) {
if (n < 2) {

1 comment on commit 72b1557

@svnpenn

@dubiousjim how would you call these functions from a script?

Please sign in to comment.