我正在处理一个期望XML的API,其格式通常是这样的。
<receiver>
<receiver_type>test</receiver_type>
<hostnames>http://posttestserver.com</hostnames>
<credentials>
<credential>
<name>app-id</name>
<value>1234</value>
<safe>true</safe>
</credential>
<credential>
<name>app-secret</name>
<value>5678</value>
</credential>
</credentials>
</receiver>
因此,在我的Go代码中,我将这些结构用于我的函数并编组到XML结构中。请注意,不同的接收者可以拥有不同的凭证集。
type Receiver1 struct {
XMLName xml.Name `xml:"receiver"`
ReceiverType string `xml:"receiver_type"`
HostNames string `xml:"hostnames"`
Credentials Receiver1Credentials `xml:"credentials"`
}
type Receiver2 struct {
XMLName xml.Name `xml:"receiver"`
ReceiverType string `xml:"receiver_type"`
HostNames string `xml:"hostnames"`
Credentials Receiver2Credentials `xml:"credentials"`
}
type Receiver1Credentials struct {
AppID Credential `xml:"credential"`
AppSecret Credential `xml:"credential"`
}
type Receiver2Credentials struct {
UserName Credential `xml:"credential"`
Password Credential `xml:"credential"`
AppID Credential `xml:"credential"`
}
type Credential struct {
Name string `xml:"name"`
Value string `xml:"value"`
Safe bool `xml:"safe"`
}
然而,这会产生Receiver1Credentials field "AppID" with tag "credential" conflicts with field "AppSecret" with tag "credential"
行的运行时错误,这意味着我无法直接标记凭据字段。我尝试在Credential结构上使用字段XMLName xml.Name xml:"credential"
(就像在Receiver结构上一样),但它会被Credentials结构上的标记覆盖。有谁知道如何解决这个问题?
答案 0 :(得分:3)
要将数据编组为xml,您只需创建一个简单的接收器结构,对其进行初始化,然后调用xml.Marshal(...)
。
(请注意,要将credential
嵌套到credentials
中,需要将显式xml标记与字段相关联)
type Receiver struct {
XMLName xml.Name `xml:"receiver"`
ReceiverType string `xml:"receiver_type"`
HostNames string `xml:"hostnames"`
Credentials []Credential `xml:"credentials>credential"` // necessary to allow tag nesting
}
type Credential struct {
Name string `xml:"name"`
Value string `xml:"value"`
Safe bool `xml:"safe,omitempty"` // omitempty does not include the tag if if it's empty
}
现在您可以简单地初始化Receiver
并将其编组为xml:
r := &Receiver{
ReceiverType: "test",
HostNames: "http://posttestserver.com",
Credentials: []Credential{
Credential{"app-id", "1234", true},
Credential{"app-secret", "5678", false},
},
}
a, _ := xml.MarshalIndent(r, "", " ") // a is []byte containing xml encoded data
(工作示例:https://play.golang.org/p/JZcUUK9P1f)
原始答案 - 将上述xml解组为接收器的方法
如果您可以避免将xml数据直接解析为Receiver[12]Credentials
,则可以使用以下方法将xml数据解组为更简单的结构(Receiver
和Credential
):< / p>
receiver := &Receiver{}
xml.Unmarshal(xmlDataByteSlice, receiver)
这会在Credential
上方存储所有receiver.Credentials
个对象:
fmt.Println(receiver.Credentials)
// [{app-id 1234 true} {app-secret 5678 false}]
然后,您可以使用switch case
上的receiver,Credential.Name
相应地初始化Receiver[12]Credentials
。