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
我不太理解你的结构体布局和 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)
}
}

