You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从XML的Item块反序列化数据并通过GORM存入数据库

Go语言XML反序列化+GORM存储:正确保存嵌套Item块字段的方案

问题场景

从API获取的XML结构如下,顶层<rates>和嵌套<item>块都包含name、title字段:

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

当前代码只能保存顶层Rates的字段,无法存储Item块的内容,需要修改代码实现Item字段的数据库存储。原代码如下:

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)

问题分析与修复方案

1. 核心问题:反序列化目标不匹配

当前代码直接把XML反序列化为Item类型,但XML根节点是<rates>,必须先反序列化为Rates类型,才能拿到嵌套的item列表数据。

2. 结构体优化与修正

  • Rates结构体里的Rates字段名语义模糊,建议改成Items,同时确保xml标签正确对应<item>节点;
  • Item的Id字段去掉xml:"id"标签,因为XML里没有<id>节点,避免反序列化失败(主键ID由数据库自增生成即可);
  • 如果需要保存顶层Rates的name和title,给Rates结构体添加对应字段。

3. 完整修正代码

import (
    "encoding/xml"
    "io"
    "net/http"

    "gorm.io/gorm"
)

type Rates struct {
    XMLName xml.Name `xml:"rates"`
    Items   []Item   `xml:"item"` // 修正字段名,语义更清晰
    Name    string   `xml:"name"` // 可选:保存顶层Rates的name
    Title   string   `xml:"title"`// 可选:保存顶层Rates的title
}

type Item struct {
    Id    int    `gorm:"primaryKey"` // 去掉xml标签,数据库自增生成ID
    Name  string `xml:"name"`
    Title string `xml:"title"`
}

// 处理请求的核心逻辑
func handleRequest(w http.ResponseWriter, r *http.Request, DB *gorm.DB) {
    response, err := http.Get("https://API")
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    defer response.Body.Close()

    responseData, err := io.ReadAll(response.Body)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    // 反序列化为Rates类型,匹配XML根节点
    var rates Rates
    err = xml.Unmarshal(responseData, &rates)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    // 批量存入所有Item,比逐个插入更高效
    if len(rates.Items) > 0 {
        if result := DB.Create(&rates.Items); result.Error != nil {
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
    }

    // 返回Item数据(示例:返回所有Item)
    w.Header().Add("Content-Type", "application/xml")
    w.WriteHeader(http.StatusOK)
    xml.NewEncoder(w).Encode(rates.Items)
}

关键修改说明

  • 反序列化目标从Item改为Rates,才能正确解析嵌套的<item>节点;
  • 批量插入rates.Items提升数据库操作效率;
  • 去掉Item.Id的xml标签,避免因XML无<id>节点导致的反序列化错误。

内容的提问来源于stack exchange,提问作者Epic555

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:12:51