我是Golang的新手,使用同名嵌套节点解析XML对我来说太困难了。这是从第三方API中提取的XML:
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2019-01-28">
<Cube currency="USD" rate="1.1418"/>
<Cube currency="JPY" rate="124.94"/>
<Cube currency="BGN" rate="1.9558"/>
</Cube>
<Cube time="2019-01-25">
<Cube currency="USD" rate="1.1346"/>
<Cube currency="JPY" rate="124.72"/>
<Cube currency="BGN" rate="1.9558"/>
</Cube>
</Cube>
</gesmes:Envelope>
我需要解析它,所以我会有这样的输出:
&{Rates:[{Currency:USD Rate:1.1418 Date:2019-01-28} {Currency:JPY Rate:124.94 Date:2019-01-28} {Currency:BGN Rate:1.9558 Date:2019-01-28} {Currency:USD Rate:1.1346 Date:2019-01-25} {Currency:JPY Rate:124.72 Date:2019-01-25} {Currency:BGN Rate:1.9558 Date:2019-01-25}]}
这是我的代码:
package main
import (
"encoding/xml"
"fmt"
)
type Rate struct {
Currency string `xml:"currency,attr"`
Rate string `xml:"rate,attr"`
Date string `xml:"time,attr"`
}
type Rates struct {
Rates []Rate `xml:"Cube>Cube>Cube"`
}
func main() {
v := &Rates{}
if err := xml.Unmarshal([]byte(src), v); err != nil {
panic(err)
}
fmt.Printf("%+v\n\n", v)
}
const src = `<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2019-01-28">
<Cube currency="USD" rate="1.1418"/>
<Cube currency="JPY" rate="124.94"/>
<Cube currency="BGN" rate="1.9558"/>
</Cube>
<Cube time="2019-01-25">
<Cube currency="USD" rate="1.1346"/>
<Cube currency="JPY" rate="124.72"/>
<Cube currency="BGN" rate="1.9558"/>
</Cube>
</Cube>
</gesmes:Envelope>`
我不知道如何将time
属性插入Rates对象。任何帮助将不胜感激。
这里是golang playground
答案 0 :(得分:1)
您可以实施自定义xml.Unmarshaler
以获得所需的结果。
type Rate struct {
Currency string `xml:"currency,attr"`
Rate string `xml:"rate,attr"`
Date string `xml:"time,attr"`
}
type Rates struct {
Rates RateList `xml:"Cube>Cube"`
}
type RateList []Rate
func (ls *RateList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
date := start.Attr[0].Value
for {
tok, err := d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if se, ok := tok.(xml.StartElement); ok {
rate := Rate{Date: date}
if err := d.DecodeElement(&rate, &se); err != nil {
return err
}
*ls = append(*ls, rate)
}
}
}
答案 1 :(得分:0)
我同意mkopriva的回答,但无法发表评论,因此我要添加回复。
确保使用XSD之类的东西来信任XML或事先对其进行验证/清除。这应该是做了两个安全原因,以及能够回过头来,看看数据你“解组”是正确的,因为当你正在处理XML的巨额资金,它的一些必然被打破。