英文:
Parsing date from XML does not work
问题
如果我使用简单的值执行time.Parse()
,一切都正常,但解析XML时出现问题。
type customDate struct {
time.Time
}
func (c *customDate) UnmarshalXml(d *xml.Decoder, start xml.StartElement) error {
var v string
if err := d.DecodeElement(&v, &start); err != nil {
return err
}
loc, _ := time.LoadLocation("Europe/Moscow")
prs, err := time.ParseInLocation("02.01.2006", v, loc)
if err != nil {
return err
}
*c = customDate{prs}
return nil
}
英文:
If I execute time.Parse()
with simple values - then everything is fine, but parsing XML does not.
type customDate struct {
time.Time
}
func (c *customDate) UnmarshalXml(d *xml.Decoder, start xml.StartElement) error {
var v string
if err := d.DecodeElement(&v, &start); err != nil{
return err
}
loc, _ := time.LoadLocation("Europe/Moscow")
prs, err := time.ParseInLocation("02.01.2006", v, loc)
if err != nil {
return err
}
*c = customDate{prs}
return nil
}
答案1
得分: 2
date
是一个XML属性,而不是元素。因此,您必须实现xml.UnmarshalerAttr
接口,而不是xml.Unmarshaler
接口:
package main
import (
"encoding/xml"
"fmt"
"time"
)
type xmlSource struct {
XMLName xml.Name `xml:"BicDBList"`
Base string `xml:"Base,attr"`
Items []item `xml:"item"`
}
// Item代表节点"item"的结构
type item struct {
File string `xml:"file,attr"`
Date customDate `xml:"date,attr"`
}
type customDate struct {
time.Time
}
func (c *customDate) UnmarshalXMLAttr(attr xml.Attr) error {
loc, err := time.LoadLocation("Europe/Moscow")
if err != nil {
return err
}
prs, err := time.ParseInLocation("02.01.2006", attr.Value, loc)
if err != nil {
return err
}
c.Time = prs
return nil
}
var data = []byte(`<BicDBList Base="/mcirabis/BIK/">
<item file="bik_db_09122016.zip" date="09.12.2016"/>
<item file="bik_db_08122016.zip" date="08.12.2016"/>
<item file="bik_db_07122016.zip" date="07.12.2016"/>
<item file="bik_db_06122016.zip" date="06.12.2016"/>
</BicDBList>`)
func main() {
var sample xmlSource
err := xml.Unmarshal(data, &sample)
if err != nil {
println(err.Error())
}
fmt.Printf("%#v\n", sample)
}
您可以在这里找到完整的代码示例。
英文:
date
is an XML attribute, not an element. Therefore, you must implement the xml.UnmarshalerAttr
interface rather than xml.Unmarshaler
:
package main
import (
"encoding/xml"
"fmt"
"time"
)
type xmlSource struct {
XMLName xml.Name `xml:"BicDBList"`
Base string `xml:"Base,attr"`
Items []item `xml:"item"`
}
// Item represent structure of node "item"
type item struct {
File string `xml:"file,attr"`
Date customDate `xml:"date,attr"`
}
type customDate struct {
time.Time
}
func (c *customDate) UnmarshalXMLAttr(attr xml.Attr) error {
loc, err := time.LoadLocation("Europe/Moscow")
if err != nil {
return err
}
prs, err := time.ParseInLocation("02.01.2006", attr.Value, loc)
if err != nil {
return err
}
c.Time = prs
return nil
}
var data = []byte(`<BicDBList Base="/mcirabis/BIK/">
<item file="bik_db_09122016.zip" date="09.12.2016"/>
<item file="bik_db_08122016.zip" date="08.12.2016"/>
<item file="bik_db_07122016.zip" date="07.12.2016"/>
<item file="bik_db_06122016.zip" date="06.12.2016"/>
</BicDBList>`)
func main() {
var sample xmlSource
err := xml.Unmarshal(data, &sample)
if err != nil {
println(err.Error())
}
fmt.Printf("%#v\n", sample)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论