使用Golang的html/template格式化JSON数据

使用Golang的html/template格式化JSON数据 你好! 我想使用GET请求的JSON输出来创建一个HTML表格,但不知道如何实现。 我的代码如下:

package main

import (

"encoding/json"

"fmt"

"html/template"

"net/http"

"os"

"time"

 )

var answer string

type AutoGenerated struct {

Latest    Latest      `json:"latest"`

Locations []Locations `json:"locations"`

}

type Latest struct {

Confirmed int `json:"confirmed"`

Deaths    int `json:"deaths"`

Recovered int `json:"recovered"`

}

type Coordinates struct {

Latitude  string `json:"latitude"`

Longitude string `json:"longitude"`

}

type Locations struct {

ID          int         `json:"id"`

Country     string      `json:"country"`

CountryCode string      `json:"country_code"`

Province    string      `json:"province"`

LastUpdated time.Time   `json:"last_updated"`

Coordinates Coordinates `json:"coordinates"`

Latest      Latest      `json:"latest"`

}

var baseUrl = "https://coronavirus-tracker-api.herokuapp.com/v2"

var latestUrl = "/locations"

 func getJson(url string, target interface{}) error {

req, err := http.NewRequest("GET", url, nil)

if err != nil {

    fmt.Println(err)

}

req.Header.Add("content-type", "application/json")

res, err := http.DefaultClient.Do(req)

if err != nil {

    fmt.Println(err)

    //return err.Error()

}

defer res.Body.Close()

return json.NewDecoder(res.Body).Decode(target)

}

var dataPage = `<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title></title>

</head>

<body>

<ul>

{{range .}}

    <li>

        <span>{{.Country}} </span>

    </li>

{{end}}

</ul>

</body>

</html>`

 func main() {

var locationsUrl = baseUrl + latestUrl

var data AutoGenerated

getJson(locationsUrl, &data)

fmt.Printf("%+v\n", data)

tmp, err := template.New("data").Parse(dataPage)

if err != nil {

    panic(err)

}

tmp.Execute(os.Stdout, data)

}

我的目标是得到类似这样的输出: https://coronavirus-tracker-api.herokuapp.com/v2/locations

我尝试使用html/template在标准输出的HTML中打印国家列表,但没有得到任何结果。

谢谢


更多关于使用Golang的html/template格式化JSON数据的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

非常感谢!

更多关于使用Golang的html/template格式化JSON数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


具体是哪里不工作?你收到错误了吗?你得到了什么输出,你期望得到什么?

https://coronavirus-tracker-api.herokuapp.com/v2/locations 返回的 JSON 对象包含两个成员:latestlocations。根据您的 HTML 模板,您似乎想要遍历 locations。请按如下方式操作:

tmp.Execute(os.Stdout, data.Locations)

我参考了这个链接:https://play.golang.org/p/EYfV-TzoA0 我期望在输出中得到类似这样的内容:

<li>
	<span>Italy</span>
</li>

<li>
	<span>Spain</span>
</li>

在您的代码中,模板期望接收的是切片类型,但您传递的是 AutoGenerated 结构体。AutoGenerated 包含 Locations 切片,但模板中的 {{range .}} 直接作用于整个结构体,因此无法正确遍历。您需要将 data.Locations 传递给模板。

以下是修改后的代码示例:

package main

import (
    "encoding/json"
    "fmt"
    "html/template"
    "net/http"
    "os"
    "time"
)

type AutoGenerated struct {
    Latest    Latest      `json:"latest"`
    Locations []Locations `json:"locations"`
}

type Latest struct {
    Confirmed int `json:"confirmed"`
    Deaths    int `json:"deaths"`
    Recovered int `json:"recovered"`
}

type Coordinates struct {
    Latitude  string `json:"latitude"`
    Longitude string `json:"longitude"`
}

type Locations struct {
    ID          int         `json:"id"`
    Country     string      `json:"country"`
    CountryCode string      `json:"country_code"`
    Province    string      `json:"province"`
    LastUpdated time.Time   `json:"last_updated"`
    Coordinates Coordinates `json:"coordinates"`
    Latest      Latest      `json:"latest"`
}

var baseUrl = "https://coronavirus-tracker-api.herokuapp.com/v2"
var latestUrl = "/locations"

func getJson(url string, target interface{}) error {
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return err
    }
    req.Header.Add("content-type", "application/json")
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()
    return json.NewDecoder(res.Body).Decode(target)
}

var dataPage = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>COVID-19 Data</title>
</head>
<body>
    <table border="1">
        <tr>
            <th>Country</th>
            <th>Confirmed</th>
            <th>Deaths</th>
            <th>Recovered</th>
        </tr>
        {{range .Locations}}
        <tr>
            <td>{{.Country}}</td>
            <td>{{.Latest.Confirmed}}</td>
            <td>{{.Latest.Deaths}}</td>
            <td>{{.Latest.Recovered}}</td>
        </tr>
        {{end}}
    </table>
</body>
</html>`

func main() {
    var locationsUrl = baseUrl + latestUrl
    var data AutoGenerated
    err := getJson(locationsUrl, &data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", data)

    tmp, err := template.New("data").Parse(dataPage)
    if err != nil {
        panic(err)
    }
    tmp.Execute(os.Stdout, data)
}

关键修改点:

  1. 模板中的 {{range .}} 改为 {{range .Locations}},以遍历 AutoGenerated 结构体中的 Locations 切片。
  2. 在模板中通过 {{.Country}}{{.Latest.Confirmed}} 等字段访问每个 Locations 元素的数据。
  3. getJson 函数中的错误直接返回,并在 main 函数中处理,避免程序静默失败。
  4. 模板内容调整为标准的 HTML 表格结构,显示国家名称和对应的疫情数据。

执行此代码后,标准输出将生成包含国家列表和对应疫情数据的 HTML 表格。

回到顶部