如何在反序列化时跳过元素?

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

How to skip elements when unmarshalling?

问题

如何在解组 XML 时删除 <Text Language="de">...</Text>(如下所示)?

我尝试使用 UnmarshalXML 方法跳过元素,但是这样做会跳过整个元素。

Play Golang 链接中的示例

  1. package main
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. )
  6. type Root struct {
  7. Translation []Text `xml:"Texts>Text>Text"`
  8. }
  9. type Text struct {
  10. Language string `xml:"Language,attr"`
  11. Value string `xml:"Value"`
  12. }
  13. func main() {
  14. foo := `
  15. <Root>
  16. <Texts>
  17. <Text>
  18. <Text Language="EN">
  19. <Value>One</Value>
  20. </Text>
  21. <Text Language="de">
  22. <Value>Eins</Value>
  23. </Text>
  24. </Text>
  25. </Texts>
  26. </Root>
  27. `
  28. var root Root
  29. e := xml.Unmarshal([]byte(foo), &root)
  30. if e != nil {
  31. panic(e)
  32. }
  33. fmt.Printf("%+v\n", root)
  34. }
  35. func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  36. tx := struct{ Language, Value string }{}
  37. if start.Attr[0].Value == "EN" {
  38. d.DecodeElement(&tx, &start)
  39. // 在这里无法获取 Language 属性
  40. *t = Text{tx.Language, tx.Value}
  41. // fmt.Printf("hey: %+v %s\n", tx, start.Attr[0].Value)
  42. } else {
  43. // 它输出了带有空字段的 DE 元素
  44. d.Skip()
  45. }
  46. return nil
  47. }

当前输出:

  1. {Translation:[{Language: Value:One} {Language: Value:}]}

我想要的输出:

  1. {Translation:[{Language:EN Value:One}]}
英文:

How can I remove &lt;Text Language=&quot;de&quot;&gt;...&lt;/Text&gt; (as shown below) when unmarshaling XML?

I tried to skip the element with UnmarshalXML method, however, it's skipping the whole element when I do that.

Example in Play Golang Link

package main

  1. import (
  2. &quot;encoding/xml&quot;
  3. &quot;fmt&quot;
  4. )
  5. type Root struct {
  6. Translation []Text `xml:&quot;Texts&gt;Text&gt;Text&quot;`
  7. }
  8. type Text struct {
  9. Language string `xml:&quot;Language,attr&quot;`
  10. Value string `xml:&quot;Value&quot;`
  11. }
  12. func main() {
  13. foo := `
  14. &lt;Root&gt;
  15. &lt;Texts&gt;
  16. &lt;Text&gt;
  17. &lt;Text Language=&quot;EN&quot;&gt;
  18. &lt;Value&gt;One&lt;/Value&gt;
  19. &lt;/Text&gt;
  20. &lt;Text Language=&quot;de&quot;&gt;
  21. &lt;Value&gt;Eins&lt;/Value&gt;
  22. &lt;/Text&gt;
  23. &lt;/Text&gt;
  24. &lt;/Texts&gt;
  25. &lt;/Root&gt;
  26. `
  27. var root Root
  28. e := xml.Unmarshal([]byte(foo), &amp;root)
  29. if e != nil {
  30. panic(e)
  31. }
  32. fmt.Printf(&quot;%+v\n&quot;, root)
  33. }
  34. func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  35. tx := struct{ Language, Value string }{}
  36. if start.Attr[0].Value == &quot;EN&quot; {
  37. d.DecodeElement(&amp;tx, &amp;start)
  38. // I couldn&#39;t got Language attr here
  39. *t = Text{tx.Language, tx.Value}
  40. // fmt.Printf(&quot;hey: %+v %s\n&quot;, tx, start.Attr[0].Value)
  41. } else {
  42. // It outputs DE element with empty fields
  43. d.Skip()
  44. }
  45. return nil
  46. }

Current Output:

  1. {Translation:[{Language: Value:One} {Language: Value:}]}

