golang: How can i access json decoded field?

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

golang: How can i access json decoded field?

问题

我有以下JSON数据:http://jsonblob.com/532d537ce4b0f2fd20c517a4

所以我想要遍历的是invoices -> invoice(是一个数组)

所以,我想要做的是:

package main
import (
	"fmt"
	"reflect"
	"encoding/json"
)

func main() {
	json_string := `{"result":"success","totalresults":"494","startnumber":0,"numreturned":2,"invoices":{"invoice":[{"id":"10660","userid":"126","firstname":"Warren","lastname":"Tapiero","companyname":"ONETIME","invoicenum":"MT-453","date":"2014-03-20","duedate":"2014-03-25","datepaid":"2013-07-20 15:51:48","subtotal":"35.00","credit":"0.00","tax":"0.00","tax2":"0.00","total":"35.00","taxrate":"0.00","taxrate2":"0.00","status":"Paid","paymentmethod":"paypalexpress","notes":"","currencycode":"USD","currencyprefix":"$","currencysuffix":" USD"},{"id":"10661","userid":"276","firstname":"koffi","lastname":"messigah","companyname":"Altech France","invoicenum":"","date":"2014-03-21","duedate":"2014-03-21","datepaid":"0000-00-00 00:00:00","subtotal":"440.00","credit":"0.00","tax":"0.00","tax2":"0.00","total":"440.00","taxrate":"0.00","taxrate2":"0.00","status":"Unpaid","paymentmethod":"paypal","notes":"","currencycode":"USD","currencyprefix":"$","currencysuffix":" USD"}]}}`

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

    invoices := dat["invoices"]

    fmt.Println("\nJSON-VALUE:",json_string)
    fmt.Println("\nVar type:",invoices)
    fmt.Println("\nVar type using REFLECT:",reflect.TypeOf(invoices))

    for index,value := range invoices.invoice {
        fmt.Println(index,value)
    }

}

但是我收到了类似这样的错误:invoices.invoice未定义(类型interface {}没有字段或方法invoice)

http://play.golang.org/p/8uTtN6KtTq

所以,请帮助我,这是我使用Go的第一天。

非常感谢。

英文:

i have the next JSON data: http://jsonblob.com/532d537ce4b0f2fd20c517a4

So what im trying to iterate ( like foreach in PHP ) is: invoices -> invoice ( is an array )

So, what im trying to do is:

package main
import (
	"fmt"
	"reflect"
	"encoding/json"
)

func main() {
	json_string := `{"result":"success","totalresults":"494","startnumber":0,"numreturned":2,"invoices":{"invoice":[{"id":"10660","userid":"126","firstname":"Warren","lastname":"Tapiero","companyname":"ONETIME","invoicenum":"MT-453","date":"2014-03-20","duedate":"2014-03-25","datepaid":"2013-07-20 15:51:48","subtotal":"35.00","credit":"0.00","tax":"0.00","tax2":"0.00","total":"35.00","taxrate":"0.00","taxrate2":"0.00","status":"Paid","paymentmethod":"paypalexpress","notes":"","currencycode":"USD","currencyprefix":"$","currencysuffix":" USD"},{"id":"10661","userid":"276","firstname":"koffi","lastname":"messigah","companyname":"Altech France","invoicenum":"","date":"2014-03-21","duedate":"2014-03-21","datepaid":"0000-00-00 00:00:00","subtotal":"440.00","credit":"0.00","tax":"0.00","tax2":"0.00","total":"440.00","taxrate":"0.00","taxrate2":"0.00","status":"Unpaid","paymentmethod":"paypal","notes":"","currencycode":"USD","currencyprefix":"$","currencysuffix":" USD"}]}}`
   
    var dat map[string]interface{}
    if err := json.Unmarshal([]byte(json_string), &dat); err != nil {
        panic(err)
    }

    invoices := dat["invoices"]
    
    fmt.Println("\nJSON-VALUE:",json_string)
    fmt.Println("\nVar type:",invoices)
    fmt.Println("\nVar type using REFLECT:",reflect.TypeOf(invoices))

    for index,value := range invoices.invoice {
    	fmt.Println(index,value)
	}

}

but im receiving errors like: invoices.invoice undefined (type interface {} has no field or method invoice)

http://play.golang.org/p/8uTtN6KtTq

So please, i need some help here, is my first day with Go.

Thank you very much.

答案1

得分: 2

当你执行invoices := dat["invoices"]时,invoices的类型是interface{},这是Go语言中表示可以是任何类型的意思。

实际上,它是一个map[string]interface{}类型。要将interface{}转换为具体类型,你需要使用type assertion,像这样:

for index, value := range invoices.(map[string]interface{}) {
    fmt.Println(index, value)
}

playground中可以看到完整的示例。

然而,如果这个结构是明确定义的(并非所有的JSON都是如此),那么我建议定义一个结构体并进行解组,这样可以使你的代码更易读。不要忘记为结构体名称使用大写字母,并使用json:"name"标签来命名字段(参见文档中的标签部分)。

英文:

When you did invoices := dat["invoices"] the type of invoices is interface{} which is go speak for could be anything.

In actual fact it is a map[string]interface{}. To turn an interface{} into it's concrete type you need to use a type assertion like this.

for index,value := range invoices.(map[string]interface{}) {
    fmt.Println(index,value)
}

See the playground for full example.

However if this structure is well defined (not all json is) then I'd define a struct and unmarshal to that which will make your code a lot easier to read. Don't forget to use Capital letters for your struct names and then name them with the json:"name" tags (see tags in the Marshal section of the docs)

huangapple
  • 本文由 发表于 2014年3月22日 17:35:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/22575847.html
匿名

发表评论

匿名网友

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

确定