解组嵌套 xml golang
Unmarshaling nested xml golang
我想将嵌套的 xml 解组为 golang 结构。我要解组的 xml 如下所示。
<?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>
为了解组,我定义了两个 go 结构,如下所示。
// 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"`
}
但是当我尝试使用 xml.Unmarshal
解组时,只有 Plan
和 Authorized
值被解组。解组结果如下图
XML: {{ } true Basic []}
试试这个 go playground. I use this tool 作弊并帮助我从 XML 数据生成 Go 类型。
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>`
为了获得 Usages
字段的值,请根据 mkopriva 的建议将 xml:"usage_reports"
修改为 xml:"usage_reports>usage_report"
。
package main
import (
"encoding/xml"
"fmt"
)
type UsageReport struct {
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"`
}
type AuthResponse struct {
Status xml.Name `xml:"status"`
Authorized bool `xml:"authorized"`
Plan string `xml:"plan"`
Usages []UsageReport `xml:"usage_reports>usage_report"`
}
var data = []byte(`<?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>
`)
func main() {
r := AuthResponse{}
if err := xml.Unmarshal(data, &r); err != nil {
panic(err)
}
fmt.Println(r)
}
输出:
{{ } true Basic [{hits day 2021-07-20 00:00:00 +0000 2021-07-21 00:00:00 +0000 1000000 0} {hits.82343 day 2021-07-20 00:00:00 +0000 2021-07-21 00:00:00 +0000 1000000 0}]}
我想将嵌套的 xml 解组为 golang 结构。我要解组的 xml 如下所示。
<?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>
为了解组,我定义了两个 go 结构,如下所示。
// 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"`
}
但是当我尝试使用 xml.Unmarshal
解组时,只有 Plan
和 Authorized
值被解组。解组结果如下图
XML: {{ } true Basic []}
试试这个 go playground. I use this tool 作弊并帮助我从 XML 数据生成 Go 类型。
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>`
为了获得 Usages
字段的值,请根据 mkopriva 的建议将 xml:"usage_reports"
修改为 xml:"usage_reports>usage_report"
。
package main
import (
"encoding/xml"
"fmt"
)
type UsageReport struct {
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"`
}
type AuthResponse struct {
Status xml.Name `xml:"status"`
Authorized bool `xml:"authorized"`
Plan string `xml:"plan"`
Usages []UsageReport `xml:"usage_reports>usage_report"`
}
var data = []byte(`<?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>
`)
func main() {
r := AuthResponse{}
if err := xml.Unmarshal(data, &r); err != nil {
panic(err)
}
fmt.Println(r)
}
输出:
{{ } true Basic [{hits day 2021-07-20 00:00:00 +0000 2021-07-21 00:00:00 +0000 1000000 0} {hits.82343 day 2021-07-20 00:00:00 +0000 2021-07-21 00:00:00 +0000 1000000 0}]}