我正在尝试解组一些XML,其结构类似于以下示例:
<player>
<stat type="first_name">Somebody</stat>
<stat type="last_name">Something</stat>
<stat type="birthday">06-12-1987</stat>
</player>
很容易将其解组为像
这样的结构type Player struct {
Stats []Stat `xml:"stat"`
}
但是我希望找到一种方法将它解组成一个更像是
的结构type Player struct {
FirstName string `xml:"stat[@Type='first_name']"`
LastName string `xml:"stat[@Type='last_name']"`
Birthday Time `xml:"stat[@Type='birthday']"`
}
有没有办法用标准的encoding / xml包来做到这一点? 如果没有,你能不能给我一个暗示如何分解这样一个“问题”? (基本上,这种任务的软件架构的最佳实践)。
谢谢你!答案 0 :(得分:0)
encoding/xml
包不实现xpath,但确实有一组可以使用的选择方法。
以下是如何使用encoding/xml
解组您所拥有的XML的示例。因为统计数据都是相同的类型,具有相同的属性,解码它们的最简单方法将是相同类型的切片。 http://play.golang.org/p/My10GFiWDa
var doc = []byte(`<player>
<stat type="first_name">Somebody</stat>
<stat type="last_name">Something</stat>
<stat type="birthday">06-12-1987</stat>
</player>`)
type Player struct {
XMLName xml.Name `xml:"player"`
Stats []PlayerStat `xml:"stat"`
}
type PlayerStat struct {
Type string `xml:"type,attr"`
Value string `xml:",chardata"`
}
如果您需要经常转换,可以使用UnamrshalXML
方法进行转换:http://play.golang.org/p/htoOSa81Cn
type Player struct {
XMLName xml.Name `xml:"player"`
FirstName string
LastName string
Birthday string
}
func (p *Player) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
break
} else if err != nil {
return err
}
if se, ok := t.(xml.StartElement); ok {
t, err = d.Token()
if err != nil {
return err
}
var val string
if c, ok := t.(xml.CharData); ok {
val = string(c)
} else {
// not char data, skip for now
continue
}
// assuming we have exactly one Attr
switch se.Attr[0].Value {
case "first_name":
p.FirstName = val
case "last_name":
p.LastName = val
case "birthday":
p.Birthday = val
}
}
}
return nil
}