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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里