我正试图解组该文件:
{
"@babel/code-frame@7.0.0": {
"licenses": "MIT",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-code-frame",
"publisher": "Sebastian McKenzie",
"email": "sebmck@gmail.com",
"path": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/@babel/code-frame",
"licenseFile": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/@babel/code-frame/LICENSE"
},
"json-schema@0.2.3": {
"licenses": [
"AFLv2.1",
"BSD"
],
"repository": "https://github.com/kriszyp/json-schema",
"publisher": "Kris Zyp",
"path": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/json-schema",
"licenseFile": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/json-schema/README.md"
}
}
进入此结构:
type Dependency struct {
Name string
URL string
Version string
License string
}
使用以下说明:
dependencies := map[string]*json.RawMessage{}
err = json.Unmarshal(file, &dependencies)
// boilerplate
for key, value := range dependencies {
depVal := map[string]string{}
err = json.Unmarshal(*value, &depVal)
// boilerplate
result = append(result, depVal)
}
这个问题是,在“ json-schema@0.2.3”中,我们有一个许可证数组而不是一个字符串,因此,我显然得到了
json: cannot unmarshal array into Go value of type string
是否有一种自动处理字段license
的方法,该字段可以是数组或字符串?
谢谢
答案 0 :(得分:2)
不幸的是,json
软件包没有为此提供真正的自动解决方案。
但是您可以取消对map[string]*json.RawMessage
而不是map[string]string
的依赖项的封送。 json.RawMessage
只是一个[]byte
,因此您可以根据第一个字节确定消息的类型。
示例:
for _, value := range dependencies {
depVal := map[string]*json.RawMessage{}
_ = json.Unmarshal(*value, &depVal)
// check if the first character of the RawMessage is a bracket
if rune([]byte(*depVal["licenses"])[0]) == '[' {
var licenses []string
json.Unmarshal(*depVal["licenses"], &licenses)
fmt.Println(licenses)
// do something with the array
}
result = append(result, Dependency{
URL: string(*depVal["repository"]),
License: string(*depVal["licenses"]),
})
}
另一个解决方案是使用2个结构。一个以字符串形式包含依赖关系,另一个以数组形式包含依赖关系。然后,您可以尝试同时调用它们上的json.Unmarshal
。
示例:
type Dependency struct {
Licenses string
// other fields
}
type DependencyWithArr struct {
Licenses []string
// other fields
}
// in your function
for _, value := range dependencies {
type1 := Dependency{}
type2 := DependencyWithArr{}
err = json.Unmarshal(*value, &type1)
if err != nil {
err = json.Unmarshal(*value, &type2)
// use the array type
} else {
// use the single string type
}
}