Unmarshalling可选的float64字段在Go上返回错误

时间:2014-07-07 02:04:04

标签: xml floating-point go

我的应用程序正在使用的外部API有时不返回其中一个float64字段的值。当发生这种情况时,我无法解组文档的其余部分。

以下是Go playground中的示例代码:

http://play.golang.org/p/Twv8b6KCtw

package main

import (
    "encoding/xml"
    "fmt"
)

func main() {

    type Result struct {
        XMLName xml.Name `xml:"Person"`
        Grade   float64  `xml:"grade"`
        Name    string   `xml:"name"`
    }

    data := `
        <Person>
            <grade/>
            <name>Jack</name>
        </Person>
    `
    var v Result
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("name: %s\n", v.Name)

}

如果我将第12行中的float64更改为string,它将起作用。知道我怎么能得到一个解决方法吗?我应该将每个字段定义为字符串并手动进行转换吗?

2 个答案:

答案 0 :(得分:4)

我相信您发现了一个错误,您应该在issue tracker 上报告错误,我提交了错误报告issue 8333

现在针对当前的问题,您有两个选择:

  1. 使用string类型,他们会根据需要自行进行对话。
  2. 完全删除<grade/>标记,并在结构中使用xml:"grade,omitempty"

答案 1 :(得分:4)

要添加到OneOfOne的解决方案,您还可以定义自己的UnmarshalXML方法。

示例(On play):

type Grade float64

func (g *Grade) UnmarshalXML(d *xml.Decoder, s xml.StartElement) error {
    for tok, err := d.Token(); err != io.EOF; tok, err = d.Token() {
        if chrdata, ok := tok.(xml.CharData); ok {
            f, err := strconv.ParseFloat(string(chrdata), 64)
            if err != nil {
                return err
            }
            *(*float64)(g) = f
        }
    }
    return nil
}

type Result struct {
    XMLName xml.Name `xml:"Person"`
    Grade   Grade    `xml:"grade"`
    Name    string   `xml:"name"`
}

通过在中间搜索<grade>标记并将其解析为float来解析CharData标记,当没有要解析的值时,将等级保留在0.0