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

时间:2014-06-14 11:41:08

标签: xml json encoding go

用例是生成(并解析)以下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的单独结构的问题?

1 个答案:

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