gpt4 book ai didi

go - 尝试将 xml.Unmarshal 构造为类型为 map[string]interface{} 的字段时出错

转载 作者:数据小太阳 更新时间:2023-10-29 03:06:56 24 4
gpt4 key购买 nike

问题是 xml.Unmarshal 的字段类型为 map[string]interface{} 的结构将失败并出现错误:

unknown type map[string]interface {}
{XMLName:{Space: Local:myStruct} Name:test Meta:map[]}

由于类型为 map[string]interface{} 的 Meta 字段是我所能定义的,因此必须动态解码其中的内容。

package main

import (
"encoding/xml"
"fmt"
)

func main() {
var myStruct MyStruct

// meta is as far as we know, inside meta, dynamic properties and nesting will happen
s := `<myStruct>
<name>test</name>
<meta>
<someProp>something</someProp>
<someOtherDynamic>
<name>test</name>
<somethingElse>test2</somethingElse>
<nested3>
<name>nested3</name>
<nested3elements>
<elem>ele1</elem>
<elem>ele2</elem>
</nested3elements>
</nested3>
</someOtherDynamic>
</meta>
</myStruct>`

err := xml.Unmarshal([]byte(s), &myStruct)
if err == nil {
fmt.Printf("%+v\n", myStruct)
} else {
fmt.Println(err)
fmt.Printf("%+v\n", myStruct)
}
}

type MyStruct struct {
XMLName xml.Name `xml:"myStruct"`
Name string `xml:"name"`
Meta map[string]interface{} `xml:"meta,omitempty"`
}

我在这里做了一个例子:http://play.golang.org/p/lTDJzXXPwT

我怎样才能做到这一点?


到目前为止我的解决方法“解决方案”:

http://play.golang.org/p/gQUlvkYl7k

基本上发生的是:

  1. Meta 字段删除了 xml 注释,因此在 xml.Unmashal 中被忽略
  2. 新类型 MapContainer 是用一个字段创建的:InnerXML []byte xml:",innerxml"
  3. 使用 xml:"meta,omitempty" 注释添加 MapContainer 类型的 MetaByte 字段

所以在第一个 xml.Unmarshal 中,我们保存了元元素 XML 的一个字节 slice 。然后在我们自定义的 xml 解码函数中,我们获取 byteSlice 并使用 mxj 包中的魔术函数 NewMapXml,并将结构的 Meta 字段设置为这个新创建的映射。

这要归功于制作此 repo 的天才,https://github.com/clbanning/mxj ,它可以从 XML 解码为映射。

更新当前最佳解决方案:

http://play.golang.org/p/_tw06klods

感谢 Adam Vincze

最佳答案

根据您最后需要对元数据执行的操作,您可能想看看这个库:https://github.com/clbanning/mxj

如果您实现自定义 UnmarshalXML 函数,您可以做得更好

func (m *MyStruct) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var v struct {
XMLName xml.Name `xml:"myStruct"`
Name string `xml:"name"`
Meta struct {
Inner []byte `xml:",innerxml"`
} `xml:"meta"`
}


err := d.DecodeElement(&v, &start)
if err != nil {
return err
}

m.Name = v.Name
myMap := make(map[string]interface{})
// ... do the mxj magic here ... -
// fill myMap
m.Meta = myMap


return nil
}

type MyStruct struct {
Name string
Meta map[string]interface{}
}

`

这让您的 MyStruct 干净整洁

关于go - 尝试将 xml.Unmarshal 构造为类型为 map[string]interface{} 的字段时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31156938/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com