Go 的标准“xml”包中的“,省略”和指针字段

将结构的布尔字段编组为 XML 时,该选项对于大多数用途来说并不是很有用 — 在 Go 中是布尔变量的零值,并且正如预期的那样,在封送处理时会忽略值为 false 的布尔字段。最常建议的解决方案似乎是使用指针,这些指针将允许指示是否存在值。以下是我对这个想法的基本实现:,omitemptyfalse,omitempty


package main


import (

    "encoding/xml"

    "fmt"

)


type Person struct {

    XMLName   xml.Name `xml:"person"`

    IsMarried *bool    `xml:"married"`           // Required field.

    IsRetired *bool    `xml:"retired,omitempty"` // Optional field.

}


func boolPointer(b bool) *bool {

    return &b

}


func printPersonXml(person Person) {

    output, err := xml.MarshalIndent(person, "  ", "    ")

    if err != nil {

        fmt.Printf("error: %v\n", err)

    } else {

        fmt.Println(string(output))

    }

}


func main() {

    person := Person{

        IsMarried: boolPointer(true),

        IsRetired: nil,

    }

    printPersonXml(person)

}

这按预期工作并产生输出


  <person>

      <married>true</married>

  </person>

但是,在这种情况下,选项似乎完全失去了意义。任何具有值的字段都不会包含在生成的 XML 代码中。例如,如果我将 的内容更改为,omitemptynilmain()


person := Person{

    IsMarried: nil,

    IsRetired: nil,

}

printPersonXml(person)

输出变为


  <person></person>

即使我更喜欢


  <person>

      <married></married>

  </person>

如此处所述,这可能是预期的行为:“Marshal 通过封送处理指针所指向的值来处理指针,或者,如果指针为 nil,则不写入任何内容。


但是,是否可以使用标准包装实现我的首选行为?如果是,是否需要为其引入新类型和自定义方法?xmlMarshalXML()


尽管出于显而易见的原因,我在这里专注于布尔变量,但我也想将此方法扩展到其他基本类型的指针。


慕丝7291255
浏览 86回答 1
1回答

萧十郎

“是否有可能使用标准xml包实现我的首选行为?如果是,是否需要为其引入新类型和自定义封送 /XML() 方法?-- 是的,是的。例如:type Bool struct {&nbsp; &nbsp; Bool&nbsp; &nbsp; bool&nbsp; &nbsp; IsValid bool}func (b Bool) MarshalXML(e *xml.Encoder, se xml.StartElement) error {&nbsp; &nbsp; if b.IsValid {&nbsp; &nbsp; &nbsp; &nbsp; return e.EncodeElement(b.Bool, se)&nbsp; &nbsp; }&nbsp; &nbsp; return e.EncodeElement("", se)}type OptionalBool struct {&nbsp; &nbsp; Bool&nbsp; &nbsp; bool&nbsp; &nbsp; IsValid bool}func (b OptionalBool) MarshalXML(e *xml.Encoder, se xml.StartElement) error {&nbsp; &nbsp; if b.IsValid {&nbsp; &nbsp; &nbsp; &nbsp; return e.EncodeElement(b.Bool, se)&nbsp; &nbsp; }&nbsp; &nbsp; return nil}https://play.golang.org/p/C2fuBfv69Ny
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go