json - 动态结构定义
问题描述
我有一个用例,我将一些 json 文件转换为 Go 结构。我有以下文档结构
{
"contentVersion": "1.0.0.0",
"paths" : [
{
"ParameterReference": "someValue",
},
{
"ParameterReference": "someOtherValue",
}
],
"parameters": {
"label": { "value": "label" },
"domainName": { "value": "domain" },
"servicePackageLink": { "value": "bin\\test.cspkg" },
"pfxContent": { "value": "SampleCert.Content" },
"sampleCertThumbprint": {"value": "SampleCert.Thumbprint"},
"anotherSampleCertContent":{ "value" : "AnotherSampleCert.Content" },
"anotherSampleCertThumbprint": {"value": "AnotherSampleCert.Thumbprint"}
},
"secrets" :[
{
"TargetReference":"SERviceConfiGURatiONLiNK",
"Replacements":
{
"__Secret_Sample__" :
{
"SecretId":"secretID",
"EncryptWith" :"encryptWithValue"
},
"__Another_Secret_Sample__" :
{
"SecretId":"anotherSecretValue",
"EncryptWith" :"anotherEncryptWithValue"
},
"__Storage_ConnectionString__" : "someConnectionString"
},
},
{
"TargetReference":"None",
"Certificates":[
{
"Name":"AnotherSampleCert",
"ContentReference" : "contentReference"
}
]
}
]
}
我面临的问题是 json 没有固定的模式,例如。
- 如果您检查
parameters
对象,特别是名称为 的条目sampleCertSchema
,在我的用例中,用户可以提供从 0 到 N 的任意数量的此类____CertSchemas值。因此,参数字段也可以如下
"parameters": {
"label": { "value": "label" },
"domainName": { "value": "domain" },
"servicePackageLink": { "value": "bin\\test.cspkg" },
"pfxContent": { "value": "SampleCert.Content" }
},
- 另一个例子是
secrets.Replacements
对象。单个替换对象的名称可以是任何形式的正则表达式/^[ A-Za-z0-9_@./#&+-]*$/
,这也是一个动态数组,如parameters
第一点中提到的字段。因此,另一个可能的值可以是
"Replacements":
{
"__Secret_Sample__" :
{
"SecretId":"secretID",
"EncryptWith" :"encryptWithValue"
},
"__Storage_ConnectionString__" : "someConnectionString"
},
- 使用 field
paths
,我可以是一个对象数组或只是一个字符串数组。例如,除了上面的格式,还可以是
"paths": [
"servicePackageLink",
"serviceConfigurationLink"
]
使用 C#/Java,我可以使用Object
该类创建一个文档来处理这些未知的动态对象名称和条目。使用 Go,我尝试定义以下结构
type pathDefinition struct {
ParameterReference string `json:"parameterReference"`
EnableHealthDimensions bool `json:"enableHealthDimensions"`
}
type parameterValue struct {
Values map[string]interface{}
}
type replacements struct {
SecretValueMap map[string]interface{} `json:"secretValueMap"`
}
type resourceCertificate struct {
Name string `json:"name"`
ContentReference string `json:"contentReference"`
PasswordReference string `json:"passwordReference"`
Content string `json:"content"`
Password string `json:"password"`
Thumbprint string `json:"thumbprint"`
SubjectName string `json:"subjectName"`
}
type resourceSecrets struct {
TargetReference string `json:"targetReference"`
Replacements replacements `json:"replacements"`
Certificates resourceCertificate `json:"certificates"`
}
type ResouceParameters struct {
Schema string `json:"$schema"`
ContentVersion string `json:"contentVersion"`
Paths interface{}
Parameters map[string]parameterValue `json:"parameters"`
Secrets resourceSecrets `json:"secrets"`
Others map[string]interface{} `json:"others"`
}
使用此定义,我无法将文件数据解组为ResouceParameters
结构变量。以下是我解组的方式
file, _ := os.Open("path/to/parameters.json")
defer file.Close()
byteValue, _ := ioutil.ReadAll(file)
fileData := new(ResouceParameters)
err := json.Unmarshal([]byte(byteValue), &fileData)
if err != nil {
fmt.Println(err)
}
fmt.Println(fileData)
这将打印一个空结构。我的问题是,我应该如何在 Go 中定义一个结构,以便它能够加载一个带有非预定义条目的 json。使用 java/C# 我可以使用Object
该类并创建一个文档,但我无法理解使用 Go 来执行此操作。
解决方案
go 中的等价物是 interface{},即空接口。例如,查看这个答案:Unmarshaling Into an Interface{} and Then Performing Type Assertion
一旦您知道要搜索的术语,您应该能够在需要时搜索更详细的内容。
推荐阅读
- json - 如何使用 JSON 数据对象在 Postman 中上传 Mltipart 文件
- c++ - C++17:通用(基于多重继承?)检查参数包中的模板
- excel - 如何使用 VBA 从网站中提取嵌套 div 中的信息?
- swift - 向领域迅速添加可编码模型
- node.js - 如何使用带有 odata.PUT 的 HTTP REQUEST PUT 来更新数据库条目?
- java - MPAndroidChart:给 Y 轴一些偏移量
- swift - Swift 图表 - 突出显示中心点
- gremlin - 如何区分 gremlin 中的选择和添加/更新查询?
- sql - 由于检索到的列名,网格视图不接受我的数据绑定,或者可能是我的错误
- javascript - nodejs对ajax的响应不在同一页面上打印