英文:
How to marshal xml with optional tags in Go
问题
我的问题是这样的:我需要将数据编组为SOAP XML。我目前得到的结果是:
<Carriage>
<mainCarriage loadFactor="70" seaCargoType="Container">
<sea xmlns="http://www.example.com/XMLSchema/standard/2012"></sea>
</mainCarriage>
</Carriage>
但我需要的结果是:
<Carriage>
<mainCarriage>
<sea xmlns="http://www.example.com/XMLSchema/standard/2012" loadFactor="70" seaCargoType="Container"></sea>
</mainCarriage>
</Carriage>
无论我尝试什么,我都无法将结构体编组为loadFactor
和seaCargoType
是sea
标签的属性。
Carriage
结构体采用空接口,因为根据货运类型,标签应该是sea
或road
,但不能同时存在。
英文:
The code for my problem is here: https://play.golang.org/p/X8Ey2hqmxL
package main
import (
"encoding/xml"
"fmt"
"log"
)
type Carriage struct {
MainCarriage interface{} `xml:"mainCarriage"`
}
type SeaCarriage struct {
Sea xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 sea"`
LoadFactor float64 `xml:"loadFactor,attr"`
SeaCargoType string `xml:"seaCargoType,attr"`
}
type RoadCarriage struct {
Road xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 road"`
}
func main() {
fr := Carriage{
MainCarriage: SeaCarriage{
LoadFactor: 70,
SeaCargoType: "Container",
},
}
xmlBlob, err := xml.MarshalIndent(&fr, "", "\t")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(xmlBlob))
}
I need to marshall data into SOAP xml. I'm currently getting this result:
<Carriage>
<mainCarriage loadFactor="70" seaCargoType="Container">
<sea xmlns="http://www.example.com/XMLSchema/standard/2012"></sea>
</mainCarriage>
</Carriage>
But I need this result:
<Carriage>
<mainCarriage>
<sea xmlns="http://www.example.com/XMLSchema/standard/2012" loadFactor="70" seaCargoType="Container"></sea>
</mainCarriage>
</Carriage>
No matter what I try I cannot marshal the structs so that the loadFactor and the seaCargoType are attrs of the sea
tag.
The Carriage struct takes an empty interface because depending on the shipment type the tag should be either sea or road but never both.
答案1
得分: 2
在mainCarriage
字段标签后面加上>.
,表示你想将字段的内容放在mainCarriage
标签内。根据编组器的要求,将Sea
字段的名称更改为XMLName
。
package main
import (
"encoding/xml"
"fmt"
"log"
)
type Carriage struct {
MainCarriage interface{} `xml:"mainCarriage>."`
}
type SeaCarriage struct {
XMLName xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 sea"`
LoadFactor float64 `xml:"loadFactor,attr"`
SeaCargoType string `xml:"seaCargoType,attr"`
}
type RoadCarriage struct {
Road xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 road"`
}
func main() {
fr := Carriage{
MainCarriage: SeaCarriage{
LoadFactor: 70,
SeaCargoType: "Container",
},
}
xmlBlob, err := xml.MarshalIndent(&fr, "", "\t")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(xmlBlob))
}
<kbd>Playground</kbd>
英文:
Put >.
after mainCarriage
field tag to indicate that you want to put contents of the field inside mainCarriage
tag. Change the name of Sea
field to XMLName
as required by marshaller.
package main
import (
"encoding/xml"
"fmt"
"log"
)
type Carriage struct {
MainCarriage interface{} `xml:"mainCarriage>."`
}
type SeaCarriage struct {
XMLName xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 sea"`
LoadFactor float64 `xml:"loadFactor,attr"`
SeaCargoType string `xml:"seaCargoType,attr"`
}
type RoadCarriage struct {
Road xml.Name `xml:"http://www.example.com/XMLSchema/standard/2012 road"`
}
func main() {
fr := Carriage{
MainCarriage: SeaCarriage{
LoadFactor: 70,
SeaCargoType: "Container",
},
}
xmlBlob, err := xml.MarshalIndent(&fr, "", "\t")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(xmlBlob))
}
<kbd>Playground</kbd>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论