Unmarshalling XML using Go: How to find attributes with the same value?

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

Unmarshalling XML using Go: How to find attributes with the same value?

问题

我正在尝试解析下面的XML,如何找到所有<info>节点中type="Genres"的节点,并将它们的值存储在[]Genre中?

  1. <manga id="4199" type="manga" name="Jinki: Extend" precision="manga">
  2. <info type="Main title" lang="EN">Jinki: Extend</info>
  3. <info type="Genres">action</info>
  4. <info type="Genres">science fiction</info>
  5. <info type="Themes">mecha</info>
  6. <info type="Number of tankoubon">9</info>
  7. <info type="Number of pages">186</info>
  8. </manga>

我希望将这些值存储在类似以下结构的结构体中:

  1. // Manga 结构体
  2. type Manga struct {
  3. WorkID int `xml:"id,attr"`
  4. Name string `xml:"name,attr"`
  5. Precision string `xml:"precision,attr"`
  6. Genres []Genre // 这部分我需要帮助
  7. }
  8. // Genre 结构体
  9. type Genre struct {
  10. Value string
  11. }

我知道这个XML不是理想的,但这是我必须处理的,希望你们能帮助我。

提前感谢。

英文:

I'm having trouble unmarshalling the XML below, how do I find all &lt;info&gt; nodes with type=&quot;Genres&quot; and store their values inside a []Genre?

  1. &lt;manga id=&quot;4199&quot; type=&quot;manga&quot; name=&quot;Jinki: Extend&quot; precision=&quot;manga&quot;&gt;
  2. &lt;info type=&quot;Main title&quot; lang=&quot;EN&quot;&gt;Jinki: Extend&lt;/info&gt;
  3. &lt;info type=&quot;Genres&quot;&gt;action&lt;/info&gt;
  4. &lt;info type=&quot;Genres&quot;&gt;science fiction&lt;/info&gt;
  5. &lt;info type=&quot;Themes&quot;&gt;mecha&lt;/info&gt;
  6. &lt;info type=&quot;Number of tankoubon&quot;&gt;9&lt;/info&gt;
  7. &lt;info type=&quot;Number of pages&quot;&gt;186&lt;/info&gt;
  8. &lt;/manga&gt;

I'm looking to store the values in structs similar to these:

  1. // Manga struct
  2. type Manga struct {
  3. WorkID int `xml:&quot;id,attr&quot;`
  4. Name string `xml:&quot;name,attr&quot;`
  5. Precision string `xml:&quot;precision,attr&quot;`
  6. Genres []Genre `[this is the part I need help on]`
  7. }
  8. // Genre struct
  9. type Genre struct {
  10. Value string
  11. }

I know the XML is not ideal, but it is what I have to work with, I hope you guys can help me with this.

Thanks in advance.

答案1

得分: 3

由于<manga>包含了一系列的<info>元素,因此更合理的做法是使用Info结构体的列表,而不是尝试将<info>元素翻译成各种类型。我会定义如下的数据结构:

  1. type Manga struct {
  2. WorkID int `xml:"id,attr"`
  3. Name string `xml:"name,attr"`
  4. Precision string `xml:"precision,attr"`
  5. Info []Info `xml:"info"`
  6. }
  7. type Info struct {
  8. Type string `xml:"type,attr"`
  9. Value string `xml:",chardata"`
  10. }

输出结果(以JSON编码方便查看)如下:

  1. {
  2. "WorkID": 4199,
  3. "Name": "Jinki: Extend",
  4. "Precision": "manga",
  5. "Info": [
  6. {
  7. "Type": "Main title",
  8. "Value": "Jinki: Extend"
  9. },
  10. {
  11. "Type": "Genres",
  12. "Value": "action"
  13. },
  14. {
  15. "Type": "Genres",
  16. "Value": "science fiction"
  17. },
  18. {
  19. "Type": "Themes",
  20. "Value": "mecha"
  21. },
  22. {
  23. "Type": "Number of tankoubon",
  24. "Value": "9"
  25. },
  26. {
  27. "Type": "Number of pages",
  28. "Value": "186"
  29. }
  30. ]
  31. }
