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

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 // 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. // 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. // false in default.
func New(data interface{}, safe ...bool) *Json { 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) j := (*Json)(nil)
switch data.(type) { switch data.(type) {
case string, []byte: case string, []byte:
@ -61,7 +73,7 @@ func New(data interface{}, safe ...bool) *Json {
case reflect.Map, reflect.Struct: case reflect.Map, reflect.Struct:
i := interface{}(nil) i := interface{}(nil)
// Note that it uses MapDeep function implementing the converting. // Note that it uses MapDeep function implementing the converting.
i = gconv.MapDeep(data, "json") i = gconv.MapDeep(data, tags)
j = &Json{ j = &Json{
p: &i, p: &i,
c: byte(gDEFAULT_SPLIT_CHAR), 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) { 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) { 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) { 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) { 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 { 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 { 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 { 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 { 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) { func VarToYaml(value interface{}) ([]byte, error) {
return New(value).ToYaml() return NewWithTag(value, "yaml").ToYaml()
} }
func VarToYamlString(value interface{}) (string, error) { func VarToYamlString(value interface{}) (string, error) {
return New(value).ToYamlString() return NewWithTag(value, "yaml").ToYamlString()
} }
func MustToYaml(value interface{}) []byte { func MustToYaml(value interface{}) []byte {
return New(value).MustToYaml() return NewWithTag(value, "yaml").MustToYaml()
} }
func MustToYamlString(value interface{}) string { 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) { func VarToToml(value interface{}) ([]byte, error) {
return New(value).ToToml() return NewWithTag(value, "toml").ToToml()
} }
func VarToTomlString(value interface{}) (string, error) { func VarToTomlString(value interface{}) (string, error) {
return New(value).ToTomlString() return NewWithTag(value, "toml").ToTomlString()
} }
func MustToToml(value interface{}) []byte { func MustToToml(value interface{}) []byte {
return New(value).MustToToml() return NewWithTag(value, "toml").MustToToml()
} }
func MustToTomlString(value interface{}) string { 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) { func VarToIni(value interface{}) ([]byte, error) {
return New(value).ToIni() return NewWithTag(value, "ini").ToIni()
} }
func VarToIniString(value interface{}) (string, error) { func VarToIniString(value interface{}) (string, error) {
return New(value).ToIniString() return NewWithTag(value, "ini").ToIniString()
} }
func MustToIni(value interface{}) []byte { func MustToIni(value interface{}) []byte {
return New(value).MustToIni() return NewWithTag(value, "ini").MustToIni()
} }
func MustToIniString(value interface{}) string { 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" "github.com/gogf/gf/encoding/gjson"
) )
// New creates a Parser object with any variable type of <data>, // New creates a Parser object with any variable type of <data>, but <data> should be a map or slice
// but <data> should be a map or slice for data access reason, // for data access reason, or it will make no sense.
// or it will make no sense. //
// The <unsafe> param specifies whether using this Parser object // The parameter <safe> specifies whether using this Json object in concurrent-safe context, which is
// in un-concurrent-safe context, which is false in default. // false in default.
func New(value interface{}, safe ...bool) *Parser { func New(data interface{}, safe ...bool) *Parser {
return gjson.New(value, safe...) 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>, // 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. // 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 // 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{} { func Map(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, false, tags...) return doMapConvert(value, false, tags...)
} }