从JSON中提取元素

huangapple go评论149阅读模式
英文:

Extracting Elements from JSON

问题

我有一个返回JSON的函数,返回类型是这样的:

map[string]interface{}

在我的特定情况下,我知道返回的JSON是这样的:

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

我想要获取"stringInArray"和"anotherString"的值。我已经从Go by Exampleblog.golang.org等地方搜索了解决方案,但没有成功。

例如,假设res是从函数调用返回的JSON,我尝试了以下代码(来自Go博客):

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")
    }
}

(我知道上面的代码不会完全实现我想要的功能,但这是一个开始。)

但是当代码执行到**b := []byte(res)**时,我得到了以下错误:

Err unmarshalling: invalid character 'r' looking for beginning of value

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

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

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

var resStruct2 LoginResponse2
// 将结果转换为JSON
b, _ := json.Marshal(res)
fmt.Println(string(b))
// Println的结果:
// {"id":1,"jsonrpc":"2.0","result":["myToken",{"a":someNumber,"b":"some string","c":someOtherNumber}]}

// 将JSON解组为结构体
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)
// Println的结果:
// {0  { {0  0}}}
英文:

I have a function that returns JSON, and the return type is this:

map[string]interface{}

In my particular case, I know that the returned JSON looks like this:

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

I want to get the value of "stringInArray" and also "anotherString". I've searched for solutions for example from Go by Example and blog.golang.org but I've not been successful.

For example, given that res is the json returned from the function call, I tried this (from the go blog):

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")
    }
}

(I know the above would not do exactly what I want but it is a start.)
But when code execution hits b := []byte(res ), I get this error:

Err unmarshalling: invalid character 'r' looking for beginning of value

What is the most efficient method / best practice for obtaining the values? I'm open to any solution, not necessarily the approach above.

@sydnash Here is the code I promised in my response to your comment:

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}}}

答案1

得分: 2

我认为你应该使用b := []byte(res)而不是b := []byte[res],并且res应该是一个JSON字符串或[]byteres不是一个合法的JSON格式。

这些信息可能对你有帮助:
将JSON解组为接口值时,Unmarshal将以下之一存储在接口值中:

  • bool,用于JSON布尔值
  • float64,用于JSON数字
  • string,用于JSON字符串
  • []interface{},用于JSON数组
  • map[string]interface{},用于JSON对象
  • nil,用于JSON null

你可以看到,JSON数字没有int类型,而是使用float64类型。

英文:

I think you should use b := []byte(res) instead b :=[]byte[res] and res should be a json string or []byte. res is not a legal json format.

this information maybe help you:
To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:

bool, for JSON booleans

float64, for JSON numbers

string, for JSON strings

[]interface{}, for JSON arrays

map[string]interface{}, for JSON objects

nil for JSON null

you can see there is no int but float64 for JSON numbers.

答案2

得分: 1

在Golang包的文档中有一个关于如何解析JSON的示例encoding/json。基本上,你的问题是unmarshal期望将JSON放入type中。因此,你的代码必须声明一个表示你要转换的JSON的类型。

以下是链接示例中的JSON和声明的类型的示例:

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

一旦你定义了类型,一切都应该就位了。

英文:

There is an example of how to unmarshal json in the docs on golang packages encoding/json. Essentially your problem is that the un-marshal expects to be putting the json into type. So your code must declare a type that represents the json you are converting from.

Example of the json and the declared type from the linked example:

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

Once you define the type it should all fall into place.

1: https://golang.org/pkg/encoding/json/ "encoding/json"

huangapple
  • 本文由 发表于 2016年12月2日 05:24:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/40920658.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定