duanhui3759 2017-07-07 15:11
浏览 51

使用Go语言解析Json时出错

I am trying to Parse Json & Print Data and save in a CSV using GO language .

It is printing the desired 10 result per page with Println but couldn't parse JSON .

This is what I am doing

  1. Visitor visits studentresults.com/page=1 RollNo. & Marks for 10 students are displayed and it is also saved in a CSV [key.rollno & key.marks]

  2. Program Makes a request to studentsapimarks.com/api/rollno1,rollno2,rollno3/detail (appending all key.rollno that we got in step1) The Json response would be like

    [{"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 & Percentage fields & save in a csv

Here is my snippet of the code that is responsible for printing and saving the results

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) is working fine and displays all 10 results per page and saves in a csv .

Problem with the code is

  1. It is not appending all key.rollno that we got in step1 as studentsapimarks.com/api/rollno1,rollno2,rollno3/detail

  2. Also how could i save the JSON extracted s[0].name results in a CSV ?

  • 写回答

1条回答 默认 最新

  • doucheng9058 2017-07-07 15:15
    关注

    The JSON parsing is failing because you're trying to unmarshal a JSON array into a struct. You want to unmarshal a JSON array into a slice - the outer struct is not necessary:

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

    Also, it can only unmarshal exported fields (those that start with a capital letter), so to get the name, you'll need to change your struct definition. I'm guessing the percentage isn't coming through either, since in the JSON it's a single float value, but in your struct you're taking a float slice.

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

    Then you'll access those fields accordingly:

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

报告相同问题?

悬赏问题

  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作