improve package gjson

This commit is contained in:
John 2020-03-21 21:32:02 +08:00
parent c2966817ce
commit e2c1e11f95
8 changed files with 282 additions and 24 deletions

View File

@ -11,20 +11,19 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"strings"
)
//Decode converts INI format to map
// Decode converts INI format to map.
func Decode(data []byte) (res map[string]interface{}, err error) {
res = make(map[string]interface{})
fieldMap := make(map[string]interface{})
a := bytes.NewReader(data)
r := bufio.NewReader(a)
var section string
var lastSection string
var haveSection bool
@ -65,30 +64,27 @@ func Decode(data []byte) (res map[string]interface{}, err error) {
if strings.Contains(lineStr, "=") && haveSection {
values := strings.Split(lineStr, "=")
fieldMap[strings.TrimSpace(values[0])] = strings.TrimSpace(strings.Join(values[1:], ""))
res[section] = fieldMap
}
}
if haveSection == false {
return nil, fmt.Errorf("Failed to parse INI file, not found section")
return nil, errors.New("failed to parse INI file, section not found")
}
return res, nil
}
//Encode converts map to INI format
// Encode converts map to INI format.
func Encode(data map[string]interface{}) (res []byte, err error) {
w := new(bytes.Buffer)
w.WriteString(";gini\n")
w.WriteString("; this ini file is produced by package gini\n")
for k, v := range data {
n, err := w.WriteString(fmt.Sprintf("[%s]\n", k))
if err != nil || n == 0 {
return nil, fmt.Errorf("write data failed. %v", err)
}
for kk, vv := range v.(map[string]interface{}) {
n, err := w.WriteString(fmt.Sprintf("%s=%s\n", kk, vv.(string)))
if err != nil || n == 0 {
@ -105,12 +101,11 @@ func Encode(data map[string]interface{}) (res []byte, err error) {
return res, nil
}
//ToJson convert INI format to JSON
// ToJson convert INI format to JSON.
func ToJson(data []byte) (res []byte, err error) {
iniMap, err := Decode(data)
if err != nil {
return nil, err
}
return json.Marshal(iniMap)
}

View File

@ -38,7 +38,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
array := strings.Split(pattern, string(j.c))
length := len(array)
value = j.convertValue(value)
// 初始化判断
// Initialization checks.
if *j.p == nil {
if gstr.IsNumeric(array[0]) {
*j.p = make([]interface{}, 0)
@ -146,9 +146,15 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
pointer = &v
}
} else {
var v interface{} = make(map[string]interface{})
pparent = j.setPointerWithValue(pointer, array[i], v)
pointer = &v
v := (*pointer).([]interface{})
if len(v) > valn {
pparent = pointer
pointer = &(*pointer).([]interface{})[valn]
} else {
var v interface{} = make(map[string]interface{})
pparent = j.setPointerWithValue(pointer, array[i], v)
pointer = &v
}
}
}

View File

@ -0,0 +1,111 @@
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gjson_test
import (
"fmt"
"github.com/gogf/gf/encoding/gjson"
)
func Example_Conversion_NormalFormats() {
data :=
`{
"users" : {
"count" : 1,
"array" : ["John", "Ming"]
}
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
fmt.Println("JSON:")
fmt.Println(j.MustToJsonString())
fmt.Println("======================")
fmt.Println("XML:")
fmt.Println(j.MustToXmlString())
fmt.Println("======================")
fmt.Println("YAML:")
fmt.Println(j.MustToYamlString())
fmt.Println("======================")
fmt.Println("TOML:")
fmt.Println(j.MustToTomlString())
}
// Output:
// JSON:
// {"users":{"array":["John","Ming"],"count":1}}
// ======================
// XML:
// <users><array>John</array><array>Ming</array><count>1</count></users>
// ======================
// YAML:
// users:
// array:
// - John
// - Ming
// count: 1
//
// ======================
// TOML:
// [users]
// array = ["John", "Ming"]
// count = 1.0
}
func Example_Conversion_GetStruct() {
data :=
`{
"users" : {
"count" : 1,
"array" : ["John", "Ming"]
}
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
type Users struct {
Count int
Array []string
}
users := new(Users)
if err := j.GetStruct("users", users); err != nil {
panic(err)
}
fmt.Printf(`%+v`, users)
}
// Output:
// &{Count:1 Array:[John Ming]}
}
func Example_Conversion_ToStruct() {
data :=
`
{
"count" : 1,
"array" : ["John", "Ming"]
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
type Users struct {
Count int
Array []string
}
users := new(Users)
if err := j.ToStruct(users); err != nil {
panic(err)
}
fmt.Printf(`%+v`, users)
}
// Output:
// &{Count:1 Array:[John Ming]}
}

View File

@ -0,0 +1,63 @@
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gjson_test
import (
"fmt"
"github.com/gogf/gf/encoding/gjson"
)
func Example_DataSet_Create1() {
j := gjson.New(nil)
j.Set("name", "John")
j.Set("score", 99.5)
fmt.Printf(
"Name: %s, Score: %v\n",
j.GetString("name"),
j.GetFloat32("score"),
)
fmt.Println(j.MustToJsonString())
// Output:
// Name: John, Score: 99.5
// {"name":"John","score":99.5}
}
func Example_DataSet_Create2() {
j := gjson.New(nil)
for i := 0; i < 5; i++ {
j.Set(fmt.Sprintf(`%d.id`, i), i)
j.Set(fmt.Sprintf(`%d.name`, i), fmt.Sprintf(`student-%d`, i))
}
fmt.Println(j.MustToJsonString())
// Output:
// [{"id":0,"name":"student-0"},{"id":1,"name":"student-1"},{"id":2,"name":"student-2"},{"id":3,"name":"student-3"},{"id":4,"name":"student-4"}]
}
func Example_DataSet_RuntimeEdit() {
data :=
`{
"users" : {
"count" : 2,
"list" : [
{"name" : "Ming", "score" : 60},
{"name" : "John", "score" : 59}
]
}
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
j.Set("users.list.1.score", 100)
fmt.Println("John Score:", j.GetFloat32("users.list.1.score"))
fmt.Println(j.MustToJsonString())
}
// Output:
// John Score: 100
// {"users":{"count":2,"list":[{"name":"Ming","score":60},{"name":"John","score":100}]}}
}

View File

@ -10,24 +10,23 @@ import (
"fmt"
"github.com/gogf/gf/debug/gdebug"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/os/gfile"
)
func Example_LoadJson() {
func Example_Load_Json() {
jsonFilePath := gdebug.TestDataPath("json", "data1.json")
j, _ := gjson.Load(jsonFilePath)
fmt.Println(j.Get("name"))
fmt.Println(j.Get("score"))
}
func Example_LoadXml() {
func Example_Load_Xml() {
jsonFilePath := gdebug.TestDataPath("xml", "data1.xml")
j, _ := gjson.Load(jsonFilePath)
fmt.Println(j.Get("doc.name"))
fmt.Println(j.Get("doc.score"))
}
func Example_LoadContent() {
func Example_Load_Content() {
jsonContent := `{"name":"john", "score":"100"}`
j, _ := gjson.LoadContent(jsonContent)
fmt.Println(j.Get("name"))

View File

@ -11,7 +11,7 @@ import (
"github.com/gogf/gf/encoding/gjson"
)
func Example_NewFromJson() {
func Example_New_FromJson() {
jsonContent := `{"name":"john", "score":"100"}`
j := gjson.New(jsonContent)
fmt.Println(j.Get("name"))
@ -21,9 +21,10 @@ func Example_NewFromJson() {
// 100
}
func Example_NewFromXml() {
func Example_New_FromXml() {
jsonContent := `<?xml version="1.0" encoding="UTF-8"?><doc><name>john</name><score>100</score></doc>`
j := gjson.New(jsonContent)
// Note that there's root node in the XML content.
fmt.Println(j.Get("doc.name"))
fmt.Println(j.Get("doc.score"))
// Output:
@ -31,7 +32,7 @@ func Example_NewFromXml() {
// 100
}
func Example_NewFromStruct() {
func Example_New_FromStruct() {
type Me struct {
Name string `json:"name"`
Score int `json:"score"`
@ -48,7 +49,7 @@ func Example_NewFromStruct() {
// 100
}
func Example_NewFromStructWithTag() {
func Example_New_FromStructWithTag() {
type Me struct {
Name string `tag:"name"`
Score int `tag:"score"`
@ -59,6 +60,8 @@ func Example_NewFromStructWithTag() {
Score: 100,
Title: "engineer",
}
// The parameter <tags> specifies custom priority tags for struct conversion to map,
// multiple tags joined with char ','.
j := gjson.NewWithTag(me, "tag")
fmt.Println(j.Get("name"))
fmt.Println(j.Get("score"))

View File

@ -0,0 +1,71 @@
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gjson_test
import (
"fmt"
"github.com/gogf/gf/encoding/gjson"
)
func Example_Pattern_Get() {
data :=
`{
"users" : {
"count" : 2,
"list" : [
{"name" : "Ming", "score" : 60},
{"name" : "John", "score" : 99.5}
]
}
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
fmt.Println("John Score:", j.GetFloat32("users.list.1.score"))
}
// Output:
// John Score: 99.5
}
func Example_Pattern_CustomSplitChar() {
data :=
`{
"users" : {
"count" : 2,
"list" : [
{"name" : "Ming", "score" : 60},
{"name" : "John", "score" : 99.5}
]
}
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
j.SetSplitChar('#')
fmt.Println("John Score:", j.GetFloat32("users#list#1#score"))
}
// Output:
// John Score: 99.5
}
func Example_Pattern_ViolenceCheck() {
data :=
`{
"users" : {
"count" : 100
},
"users.count" : 101
}`
if j, err := gjson.DecodeToJson(data); err != nil {
panic(err)
} else {
j.SetViolenceCheck(true)
fmt.Println("Users Count:", j.GetInt("users.count"))
}
// Output:
// Users Count: 101
}

View File

@ -400,11 +400,21 @@ func Test_Basic(t *testing.T) {
err = j.Remove("1")
t.Assert(err, nil)
t.Assert(j.Get("0"), 1)
t.Assert(len(j.ToArray()), 2)
j = gjson.New(`[1,2,3]`)
// If index 0 is delete, its next item will be at index 0.
t.Assert(j.Remove("0"), nil)
t.Assert(j.Remove("0"), nil)
t.Assert(j.Remove("0"), nil)
t.Assert(j.Get("0"), nil)
t.Assert(len(j.ToArray()), 0)
j = gjson.New(`[1,2,3]`)
err = j.Remove("3")
t.Assert(err, nil)
t.Assert(j.Get("0"), 1)
t.Assert(len(j.ToArray()), 3)
j = gjson.New(`[1,2,3]`)
err = j.Remove("0.3")
@ -414,7 +424,7 @@ func Test_Basic(t *testing.T) {
j = gjson.New(`[1,2,3]`)
err = j.Remove("0.a")
t.Assert(err, nil)
t.Assert(len(j.Get("0").(g.Map)), 0)
t.Assert(j.Get("0"), 1)
name := struct {
Name string