英文:
Parsing nested JSON in go language
问题
如何解析和提取以下JSON中的特定值?
这是示例JSON响应:
{
   "success":true,
   "endpoint":"https://api.abcxyz.com",
   "info":{
      "Guestconnected":134,
      "Guestratio":100000.06963,
      "symbol1":{
         "code":"NY",
         "symbol":"*",
         "name":"newyear",
         "codev":391.78161,
         "symbolAppearsAfter":false,
         "local":true
      },
      "symbol2":{
         "code":"HNY",
         "symbol":"@",
         "name":"HappyNewYear",
         "codev":1000000.0960,
         "symbolAppearsAfter":true,
         "local":false
      },
      "latest":{
         "value":1597509,
         "autovalue":"00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height":474696,
         "time":1499527696
      }
   },
   "Allguest":{
      "all":4,
      "filtered":4,
      "total_invitations":15430,
      "sent_invitations":15430,
      "final_invitations":0
   },
   "Guestlist":[
      {
         "GuestCode":"369AR",
         "all":2,
         "total_invitations":5430,
         "sent_invitations":5430,
         "final_invitations":0,
         "change":0,
         "accounts":0
      },
      {
         "GuestCode":"6POIA96TY",
         "all":2,
         "total_invitations":10000,
         "sent_invitations":10000,
         "final_invitations":0,
         "change":0,
         "accounts":0
      }
   ]
}
我的代码是:
package main
import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)
type object struct {
    Success bool `json:"success"`
    Endpoint string `json:"endpoint"`
    Allguest struct {
        All int `json:"all"`
        Filtered int `json:"filtered"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
    } `json:"Allguest"`
    Guestlist []struct {
        GuestCode string `json:"GuestCode"`
        All int `json:"all"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
        Change int `json:"change"`
        Accounts int `json:"accounts"`
    } `json:"Guestlist"`
}
func main() {
uri := "https://siteurl.com/api?lists=1"
res, err := http.Get(uri)
fmt.Println(uri)
if err != nil {
fmt.Println("Error:", err)
    log.Fatal(err)
}
defer res.Body.Close()
 var s object
err := json.NewDecoder(res.Body).Decode(&s)
if err != nil {
    log.Fatal(err)
    fmt.Println("Error:", err)
}
fmt.Println(s.Success)
fmt.Println(s.Allguest.TotalInvitations)
for i := 0; i < 6; i++ {
fmt.Println(s.Guestlist[i].TotalInvitations)
}
}
问题是:
- 
如果响应为空,它会给出“索引超出范围错误”,我们如何避免这种情况?
 - 
