Golang如何从XML中解析数据块

Golang如何从XML中解析数据块 如何从XML中的Item块解组数据?Rates和Item块具有相同名称的字段。我从API获取XML数据并保存到数据库,使用gorm进行数据库操作。

我的代码保存了来自Rates块的数据(名称和标题)。我需要保存来自Item块的数据(名称和标题)。

API返回如下内容:

<rates>
    <name>text1</name>
    <title>text2</title>
    <item>
        <name>text3</name>
        <title>text4</title>
    </item>
</rates>

我的代码:

type Rates struct {
    XMLName xml.Name     `xml:"rates"`
    Rates   []Item       `xml:"item"`
}

type Item struct {
    Id          int    `xml:"id" gorm:"primaryKey"`
    Name        string `xml:"name"`
    Title       string `xml:"title"`
}

response, err := http.Get("https://API")
responseData, err := io.ReadAll(response.Body)

var var1 Item 
xml.Unmarshal(responseData, &var1)

if result := h.DB.Create(&var1); result.Error != nil {
    fmt.Println(result.Error)
}

w.Header().Add("Content-Type", "application/xml")
w.WriteHeader(http.StatusOK)
xml.NewEncoder(w).Encode(var1)

我删除了一些不必要的行,例如“if err != nil”,所以不必在意。


更多关于Golang如何从XML中解析数据块的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

我不太理解你的结构体布局和 xml 结构体标签,但这个方法对我有效:Go Playground - The Go Programming Language

func main() {
    fmt.Println("hello world")
}

更多关于Golang如何从XML中解析数据块的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我看到你使用了 Root 类型作为根变量,而我使用了 Item 类型作为此类变量。在你的情况下,当我写入数据库时遇到了错误:“在结构体 Rates 的字段 XMLName 中发现了无效字段:为关系定义一个有效的外键或实现 Valuer/Scanner 接口”

ChatGPT 帮助我解决了添加新结构体和额外代码的问题:

type Rate struct {
	Name   string `xml:"name"`
	Title  string `xml:"title"`
	Items  []Item `xml:"item"`
}

type Item struct {
	Name  string `xml:"name"`
	Title string `xml:"title"`
}

type RateModel struct {
	gorm.Model
	Name   string
	Title  string
	Item   []ItemModel
}

type ItemModel struct {
	gorm.Model
	RateModelID uint
	Name        string
	Title       string
}

// 创建一个新的 RateModel 实例
rateModel := RateModel{
	Name:  rate.Name,
	Title: rate.Title,
}

// 转换并保存项目
for _, item := range rate.Items {
	rateModel.Item = append(rateModel.Item, ItemModel{
		Name:  item.Name,
		Title: item.Title,
	})
}

你的代码有几个问题需要解决。首先,你的结构体定义没有正确反映XML结构,其次你试图解析整个XML到单个Item结构体,但实际需要先解析Rates再访问其中的Item

以下是修正后的代码:

type Rates struct {
    XMLName xml.Name `xml:"rates"`
    Name    string   `xml:"name"`
    Title   string   `xml:"title"`
    Items   []Item   `xml:"item"`
}

type Item struct {
    Id    int    `xml:"id" gorm:"primaryKey"`
    Name  string `xml:"name"`
    Title string `xml:"title"`
}

response, err := http.Get("https://API")
responseData, err := io.ReadAll(response.Body)

var rates Rates
xml.Unmarshal(responseData, &rates)

// 保存Rates级别的数据(如果需要)
// 保存Items数据
for _, item := range rates.Items {
    if result := h.DB.Create(&item); result.Error != nil {
        fmt.Println(result.Error)
    }
}

// 如果需要返回XML响应
w.Header().Add("Content-Type", "application/xml")
w.WriteHeader(http.StatusOK)
xml.NewEncoder(w).Encode(rates)

如果你只需要保存Item数据而不需要Rates级别的name和title,可以这样简化:

type Rates struct {
    XMLName xml.Name `xml:"rates"`
    Items   []Item   `xml:"item"`
}

type Item struct {
    Id    int    `xml:"id" gorm:"primaryKey"`
    Name  string `xml:"name"`
    Title string `xml:"title"`
}

response, err := http.Get("https://API")
responseData, err := io.ReadAll(response.Body)

var rates Rates
xml.Unmarshal(responseData, &rates)

for _, item := range rates.Items {
    if result := h.DB.Create(&item); result.Error != nil {
        fmt.Println(result.Error)
    }
}

如果你的XML中item可能有多个,使用循环批量插入会更高效:

if len(rates.Items) > 0 {
    if result := h.DB.Create(&rates.Items); result.Error != nil {
        fmt.Println(result.Error)
    }
}
回到顶部