drvfqr5609 2019-01-29 14:37
浏览 521
已采纳

如何解析具有相同名称的嵌套节点的XML?

I'm new to Golang and parsing XML with nested nodes of the same name is too difficult to me. This is a XML pulled from a third party API:

<?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>

I need to parse it so I have an output like this:

&{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}]}

And here's my code:

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

", 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>`

I'm out of ideas how to insert time attribute into Rates object. Any help would be appreciated.

Here it is in golang playground

  • 写回答

2条回答 默认 最新

  • down101102 2019-01-29 23:54
    关注

    You could implement a custom xml.Unmarshaler to get the results you want.

    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)
            }
        }
    }
    

    Go Playground

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 vscode的问题提问
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM