为了账号安全,请及时绑定邮箱和手机立即绑定

Marshal 一个 JSON Marshal 兼容映射到 XML

Marshal 一个 JSON Marshal 兼容映射到 XML

Go
墨色风雨 2022-06-01 09:53:18
我有一张地图:[]map[string]string。将结果填充到json.marshal()兼容的对象中。输出:[  {    "key1": "val1",    "key2": "val2"  },  {    "randval3": "val1",    "randval2": "xyz1"    "randval1": "xyz3"  },  ...]但是,当我运行xml.marshal(). 我收到一个xml: unsupported type: map[string]string. 考虑到 XML 需要节点名称等这一事实,这似乎是合理的。所以我基本上要寻找的是一种获得方法:<rootElement>    <child>        <key1>val1</key1>        <key2>val1</key2>    </child>    <child>        <randval3>val1</randval3>        <randval2>xyz1</randval2>        <randval1>xyz1</randval1>    </child></rootElement>但是我一直无法获得与兼容的“对象”xml.unmarshal()
查看完整描述

2 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

您可以声明一个自定义地图并让它实现xml.Marshaler接口。


type mymap map[string]string


func (m mymap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {

    if err := e.EncodeToken(start); err != nil {

        return err

    }


    for key, val := range m {

        s := xml.StartElement{Name: xml.Name{Local: key}}

        if err := e.EncodeElement(val, s); err != nil {

            return err

        }

    }


    return e.EncodeToken(start.End())

}


type RootElement struct {

    XMLName  xml.Name `xml:"rootElement"`

    Children []mymap  `xml:"child"`

https://play.golang.com/p/0_qA9UUvhKV


func main() {

    root := RootElement{Children: []mymap{

        {"key1": "val1", "key2": "val2"},

        {"randval1": "val1", "randval2": "xyz1", "randval3": "abc3"},

    }}


    data, err := xml.MarshalIndent(root, "", "  ")

    if err != nil {

        panic(err)

    }

    fmt.Println(string(data))

}

输出:


<rootElement>

  <child>

    <key2>val2</key2>

    <key1>val1</key1>

  </child>

  <child>

    <randval3>abc3</randval3>

    <randval1>val1</randval1>

    <randval2>xyz1</randval2>

  </child>

</rootElement>


查看完整回答
反对 回复 2022-06-01
?
侃侃无极

TA贡献2051条经验 获得超10个赞

对于 Marshalling/Unmarshalling 映射,您需要编写自己的Marshal()和Unmarshal()函数。


下面是一个实现这些功能type Maps []map[string]string以及如何使用它们的示例。


type Maps []map[string]string


type xmlMapEntry struct {

    XMLName xml.Name

    Value   string `xml:",chardata"`

}


func (m Maps) MarshalXML(e *xml.Encoder, start xml.StartElement) error {

    if len(m) == 0 {

        return nil

    }


    err := e.EncodeToken(start)

    if err != nil {

        return err

    }


    for _, ma := range m {

        for k, v := range ma {

            e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: v})

        }

    }


    return e.EncodeToken(start.End())

}


func (m *Maps) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {

    *m = Maps{}


    for {

        var e xmlMapEntry


        err := d.Decode(&e)

        if err == io.EOF {

            break

        } else if err != nil {

            return err

        }


        *m = append(*m, map[string]string{e.XMLName.Local: e.Value})

    }

    return nil

}


func main() {

    myarraymap := []map[string]string{

        0: {"Key1": "val1"},

        1: {"Key2": "val2"},

        2: {"Randval3": "val1"},

        3: {"Randval2": "xyz1"},

        4: {"Randval1": "xyz2"},

    }


    // Encode to XML

    x, _ := xml.MarshalIndent(Maps(myarraymap), "", "  ")

    fmt.Printf("my marshaled xml map: %v\n", string(x))



    // Decode back from XML

    var rm []map[string]string

    xml.Unmarshal(x, (*Maps)(&rm))

    fmt.Printf("my unmarshalled xml map: %v \n", rm)

}


查看完整回答
反对 回复 2022-06-01
  • 2 回答
  • 0 关注
  • 147 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信