xml - 在 Go 中解码 XML

标签 xml go

我有以下 xml"file":

<pinnacle_line_feed>
    <PinnacleFeedTime>1439954818555</PinnacleFeedTime>
    <lastContest>34317132</lastContest>
    <lastGame>218491030</lastGame>
    <events>
        <event>
            <event_datetimeGMT>2015-08-21 09:50</event_datetimeGMT>
            <gamenumber>483406220</gamenumber>
            <sporttype>Aussie Rules</sporttype>
            <league>AFL</league>
            <IsLive>No</IsLive>
            <participants>
                <participant>
                    <participant_name>Hawthorn Hawks</participant_name>
                    <contestantnum>1251</contestantnum>
                    <rotnum>1251</rotnum>
                    <visiting_home_draw>Visiting</visiting_home_draw>
                    </participant>
                <participant>
                    <participant_name>Port Adelaide Power</participant_name>
                    <contestantnum>1252</contestantnum>
                    <rotnum>1252</rotnum>
                    <visiting_home_draw>Home</visiting_home_draw>
                </participant>
            </participants>
            <periods></periods>
        </event>
    </events>
</pinnacle_line_feed>

我正在尝试用 Golang 解析它,到目前为止已经编写了以下内容:

package main
import (
	"fmt"
	"encoding/xml"
)

type Participant struct {
	XMLName            xml.Name `xml:"participant"`
	participant_name   string `xml:"participant_name"`
	contestantnum      int `xml:"contestantnum"`
	rotnum             int `xml:"rotnum"`
	visiting_home_draw string `xml:"visiting_home_draw"`
}

type Event struct {
	XMLName           xml.Name `xml:"event"`
	event_datetimeGMT string `xml:"event_datetimeGMT"`
	gamenumber        string `xml:"gamenumber"`
	sporttype         string `xml:"sporttype"`
	league            string `xml:"league"`
	IsLive            string `xml:"IsLive"`
	Participant       []Participant `xml:"participant"`
}

type Events struct {
	XMLName xml.Name `xml:"events"`
	Event   []Event `xml:"event"`
}

type Pinnacle_Line_Feed struct {
	XMLName          xml.Name `xml:"pinnacle_line_feed"`
	PinnacleFeedTime string `xml:"PinnacleFeedTime"`
	lastContest      string `xml:"lastContest"`
	lastGame         string `xml:"lastGame"`
	Events           []Events `xml:"events"`
}

坦率地说,我对 Golang 中的深度嵌套 xml 解析进行了相当多的研究,但我没有发现对这段代码的 Unmarshal 部分有太多帮助。理想情况下,代码会返回类似于 python 字典的内容,例如

{event_datetimeGMT:2015-08-21,游戏编号:483406220,...,visiting_home_draw:“家”}

编辑:

根据下面 Nicolas 的评论,我添加了以下内容。运行时没有错误,但产生空结果。

 func main() {
         pinny_xml := `
         <pinnacle_line_feed>
            <PinnacleFeedTime>1439954818555</PinnacleFeedTime>
            <lastContest>34317132</lastContest>
            <lastGame>218491030</lastGame>
            <events>
                <event>
                    <event_datetimeGMT>2015-08-21 09:50</event_datetimeGMT>
                    <gamenumber>483406220</gamenumber>
                    <sporttype>Aussie Rules</sporttype>
                    <league>AFL</league>
                    <IsLive>No</IsLive>
                    <participants>
                        <participant>
                            <participant_name>Hawthorn Hawks</participant_name>
                            <contestantnum>1251</contestantnum>
                            <rotnum>1251</rotnum>
                            <visiting_home_draw>Visiting</visiting_home_draw>
                            </participant>
                        <participant>
                            <participant_name>Port Adelaide Power</participant_name>
                            <contestantnum>1252</contestantnum>
                            <rotnum>1252</rotnum>
                            <visiting_home_draw>Home</visiting_home_draw>
                        </participant>
                    </participants>
                    <periods></periods>
                </event>
            </events>
        </pinnacle_line_feed>
        `

        xmlReader := bytes.NewReader([]byte(pinny_xml))
        yourPinnacleLineFeed := new(Pinnacle_Line_Feed)
        if err := xml.NewDecoder(xmlReader).Decode(yourPinnacleLineFeed); err != nil {
            return // or log.Panic(err.Error()) if in main
        }
}

最佳答案

