2

是否有一种标准方法可以将属性指定为字典或以字符串为键的映射,其值类型为 T 在架构中的其他位置指定?

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

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

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

4

3 回答 3

5

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

看到这一点的最好方法是找到一些例子。碰巧在draft04模式本身中有几个这样的例子(定义属性、模式属性,...),它们通常遵循相同的模式。

例如,draft04 模式的定义属性定义了模式中应该出现的定义属性。这是与定义 属性关联的子模式:

"definitions": {
    "type": "object",
    "additionalProperties": { "$ref": "#" },
    "default": {}
},

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

std::map< std::string, Schema > definitions;

实际上,可以将具有字符串键的映射视为具有结构化值类型的 json 对象。因此,要创建自己的:

std::map< std::string, T >
  • 首先定义 T 的模式。例如:

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

     "definitions" : {
       "movie" : {
           "additionalProperties" : false,
           "properties": {
              "title" : { "type" : "string" },
              "year_made" : { "type" : "integer" },
              "rating" : { "type" : "integer" }
           }
        }
     }
    
  • 还要确定您是否真的需要所有属性都存在才能使电影有效。如果是这样,请添加一个必需的条目。

    "definitions" : {
      "movie" : {
        "additionalProperties": false,
        "required" : [ "title", "year_made", "rating" ],
        "properties": {
          "title" : { "type" : "string" },
          "year_made" : { "type" : "integer" },
          "rating" : { "type" : "integer" }
      }
    },
    
  • 现在定义了电影的形状T。为引用电影模式的电影集合或映射创建定义,如草案模式中的定义所做的那样。注意:“movie_map”中的additionalProperties与“movie”的含义不同。在“电影”的情况下,它是一个布尔值false ,表示除了 properties 中列出的内容之外没有其他 属性。在“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": {}
        }
      }
    }
    
  • 现在在模式中的某处使用定义的模式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": {}
        }
      }
    }
    

这是一个示例对象,可以被认为是一个map,它是针对模式进行验证的电影:

{
  "movies" : {
    "the mission" : {
      "title":"The Mission",
      "year_made":1986,
      "rating":5
    },
    "troll 2" : {
      "title":"Troll 2",
      "year_made":1990,
      "rating":2
    }
  }
}

在此处输入图像描述

于 2013-08-30T14:43:07.133 回答
1

如果我想为用户最喜欢的电影建模一个结构(提醒 Json Schema 用于结构验证),我会做这样的事情:

{
"description":"moviesFan",
"properties": [
    "favoriteMovies": {
        "type":"array",
        "uniqueItems":True
        "allOf": [{ "$ref": "#/definitions/movie" }]
    }
],
"definitions": {
    "movie": {
        "type": "object",
        "properties": {
            "yearMade": {}
            ...
        }
    }
}

这对你有意义吗?

于 2013-08-22T07:15:21.783 回答
0

这是我支持地图的方式。希望有所帮助。

    {
      “类型”:“对象”,
      "title": "地图数据",
      “必需的”: [
        “地图”
      ],
      “特性”: {
        “sOnePurRecord”:{
          “标题”:“地图”,
          “附加属性”:假,
          “特性”: {
            “地图项”:{
              “类型”:“对象”,
              “最大属性”:10,
              “最小属性”:1,
              “模式属性”:{
                "^[a-zA-Z0-9]{5,20}$": {
                  "$ref": "#/定义/值"
                }
              },
              “附加属性”:{
                "$ref": "#/定义/值"
              }
            }
          },
          “必需的”: [
            “地图项”
          ]
        }
      },
      “定义”:{
        “价值”: {
          “类型”:“对象”,
          “特性”: {
            “姓名”: {
              “类型”:“字符串”
            },
            “ID”: {
              “类型”:“整数”
            }
          }
        }
      }
    }

于 2016-10-11T10:04:49.203 回答