From c52ef8602eec8a3b36a7bc44681fefb0bf2a2008 Mon Sep 17 00:00:00 2001 From: Chen Peng Date: Sat, 24 Mar 2018 18:26:58 +0800 Subject: [PATCH] #10 Unclear how to escape a dot . in JSON keys --- README.md | 3 ++- sjson.go | 11 ++++++++++- sjson_test.go | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a7c5c4..ffe5a55 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Path syntax ----------- A path is a series of keys separated by a dot. -The dot and colon characters can be escaped with '\'. +The dot and colon characters can be escaped with ``\``. ```json { @@ -78,6 +78,7 @@ The dot and colon characters can be escaped with '\'. "age" >> 37 "children.1" >> "Alex" "friends.1.last" >> "Craig" +"fav\\.movie" >> "Deer Hunter" ``` The `-1` key can be used to append a value to an existing array: diff --git a/sjson.go b/sjson.go index 7f1d358..631602b 100644 --- a/sjson.go +++ b/sjson.go @@ -36,6 +36,7 @@ type Options struct { type pathResult struct { part string // current key part + partRaw string // current key raw part path string // remaining path force bool // force a string key more bool // there is more path to parse @@ -50,6 +51,7 @@ func parsePath(path string) (pathResult, error) { for i := 0; i < len(path); i++ { if path[i] == '.' { r.part = path[:i] + r.partRaw=r.part r.path = path[i+1:] r.more = true return r, nil @@ -63,19 +65,23 @@ func parsePath(path string) (pathResult, error) { // go into escape mode. this is a slower path that // strips off the escape character from the part. epart := []byte(path[:i]) + epartRaw := []byte(path[:i+1]) i++ if i < len(path) { epart = append(epart, path[i]) + epartRaw = append(epartRaw, path[i]) i++ for ; i < len(path); i++ { if path[i] == '\\' { i++ if i < len(path) { epart = append(epart, path[i]) + epartRaw = append(epartRaw, path[i-1],path[i]) } continue } else if path[i] == '.' { r.part = string(epart) + r.partRaw = string(epartRaw) r.path = path[i+1:] r.more = true return r, nil @@ -87,14 +93,17 @@ func parsePath(path string) (pathResult, error) { "array access character not allowed in path"} } epart = append(epart, path[i]) + epartRaw = append(epartRaw, path[i]) } } // append the last part r.part = string(epart) + r.partRaw = string(epartRaw) return r, nil } } r.part = path + r.partRaw=r.part return r, nil } @@ -249,7 +258,7 @@ func appendRawPaths(buf []byte, jstr string, paths []pathResult, raw string, } } if !found { - res = gjson.Get(jstr, paths[0].part) + res = gjson.Get(jstr, paths[0].partRaw) } if res.Index > 0 { if len(paths) > 1 { diff --git a/sjson_test.go b/sjson_test.go index a7a8f7e..725aebc 100644 --- a/sjson_test.go +++ b/sjson_test.go @@ -128,6 +128,10 @@ func TestBasic(t *testing.T) { `{":\1":{"this":[null,null,null,null,{".HI":4}]}}`, ``, "\\:\\\\1.this.4.\\.HI", `4`) + testRaw(t, setRaw, + `{"app.token":"cde"}`, + `{"app.token":"abc"}`, + "app\\.token", `"cde"`) testRaw(t, setRaw, `{"b":{"this":{"😇":""}}}`, ``,