从JSON中提取元素

时间:2016-12-01 21:24:56

标签: json go unmarshalling

我有一个返回JSON的函数,返回类型为:

{
  "someNumber": 1,
  "someString": "ee",
  "someArray": [
    "stringInArray",
    {
      "anotherNumber": 100,
      "anotherString": "asdf",
      "yetAnotherString": "qwer"
    }
  ]
}

在我的特定情况下,我知道返回的JSON看起来像这样:

var f interface{}
b := []byte(`res` )
err2 := json.Unmarshal(b, &f)
if err2!=nil{
    log.Fatalf("Err unmarshalling: %v", err2)
}

m := f.( map[string]interface{} )

for k, v := range m {
    switch vv := v.(type) {
    case string:
        fmt.Println(k, "is string", vv)
    case int:
        fmt.Println(k, "is int", vv)
    case []interface{}:
        fmt.Println(k, "is an array:")
        for i, u := range vv {
            fmt.Println(i, u)
        }
    default:
        fmt.Println(k, "is of a type I don't know how to handle")
    }
}

我想获得" stringInArray"的价值还有" anotherString"。我从Go by Exampleblog.golang.org搜索了解决方案,但我没有成功。

例如,假设 res 是从函数调用返回的json,我尝试了这个(来自go博客):

res

(我知道上面的内容不会完全符合我的要求,但这是一个开始。) 但是当代码执行命中 b:= [] byte(Err unmarshalling: invalid character 'r' looking for beginning of value 时,我收到此错误:

type LoginResponse2 struct {

    id float64
    jsonrpc string
    result struct {
        token string
        details struct {
            a float64
            b string
            c float64
        }
    }   
}

var resStruct2 LoginResponse2
// Convert result to json
b, _ :=json.Marshal(res)
fmt.Println( string(b) )
// results of Println:
{"id":1,"jsonrpc":"2.0","result":[ "myToken",{"a":someNumber,"b":"some string","c":someOtherNumber} ] }


// Unmarshall json into struct
err2 := json.Unmarshal(b, &resStruct2)
if err2 != nil {
    log.Fatalf("Error unmarshalling json: %v", err)
}

fmt.Println("Here is json unmarshalled into a struct")
fmt.Println( resStruct2 )
// results of Println
{0  { {0  0}}}

获取价值的最有效方法/最佳做法是什么?我对任何解决方案持开放态度,不一定是上述方法。

@sydnash这是我在回复你的评论时承诺的代码:

{{1}}

2 个答案:

答案 0 :(得分:2)

我认为你应该使用b:= [] byte(res)而不是b:= [] byte [res]而res应该是json字符串或[]字节。 res不是合法的json格式。

此信息可能对您有所帮助: 要将JSON解组为接口值,Unmarshal将其中一个存储在接口值中:

bool,适用于JSON布尔值

float64,用于JSON编号

字符串,用于JSON字符串

[] interface {},用于JSON数组

map [string] interface {},用于JSON对象

为JSON null

为零

你可以看到没有int但是没有用于JSON数字的float64。

答案 1 :(得分:1)

有一个例子说明如何在golang包encoding/json上的文档中解组json。基本上你的问题是,非编组期望将json放入type。因此,您的代码必须声明一个代表您要转换的json的类型。

来自链接示例的json和声明类型的示例:

var jsonBlob = []byte(`[
    {"Name": "Platypus", "Order": "Monotremata"},
    {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`)
type Animal struct {
    Name  string
    Order string
}

一旦你定义了类型,它就应该全部落实到位。