用例是生成(并解析)以下XML和JSON,而不是为每个XML和JSON创建单独的结构。
XML
<xxx xmlns="http://example.org/ns">
<data type="plaintext">Hello</data>
<field1>Something1</field1>
<field2>Something2</field2>
...
</xxx>
JSON
{
"data": "Hello",
"data_type": "plaintext",
"field1": "Something1",
"field2": "Something2"
...
}
可能的解决方案将:
type Xxx struct {
XMLName xml.Name `xml:"http://example.org/ns xxx" json:"-"`
// **If only "inline" attribute had existed**
Data Data `xml:"data" json:",inline"`
// There are a lot of other fields here
Field1 string `xml:"field1" json:"field1"`
Field2 string `xml:"field2" json:"field2"`
...
}
type Data struct {
Value string `xml:",chardata" json:"data"`
Type string `xml:"type,attr" data_type:"data"`
}
但是,现在它产生以下JSON:
{"Data": {"data": "Hello", "type": "plaintext"}, "field1": "Something1", "field2": "Something2"}
这不是我需要的。那么,有没有其他方法可以解决不使用xml和json的单独结构的问题?
答案 0 :(得分:2)
解决方案是编写自定义MarshalJSON
(或MarshalXML
)和UnmarshalJSON
(或UnmarshalXML
)来处理文本表示形式的差异。例如:
func (x *Xxx) MarshalJSON() ([]byte, error) {
return []byte(`{"data": "` + x.Data.Value + `","type":"` + x.Data.Type + `","field1":"` + x.Field1 + `","field2":"` + x.Field2 + `"}`), nil
}
这个例子是一个粗略的例子来说明这个原理。为了更有效,您应该使用另一种结构来处理该过程。这个结构不需要导出(事实上你不想导出它),只是在你的函数中使用它。例如:
type xxxJSON struct {
Data string
Type string
Field1 string
Field2 string
}
func (x *Xxx) MarshalJSON() ([]byte, error) {
out := xxxJSON{}
out.Data = x.Data.Value
out.Type = x.Data.Type
out.Field1 = x.Field1
out.Field2 = x.Field2
return json.Marshal(out)
}