xml-parsing - 使用 (xpath) 条件解码 XML

标签 xml-parsing go

我正在尝试解码一些结构类似于以下示例的 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']"`
}

有什么办法可以用标准的编码/xml 包做到这一点吗? 如果没有,你能给我一个提示,如何在 go 中分解这样的“问题”吗? (基本上是针对此类任务的围棋软件架构的最佳实践)。

谢谢!

最佳答案

encoding/xml 包没有实现 xpath,但是有一组简单的选择方法可供使用。

这是一个示例,说明如何使用 encoding/xml 解码 XML。因为统计数据都是同一类型,具有相同的属性,所以解码它们的最简单方法是将其放入同一类型的 slice 中。 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
}

关于xml-parsing - 使用 (xpath) 条件解码 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27534773/

相关文章:

Golang 地址运算符和 (*int)(Type) 语法

go - 按时选择。结果死锁后

android - 使用 Android XmlPullParser 解析无效的符号

c++ - 从 *.xsd 模式文件自动生成 objective-c 类

java - 在线读取 XML 并存储它(使用 Java)

c++ - Libxml2 xmlSchemaParse 失败

java - 使用 NodeList 解析 Xml

go - Golang如何将整数类型转换为字节类型

go - 我正在编写一个具有 irc 样式命令的聊天应用程序。构建程序以处理这些命令的最佳方式是什么?

heroku - 在后台执行 go routines