如何(如果可能的话)在JSON模式中定义一个数组项属性应该是唯一的?

时间:2014-07-15 16:45:58

标签: json jsonschema

鉴于以下JSON模式,可以指示“name”属性应该是唯一的(即,“elements”数组中不应该有两个具有相同“name”的项。

{
    "root":{
        "type":"object",
        "properties": {
            "elements": {
                "type":"array",
                "minItems": 1,
                "items":{
                    "type":"object",
                    "properties":{
                        "name": {
                            "type":"string",
                            "title":"Element Name",
                            "minLength":3,
                        },
                        "url": {
                            "type":"string",
                            "title":"Some URL"
                        }
                    }
                }
            }
        }
    }
}

我尝试使用uniqueItems关键字,但它似乎是为简单的值列表而设计的。

4 个答案:

答案 0 :(得分:20)

不,这是不可能的。从文档中,json-schema:...一种基于JSON的格式,用于定义JSON数据的结构。

进行数据值验证非常有限,因为它不是标准的目的。许多人之前已经问过这个问题,因为通常会要求一种“唯一ID”功能。不幸的是,对于那些需要它的人来说,json-schema并没有为你提供。

因此,如果您想确保唯一性,您唯一的选择是将“name”作为属性键而不是属性值。

答案 1 :(得分:6)

如果重构数据结构是一种选择,则以下方法可能会有所帮助:

  • 用地图替换数组。这可以通过使用patternProperties的对象轻松实现。模式是正则表达式。匹配模式的任何对象都将根据pattern-property的模式进行验证。匹配任何字符串> = 3个字符的模式如下所示:"....*",但似乎始终暗示尾随".*",因此"..."也可以。
  • 添加additionalProperties:false是强制执行约束的另一步骤(minLength:3)。
  • 要在地图中强制实施至少一个元素(您的数组使用minItems:1),请将minItems替换为minProperties

...产生下面的架构:

"root": {
  "type": "object", 
  "properties": {
    "elements": {
      "type": "object", 
      "patternProperties": {
        "...": {
          "type": "object", 
          "properties": {
            "url": {
              "type": "string"
            }
          }
        }
      }, 
      "additionalProperties": false, 
      "minProperties": 1
    }
  }
}

如果以下文档(摘录)与您的旧架构匹配,

"elements": [
  {
    "name": "abc", 
    "url": "http://myurl1"
  }, 
  {
    "name": "def", 
    "url": "http://myurl2"
  }, 
  {
    "name": "ghij", 
    "url": "http://myurlx"
  }
]

......像这样的文件(摘录)将匹配新的架构:

"elements": {
  "abc": {
    "url": "http://myurl1"
  }, 
  "def": {
    "url": "http://myurl2"
  }, 
  "ghij": {
    "url": "http://myurlx"
  }
}

答案 2 :(得分:1)

对于 Ajv 验证器,您可以使用自定义 JSON-Schema 关键字 uniqueItemPropertiesajv-validator/ajv-keywords

答案 3 :(得分:0)

如果用例可以处理增加的开销,则可以对文档进行转换以生成精简文档,然后对精简文档使用单独的小型模式再次应用验证。

以下是有关Json转换工具信息的一些链接:

在JSONata中处理示例案例非常简单。