在Go中,您可以将结构编组为XML,例如:
package main
import (
"encoding/xml"
"fmt"
)
type person struct {
Name string
Starsign string
}
func main() {
p := &person{"John Smith", "Capricorn"}
b,_ := xml.MarshalIndent(p,""," ")
fmt.Println(string(b))
}
产生输出:
<person>
<Name>John Smith</Name>
<Starsign>Capricorn</Starsign>
</person>
我的问题是,人员类型是小写的“p”,因为我希望它是私有的包。但我更喜欢XML元素是大写的:<Person>
。结构中的字段可以使用标记(例如`xml:“name”`)对结构字段编组为其他名称,但这似乎不是结构类型的选项。
我有一个使用模板的解决方法,但知道更好的答案会很好。
答案 0 :(得分:5)
根据encoding/xml.Marshal文档:
XML元素的名称取自优先顺序:
- XMLName字段上的标记,如果数据是结构
- xml.Name
类型的XMLName字段的值- 用于获取数据的struct字段的标记
- 用于获取数据的struct字段的名称
- 编组类型的名称
您可以在结构中的XMLName字段上使用标记来覆盖person结构的XML标记名称。为了避免将它放在你的实际person结构中,你可以创建一个嵌入你正在编组的人结构的匿名结构。
package main
import (
"encoding/xml"
"fmt"
)
type person struct {
Name string
Starsign string
}
func marshalPerson(p person) ([]byte, error) {
tmp := struct {
person
XMLName struct{} `xml:"Person"`
}{person: p}
return xml.MarshalIndent(tmp, "", " ")
}
func main() {
p := person{"John Smith", "Capricorn"}
b, _ := marshalPerson(p)
fmt.Println(string(b))
}
答案 1 :(得分:1)
这也有效,但我不认为它特别漂亮。
然而,对于我来说,这比5年前其他公认的解决方案更为直接。
package main
import (
"encoding/xml"
"fmt"
)
type person struct {
XMLName xml.Name
Name string
Starsign string
}
func main() {
p := &person{xml.Name{Local: "Person"}, "John Smith", "Capricorn"}
b,_ := xml.MarshalIndent(p,""," ")
fmt.Println(string(b))
}
答案 2 :(得分:1)
我认为最简单的方法就是使用 XML 标记向 person 结构中添加一个虚拟字段。
struct{}
元素不使用任何存储空间,我检查了 unsafe.Sizeof()
。
唯一的缺点是,在本例中,e 需要为该字段添加一个 struct{}{}
初始值。
package main
import (
"encoding/xml"
"fmt"
)
type person struct {
Name string
Starsign string
XMLName struct{} `xml:Person`
}
func main() {
p := &person{"John Smith", "Capricorn", struct{}{}}
b,_ := xml.MarshalIndent(p,""," ")
fmt.Println(string(b))
}