gparser

    使用方式

    https://godoc.org/github.com/gogf/gf/encoding/gparser

    简要说明,

    1. LoadLoadContent方法支持根据文件及内容,生成gparser.Parser对象;
    2. New方法支持生成一个空的gparser.Parser对象,常用用于动态数据生成;
    3. New方法同时也支持按照给定的任意Go变量生成一个gparser.Parser对象;
    4. Get*相关方法支持按照层级检索数据,pattern参数中使用英文”.“号区分层级关系;
    5. Set方法支持按照层级新增/修改,给定的变量类型支持任意类型
    6. Remove方法支持按照层级删除变量,只需要给定pattern层级检索参数即可;
    7. To*相关方法支持将gparser.Parser对象生成为支持的数据格式字符串;
    8. VarTo*相关方法支持将任意的Go变量直接转换为支持的数据格式字符串;

    使用示例

    1. 数据层级检索

      示例1,读取JSON:

      1. data :=
      2. `{
      3. "users" : {
      4. "count" : 100,
      5. "list" : [
      6. {"name" : "Ming", "score" : 60},
      7. {"name" : "John", "score" : 99.5}
      8. ]
      9. }
      10. }`
      11. if p, e := gparser.LoadContent([]byte(data), "json"); e != nil {
      12. glog.Error(e)
      13. } else {
      14. fmt.Println("John Score:", p.GetFloat32("users.list.1.score"))
      15. }

      可以看到我们可以通过英文”.”号实现非常方便的层级访问,针对于数组列表,索引从0开始,我们也可以通过”.”号访问其对应的索引项数据。

      示例2,读取XML:

      1. data :=
      2. `<?xml version="1.0" encoding="UTF-8"?>
      3. <note>
      4. <to>Tove</to>
      5. <from>Jani</from>
      6. <heading>Reminder</heading>
      7. <body>Don't forget me this weekend!</body>
      8. if p, e := gparser.LoadContent([]byte(data), "xml"); e != nil {
      9. } else {
      10. fmt.Println("Heading:", p.GetString("note.heading"))
      11. }

      LoadContent方法的第二个参数指定内容的数据类型,可选值为(json,xml,yaml/yml,toml)。其他两种数据类型可自行测试,这里不再赘述。

    2. 处理键名本身带有层级符号”.”的情况

      当键名和层级在访问时存在pattern同名的情况,当然这并不是什么问题,以下是一个示例。

      1. data :=
      2. `{
      3. "users" : {
      4. "count" : 100
      5. },
      6. "users.count" : 101
      7. }`
      8. if p, e := gparser.LoadContent([]byte(data), "json"); e != nil {
      9. glog.Error(e)
      10. } else {
      11. p.SetViolenceCheck(true)
      12. fmt.Println("Users Count:", p.Get("users.count"))
      13. }

      运行之后打印出的结果为101。当键名存在”.”号时,检索优先级:键名->层级,因此并不会引起歧义。

      1. data :=
      2. `{
      3. "users" : {
      4. "count" : {
      5. "type1" : 1,
      6. "type2" : 2
      7. },
      8. "count.type1" : 100
      9. }
      10. }`
      11. if p, e := gparser.LoadContent([]byte(data), "json"); e != nil {
      12. glog.Error(e)
      13. } else {
      14. p.SetViolenceCheck(true)
      15. fmt.Println("Users Count:", p.Get("users.count.type1"))
      16. fmt.Println("Users Count:", p.Get("users.count.type2"))
      17. }

      执行后,输出结果为:

      1. 100
      2. 2

      看到了么,gparser会按照给定pattern对层级进行自动探测,检索时按照键名优先的原则进行匹配,并不会出现歧义冲突。

    1. 运行时动态修改数据

      修改count为2,并在users节点下新增增加list节点,节点类型为数组。 执行后输出结果为:

        gparser包的数据运行时修改特性非常强大,在该特性的支持下,各种数据结构的编码/解析显得异常的灵活方便。

      1. 运行时动态删除变量

        我们再来看一个删除变量的例子:

        1. data :=
        2. `<?xml version="1.0" encoding="UTF-8"?>
        3. <article>
        4. <count>10</count>
        5. <list><title>gf article1</title><content>gf content1</content></list>
        6. <list><title>gf article2</title><content>gf content2</content></list>
        7. <list><title>gf article3</title><content>gf content3</content></list>
        8. </article>`
        9. if p, e := gparser.LoadContent([]byte(data), "xml"); e != nil {
        10. glog.Error(e)
        11. } else {
        12. p.Remove("article.list.0")
        13. c, _ := p.ToJson()
        14. fmt.Println(string(c))
        15. }

        以上程序输出结果为:

        1. {"article":{"count":"10","list":[{"content":"gf content2","title":"gf article2"},{"content":"gf content3","title":"gf article3"}]}}

        可以看到,使用Remove方法可以非常方便地根据pattern参数动态删除变量。在该示例中,我们删除了article.list数组的索引0数据项,并将XML转换为JSON数据格式返回。

      2. 动态生成指定格式的编码数据

        我们来动态生成一个XML,先来一个简单一点的。

        1. p := gparser.New(nil)
        2. p.Set("name", "john")
        3. p.Set("age", 18)
        4. p.Set("scores", map[string]int{
        5. "语文" : 100,
        6. "数学" : 100,
        7. "英语" : 100,
        8. })
        9. c, _ := p.ToXmlIndent("simple-xml")
        10. fmt.Println(string(c))
        1. <simple-xml>
        2. <age>18</age>
        3. <name>john</name>
        4. <scores>
        5. <数学>100</数学>
        6. <英语>100</英语>
        7. <语文>100</语文>
        8. </scores>
        9. </simple-xml>

        可以看到,我们直接使用Set方式便创建了一个XML数据格式,根本就不需要struct有木有?!想要struct?当然也可以,请看下面的示例。

      1. 数据格式相互转换

        由于只是演示数据格式的转换,咱们来个数据结构简单点的:

         p := gparser.New(map[string]string{
             "name" : "gf",
             "site" : "https://gitee.com/johng",
         })
         c, _ := p.ToJson()
         fmt.Println("JSON:")
         fmt.Println(string(c))
         fmt.Println("======================")
        
         fmt.Println("XML:")
         c, _ = p.ToXmlIndent()
         fmt.Println(string(c))
         fmt.Println("======================")
        
         fmt.Println("YAML:")
         c, _ = p.ToYaml()
         fmt.Println(string(c))
         fmt.Println("======================")
        
         fmt.Println("TOML:")
         c, _ = p.ToToml()
         fmt.Println(string(c))
        
        
        

        可以看到,gparser包使得数据格式的转换变得异常的方便灵活。