使用Go语言解析Json时出错

时间:2017-07-07 15:11:25

标签: go

我正在尝试解析Json&打印数据并使用GO语言以CSV格式保存。

它使用Println每页打印所需的10个结果,但无法解析JSON。

这就是我正在做的事情

  1. 访客访问studentresults.com/page=1 RollNo。 &安培;显示10名学生的成绩,并将其保存为CSV [key.rollno& key.marks]

  2. 程序向studentsapimarks.com/api/rollno1,rollno2,rollno3/detail发出请求(附加我们在第1步中获得的所有key.rollno) Json的回应就像

    [{"name":"James","Percentage":96.5,"Remarks":"VeryGood"}, 
    {"name":"William","Percentage":36.0,"Remarks":"Bad"}, 
    {"name":"Jacob","Percentage":63.0,"Remarks":"Average"}, 
    {"name":"Wilson","Percentage":69.3,"Remarks":"Average"}, 
    {"name":"Kurtson","Percentage":16.9,"Remarks":"VeryBad"}, 
    {"name":"Tom","Percentage":86.3,"Remarks":"Good"}]
    
  3. Extract Name&百分比字段&保存在csv

  4. 以下是我负责打印和保存结果的代码片段

    package main
    
    import (
        "encoding/csv"
        "fmt"
        "net/http"
        "os"
        "strings"
        "encoding/json"
    
    )
    
    
    type Key struct {
        fname      string
        marks      int
        rollno     int
        }
    
    type object struct {
        Percentage float64
        Name string `json:"name"`
        }
    
    
    func PageRequest(w http.ResponseWriter, r *http.Request) {
    
    
        // Page header
        fmt.Fprintf(w, PageHeader, pages, previous, next)
    
        // Save in csv
        csvfile, err := os.OpenFile("marks.csv", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
        if err != nil {
            fmt.Println("Error:", err)
            return
        }
        defer csvfile.Close()
    
        writer := csv.NewWriter(csvfile)
        defer writer.Flush()
    
        // Defining RollNos
        var rollNos []string
    
        // Marks for UID
        UID, length := compute(start)
        for i := 0; i < length; i++ {
            key := UID[i]
    
        // Prints firstname, Marks and Rollno
            fmt.Fprintf(w, key.fname, key.marks, key.rollno) 
    
    
    
            records := [][]string{{key.fname, key.marks, key.rollno}}
    
            for _, record := range records {
                err := writer.Write(record)
                if err != nil {
                    fmt.Println("Error:", err)
                    return
                }
            }
    
        // Append All key.rollno
            rollNos := append(rollNos, key.rollno)
    
        // Makes a request to as studentsapimarks.com/api/rollno1,rollno2,rollno3/detail
            uri := "https://studentsapimarks.com/api/" + strings.Join(rollNos, ",") + "/detail"
    
            res, err := http.Get(uri)
            if err != nil {
                log.Fatal(err)
            }
            defer res.Body.Close()
    
            var s []object
            err = json.NewDecoder(res.Body).Decode(&s)
            if err != nil {
                log.Fatal(err)
            }
    
        // Prints Name/ Percentage
            fmt.Println(s[0].Name)
            fmt.Println(s[0].Percentage)
        }
    
        // Page Footer
        fmt.Fprintf(w, PageFooter, previous, next)
    }
    
    
    func main() {
        http.HandleFunc("/", PageRequest)
    
    log.Println("Listening")
    log.Fatal(http.ListenAndServe(":8080", nil))
    
    }
    

    fmt.Fprintf(w, key.fname, key.marks, key.rollno)工作正常,每页显示10个结果并保存在csv中。

    代码问题是

    1. 我们在第1步中将所有key.rollno追加为studentsapimarks.com/api/rollno1,rollno2,rollno3/detail

    2. 另外,如何将JSON提取的s[0].name结果保存为CSV?

1 个答案:

答案 0 :(得分:1)

JSON解析失败,因为您正在尝试将JSON数组解组为结构。您希望将JSON数组解组为切片 - 外部结构不是必需的:

var s []object
err = json.NewDecoder(res.Body).Decode(&s)

此外,它只能解组导出的字段(以大写字母开头的字段),因此要获取名称,您需要更改结构定义。我猜这个百分比也没有通过,因为在JSON中它只是一个浮点值,但在你的结构中你需要一个浮动切片。

type object struct {
    // "Percentage": 96.4 is not a slice.
    // Also if the field name in Go and JSON are identical, you dont need the json tag.
    Percentage float64
    // The field must be capitalized, the tag can stay lowercase
    Name string `json:"name"`
}

然后您将相应地访问这些字段:

// Prints Name/ Percentage
fmt.Println(s[0].Name)
fmt.Println(s[0].Percentage)