Golang:生成/解析XML和JSON的结构体

3
使用案例是生成(并解析)以下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?

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)
}

嘿,@elwinar。感谢你的回答。但是如果这个结构体除了“Data”字段之外还应该包含其他字段呢? - user3366304
@user3366304:我不明白问题出在哪里。请更新你的问题并提供更多使用案例。 - Elwinar
@user3366304:更新了我的回答。 - Elwinar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接