英文:
Loop over nested JSON elements in Go
问题
您遇到的问题是在访问orderaddress.Region
时出现错误,错误信息显示OrderAddresses
类型没有Region
字段或方法。
问题出在OrderAddresses
的定义上。OrderAddresses
应该是一个结构体切片,而不是一个结构体数组。请将OrderAddresses
的定义更改为以下形式:
type OrderAddresses []struct {
Region string `json:"region"`
Postcode string `json:"postcode"`
Lastname string `json:"lastname"`
Street string `json:"street"`
City string `json:"city"`
Email string `json:"email"`
Telephone string `json:"telephone"`
CountryID string `json:"country_id"`
Firstname string `json:"firstname"`
AddressType string `json:"address_type"`
Prefix *string `json:"prefix"`
Middlename *string `json:"middlename"`
Suffix *string `json:"suffix"`
Company *string `json:"company"`
}
然后,您可以通过索引访问OrderAddresses
切片中的每个元素的字段。例如:
for _, orderaddress := range order.Addresses {
fmt.Println(orderaddress.Region)
}
这样应该就能够正确访问Region
字段了。
英文:
I am receiving a JSON response from an API that contains one or more "entities". The JSON looks like this:
{
"3211": {
"entity_id": "3211",
"status": "complete",
"coupon_code": "COUPON",
"shipping_description": "Shipping - AU Courier",
"customer_id": "2775",
"base_discount_amount": "-50.0000",
"base_grand_total": "149.0000",
"base_shipping_amount": "0.0000",
"base_shipping_tax_amount": "0.0000",
"base_subtotal": "199.0000",
"base_tax_amount": "0.0000",
"base_total_paid": "149.0000",
"base_total_refunded": null,
"discount_amount": "-50.0000",
"grand_total": "149.0000",
"shipping_amount": "0.0000",
"shipping_tax_amount": "0.0000",
"store_to_order_rate": "1.0000",
"subtotal": "199.0000",
"tax_amount": "0.0000",
"total_paid": "149.0000",
"total_refunded": null,
"base_shipping_discount_amount": "0.0000",
"base_subtotal_incl_tax": "199.0000",
"base_total_due": "0.0000",
"shipping_discount_amount": "0.0000",
"subtotal_incl_tax": "199.0000",
"total_due": "0.0000",
"increment_id": "200000423",
"base_currency_code": "AUD",
"discount_description": "COUPON",
"remote_ip": "123.123.123.123",
"store_currency_code": "AUD",
"store_name": "Australia",
"created_at": "2017-07-17 03:07:40",
"shipping_incl_tax": "0.0000",
"payment_method": "ewayrapid_ewayone",
"gift_message_from": null,
"gift_message_to": null,
"gift_message_body": null,
"tax_name": null,
"tax_rate": null,
"addresses": [
{
"region": "South Australia",
"postcode": "5000",
"lastname": "Doe",
"street": "Level 6\n25 Example Street",
"city": "Adelaide",
"email": "example@email.com",
"telephone": "+61 123 456 789",
"country_id": "AU",
"firstname": "John",
"address_type": "billing",
"prefix": null,
"middlename": null,
"suffix": null,
"company": null
},
{
"region": "South Australia",
"postcode": "5000",
"lastname": "Doe",
"street": "Level 6\n25 Example Street",
"city": "Adelaide",
"email": "example@email.com",
"telephone": "+61 123 456 789",
"country_id": "AU",
"firstname": "John",
"address_type": "shipping",
"prefix": null,
"middlename": null,
"suffix": null,
"company": null
}
]
}
}
I have written the following struct
types:
type Orders map[string]Order
type Order struct {
EntityID string `json:"entity_id"`
Status string `json:"status"`
CouponCode string `json:"coupon_code"`
ShippingDescription string `json:"shipping_description"`
CustomerID string `json:"customer_id"`
BaseDiscountAmount string `json:"base_discount_amount"`
BaseGrandTotal string `json:"base_grand_total"`
BaseShippingAmount string `json:"base_shipping_amount"`
BaseShippingTaxAmount string `json:"base_shipping_tax_amount"`
BaseSubtotal string `json:"base_subtotal"`
BaseTaxAmount string `json:"base_tax_amount"`
BaseTotalPaid string `json:"base_total_paid"`
BaseTotalRefunded string `json:"base_total_refunded"`
DiscountAmount string `json:"discount_amount"`
GrandTotal string `json:"grand_total"`
ShippingAmount string `json:"shipping_amount"`
ShippingTaxAmount string `json:"shipping_tax_amount"`
StoreToOrderRate string `json:"store_to_order_rate"`
Subtotal string `json:"subtotal"`
TaxAmount string `json:"tax_amount"`
TotalPaid string `json:"total_paid"`
TotalRefunded string `json:"total_refunded"`
BaseShippingDiscountAmount string `json:"base_shipping_discount_amount"`
BaseSubtotalInclTax string `json:"base_subtotal_incl_tax"`
BaseTotalDue string `json:"base_total_due"`
ShippingDiscountAmount string `json:"shipping_discount_amount"`
SubtotalInclTax string `json:"subtotal_incl_tax"`
TotalDue string `json:"total_due"`
IncrementID string `json:"increment_id"`
BaseCurrencyCode string `json:"base_currency_code"`
DiscountDescription string `json:"discount_description"`
RemoteIP string `json:"remote_ip"`
StoreCurrencyCode string `json:"store_currency_code"`
StoreName string `json:"store_name"`
CreatedAt string `json:"created_at"`
ShippingInclTax string `json:"shipping_incl_tax"`
PaymentMethod string `json:"payment_method"`
TaxName string `json:"tax_name"`
TaxRate string `json:"tax_rate"`
Addresses map[string]OrderAddresses `json:"addresses"`
}
type OrderAddresses []struct {
Region string `json:"region"`
Postcode string `json:"postcode"`
Lastname string `json:"lastname"`
Street string `json:"street"`
City string `json:"city"`
Email string `json:"email"`
Telephone string `json:"telephone"`
CountryID string `json:"country_id"`
Firstname string `json:"firstname"`
AddressType string `json:"address_type"`
Prefix *string `json:"prefix"`
Middlename *string `json:"middlename"`
Suffix *string `json:"suffix"`
Company *string `json:"company"`
}
I am then trying to process it like so (the getFromOrdersAPI(page)
function returns the JSON mentioned above in the Orders
type):
for page := 1; page < 3; page++ {
orders := getFromOrdersAPI(page)
for _, order := range orders {
//Process all the order items except addresses
fmt.Println("Processing entity:", orders.EntityID)
for _, orderaddress := range order.Addresses {
//Trying to access address values - example below
fmt.Println(orderaddress.Region)
}
}
}
When running this, I get the error:
> orderaddress.Region undefined (type OrderAddresses has no field or method Region)
Where am I going wrong?
答案1
得分: 2
你遇到的错误是由于你定义OrderAddresses
结构体的方式不正确。你应该使用以下方式进行定义:
type OrderAddresses struct {
// fields of OrderAddresses
}
不要使用大括号,这样你的编译错误应该会消失。
话虽如此,根据我查看的数据块,我不确定你的 JSON 是否会按照你的预期进行解析。看起来 JSON 数据中的 addresses
是一个数组。这意味着你应该将其表示为一个 OrderAddresses
的切片,而不是一个 map
。
Addresses []OrderAddresses `json:"addresses"`
希望对你有所帮助!
英文:
The error you are getting is due to the way you are defining your OrderAddresses
struct. Instead of
type OrderAddresses []struct {
If you use
type OrderAddresses struct {
without the braces, your compile error should go away.
That being said, I'm not sure if your json will parse as you expect given the blob I'm looking at. It appears that addresses
in the json blob is an array. This means that instead of representing it as
Addresses map[string]OrderAddresses `json:"addresses"`
You should simply make it a slice of OrderAddresses
Addresses []OrderAddresses `json:"addresses"`
答案2
得分: 1
你之所以会收到orderaddress.Region undefined
错误是因为根据你的OrderAddresses
类型,在你的for
循环中,orderaddress
是一个数组。显然,数组没有名为Region
的字段或方法。
如果你想查看for
循环中的orderaddress
的内容,你可以像这样使用range
:
for _, orderaddress := range order.Addresses {
for _, addressData := range orderaddress{
fmt.Printf("%+v\n", addressData)
}
}
我在这里创建了一个示例:链接。
话虽如此,在你的JSON数据中,addresses
字段是一个数组,而不是一个映射。所以你的Order
结构体中的Addresses
字段也必须是一个数组。然后你的OrderAddresses
应该只是一个结构体,而不是结构体的切片。
英文:
The reason you are getting the orderaddress.Region undefined
error is because the orderaddress
in your for
loop is an array, based on your OrderAddresses
type. Obviously, an array doesn't have fields or methods named Region
.
If you want to examine what orderaddress
in your for
loop looks like, you can range
over it like this:
for _, orderaddress := range order.Addresses {
for _, addressData := range orderaddress{
fmt.Printf("%+v\n", addressData)
}
}
I have created an example here.
That said, in your JSON data, the addresses
field is an array, not a map. So the Addresses
field in your Order
struct must be an array too. Then your OrderAddresses
should just be a struct, not a slice of struct.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论