如果
TotalInvitations的值大于100,则将其保存在100.csv中,否则保存在others.csv中。 
英文:
How could I parse and extract certain values from below JSON
Here is the sample JSON response
{
"success":true,
"endpoint":"https://api.abcxyz.com",
"info":{
"Guestconnected":134,
"Guestratio":100000.06963,
"symbol1":{
"code":"NY",
"symbol":"*",
"name":"newyear",
"codev":391.78161,
"symbolAppearsAfter":false,
"local":true
},
"symbol2":{
"code":"HNY",
"symbol":"@",
"name":"HappyNewYear",
"codev":1000000.0960,
"symbolAppearsAfter":true,
"local":false
},
"latest":{
"value":1597509,
"autovalue":"00099cf8da58a36c08f2ef98650ff6043ddfb",
"height":474696,
"time":1499527696
}
},
"Allguest":{
"all":4,
"filtered":4,
"total_invitations":15430,
"sent_invitations":15430,
"final_invitations":0
},
"Guestlist":[
{
"GuestCode":"369AR",
"all":2,
"total_invitations":5430,
"sent_invitations":5430,
"final_invitations":0,
"change":0,
"accounts":0
},
{
"GuestCode":"6POIA96TY",
"all":2,
"total_invitations":10000,
"sent_invitations":10000,
"final_invitations":0,
"change":0,
"accounts":0
}
]
}
My Code is :
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type object struct {
Success bool `json:"success"`
Endpoint string `json:"endpoint"`
Allguest struct {
All int `json:"all"`
Filtered int `json:"filtered"`
TotalInvitations int `json:"total_invitations"`
SentInvitations int `json:"sent_invitations"`
FinalInvitations int `json:"final_invitations"`
} `json:"Allguest"`
Guestlist []struct {
GuestCode string `json:"GuestCode"`
All int `json:"all"`
TotalInvitations int `json:"total_invitations"`
SentInvitations int `json:"sent_invitations"`
FinalInvitations int `json:"final_invitations"`
Change int `json:"change"`
Accounts int `json:"accounts"`
} `json:"Guestlist"`
}
func main() {
uri := "https://siteurl.com/api?lists=1"
res, err := http.Get(uri)
fmt.Println(uri)
if err != nil {
fmt.Println("Error:", err)
log.Fatal(err)
}
defer res.Body.Close()
var s object
err := json.NewDecoder(res.Body).Decode(&s)
if err != nil {
log.Fatal(err)
fmt.Println("Error:", err)
}
fmt.Println(s.Success)
fmt.Println(s.Allguest.TotalInvitations)
for i := 0; i < 6; i++ {
fmt.Println(s.Guestlist[i].TotalInvitations)
)
}
The problem is :
- 
If the response is null it is giving
index out of range errorhow can we avoid this ? - 
Applying condition if
TotalInvitationsvalue is greater than100then save in100.csvelse save inothers.csv 
答案1
得分: 1
如果您只需要从JSON中获取特定的条目,您可以定义一个只包含您感兴趣的字段的结构。如果值可以为null,最好在结构中声明一个指针。请查看Go Playground上的示例:https://play.golang.org/p/mEwSXvPg3D
英文:
If you need only certain entries from JSON you can define a structure with only those fields you are interested in. And if value can be null it is better to declare a pointer in the structure. Please take a look at an example at go playground: https://play.golang.org/p/mEwSXvPg3D
答案2
得分: 0
使用gjson包以简单的方式从JSON文档中获取值
示例:
package main
import (
	"fmt"
	"github.com/tidwall/gjson"
)
func main() {
	data := []byte(`{
   "success": true,
   "endpoint": "https://api.abcxyz.com",
   "info": {
      "Guestconnected": 134,
      "Guestratio": 100000.06963,
      "symbol1": {
         "code": "NY",
         "symbol": "*",
         "name": "newyear",
         "codev": 391.78161,
         "symbolAppearsAfter": false,
         "local": true
      },
      "symbol2": {
         "code": "HNY",
         "symbol": "@",
         "name": "HappyNewYear",
         "codev": 1000000.096,
         "symbolAppearsAfter": true,
         "local": false
      },
      "latest": {
         "value": 1597509,
         "autovalue": "00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height": 474696,
         "time": 1499527696
      }
   },
   "Allguest": {
      "all": 4,
      "filtered": 4,
      "total_invitations": 15430,
      "sent_invitations": 15430,
      "final_invitations": 0
   },
   "Guestlist": [
      {
         "GuestCode": "369AR",
         "all": 2,
         "total_invitations": 5430,
         "sent_invitations": 5430,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      },
      {
         "GuestCode": "6POIA96TY",
         "all": 2,
         "total_invitations": 10000,
         "sent_invitations": 10000,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      }
   ]
	}
	`)
	r := gjson.GetBytes(data, "Allguest.total_invitations")
	fmt.Println(r.Value()) // 输出 15430
	r = gjson.GetBytes(data, "Guestlist.#.total_invitations")
	fmt.Println(r.Value()) // 输出 [5430 10000]
}
英文:
use gjson pkg to get value from json document an simple way
example:
package main
import (
"fmt"
"github.com/tidwall/gjson"
)
func main() {
data := []byte(`{
"success": true,
"endpoint": "https://api.abcxyz.com",
"info": {
"Guestconnected": 134,
"Guestratio": 100000.06963,
"symbol1": {
"code": "NY",
"symbol": "*",
"name": "newyear",
"codev": 391.78161,
"symbolAppearsAfter": false,
"local": true
},
"symbol2": {
"code": "HNY",
"symbol": "@",
"name": "HappyNewYear",
"codev": 1000000.096,
"symbolAppearsAfter": true,
"local": false
},
"latest": {
"value": 1597509,
"autovalue": "00099cf8da58a36c08f2ef98650ff6043ddfb",
"height": 474696,
"time": 1499527696
}
},
"Allguest": {
"all": 4,
"filtered": 4,
"total_invitations": 15430,
"sent_invitations": 15430,
"final_invitations": 0
},
"Guestlist": [
{
"GuestCode": "369AR",
"all": 2,
"total_invitations": 5430,
"sent_invitations": 5430,
"final_invitations": 0,
"change": 0,
"accounts": 0
},
{
"GuestCode": "6POIA96TY",
"all": 2,
"total_invitations": 10000,
"sent_invitations": 10000,
"final_invitations": 0,
"change": 0,
"accounts": 0
}
]
}
`)
r := gjson.GetBytes(data, "Allguest.total_invitations")
fmt.Println(r.Value()) // output 15430
r = gjson.GetBytes(data, "Guestlist.#.total_invitations")
fmt.Println(r.Value()) // output [5430 10000]
}
答案3
得分: 0
> 如果响应为null,则会出现索引超出范围的错误,我们如何避免这种情况?
除非我误解了你的意思,响应为null不应该有影响。如果你收到了2个Guestlist项,你只能循环遍历这2个项,意味着for i := 0; i < 6; i++是错误的。将其改为for i := 0; i < len(s.Guestlist); i++或for i := range s.Guestlist。
> 如果TotalInvitations的值大于100,则保存在100.csv中,否则保存在others.csv中。
你可能需要使用os包的Create函数来创建一个新的文件用于写入,或者使用OpenFile函数、O_CREATE、O_WRONLY和O_APPEND文件打开标志,并且可以将0755作为权限模式(或者如果你想更改文件的访问权限,可以使用其他一组八进制权限)。
然后,你可以使用csvWriter := csv.NewWriter(csvFile)来包装生成的io.Writer(假设打开文件时没有错误)。然后,你可以将所需的任何信息以CSV记录的形式写入文件。不要忘记调用csvWriter.Flush来刷新输出缓冲区,以及使用csvWriter.Error来检查是否在刷新输出缓冲区时出现错误。还要记得关闭你打开的文件。
英文:
> If the response is null it is giving index out of range error how can
> we avoid this?
Unless I'm misunderstanding you, the response being null shouldn't matter.  If you receive 2 Guestlist items, you can only loop over those 2, meaning `for i := 0; i < 6; i++` is wrong.  Change it to `for i := 0; i < len(s.Guestlist); i++` or `for i := range s.Guestlist`.
> Applying condition if TotalInvitations value is greater than 100 then
> save in 100.csv else save in others.csv
You will probably want the `os` package's [`Create`](https://golang.org/pkg/os/#Create) function to create a new file for writing or the [`OpenFile`](https://golang.org/pkg/os/#OpenFile) function, the [`O_CREATE`, `O_WRONLY`, and `O_APPEND`](https://golang.org/pkg/os/#O_WRONLY) file-open flags, and you can pass `0755` as the permission mode (or another set of octal permissions if you want to change access of a file).
You can then use `csvWriter := csv.NewWriter(csvFile)` to wrap the resulting `io.Writer` (assuming there is no error opening the file).  From there, you can just write whatever information you require to the file as CSV records.  Don't forget to call `csvWriter.Flush` to flush the output buffer and `csvWriter.Error` to check whether there was an error flushing the output buffer.  Also don't forget to close the file you opened.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论