在json模式中支持std :: map <std :: string,T>

use*_*952 2 json jsonschema

是否有标准方法将属性指定为字符串或由字符串键控的映射,并在模式中的其他位置指定值类型T?

例如,假设您要为用户最喜欢的电影建模,其中键类型是电影的名称,值类型是关于电影的一些属性集(年份,预算,总收入等)

我想你可以首先将MovieDataPair建模为具有name属性的类型和包含所需属性的value属性.然后地图就是那些数组.但是,那么你需要一个特殊的唯一约束来确保任何电影名称只出现一次.

是否有json架构中的某些东西支持这个,或者用于它的标准模式?如果没有在json架构中内置支持,那么其他架构解决方案呢?

use*_*952 5

经过一番研究,我得出以下答案:

查看此操作的最佳方法是查找一些示例.碰巧在draft04模式本身(定义,属性,patternProperties,...)中有几个例子,它们通常遵循相同的模式.

例如,定义了draft04架构的属性定义应该出现在该架构是什么定义属性.以下是与定义 属性关联的子模式:

"definitions": {
    "type": "object",
    "additionalProperties": { "$ref": "#" },
    "default": {}
},
Run Code Online (Sandbox Code Playgroud)

这表示"#/ definitions /"的条目必须是一个对象.它是一个json对象的事实意味着它本身将拥有唯一的键.现在,对于对象中的,这就是additionalProperties旨在描述的内容.在这种情况下,它表示每个属性的值本身必须符合模式"#"的根.这意味着有效json模式对象的definitions属性对象中的每个值也必须是模式.如果输入类似于C++,它可能看起来像:

std::map< std::string, Schema > definitions;
Run Code Online (Sandbox Code Playgroud)

实际上,带有字符串键的映射可以被视为具有结构化值类型的json对象.所以,创建自己的:

std::map< std::string, T >
Run Code Online (Sandbox Code Playgroud)
  • 首先为T定义模式.例如:

    "definitions" : {
       "movie" : {
           "properties": {
              "title" : { "type" : "string" },
              "year_made" : { "type" : "integer" },
              "rating" : { "type" : "integer" }
           }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于存储的值类型T,确定是否要允许任何属性,只要按上面指定的方式键入这些指定的属性即可.如果您只想要这些属性,请添加 "additionalProperties":false

     "definitions" : {
       "movie" : {
           "additionalProperties" : false,
           "properties": {
              "title" : { "type" : "string" },
              "year_made" : { "type" : "integer" },
              "rating" : { "type" : "integer" }
           }
        }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  • 还要确定您是否确实需要所有属性才能使电影有效.如果是,请添加必填项.

    "definitions" : {
      "movie" : {
        "additionalProperties": false,
        "required" : [ "title", "year_made", "rating" ],
        "properties": {
          "title" : { "type" : "string" },
          "year_made" : { "type" : "integer" },
          "rating" : { "type" : "integer" }
      }
    },
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在定义了电影的形状 T. 为集合创建定义,或者引用电影架构的电影地图定义为草图架构中的定义.注意:在"movie_map"中,additionalProperties具有与"movie"不同的含义.在"movie"的情况下,它是一个布尔值false ,表示除了属性中列出的属性之外没有其他 属性.在"movie_map"的情况下,它意味着 - 如果有其他属性,它们必须看起来像这个模式.但是,由于在movie_map中没有指定任何属性,它实际上意味着对象实例中的所有属性必须符合#/ definitions/movie.现在,"movie_map"中的所有值都将看起来像定义的电影架构.

    {
      "definitions" : {
        "movie" : {
          "additionalProperties": false,
          "required" : [ "title", "year_made", "rating" ],
          "properties": {
            "title" : { "type" : "string" },
            "year_made" : { "type" : "integer" },
            "rating" : { "type" : "integer" }
          }
        },
        "movie_map" : {
          "type": "object",
          "additionalProperties": { "$ref": "#/definitions/movie" },
          "default": {}
        }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在在模式中的某处使用已定义的模式movie_map:

    {
      "title" : "movie data",
      "additionalProperties" : false,
      "required" : [ "movies" ],
      "properties" : {
        "movies" : { "$ref" : "#/definitions/movie_map" }
      },
      "definitions" : {
        "movie" : {
          "additionalProperties": false,
          "required" : [ "title", "year_made", "rating" ],
          "properties": {
            "title" : { "type" : "string" },
            "year_made" : { "type" : "integer" },
            "rating" : { "type" : "integer" }
          }
        },
        "movie_map" : {
          "type": "object",
          "additionalProperties": { "$ref": "#/definitions/movie" },
          "default": {}
        }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这是一个示例对象,可以将其视为地图,用于验证模式的电影:

{
  "movies" : {
    "the mission" : {
      "title":"The Mission",
      "year_made":1986,
      "rating":5
    },
    "troll 2" : {
      "title":"Troll 2",
      "year_made":1990,
      "rating":2
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述