dqdfpmmi022763 2015-11-12 03:22
浏览 152
已采纳

我可以修改json.RawMessage吗?

This is a follow up to JSON sometimes array sometimes object

In the original question, I asked how to deal with: "I am consuming a json API that might return a string for a variable or might return an array for a variable"

I have a solution but I was wondering, is there a way to modify json.RawMessage?

Rather then if/then looking at the RawMessage for a [ or { char to determine if the object is an array or an string, what if I always took a RawMessage variable string and turned it into an array?

This way, I don't have to code all of the accessors for BOTH strings AND arrays. I could simply deal with arrays.

So my question is: Is there a way to modify the json.RawMessage?

eg:

Turn this:

{ 
  "net": {
    "comment": {
        "line":
            {
                "$": "All abuse issues will only be responded to by the Abuse",
                "@number": "0"
            }
    }
}

Into This:

{ 
  "net": {
    "comment": {
        "line": [
            {
                "$": "All abuse issues will only be responded to by the Abuse",
                "@number": "0"
            }
        ]
    }
}

So, that way, when I unmarshal into my struct, there is only 1 type of comment.line, Just line[] vs line[] AND line.

Thanks in advance.

I am a golang neophyte and I'm just getting my head wrapped around the difficulties of unmarshaling into an strongly typed language.

  • 写回答

2条回答 默认 最新

  • douhu1990 2015-11-12 04:52
    关注

    Yes, you can edit json.RawMessage type as it is simply an alias for []byte.

    That said, you don't need to keep raw type, just make your own implementation of the array type and in your custom Unmarshal function, make scalars an array.

    Here's an example (on Play).

    All we do here is see if the bytes for MagicArray starts with '[', if so, just unmarshal as normal. Otherwise, Unmarshal and append to slice.

    you will have to implement custom array for each type you want to work like this, but that's still probably better than trying to safely manipulate the json binary to try coerce the scalars into arrays.

    Another side benefit to this approach is you can it with the streaming json decoder, as in json.NewDecoder(reader).Decode(&obj)

    package main
    
    import "encoding/json"
    import "log"
    
    type MagicArray []interface{}
    
    func (ma *MagicArray) UnmarshalJSON(b []byte) error {
        if b[0] == '[' {
            return json.Unmarshal(b, (*[]interface{})(ma))
        } else {
            var obj interface{}
            if err := json.Unmarshal(b, &obj); err != nil {
                return err
            }
            *ma = append(*ma, obj)
        }
        return nil
    }
    func main() {
        myStruct := struct {
            A MagicArray
            B MagicArray
        }{}
    
        err := json.Unmarshal(jsonToDecode, &myStruct)
        if err != nil {
            log.Println("Fail:", err)
        } else {
            log.Println(myStruct)
        }
    }
    
    var jsonToDecode = []byte(`
        { 
        "A": "I am not an array", 
        "B":["I am an array"]
        }
    `)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据