2015-08-20 64 views
1

我有以下XML 「文件」:解析XML在Golang - 拆封

<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 (
 
\t "fmt" 
 
\t "encoding/xml" 
 
) 
 

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

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

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

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

坦率地說,我研究了很多關於Golang的深層嵌套xml解析,並且我還沒有發現很多可以幫助解決此代碼的Unmarshal部分。理想情況下,代碼將返回類似於Python字典的東西,比如,

{event_datetimeGMT:2015年8月21日,gamenumber:483406220,...,visiting_home_draw: 「主頁」}

我是新到Golang,所以如果你發現這個問題的話,請和我一起露面。

編輯:

基於尼古拉斯的評論下面,我增加了以下內容。這運行沒有錯誤,但產生一個空的結果。

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 
 
     } 
 
}

回答

1

你可以這樣說:

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 「文件」 是一個字符串。如果你從互聯網上獲得它(例如http響應的主體),resp.Body已經會滿足一個Reader,所以你可以跳過第一行。如果你在操作系統上打開一個真實的文件,你也可以打開它作爲一個閱讀器,同樣的事情。

編輯:兩件事:

  • 可以嵌套結構,並放棄對簡單和清晰的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 
} 
+0

謝謝Nicolas!我根據你的回答編輯了我的評論,看起來這會毫無問題地運行,但結果只是空的。 – amachure

+0

看起來我有點晚了,Jay Crumb是對的!大寫首字母在你的結構中! –

1

您需要大寫結構中的所有字段。 xml解碼器需要輸出這些字段才能正常工作。去操場here