尝试解组嵌套的XML时,获取所有字段。

huangapple go评论123阅读模式
英文:

Grabbing all fields when trying to unmarshal nested XML

问题

这是我试图在Golang中提取的XML文件的一部分。实际的XML文件超过500MB。

<artists>
   <artist>
      <id>1</id>
      <name>The Persuader</name>
      <realname>Jesper Dahlbäck</realname>
      <profile />
   </artist>
    <artist>
       <id>22</id>
       <name>DATacide</name>
       <profile>Datacide于1993年开始一起录制,当时Tetsu Inoue在法兰克福附近度假时遇到了Uwe Schmidt。</profile>
       <members>
          <id>25</id>
          <name>Tetsu Inoue</name>
          <id>519207</id>
          <name>Uwe Schmidt</name>
       </members>
    </artist>
</artists>

这是Go代码。我想要获取MEMBERS部分中的所有ID字段,但是我的代码只获取了最后一个ID字段,而实际上可能没有、一个或多个。如何将所有ID都获取到MEMBERS数组中?

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

type Artists struct {
	XMLName xml.Name `xml:"artists"`
	Artist  []Artist `xml:"artist"`
}

type Artist struct {
	XMLName    xml.Name   `xml:"artist"`
	ArtistID   uint32     `xml:"id,omitempty"`
	ArtistName string     `xml:"name,omitempty"`
	Profile    string     `xml:"profile,omitempty"`
	RealName   string     `xml:"realname,omitempty"`
	Members    []MemberID `xml:"members>id"`
}

type MemberID struct {
	ID   uint32 `xml:",chardata"`
}

func main() {

	xmlFile, err := os.Open("short_artists.xml")
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println("Successfully opened artists file")
	defer xmlFile.Close()

	byteValue, _ := ioutil.ReadAll(xmlFile)
	var artists Artists
 	xml.Unmarshal(byteValue, &artists)

	for i := 0; i < len(artists.Artist); i++ {
		fmt.Println("ArtistID: " + fmt.Sprint(artists.Artist[i].ArtistID))
		fmt.Println("Name: " + artists.Artist[i].ArtistName)
		fmt.Println("Real Name: " + artists.Artist[i].RealName)
		fmt.Println("Profile: " + artists.Artist[i].Profile)
		fmt.Println("")
		for j := 0; j < len(artists.Artist[i].Members); j++ {
			fmt.Println("Member ID: " + fmt.Sprint(artists.Artist[i].Members[j].ID))
		}
		fmt.Println("")
	}
}

所有我的Google和DuckDuckGo搜索结果都是紫色的。谢谢你的帮助。

英文:

Here is a bit of the XML file I'm trying to pull into Golang. The actual XML file is over 500 MB.

&lt;artists&gt;
   &lt;artist&gt;
      &lt;id&gt;1&lt;/id&gt;
      &lt;name&gt;The Persuader&lt;/name&gt;
      &lt;realname&gt;Jesper Dahlb&#195;&#164;ck&lt;/realname&gt;
      &lt;profile /&gt;
   &lt;/artist&gt;
    &lt;artist&gt;
       &lt;id&gt;22&lt;/id&gt;
       &lt;name&gt;DATacide&lt;/name&gt;
       &lt;profile&gt;Datacide began recording together in 1993, after Tetsu Inoue met Uwe Schmidt while vacationing near Frankfurt.
       &lt;/profile&gt;
       &lt;members&gt;
          &lt;id&gt;25&lt;/id&gt;
          &lt;name&gt;Tetsu Inoue&lt;/name&gt;
          &lt;id&gt;519207&lt;/id&gt;
          &lt;name&gt;Uwe Schmidt&lt;/name&gt;
       &lt;/members&gt;
    &lt;/artist&gt;
&lt;/artists&gt;

Here's the Go code. I'm wanting to get ALL of the ID fields in the MEMBERS section, but my code is only grabbing the last ID field where there may be none, one, or many. How can I grab all IDs in the MEMBERS section into the MEMBERS array?

package main

import (
	&quot;encoding/xml&quot;
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;os&quot;
)

type Artists struct {
	XMLName xml.Name `xml:&quot;artists&quot;`
	Artist  []Artist `xml:&quot;artist&quot;`
}

type Artist struct {
	XMLName xml.Name `xml:&quot;artist&quot;`
	ArtistID uint32 `xml:&quot; id,omitempty&quot;`
	ArtistName string `xml:&quot; name,omitempty&quot;`
	Profile string `xml:&quot; profile,omitempty&quot;`
	RealName string `xml:&quot; realname,omitempty&quot;`
	Members MembersID `xml:&quot;members,omitempty&quot;`
}

type MembersID struct {
	MemberID uint32 `xml:&quot;id,omitempty&quot;`
}

func main() {

	xmlFile, err := os.Open(&quot;short_artists.xml&quot;)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(&quot;Successfully opened artists file&quot;)
	defer xmlFile.Close()

	byteValue, _ := ioutil.ReadAll(xmlFile)
	var artists Artists
 	xml.Unmarshal(byteValue, &amp;artists)

	for i := 0; i &lt; len(artists.Artist); i++ {
		fmt.Println(&quot;ArtistID: &quot; + fmt.Sprint(artists.Artist[i].ArtistID))
		fmt.Println(&quot;Name: &quot; + artists.Artist[i].ArtistName)
		fmt.Println(&quot;Real Name: &quot; + artists.Artist[i].RealName)
		fmt.Println(&quot;Profile: &quot; + artists.Artist[i].Profile)
		fmt.Println(&quot;&quot;)
		fmt.Printf(&quot;%v\n&quot;,artists.Artist[i].Members)
		fmt.Println(&quot;&quot;)
	}
}

All my Google and DuckDuckGo searches are purple. Thank you for your help.

答案1

得分: 1

问题是MembersID结构体的定义。你需要使用切片。

type MembersID struct {
    MemberID []uint32 `xml:"id,omitempty"`
}

播放链接:https://play.golang.org/p/h4qTmSQoRg

输出:

ArtistID: 1
Name: The Persuader
Real Name: Jesper Dahlbäck
Profile: 

Members: []

ArtistID: 22
Name: DATacide
Real Name: 
Profile: Datacide began recording together in 1993, after Tetsu Inoue met Uwe Schmidt while vacationing near Frankfurt.
           

Members: [25 519207]

额外提示:

如果需要的话,可以选择性地获取XML路径值。例如,获取XML路径artist>members>id的所有ID。

type MemberID struct {
    IDs []uint32 `xml:"artist>members>id"`
}

播放链接:https://play.golang.org/p/sj7XPisgl7

输出:

[25 519207]
英文:

Issue is MembersID struct definition. You have to use slice.

type MembersID struct {
    MemberID []uint32 `xml:&quot;id,omitempty&quot;`
}

Play link: https://play.golang.org/p/h4qTmSQoRg

Output:

ArtistID: 1
Name: The Persuader
Real Name: Jesper Dahlb&#195;&#164;ck
Profile: 

Members: []

ArtistID: 22
Name: DATacide
Real Name: 
Profile: Datacide began recording together in 1993, after Tetsu Inoue met Uwe Schmidt while vacationing near Frankfurt.
       

Members: [25 519207]

Bonus Tip:

Selectively fetching XML path values, if need be. For example getting all IDs of XML path artist&gt;members&gt;id

type MemberID struct {
	IDs []uint32 `xml:&quot;artist&gt;members&gt;id&quot;`
}

Play link: https://play.golang.org/p/sj7XPisgl7

Output:

[25 519207]

huangapple
  • 本文由 发表于 2017年8月3日 11:42:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/45474394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定