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

报告相同问题?

悬赏问题

  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R
  • ¥15 在线请求openmv与pixhawk 实现实时目标跟踪的具体通讯方法
  • ¥15 八路抢答器设计出现故障
  • ¥15 opencv 无法读取视频
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档