英文:
Searching for a JSON Object in a JSON Schema based on the name and getting the Path
问题
我正在使用JSON Schema,并使用gojsonschema自动生成它。不幸的是,它对几个字段的处理有误,我想要修复它们。
以下是模式:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/filecoin-project/bacalhau/pkg/model/job",
"$ref": "#/$defs/Job",
"$defs": {
"Deal": {
"properties": {
"Concurrency": {
"type": "integer"
},
"Confidence": {
"type": "integer"
},
"MinBids": {
"type": "integer"
}
},
"additionalProperties": false,
"type": "object"
},
"Spec": {
"properties": {
"Engine": {
"type": "integer"
},
"Verifier": {
"type": "integer"
}
}
}
}
}
我想要做的是以编程方式找到给定字段(在本例中为"Engine")的路径。这样我就可以列出所有需要更改的对象(它们都需要以相同的方式更改),并在数组中循环遍历它们。所以类似这样的代码(目前有效)。
func FixJSONSchema() ([]byte, error) {
s := jsonschema.Reflect(&model.Job{})
jsonSchemaData, err := json.MarshalIndent(s, "", " ")
if err != nil {
return nil, fmt.Errorf("error indenting %s", err)
}
// JSON字符串
jsonString := string(jsonSchemaData)
enumTypes := []struct {
Name string
Path string
}{
{Name: "Engine", Path: "$defs.Spec.properties.Engine.type"},
{Name: "Verifier", Path: "$defs.Spec.properties.Verifier.type"},
}
for _, enumType := range enumTypes {
// 使用sjson在JSON中查找枚举类型的路径
jsonString, _ = sjson.Set(jsonString, enumType.Path, "string")
}
return []byte(jsonString), nil
}
我正在使用出色的sjson库来实现这一点。https://github.com/tidwall/sjson
因此,总结起来,我真正想做的是只有一个数组["Engine", "Verifier", ...]
,并使用工具搜索整个结构并返回路径(如果有多个匹配项,则返回多个路径)。
英文:
I'm using JSON Schema and auto generating it using gojsonschema. Unfortunately, it's getting several of the fields wrong, and I want to fix them.
Here is the schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/filecoin-project/bacalhau/pkg/model/job",
"$ref": "#/$defs/Job",
"$defs": {
"Deal": {
"properties": {
"Concurrency": {
"type": "integer"
},
"Confidence": {
"type": "integer"
},
"MinBids": {
"type": "integer"
}
},
"additionalProperties": false,
"type": "object"
},
"Spec": {
"properties": {
"Engine": {
"type": "integer"
},
"Verifier": {
"type": "integer"
},
},
}
}
}
What I'd like to do is find the path to a given field (in this case "Engine") programatically. This is so I can just list all the objects that need changing (they all need changing in the same way), and loop through them in an array. So something like this (which works today).
func FixJSONSchema() ([]byte, error) {
s := jsonschema.Reflect(&model.Job{})
jsonSchemaData, err := json.MarshalIndent(s, "", " ")
if err != nil {
return nil, fmt.Errorf("error indenting %s", err)
}
// JSON String
jsonString := string(jsonSchemaData)
enumTypes := []struct {
Name string
Path string
}{
{Name: "Engine", Path: "$defs.Spec.properties.Engine.type"},
{Name: "Verifier", Path: "$defs.Spec.properties.Verifier.type"},
}
for _, enumType := range enumTypes {
// Use sjson to find the enum type path in the JSON
jsonString, _ = sjson.Set(jsonString, enumType.Path, "string")
}
return []byte(jsonString), nil
}
I'm using the excellent sjson library to accomplish this. https://github.com/tidwall/sjson
So, in summary, what I'd really prefer to do, is just have an array ["Engine", "Verifier", ...]
and use a tool to search the entire structure and return the path (or paths if multiple things match).
答案1
得分: 2
老实说,你似乎把任务复杂化了。使用反射(reflect)很少是解决问题的正确方法,相反,你可以使用类似 Gron 的工具。以下是使用 PowerShell 的示例:
> gron schema.json | Select-String engine
json.$defs.Spec.properties.Engine = {};
json.$defs.Spec.properties.Engine.type = "integer";
或者使用 POSIX shell:
gron schema.json | grep engine
https://github.com/tomnomnom/gron
英文:
Honestly it seems like you are over-complicating the task. Using reflect is
rarely the right solution to any problem, instead you could use something like
Gron. Here it is with PowerShell:
> gron schema.json | Select-String engine
json.$defs.Spec.properties.Engine = {};
json.$defs.Spec.properties.Engine.type = "integer";
or POSIX shell:
gron schema.json | grep engine
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论