How to unmarshal data block from xml

How to unmarshal data from the Item block from XML? Rates and Item blocks have fields with the same names. I get XML data from API and save it to DB, I use gorm for DB.

My code saves data (name and title) from Rates block. I need to save data (name and title) from Item block.

API gives this:

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

My Code:

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)

I removed some unnecessary lines like “if err != nil”, so dont pay attention on it.

I don’t quite understand your struct layout & xml struct tags, but this works for me: Go Playground - The Go Programming Language

i see u used Root type for root variable, i used Item type for such variable. In your case i receive error when writing to db: “invalid field found for struct Rates’s field XMLName: define a valid foreign key for relations or implement the Valuer/Scanner interface”

ChatGPT helped me to solve my problem with adding new structs and additional code:

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
}

// Create a new RateModel instance
rateModel := RateModel{
	Name:  rate.Name,
	Title: rate.Title,
}

// Convert and save items
for _, item := range rate.Items {
	rateModel.Item = append(rateModel.Item, ItemModel{
		Name:  item.Name,
		Title: item.Title,
	})
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.