Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

json->parse_json, add query_json

  • Loading branch information...
commit 72b1557bf0677024dbe6b1244cae77b0ea231963 1 parent d6cb8b8
dubiousjim authored May 06, 2012

Showing 2 changed files with 102 additions and 2 deletions. Show diff stats Hide diff stats

  1. 39  README.lib
  2. 65  library.awk
39  README.lib
@@ -285,7 +285,7 @@ delete_quoted(str, [repl=""])
285 285
 Optionally permits substituting a different replacement string (rather than "").
286 286
 
287 287
 
288  
-json(str, T, V, [slack=""])
  288
+parse_json(str, T, V, [slack=""])
289 289
     Parses JSON str. A successful parse will fill the T and V arrays like this:
290 290
 
291 291
         parse of: {"one": 10, "two": [20,30,[40,[50,60]]], "three": {}}
@@ -317,6 +317,43 @@ a return value < 1.
317 317
       they conform to JavaScript identifier syntax.
318 318
 
319 319
 
  320
+query_json(str, A, [root, [slack]])
  321
+    Parses JSON str with supplied slack, if any. Unpacks the returned object or
  322
+array into A. Optionally permits specifying a different root to unpack.
  323
+Example:
  324
+
  325
+    query of: {"one": 1, "two": {"alpha":0, "beta": {"uno": { "id":1, "child": {
  326
+"legal": true, "id": 11 }}, "dos": {"id": 2, "child": {"legal": true,
  327
+"id": 21 }}}}}
  328
+    with root="two.beta"
  329
+
  330
+    A["uno","id"] = 1
  331
+    A["uno","child", "legal"] = 1
  332
+    A["uno","child", "id"] = 11
  333
+    A["dos","id"] = 2
  334
+    A["dos","child", "legal"] = 1
  335
+    A["dos","child", "id"] = 21
  336
+
  337
+Arrays are handled like this:
  338
+
  339
+    query of: {"one": 1, "two": {"alpha":0, "beta": {"uno": { "id":[1,101,1001], "child": {
  340
+"legal": true, "id": [11,-11] }}, "dos": {"id": 2, "child": {"legal": true,
  341
+"id": 21 }}}}}
  342
+    with root="two.beta"
  343
+
  344
+    A["uno","id", 0] = 3
  345
+    A["uno","id", 1] = 1
  346
+    A["uno","id", 2] = 101
  347
+    A["uno","id", 3] = 1001
  348
+    A["uno","child", "legal"] = 1
  349
+    A["uno","child", "id", 0] = 2
  350
+    A["uno","child", "id", 1] = 11
  351
+    A["uno","child", "id", 2] = -11
  352
+    A["dos","id"] = 2
  353
+    A["dos","child", "legal"] = 1
  354
+    A["dos","child", "id"] = 21
  355
+
  356
+
320 357
 rep(str, n, [sep=""])
321 358
     Returns the concatenation of n copies of str, optionally joined by sep.
322 359
 
65  library.awk
@@ -579,7 +579,7 @@ function delete_quoted(str, repl) {
579 579
 }
580 580
 
581 581
 
582  
-function json(str, T, V,  slack,    c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) {
  582
+function parse_json(str, T, V,  slack,    c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) {
583 583
     # use strings, numbers, booleans as separators
584 584
     # c = "[^\"\\\\[:cntrl:]]|\\\\[\"\\\\/bfnrt]|\\u[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]"
585 585
     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) {
699 699
 }
700 700
 
701 701
 
  702
+function query_json(str, X,  root, slack,   T, V, A, B, C, i, j, k) {
  703
+    k = parse_json(str, T, V, slack)
  704
+    if (k < 1) return k
  705
+    split(root, C, ".")
  706
+    j = 1
  707
+    while (j in C) {
  708
+        if (T[k] == "array")
  709
+            split(V[k], A, ",")
  710
+        else {
  711
+            split("", A)
  712
+            asplit(V[k], B, ":", ",")
  713
+            for (i in B)
  714
+                A[V[i]] = B[i]
  715
+        }
  716
+        if (C[j] in A) {
  717
+            k = A[C[j]]
  718
+            j++
  719
+        } else return -11 # can't find requested root
  720
+    }
  721
+    # split("", B)
  722
+    # split("", C)
  723
+    B[k] = ""
  724
+    C[k] = 0
  725
+    C[0] = k
  726
+    do {
  727
+        C[0] = C[k]
  728
+        delete C[k]
  729
+        j = T[k]
  730
+        if (j == "array") {
  731
+            j = split(V[k], A, ",")
  732
+            k = B[k] ? B[k] SUBSEP : ""
  733
+            X[k 0] = j
  734
+            for (i=1; i<=j; i++) {
  735
+               # push A[i] to C, (B[k],i) to B 
  736
+                C[A[i]] = C[0]
  737
+                B[A[i]] = k i
  738
+                C[0] = A[i]
  739
+            }
  740
+        } else if (j == "object") {
  741
+            asplit(V[k], A, ":", ",")
  742
+            k = B[k] ? B[k] SUBSEP : ""
  743
+            for (i in A) {
  744
+                # push A[i] to C, (B[k],V[i]) to B 
  745
+                C[A[i]] = C[0]
  746
+                B[A[i]] = k V[i]
  747
+                C[0] = A[i]
  748
+            }
  749
+        } else if (j == "number") {
  750
+            X[B[k]] = V[k]
  751
+        } else if (j == "true") {
  752
+            X[B[k]] = 1
  753
+        } else if (j == "false") {
  754
+            X[B[k]] = 0
  755
+        } else {
  756
+            # null will satisfy ismissing()
  757
+            X[B[k]]
  758
+        }
  759
+        k = C[0]
  760
+    } while (k)
  761
+    return 0
  762
+}
  763
+
  764
+
702 765
 # repeat str n times, from http://awk.freeshell.org/RepeatAString
703 766
 function rep(str, n,  sep,   remain, result) {
704 767
     if (n < 2) {

1 note on commit 72b1557

Steven Penny

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

Please sign in to comment.
Something went wrong with that request. Please try again.