代码之家  ›  专栏  ›  技术社区  ›  aronchick

根据名称在JSON模式中搜索JSON对象并获取路径

go
  •  1
  • aronchick  · 技术社区  · 3 年前

    我使用JSON模式,并使用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"
            },
          },
        }
      }
    }
    

    我想做的是用程序找到一个给定字段(在本例中为“引擎”)的路径。这样我就可以列出所有需要更改的对象(它们都需要以相同的方式更改),并在数组中循环遍历它们。所以像这样的东西(今天有效)。

    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
    }
    

    我正在使用优秀的sjson库来实现这一点。 https://github.com/tidwall/sjson

    总之,我真正想做的是,只需要一个数组 ["Engine", "Verifier", ...] 并使用工具搜索整个结构并返回路径(如果多个内容匹配,则返回路径)。

    1 回复  |  直到 3 年前
        1
  •  1
  •   045    3 年前

    老实说,你似乎把任务搞得过于复杂了。使用反射是 很少是解决任何问题的正确方法,相反,你可以使用 Gron。以下是PowerShell:

    > gron schema.json | Select-String engine
    json.$defs.Spec.properties.Engine = {};
    json.$defs.Spec.properties.Engine.type = "integer";
    

    或POSIX外壳:

    gron schema.json | grep engine
    

    https://github.com/tomnomnom/gron