当前位置: 首页 > 面试题库 >

如何解组可以是字符串*或*字符串数组的不一致的JSON字段?

向俊贤
2023-03-14
问题内容

我在解组一些我无法控制的Json时遇到麻烦。在一个字段中,有99%的时间是字符串,但偶尔是数组。

type MyListItem struct {
    Date  string `json:"date"`
    DisplayName       string `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}

var mylist MyListings
err = json.Unmarshal(jsn, &mylist)
if err != nil {
    fmt.Print("JSON:\n%s\n error:%v\n", string(jsn),err)
    return
}

杰森如下:

{       
    "date": "30 Apr",
    "display_name": "Mr Smith"
},
{
    "date": "30 Apr",
    "display_name": ["Mr Smith", "Mr Jones"],
}

错误:json:无法将数组解组为字符串类型的Go结构字段MyListItem.display_name


问题答案:

使用json.RawMessage捕获变化的字段。

使用json“-”名称对DisplayName解码器隐藏字段。顶级JSON解码后,应用程序将填充此字段。

type MyListItem struct {
    Date           string          `json:"date"`
    RawDisplayName json.RawMessage `json:"display_name"`
    DisplayName    []string        `json:"-"`
}

解组顶级JSON:

var li MyListItem
if err := json.Unmarshal(data, &li); err != nil {
    // handle error
}

根据原始数据的类型取消对显示名称的编组:

if len(li.RawDisplayName) > 0 {
    switch li.RawDisplayName[0] {
    case '"':
        if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil {
            // handle error
        }
    case '[':
        var s []string
        if err := json.Unmarshal(li.RawDisplayName, &s); err != nil {
            // handle error
        }
        // Join arrays with "&" per OP's comment on the question.
        li.DisplayName = strings.Join(s, "&")
    }
}

游乐场的例子

将以上内容合并到for循环中以进行处理MyListings

var listings MyListings
if err := json.Unmarshal([]byte(data), &listings); err != nil {
    // handle error
}
for i := range listings.CLItems {
    li := &listings.CLItems[i]
    if len(li.RawDisplayName) > 0 {
        switch li.RawDisplayName[0] {
        case '"':
            if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil {
                // handle error
            }
        case '[':
            var s []string
            if err := json.Unmarshal(li.RawDisplayName, &s); err != nil {
                // handle error
            }
            li.DisplayName = strings.Join(s, "&")
        }
    }
}

游乐场的例子

如果数据模型中有多个位置,值可以是字符串或[]字符串,则将逻辑封装为类型可能会有所帮助。在json.Unmarshaler接口的实现中解析JSON数据。

type multiString string

func (ms *multiString) UnmarshalJSON(data []byte) error {
    if len(data) > 0 {
        switch data[0] {
        case '"':
            var s string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(s)
        case '[':
            var s []string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(strings.Join(s, "&"))
        }
    }
    return nil
}

像这样使用它:

type MyListItem struct {
    Date        string      `json:"date"`
    DisplayName multiString `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}

var listings MyListings
if err := json.Unmarshal([]byte(data), &listings); err != nil {
    log.Fatal(err)
}

操场上的例子



 类似资料:
  • 问题内容: 我正试图解组该文件: 进入这个结构: 使用以下说明: 问题是在“ json-schema@0.2.3”中,我们有一个许可证数组而不是一个字符串,由于这个原因,我显然得到了 有没有一种方法可以自动处理可以是数组或字符串的字段? 谢谢 问题答案: 不幸的是,软件包没有提供真正的自动解决方案。 但是您可以将依赖项解组为a 而不是。只是一个,因此您可以根据第一个字节确定消息的类型。 例: 另一

  • 我需要使用Jackson解析字符串数组(标识符)。我在互联网上没有找到任何例子,所有的例子都展示了如何反序列化某个类的对象数组,但我只需要解析一个字符串数组(不需要为它编写模型类),我该怎么做呢?JSON示例:

  • 问题内容: 我如何提取字符串[]或arraylist中的所有元素,并以适当的格式(所有空格之间使用单个空格)组合所有单词并存储在数组中。 输出:Java很酷。 问题答案: 使用。 或使用Apache Commons Lang 。 或使用Java8的。

  • 问题内容: 如何在Android中解析Json字符串数组并将其保存在Java字符串数组中(例如:xy [])? 我要解析的Json: 稍后在我的代码中,我想用该数组填充布局中的微调项。我尝试过的所有内容都只包含微调框中列出的一个街头商品。 问题答案: 解析 一旦解析并将其添加到数组。使用相同的控件来填充微调框。 表示json数组节点 表示json对象节点

  • 问题内容: 在执行过程中,您将json解组为结构。问题是我有一个api,可能会在请求之间更改键值的类型。 例如,可能是内联对象的对象如下: 而且还可以通过键指向对象,如下所示: 可以内联某些对象,但是可以从多个位置引用其他对象。 在javascript或python中这不是问题。只需检查类型。 解组和解析这两个对象的惯用方式是什么?是反映的唯一方法吗? 问题答案: 您可以将此JSON解组为如下结构

  • 我当前的项目使用Kotlin序列化来使用一系列远程RESTFul API。 API响应是Json,我无法修改它们。 其中一个API将“Person”作为字符串或字符串数组返回。 我如何让Kotlin序列化自动消耗任何一个值? 我使用这个版本的静态编程语言序列化