I want to unmarshall a nested xml to a golang struct. The xml that I want to unmarshall is shown below.
<?xml version="1.0" encoding="UTF-8"?>
<status>
<authorized>true</authorized>
<plan>Basic</plan>
<usage_reports>
<usage_report metric="hits" period="day">
<period_start>2021-07-20 00:00:00 +0000</period_start>
<period_end>2021-07-21 00:00:00 +0000</period_end>
<max_value>1000000</max_value>
<current_value>0</current_value>
</usage_report>
<usage_report metric="hits.82343" period="day">
<period_start>2021-07-20 00:00:00 +0000</period_start>
<period_end>2021-07-21 00:00:00 +0000</period_end>
<max_value>1000000</max_value>
<current_value>0</current_value>
</usage_report>
</usage_reports>
</status>
To unmarshall I have defined two go structs as follows.
// UsageReport represents the usage report of a particular metric.
type UsageReport struct {
Usage string `xml:"usage_report,chardata"`
Metric string `xml:"metric,attr"`
Period string `xml:"period,attr"`
Start string `xml:"period_start"`
End string `xml:"period_end"`
Max int64 `xml:"max_value"`
Current int64 `xml:"current_value"`
}
// AuthResponse represents the structure of the response from authorize calls.
type AuthResponse struct {
Status xml.Name `xml:"status"`
Authorized bool `xml:"authorized"`
Plan string `xml:"plan"`
Usages []UsageReport `xml:"usage_reports"`
}
But when I try to unmarshall using xml.Unmarshal
, only Plan
and Authorized
values gets unmarshalled. The result of unmarshalling is shown below.
XML: {{ } true Basic []}
Try this go playground. I use this tool to cheat and help me generate Go types from XML data.
package main
import (
"encoding/xml"
"fmt"
)
type Status struct {
XMLName xml.Name `xml:"status"`
Text string `xml:",chardata"`
Authorized string `xml:"authorized"`
Plan string `xml:"plan"`
UsageReports struct {
Text string `xml:",chardata"`
UsageReport []struct {
Text string `xml:",chardata"`
Metric string `xml:"metric,attr"`
Period string `xml:"period,attr"`
PeriodStart string `xml:"period_start"`
PeriodEnd string `xml:"period_end"`
MaxValue string `xml:"max_value"`
CurrentValue string `xml:"current_value"`
} `xml:"usage_report"`
} `xml:"usage_reports"`
}
func main() {
status := Status{}
err := xml.Unmarshal([]byte(xmlStr), &status)
if err != nil {
panic(err)
}
fmt.Println(status.UsageReports.UsageReport[0].MaxValue)
}
const xmlStr = `<?xml version="1.0" encoding="UTF-8"?><status><authorized>true</authorized><plan>Basic</plan><usage_reports><usage_report metric="hits" period="day"><period_start>2021-07-20 00:00:00 +0000</period_start><period_end>2021-07-21 00:00:00 +0000</period_end><max_value>1000000</max_value><current_value>0</current_value></usage_report><usage_report metric="hits.82343" period="day"><period_start>2021-07-20 00:00:00 +0000</period_start><period_end>2021-07-21 00:00:00 +0000</period_end><max_value>1000000</max_value><current_value>0</current_value></usage_report></usage_reports></status>`