How to marshal xml with optional tags in Go

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

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>

无论我尝试什么,我都无法将结构体编组为loadFactorseaCargoTypesea标签的属性。

Carriage结构体采用空接口,因为根据货运类型,标签应该是searoad,但不能同时存在。

英文:

The code for my problem is here: https://play.golang.org/p/X8Ey2hqmxL

package main

import (
	&quot;encoding/xml&quot;
	&quot;fmt&quot;
	&quot;log&quot;
)

type Carriage struct {
	MainCarriage interface{} `xml:&quot;mainCarriage&quot;`
}

type SeaCarriage struct {
	Sea          xml.Name `xml:&quot;http://www.example.com/XMLSchema/standard/2012 sea&quot;`
	LoadFactor   float64  `xml:&quot;loadFactor,attr&quot;`
	SeaCargoType string   `xml:&quot;seaCargoType,attr&quot;`
}

type RoadCarriage struct {
	Road xml.Name `xml:&quot;http://www.example.com/XMLSchema/standard/2012 road&quot;`
}

func main() {

	fr := Carriage{
		MainCarriage: SeaCarriage{
			LoadFactor:   70,
			SeaCargoType: &quot;Container&quot;,
		},
	}
	xmlBlob, err := xml.MarshalIndent(&amp;fr, &quot;&quot;, &quot;\t&quot;)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(xmlBlob))
}

I need to marshall data into SOAP xml. I'm currently getting this result:

&lt;Carriage&gt;
	&lt;mainCarriage loadFactor=&quot;70&quot; seaCargoType=&quot;Container&quot;&gt;
		&lt;sea xmlns=&quot;http://www.example.com/XMLSchema/standard/2012&quot;&gt;&lt;/sea&gt;
	&lt;/mainCarriage&gt;
&lt;/Carriage&gt;

But I need this result:

&lt;Carriage&gt;
	&lt;mainCarriage&gt;
		&lt;sea xmlns=&quot;http://www.example.com/XMLSchema/standard/2012&quot; loadFactor=&quot;70&quot; seaCargoType=&quot;Container&quot;&gt;&lt;/sea&gt;
	&lt;/mainCarriage&gt;
&lt;/Carriage&gt;

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字段标签后面加上&gt;.,表示你想将字段的内容放在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 &gt;. 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 (
	&quot;encoding/xml&quot;
	&quot;fmt&quot;
	&quot;log&quot;
)

type Carriage struct {
	MainCarriage interface{} `xml:&quot;mainCarriage&gt;.&quot;`
}

type SeaCarriage struct {
	XMLName      xml.Name `xml:&quot;http://www.example.com/XMLSchema/standard/2012 sea&quot;`
	LoadFactor   float64  `xml:&quot;loadFactor,attr&quot;`
	SeaCargoType string   `xml:&quot;seaCargoType,attr&quot;`
}

type RoadCarriage struct {
	Road xml.Name `xml:&quot;http://www.example.com/XMLSchema/standard/2012 road&quot;`
}

func main() {

	fr := Carriage{
		MainCarriage: SeaCarriage{
			LoadFactor:   70,
			SeaCargoType: &quot;Container&quot;,
		},
	}
	xmlBlob, err := xml.MarshalIndent(&amp;fr, &quot;&quot;, &quot;\t&quot;)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(xmlBlob))
}

<kbd>Playground</kbd>

huangapple
  • 本文由 发表于 2015年12月11日 18:32:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/34221384.html
匿名

发表评论

匿名网友

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

确定