英文:

Since &lt;manga&gt; contains a list of &lt;info&gt; elements, it makes more sense to have a list of Info structs rather than trying to translate the &lt;info&gt; elements into various types. I would define the data structures like:

  1. type Manga struct {
  2. WorkID int `xml:&quot;id,attr&quot;`
  3. Name string `xml:&quot;name,attr&quot;`
  4. Precision string `xml:&quot;precision,attr&quot;`
  5. Info []Info `xml:&quot;info&quot;`
  6. }
  7. type Info struct {
  8. Type string `xml:&quot;type,attr&quot;`
  9. Value string `xml:&quot;,chardata&quot;`
  10. }

The output (json encoded for convenience) looks like:

  1. {
  2. &quot;WorkID&quot;: 4199,
  3. &quot;Name&quot;: &quot;Jinki: Extend&quot;,
  4. &quot;Precision&quot;: &quot;manga&quot;,
  5. &quot;Info&quot;: [
  6. {
  7. &quot;Type&quot;: &quot;Main title&quot;,
  8. &quot;Value&quot;: &quot;Jinki: Extend&quot;
  9. },
  10. {
  11. &quot;Type&quot;: &quot;Genres&quot;,
  12. &quot;Value&quot;: &quot;action&quot;
  13. },
  14. {
  15. &quot;Type&quot;: &quot;Genres&quot;,
  16. &quot;Value&quot;: &quot;science fiction&quot;
  17. },
  18. {
  19. &quot;Type&quot;: &quot;Themes&quot;,
  20. &quot;Value&quot;: &quot;mecha&quot;
  21. },
  22. {
  23. &quot;Type&quot;: &quot;Number of tankoubon&quot;,
  24. &quot;Value&quot;: &quot;9&quot;
  25. },
  26. {
  27. &quot;Type&quot;: &quot;Number of pages&quot;,
  28. &quot;Value&quot;: &quot;186&quot;
  29. }
  30. ]
  31. }

答案2

得分: 0

如果XML文件不是很大,我会写一个实用函数,类似于:

  1. type Manga struct {
  2. WorkID int `xml:"id,attr"`
  3. Name string `xml:"name,attr"`
  4. Precision string `xml:"precision,attr"`
  5. Info []Info `xml:"info"`
  6. }
  7. type Info struct {
  8. Type string `xml:"type,attr"`
  9. Data string `xml:",chardata"`
  10. }
  11. func (m *Manga) Genres() []Info {
  12. var g []Info
  13. for _, v := range m.Info {
  14. if v.Type == "Genres" {
  15. g = append(g, v)
  16. }
  17. }
  18. return g
  19. }

在这里查看它的运行效果:https://play.golang.org/p/bebUwwbSwG

英文:

In case the XML won't not very large, I would just write an utility function like:

  1. type Manga struct {
  2. WorkID int `xml:&quot;id,attr&quot;`
  3. Name string `xml:&quot;name,attr&quot;`
  4. Precision string `xml:&quot;precision,attr&quot;`
  5. Info []Info `xml:&quot;info&quot;`
  6. }
  7. type Info struct {
  8. Type string `xml:&quot;type,attr&quot;`
  9. Data string `xml:&quot;,chardata&quot;`
  10. }
  11. func (m *Manga) Genres() []Info {
  12. var g []Info
  13. for _, v := range m.Info {
  14. if v.Type == &quot;Genres&quot; {
  15. g = append(g, v)
  16. }
  17. }
  18. return g
  19. }

See it in action: https://play.golang.org/p/bebUwwbSwG

huangapple
  • 本文由 发表于 2016年8月5日 22:24:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/38791598.html
匿名

发表评论

匿名网友

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

确定