你可以这样做:

xmlReader := bytes.NewReader([]byte(your_xml_as_a_string_here))
yourPinnacleLineFeed := new(Pinnacle_Line_Feed)
if err := xml.NewDecoder(xmlReader).Decode(yourPinnacleLineFeed); err != nil {
    return // or log.Panic(err.Error()) if in main
}

这是如果您的 xml"file"是一个字符串。如果您从互联网获取它(例如作为 http 响应的正文),则 resp.Body 已经可以满足读者的要求,因此您可以跳过第一行。如果您在操作系统上打开真实文件,您也可以将其作为阅读器打开,同样的事情。

编辑:还有两件事:

  • 为了简单和清晰,您可以嵌套结构并删除 xml.Name 字段
  • 我还注意到您忘记了结构中的参与者级别,导致没有参与者被解码

这是一个更简单的版本,带有一个可选函数来检查结果中的内容:

package main

import (
    "bytes"
    "encoding/json"
    "encoding/xml"
    "fmt"
    "log"
)

type Pinnacle_Line_Feed struct {
    PinnacleFeedTime string `xml:"PinnacleFeedTime"`
    LastContest      string `xml:"lastContest"`
    LastGame         string `xml:"lastGame"`
    Events           struct {
        Event []struct {
            Event_datetimeGMT string `xml:"event_datetimeGMT"`
            Gamenumber        string `xml:"gamenumber"`
            Sporttype         string `xml:"sporttype"`
            League            string `xml:"league"`
            IsLive            string `xml:"IsLive"`
            Participants      struct {
                Participant []struct {
                    Participant_name   string `xml:"participant_name"`
                    Contestantnum      int    `xml:"contestantnum"`
                    Rotnum             int    `xml:"rotnum"`
                    Visiting_home_draw string `xml:"visiting_home_draw"`
                } `xml:"participant"`
            } `xml:"participants"`
        } `xml:"event"`
    } `xml:"events"`
}

func main() {
    pinny_xml := `
         <pinnacle_line_feed>
            <PinnacleFeedTime>1439954818555</PinnacleFeedTime>
            <lastContest>34317132</lastContest>
            <lastGame>218491030</lastGame>
            <events>
                <event>
                    <event_datetimeGMT>2015-08-21 09:50</event_datetimeGMT>
                    <gamenumber>483406220</gamenumber>
                    <sporttype>Aussie Rules</sporttype>
                    <league>AFL</league>
                    <IsLive>No</IsLive>
                    <participants>
                        <participant>
                            <participant_name>Hawthorn Hawks</participant_name>
                            <contestantnum>1251</contestantnum>
                            <rotnum>1251</rotnum>
                            <visiting_home_draw>Visiting</visiting_home_draw>
                        </participant>
                        <participant>
                            <participant_name>Port Adelaide Power</participant_name>
                            <contestantnum>1252</contestantnum>
                            <rotnum>1252</rotnum>
                            <visiting_home_draw>Home</visiting_home_draw>
                        </participant>
                    </participants>
                    <periods></periods>
                </event>
            </events>
        </pinnacle_line_feed>
    `

    xmlReader := bytes.NewReader([]byte(pinny_xml))
    yourPinnacleLineFeed := new(Pinnacle_Line_Feed)
    if err := xml.NewDecoder(xmlReader).Decode(yourPinnacleLineFeed); err != nil {
        log.Panic(err.Error())
    }

    printX(yourPinnacleLineFeed)
}

func printX(x interface{}) (err error) {
    var xBytes []byte
    xBytes, err = json.MarshalIndent(x, "", "  ")
    if err != nil {
        return
    }
    fmt.Println(string(xBytes))
    return
}

关于xml - 在 Go 中解码 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32125816/

相关文章:

go - 有人可以解释一下 "Readdir"和 "Open"包装方法吗

go - Golang中的0x1是什么意思?

java - ant 失败未知参数 : -buildfile=build. xml

xml - Zend Framework 中的简单内容存储(无数据库)

xml - 使用 XSLT 1.0 将 XHTML 转换为结构化 XML

java - 命名 Talend 自定义组件 - 除 tTutorialRow 外不工作

go - 从函数返回空接口(interface)的 slice

postgresql - Golang Postgres 连接字符串未打开返回 null

java - JAXB - 类集合的 PascalCase 包装器

go - 从 golang 中的模板创建 yaml 文件