如何解析Go中的JSON?

时间:2014-02-28 10:53:44

标签: json go

JSON

{
  "id" : "12387",
  "inv" :[
    {
      "qty" : 5,

       "seq" : 2,
       "invIs" : "1HG9876",
       "addCharges" :[
         {
          "amnt" : 24,
          "char" : "REI",
          "type" : "MT"
          },
          {
          "amnt" : 24,
          "char" : "REI",
          "type" : "MT"
          }
        ],

      "seq" : 3

    },
    {
      "qty" : 5,

       "seq" : 2,
       "invIs" : "1HG9876",
       "addCharges" :[
         {
          "amnt" : 24,
          "char" : "REI",
          "type" : "MT"
          },
          {
          "amnt" : 24,
          "char" : "REI",
          "type" : "MT"
          }
        ],

      "seq" : 3

    }
  ],
    "charges" : {
      "fee" : 24 ,
      "bkg" : 7676
    }

}

我的JSON结构如上所示。我需要在inv-addCharges中使用 amnt 在数组中。如果它在数组中有十个元素,我需要在一个包含特定amnt的数组中以这样的方式获取它,如

[{"amnt" : 34 } ,{"amnt" : 34} .... so on ]

我尝试的事情:

var j map[string]interface{}
    err := json.Unmarshal([]byte(ticket), &j)
    if err != nil {
        panic(err)
    }

    // Pull out the parents object
    bytInv := j["inv"].([]interface{})    

    // // Print out mother and father
    fmt.Println(bytInv)

输出

[map[qty:5 seq:3 invIs:1HG9876 addCharges:[map[amnt:24 char:REI type:MT] map[amnt:24 char:REI type:MT]]] map[qty:5 seq:3 invIs:1HG9876 addCharges:[map[amnt:24 char:REI type:MT] map[amnt:24 char:REI type:MT]]]]

在此之后,我无法继续下去。

注意:我不想使用结构,因为我有很多JSON结构。这是我的要求。

1 个答案:

答案 0 :(得分:6)

是否要求,我真的不明白为什么你坚持不使用结构。 你能详细说明为什么会这样吗?

正如下面的示例程序所证明的那样,如果您只是将数据表示为正确类型的结构,那么解决方案就更容易理解和推理。您可以在Go playground上运行它以查看其实际效果。

您的JSON数据中有一部分让我感到困惑。每个Item节点包含seq字段两次。两者都有不同的价值。您使用哪种方式来解释数据,其中一个字段将丢失。根据unmarshaller的实现,它将忽略第二个字段,或用第二个值覆盖第一个字段。这是数据生成方式的错误。

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

func main() {
    charges, err := findCharges()
    if err != nil {
        fmt.Fprintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }

    for _, c := range charges {
        fmt.Printf("%+v\n", c)
    }
}

// findCharges locates all 'AddCharge` instances and returns them in a slice.
func findCharges() ([]AddCharge, error) {
    var prod Product

    data := []byte(jsonString)
    err := json.Unmarshal(data, &prod)
    if err != nil {
        return nil, err
    }

    var charges []AddCharge

    for _, item := range prod.Items {
        charges = append(charges, item.AddCharges...)
    }

    return charges, nil
}

type Product struct {
    Id    string `json:"id"`
    Items []Item `json:"inv"`
}

type Item struct {
    Quantity   int         `json:"qty"`
    Sequence   int         `json:"seq"`
    Inventory  string      `json:"invIs"`
    AddCharges []AddCharge `json:"addCharges"`
    Charges    []Charge    `json:"charges"`
}

type Charge struct {
    Fee int `json:"fee"`
    Bkg int `json:"bkg"`
}

type AddCharge struct {
    Amount int    `json:"amnt"`
    Char   string `json:"char"`
    Type   string `json:"type"`
}

const jsonString = `{
  "id" : "12387",
  "inv" :[
    {
      "qty" : 5,
       "seq" : 2,
       "invIs" : "1HG9876",
       "addCharges" :[
         {
          "amnt" : 24,
          "char" : "REI",
          "type" : "MT"
          },
          {
          "amnt" : 12,
          "char" : "REI",
          "type" : "MT"
          }
        ],

      "seq" : 3

    },
    {
      "qty" : 5,

       "seq" : 2,
       "invIs" : "1HG9876",
       "addCharges" :[
         {
          "amnt" : 64,
          "char" : "REI",
          "type" : "MT"
          },
          {
          "amnt" : 36,
          "char" : "REI",
          "type" : "MT"
          }
        ],

      "seq" : 3

    }
  ],
    "charges" : {
      "fee" : 24 ,
      "bkg" : 7676
    }

}`

编辑:如果您感兴趣的是addCharges数据,则可以省略结构中不需要的所有字段。 unmarshaller将简单地忽略struct没有字段定义的数据。