add NewWithTag function for gjson/gparser

This commit is contained in:
John 2020-02-08 14:07:32 +08:00
parent 83dcc4a5e0
commit cdb3b94e22
7 changed files with 173 additions and 59 deletions

View File

@ -2,35 +2,27 @@ package main
import (
"fmt"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/encoding/gparser"
)
func main() {
type Item struct {
Title string `json:"title"`
Key string `json:"key"`
}
type M struct {
Id string `json:"id"`
Me map[string]interface{} `json:"me"`
Txt string `json:"txt"`
Items []*Item `json:"items"`
}
txt := `{
"id":"88888",
"me":{"name":"mikey","day":"20009"},
"txt":"hello",
"items":null
}`
json, _ := gjson.LoadContent(txt)
fmt.Println(json)
m := new(M)
e := json.ToStructDeep(m)
fmt.Println(e)
fmt.Println(m)
type User struct {
Name string `xml:"name" json:"name"`
Age int `xml:"bb" json:"dd" gconv:"aa"`
Addr string `xml:"cc"`
}
func main() {
user := User{
Name: "sss",
Age: 22,
Addr: "kaldsj",
}
xmlStr, err := gparser.VarToXmlIndent(user, "user")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(xmlStr))
}

View File

@ -27,9 +27,21 @@ import (
// New creates a Json object with any variable type of <data>, but <data> should be a map or slice
// for data access reason, or it will make no sense.
// The <safe> param specifies whether using this Json object in concurrent-safe context, which is
//
// The parameter <safe> specifies whether using this Json object in concurrent-safe context, which is
// false in default.
func New(data interface{}, safe ...bool) *Json {
return NewWithTag(data, "json", safe...)
}
// NewWithTag creates a Json object with any variable type of <data>, but <data> should be a map or slice
// for data access reason, or it will make no sense.
//
// The parameter <tags> specifies priority tags for struct conversion to map, multiple tags joined with char ','.
//
// The parameter <safe> specifies whether using this Json object in concurrent-safe context, which is
// false in default.
func NewWithTag(data interface{}, tags string, safe ...bool) *Json {
j := (*Json)(nil)
switch data.(type) {
case string, []byte:
@ -61,7 +73,7 @@ func New(data interface{}, safe ...bool) *Json {
case reflect.Map, reflect.Struct:
i := interface{}(nil)
// Note that it uses MapDeep function implementing the converting.
i = gconv.MapDeep(data, "json")
i = gconv.MapDeep(data, tags)
j = &Json{
p: &i,
c: byte(gDEFAULT_SPLIT_CHAR),

View File

@ -0,0 +1,49 @@
// 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 (
"testing"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/test/gtest"
)
func Test_Load_NewWithTag(t *testing.T) {
type User struct {
Age int `xml:"age-xml" json:"age-json"`
Name string `xml:"name-xml" json:"name-json"`
Addr string `xml:"addr-xml" json:"addr-json"`
}
data := User{
Age: 18,
Name: "john",
Addr: "chengdu",
}
// JSON
gtest.Case(t, func() {
j := gjson.New(data)
gtest.AssertNE(j, nil)
gtest.Assert(j.Get("age-xml"), nil)
gtest.Assert(j.Get("age-json"), data.Age)
gtest.Assert(j.Get("name-xml"), nil)
gtest.Assert(j.Get("name-json"), data.Name)
gtest.Assert(j.Get("addr-xml"), nil)
gtest.Assert(j.Get("addr-json"), data.Addr)
})
// XML
gtest.Case(t, func() {
j := gjson.NewWithTag(data, "xml")
gtest.AssertNE(j, nil)
gtest.Assert(j.Get("age-xml"), data.Age)
gtest.Assert(j.Get("age-json"), nil)
gtest.Assert(j.Get("name-xml"), data.Name)
gtest.Assert(j.Get("name-json"), nil)
gtest.Assert(j.Get("addr-xml"), data.Addr)
gtest.Assert(j.Get("addr-json"), nil)
})
}

View File

@ -47,35 +47,35 @@ func MustToJsonIndentString(value interface{}) string {
// ========================================================================
func VarToXml(value interface{}, rootTag ...string) ([]byte, error) {
return New(value).ToXml(rootTag...)
return NewWithTag(value, "xml").ToXml(rootTag...)
}
func VarToXmlString(value interface{}, rootTag ...string) (string, error) {
return New(value).ToXmlString(rootTag...)
return NewWithTag(value, "xml").ToXmlString(rootTag...)
}
func VarToXmlIndent(value interface{}, rootTag ...string) ([]byte, error) {
return New(value).ToXmlIndent(rootTag...)
return NewWithTag(value, "xml").ToXmlIndent(rootTag...)
}
func VarToXmlIndentString(value interface{}, rootTag ...string) (string, error) {
return New(value).ToXmlIndentString(rootTag...)
return NewWithTag(value, "xml").ToXmlIndentString(rootTag...)
}
func MustToXml(value interface{}, rootTag ...string) []byte {
return New(value).MustToXml(rootTag...)
return NewWithTag(value, "xml").MustToXml(rootTag...)
}
func MustToXmlString(value interface{}, rootTag ...string) string {
return New(value).MustToXmlString(rootTag...)
return NewWithTag(value, "xml").MustToXmlString(rootTag...)
}
func MustToXmlIndent(value interface{}, rootTag ...string) []byte {
return New(value).MustToXmlIndent(rootTag...)
return NewWithTag(value, "xml").MustToXmlIndent(rootTag...)
}
func MustToXmlIndentString(value interface{}, rootTag ...string) string {
return New(value).MustToXmlIndentString(rootTag...)
return NewWithTag(value, "xml").MustToXmlIndentString(rootTag...)
}
// ========================================================================
@ -83,19 +83,19 @@ func MustToXmlIndentString(value interface{}, rootTag ...string) string {
// ========================================================================
func VarToYaml(value interface{}) ([]byte, error) {
return New(value).ToYaml()
return NewWithTag(value, "yaml").ToYaml()
}
func VarToYamlString(value interface{}) (string, error) {
return New(value).ToYamlString()
return NewWithTag(value, "yaml").ToYamlString()
}
func MustToYaml(value interface{}) []byte {
return New(value).MustToYaml()
return NewWithTag(value, "yaml").MustToYaml()
}
func MustToYamlString(value interface{}) string {
return New(value).MustToYamlString()
return NewWithTag(value, "yaml").MustToYamlString()
}
// ========================================================================
@ -103,19 +103,19 @@ func MustToYamlString(value interface{}) string {
// ========================================================================
func VarToToml(value interface{}) ([]byte, error) {
return New(value).ToToml()
return NewWithTag(value, "toml").ToToml()
}
func VarToTomlString(value interface{}) (string, error) {
return New(value).ToTomlString()
return NewWithTag(value, "toml").ToTomlString()
}
func MustToToml(value interface{}) []byte {
return New(value).MustToToml()
return NewWithTag(value, "toml").MustToToml()
}
func MustToTomlString(value interface{}) string {
return New(value).MustToTomlString()
return NewWithTag(value, "toml").MustToTomlString()
}
// ========================================================================
@ -123,17 +123,17 @@ func MustToTomlString(value interface{}) string {
// ========================================================================
func VarToIni(value interface{}) ([]byte, error) {
return New(value).ToIni()
return NewWithTag(value, "ini").ToIni()
}
func VarToIniString(value interface{}) (string, error) {
return New(value).ToIniString()
return NewWithTag(value, "ini").ToIniString()
}
func MustToIni(value interface{}) []byte {
return New(value).MustToIni()
return NewWithTag(value, "ini").MustToIni()
}
func MustToIniString(value interface{}) string {
return New(value).MustToIniString()
return NewWithTag(value, "ini").MustToIniString()
}

View File

@ -10,13 +10,24 @@ import (
"github.com/gogf/gf/encoding/gjson"
)
// New creates a Parser object with any variable type of <data>,
// but <data> should be a map or slice for data access reason,
// or it will make no sense.
// The <unsafe> param specifies whether using this Parser object
// in un-concurrent-safe context, which is false in default.
func New(value interface{}, safe ...bool) *Parser {
return gjson.New(value, safe...)
// New creates a Parser object with any variable type of <data>, but <data> should be a map or slice
// for data access reason, or it will make no sense.
//
// The parameter <safe> specifies whether using this Json object in concurrent-safe context, which is
// false in default.
func New(data interface{}, safe ...bool) *Parser {
return gjson.New(data, safe...)
}
// NewWithTag creates a Parser object with any variable type of <data>, but <data> should be a map or slice
// for data access reason, or it will make no sense.
//
// The parameter <tags> specifies priority tags for struct conversion to map, multiple tags joined with char ','.
//
// The parameter <safe> specifies whether using this Json object in concurrent-safe context, which is
// false in default.
func NewWithTag(data interface{}, tags string, safe ...bool) *Parser {
return gjson.NewWithTag(data, tags, safe...)
}
// Load loads content from specified file <path>,

View File

@ -0,0 +1,49 @@
// 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 gparser_test
import (
"github.com/gogf/gf/encoding/gparser"
"testing"
"github.com/gogf/gf/test/gtest"
)
func Test_Load_NewWithTag(t *testing.T) {
type User struct {
Age int `xml:"age-xml" json:"age-json"`
Name string `xml:"name-xml" json:"name-json"`
Addr string `xml:"addr-xml" json:"addr-json"`
}
data := User{
Age: 18,
Name: "john",
Addr: "chengdu",
}
// JSON
gtest.Case(t, func() {
j := gparser.New(data)
gtest.AssertNE(j, nil)
gtest.Assert(j.Get("age-xml"), nil)
gtest.Assert(j.Get("age-json"), data.Age)
gtest.Assert(j.Get("name-xml"), nil)
gtest.Assert(j.Get("name-json"), data.Name)
gtest.Assert(j.Get("addr-xml"), nil)
gtest.Assert(j.Get("addr-json"), data.Addr)
})
// XML
gtest.Case(t, func() {
j := gparser.NewWithTag(data, "xml")
gtest.AssertNE(j, nil)
gtest.Assert(j.Get("age-xml"), data.Age)
gtest.Assert(j.Get("age-json"), nil)
gtest.Assert(j.Get("name-xml"), data.Name)
gtest.Assert(j.Get("name-json"), nil)
gtest.Assert(j.Get("addr-xml"), data.Addr)
gtest.Assert(j.Get("addr-json"), nil)
})
}

View File

@ -25,7 +25,8 @@ type apiMapStrAny interface {
// map/struct/*struct type, then the conversion will fail and returns nil.
//
// If <value> is a struct/*struct object, the second parameter <tags> specifies the most priority
// tags that will be detected, otherwise it detects the tags in order of: gconv, json, and then the field name.
// tags that will be detected, otherwise it detects the tags in order of:
// gconv, json, field name.
func Map(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, false, tags...)
}