Golang的xml编码不会将空值映射为nil。

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

Golang encoding xml doesn't map empty value to nil

问题

我想将标签中的空值映射为对象中的nil值,例如:
我有以下的XML:

  1. <Address>
  2. <city>city</city>
  3. <streetNumber></streetNumber>
  4. </Address>

我的类型是:

  1. type Address struct{
  2. city string `xml:"city"`
  3. streetNumber *int `xml:"streetNumber"`
  4. }

在这种情况下,streetNumber 是 0,但是当我从 XML 中删除 streetNumber 标签时,值应该是 nil。
是否可能在标签为空时将 streetNumber 标签映射为 nil?

英文:

I would like to map empty value from tag to nill value in my object e.g.
I have this xml

  1. &lt;Address&gt;
  2. &lt;city&gt;city&lt;/city&gt;
  3. &lt;streetNumber&gt;&lt;/streetNumber&gt;
  4. &lt;/Address&gt;

a my type is

  1. type Address struct{
  2. city string `xml:&quot;city&quot;`
  3. streetNumber *int `xml:&quot;streetNumber&quot;`
  4. }

and in this case streetNumber is 0 but when I delete tag streetNumber from xml value is nil
Is it possible to map streetNumber tag to nil when it is empty?

答案1

得分: 2

你可能想要考虑将streetNumber作为自己的类型,并使用自定义编组(marshaling),就像这里使用时间格式进行编组一样:https://www.programming-books.io/essential/go/custom-xml-marshaling-aa8105fe264b4b198647cbc718480ba1

我倾向于使用int + Valid bool的组合,但你也可以使用int指针。

**编辑:**更新以包括marshal/unmarshal的潜在实现。

  1. type Address struct {
  2. City string `xml:"city"`
  3. StreetNumber StreetNumber `xml:"streetNumber"`
  4. }
  5. type StreetNumber struct {
  6. Value int
  7. Valid bool
  8. }
  9. func (s StreetNumber) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  10. // 如果地址为null/unset/invalid,我们将空字符串序列化为值。
  11. v := ""
  12. if s.Valid {
  13. // 地址有值,所以我们将整数转换为字符串。
  14. v = strconv.Itoa(s.Value)
  15. }
  16. // 将字符串`v`编码为XML元素。
  17. return e.EncodeElement(v, start)
  18. }
  19. func (s *StreetNumber) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  20. // 假设值无效,以便我们可以快速退出。
  21. s.Valid = false
  22. s.Value = 0
  23. var v string
  24. if err := d.DecodeElement(&v, &start); err != nil {
  25. // 如果无法解码原始XML,则转发错误。
  26. return err
  27. }
  28. if v == "" {
  29. // 值为空,但这只是第三个null状态,不是错误。
  30. return nil
  31. }
  32. i, err := strconv.Atoi(v)
  33. if err != nil {
  34. // 元素值不是整数,因此这是一个无效状态--转发错误。
  35. return err
  36. }
  37. // 街道号码是有效的整数。
  38. s.Valid = true
  39. s.Value = i
  40. return nil
  41. }

以上是你要翻译的内容。

英文:

You may want to look at making streetNumber its own type with custom marshaling like what they're doing here with time format:
https://www.programming-books.io/essential/go/custom-xml-marshaling-aa8105fe264b4b198647cbc718480ba1

I'd lean towards the int + Valid bool combo but you could do an int pointer.

Edit: updated to include a potential implementation of marshal/unmarshal.

  1. type Address struct {
  2. City string `xml:&quot;city&quot;`
  3. StreetNumber StreetNumber `xml:&quot;streetNumber&quot;`
  4. }
  5. type StreetNumber struct {
  6. Value int
  7. Valid bool
  8. }
  9. func (s StreetNumber) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  10. // If the address is null/unset/invalid, we serialize an empty string as the value.
  11. v := &quot;&quot;
  12. if s.Valid {
  13. // The address has a value so we convert the integer to string.
  14. v = strconv.Itoa(s.Value)
  15. }
  16. // Encode the string `v` to the XML element.
  17. return e.EncodeElement(v, start)
  18. }
  19. func (s *StreetNumber) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  20. // Assume the value is invalid so we can just shortcut out.
  21. s.Valid = false
  22. s.Value = 0;
  23. var v string
  24. if err := d.DecodeElement(&amp;v, &amp;start); err != nil {
  25. // Forward the error if it failed to decode the raw XML
  26. return err
  27. }
  28. if v == &quot;&quot; {
  29. // The value was empty, but this is just the 3rd null state, not an error.
  30. return nil
  31. }
  32. i, err := strconv.Atoi(v)
  33. if err != nil {
  34. // The element value was not an integer so this is an invalid state -- forward the error.
  35. return err
  36. }
  37. // The street number was a valid integer.
  38. s.Valid = true
  39. s.Value = i
  40. return nil
  41. }

huangapple
  • 本文由 发表于 2022年5月20日 20:24:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/72318894.html
匿名

发表评论

匿名网友

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

确定