根据名称在基于名称的 JSON 模式中搜索 JSON 对象,并获取路径。

huangapple go评论86阅读模式
英文:

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

https://github.com/tomnomnom/gron

huangapple
  • 本文由 发表于 2022年9月29日 06:08:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/73888305.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定