What I Want:

  1. {Translation:[{Language:EN Value:One}]}

答案1

得分: 2

你的代码中存在问题,导致第二个元素为空。你可以尝试以下修改:

  1. package main
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. )
  6. type Root struct {
  7. Translation Text `xml:"Texts>Text>Text"`
  8. }
  9. type Text []struct {
  10. Language string `xml:"Language,attr"`
  11. Value string `xml:"Value"`
  12. }
  13. func main() {
  14. foo := `
  15. <Root>
  16. <Texts>
  17. <Text>
  18. <Text Language="EN">
  19. <Value>One</Value>
  20. </Text>
  21. <Text Language="de">
  22. <Value>Eins</Value>
  23. </Text>
  24. </Text>
  25. </Texts>
  26. </Root>
  27. `
  28. var root Root
  29. e := xml.Unmarshal([]byte(foo), &root)
  30. if e != nil {
  31. panic(e)
  32. }
  33. fmt.Printf("%+v\n", root)
  34. }
  35. func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  36. tx := []struct {
  37. Language string `xml:"Language,attr"`
  38. Value string `xml:"Value"`
  39. }{}
  40. d.DecodeElement(&tx, &start)
  41. tSl := *t
  42. for _, elem := range tx {
  43. switch elem.Language {
  44. case "EN":
  45. tSl = append(tSl, struct {
  46. Language string `xml:"Language,attr"`
  47. Value string `xml:"Value"`
  48. }{elem.Language, elem.Value})
  49. default:
  50. d.Skip()
  51. }
  52. }
  53. *t = tSl
  54. return nil
  55. }

输出结果应为:

  1. {Translation:[{Language:EN Value:One}]}
英文:

You're operating too low by unmarshalling at the Text Level - you're still Unmarshalling 2 Texts elements which is why you are seeing an empty second element. You could try something like this:

  1. package main
  2. import (
  3. &quot;encoding/xml&quot;
  4. &quot;fmt&quot;
  5. )
  6. type Root struct {
  7. Translation Text `xml:&quot;Texts&gt;Text&gt;Text&quot;`
  8. }
  9. type Text []struct {
  10. Language string `xml:&quot;Language,attr&quot;`
  11. Value string `xml:&quot;Value&quot;`
  12. }
  13. func main() {
  14. foo := `
  15. &lt;Root&gt;
  16. &lt;Texts&gt;
  17. &lt;Text&gt;
  18. &lt;Text Language=&quot;EN&quot;&gt;
  19. &lt;Value&gt;One&lt;/Value&gt;
  20. &lt;/Text&gt;
  21. &lt;Text Language=&quot;de&quot;&gt;
  22. &lt;Value&gt;Eins&lt;/Value&gt;
  23. &lt;/Text&gt;
  24. &lt;/Text&gt;
  25. &lt;/Texts&gt;
  26. &lt;/Root&gt;
  27. `
  28. var root Root
  29. e := xml.Unmarshal([]byte(foo), &amp;root)
  30. if e != nil {
  31. panic(e)
  32. }
  33. fmt.Printf(&quot;%+v\n&quot;, root)
  34. }
  35. func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  36. tx := []struct{
  37. Language string `xml:&quot;Language,attr&quot;`
  38. Value string `xml:&quot;Value&quot;`
  39. }{}
  40. d.DecodeElement(&amp;tx, &amp;start)
  41. tSl := *t
  42. for _, elem := range tx {
  43. switch elem.Language {
  44. case &quot;EN&quot;:
  45. tSl = append(tSl, struct{
  46. Language string `xml:&quot;Language,attr&quot;`
  47. Value string `xml:&quot;Value&quot;`}{elem.Language, elem.Value})
  48. default:
  49. d.Skip()
  50. }
  51. }
  52. *t = tSl
  53. return nil
  54. }

Output:

  1. {Translation:[{Language:EN Value:One}]}

huangapple
  • 本文由 发表于 2017年6月9日 18:48:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/44455853.html
匿名

发表评论

匿名网友

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

确定