英文:
Golang: structure to generate/parse both XML and JSON
问题
使用相同的结构来生成XML和JSON,而不是为每个格式创建单独的结构。目前的解决方案产生了不符合要求的JSON结果。是否有其他方法可以解决这个问题,而不是使用单独的结构来处理XML和JSON?
英文:
The use case is to generate (and parse) the following XML and JSON not creating separate structures for every of them.
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"
...
}
Possible solution would be:
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"`
}
However, right now it produces the following JSON:
{"Data": {"data": "Hello", "type": "plaintext"}, "field1": "Something1", "field2": "Something2"}
which is not what I need. So, is there any other way to solve the problem not using separate structures for xml and json?
答案1
得分: 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)
}
以上是翻译好的内容,请确认是否满意。
英文:
The solution is to write a custom MarshalJSON
(or MarshalXML
) and UnmarshalJSON
(or UnmarshalXML
) to handle the differences in your text-representations. Example:
func (x *Xxx) MarshalJSON() ([]byte, error) {
return []byte(`{"data": "` + x.Data.Value + `","type":"` + x.Data.Type + `","field1":"` + x.Field1 + `","field2":"` + x.Field2 + `"}`), nil
}
This example is a rough one to demonstrate the principle. For something more efficient, you should use another structure to handle the process. This structure doesn't need to be exported (in fact you don't want to export it), just to be there and used by your function. Example:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论